?? cssparser.cpp
字號:
/*
* This file is part of the DOM implementation for KDE.
*
* Copyright (C) 2003 Lars Knoll (knoll@kde.org)
* Copyright (C) 2004 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
// #define CSS_DEBUG
// #define TOKEN_DEBUG
#define YYDEBUG 0
#include <kdebug.h>
#include <kurl.h>
#include "cssparser.h"
#include "css_valueimpl.h"
#include "css_ruleimpl.h"
#include "css_stylesheetimpl.h"
#include "cssproperties.h"
#include "cssvalues.h"
#include "misc/helper.h"
#include "xml/dom_docimpl.h"
#include "csshelper.h"
using namespace DOM;
#include <stdlib.h>
#if APPLE_CHANGES
void qFatal ( const char * msg ) {}
#endif
#ifdef __OOM__
#include <allocs.h>
#endif
ValueList::ValueList()
{
values = (Value *) malloc( 16 * sizeof ( Value ) );
numValues = 0;
currentValue = 0;
maxValues = 16;
}
ValueList::~ValueList()
{
for ( int i = 0; i < numValues; i++ ) {
#ifdef CSS_DEBUG
kdDebug( 6080 ) << " value: (unit=" << values[i].unit <<")"<< endl;
#endif
if ( values[i].unit == Value::Function )
delete values[i].function;
}
free( values );
}
void ValueList::addValue( const Value &val )
{
if ( numValues >= maxValues ) {
maxValues += 16;
values = (Value *) realloc( values, maxValues*sizeof( Value ) );
}
values[numValues++] = val;
}
using namespace DOM;
#if YYDEBUG > 0
extern int cssyydebug;
#endif
extern int cssyyparse( void * parser );
CSSParser *CSSParser::currentParser = 0;
CSSParser::CSSParser( bool strictParsing )
{
#ifdef CSS_DEBUG
kdDebug( 6080 ) << "CSSParser::CSSParser this=" << this << endl;
#endif
strict = strictParsing;
parsedProperties = (CSSProperty **) malloc( 32 * sizeof( CSSProperty * ) );
numParsedProperties = 0;
maxParsedProperties = 32;
data = 0;
valueList = 0;
rule = 0;
id = 0;
important = false;
inParseShortHand = false;
defaultNamespace = anyNamespace;
yy_start = 1;
#if YYDEBUG > 0
cssyydebug = 1;
#endif
}
CSSParser::~CSSParser()
{
if ( numParsedProperties )
clearProperties();
free( parsedProperties );
delete valueList;
#ifdef CSS_DEBUG
kdDebug( 6080 ) << "CSSParser::~CSSParser this=" << this << endl;
#endif
free( data );
}
void ParseString::lower()
{
for (int i = 0; i < length; i++)
string[i] = QChar(string[i]).lower().unicode();
}
void CSSParser::setupParser(const char *prefix, const DOMString &string, const char *suffix)
{
int length = string.length() + strlen(prefix) + strlen(suffix) + 2;
data = (unsigned short *)malloc( length *sizeof( unsigned short ) );
for ( unsigned int i = 0; i < strlen(prefix); i++ )
data[i] = prefix[i];
memcpy( data + strlen( prefix ), string.unicode(), string.length()*sizeof( unsigned short) );
unsigned int start = strlen( prefix ) + string.length();
unsigned int end = start + strlen(suffix);
for ( unsigned int i = start; i < end; i++ )
data[i] = suffix[i-start];
data[length-1] = 0;
data[length-2] = 0;
yy_hold_char = 0;
yyleng = 0;
yytext = yy_c_buf_p = data;
yy_hold_char = *yy_c_buf_p;
}
void CSSParser::parseSheet( CSSStyleSheetImpl *sheet, const DOMString &string )
{
styleElement = sheet;
defaultNamespace = anyNamespace; // Reset the default namespace.
setupParser ("", string, "");
#ifdef CSS_DEBUG
kdDebug( 6080 ) << ">>>>>>> start parsing style sheet" << endl;
#endif
CSSParser *old = currentParser;
currentParser = this;
cssyyparse( this );
currentParser = old;
#ifdef CSS_DEBUG
kdDebug( 6080 ) << "<<<<<<< done parsing style sheet" << endl;
#endif
delete rule;
rule = 0;
}
CSSRuleImpl *CSSParser::parseRule( DOM::CSSStyleSheetImpl *sheet, const DOM::DOMString &string )
{
styleElement = sheet;
setupParser ("@-khtml-rule{", string, "} ");
CSSParser *old = currentParser;
currentParser = this;
cssyyparse( this );
currentParser = old;
CSSRuleImpl *result = rule;
rule = 0;
return result;
}
bool CSSParser::parseValue( CSSMutableStyleDeclarationImpl *declaration, int _id, const DOMString &string,
bool _important)
{
#ifdef CSS_DEBUG
kdDebug( 6080 ) << "CSSParser::parseValue: id=" << _id << " important=" << _important
<< " value='" << string.string() << "'" << endl;
#endif
styleElement = declaration->stylesheet();
setupParser ("@-khtml-value{", string, "} ");
id = _id;
important = _important;
CSSParser *old = currentParser;
currentParser = this;
cssyyparse( this );
currentParser = old;
delete rule;
rule = 0;
bool ok = false;
if ( numParsedProperties ) {
ok = true;
declaration->addParsedProperties(parsedProperties, numParsedProperties);
clearProperties();
}
return ok;
}
QRgb CSSParser::parseColor( const DOM::DOMString &string )
{
QRgb color = 0;
CSSMutableStyleDeclarationImpl *dummyStyleDeclaration = new CSSMutableStyleDeclarationImpl;
dummyStyleDeclaration->ref();
DOM::CSSParser parser(true);
// First try creating a color specified by name or the "#" syntax.
if (!parser.parseColor(string.string(), color)) {
// Now try to create a color from the rgb() or rgba() syntax.
bool ok = parser.parseColor(dummyStyleDeclaration, string);
if ( ok ) {
CSSValueImpl *value = parser.parsedProperties[0]->value();
if (value->cssValueType() == DOM::CSSValue::CSS_PRIMITIVE_VALUE) {
DOM::CSSPrimitiveValueImpl *primitiveValue = static_cast<DOM::CSSPrimitiveValueImpl *>(value);
color = primitiveValue->getRGBColorValue();
}
}
}
dummyStyleDeclaration->deref();
return color;
}
bool CSSParser::parseColor( CSSMutableStyleDeclarationImpl *declaration, const DOMString &string )
{
styleElement = declaration->stylesheet();
setupParser ( "@-khtml-decls{color:", string, "} ");
CSSParser *old = currentParser;
currentParser = this;
cssyyparse( this );
currentParser = old;
delete rule;
rule = 0;
bool ok = false;
if ( numParsedProperties && parsedProperties[0]->m_id == CSS_PROP_COLOR) {
ok = true;
}
return ok;
}
bool CSSParser::parseDeclaration( CSSMutableStyleDeclarationImpl *declaration, const DOMString &string )
{
#ifdef CSS_DEBUG
kdDebug( 6080 ) << "CSSParser::parseDeclaration:value='" << string.string() << "'" << endl;
#endif
styleElement = declaration->stylesheet();
setupParser ( "@-khtml-decls{", string, "} ");
CSSParser *old = currentParser;
currentParser = this;
cssyyparse( this );
currentParser = old;
delete rule;
rule = 0;
bool ok = false;
if ( numParsedProperties ) {
ok = true;
declaration->addParsedProperties(parsedProperties, numParsedProperties);
clearProperties();
}
return ok;
}
void CSSParser::addProperty( int propId, CSSValueImpl *value, bool important )
{
CSSProperty *prop = new CSSProperty;
prop->m_id = propId;
prop->setValue( value );
prop->m_bImportant = important;
if ( numParsedProperties >= maxParsedProperties ) {
maxParsedProperties += 32;
parsedProperties = (CSSProperty **) realloc( parsedProperties,
maxParsedProperties*sizeof( CSSProperty * ) );
}
parsedProperties[numParsedProperties++] = prop;
}
CSSMutableStyleDeclarationImpl *CSSParser::createStyleDeclaration( CSSStyleRuleImpl *rule )
{
CSSMutableStyleDeclarationImpl *result = new CSSMutableStyleDeclarationImpl(rule, parsedProperties, numParsedProperties);
clearProperties();
return result;
}
void CSSParser::clearProperties()
{
for ( int i = 0; i < numParsedProperties; i++ )
delete parsedProperties[i];
numParsedProperties = 0;
}
DOM::DocumentImpl *CSSParser::document() const
{
StyleBaseImpl *root = styleElement;
DocumentImpl *doc = 0;
while (root->parent())
root = root->parent();
if (root->isCSSStyleSheet())
doc = static_cast<CSSStyleSheetImpl*>(root)->doc();
return doc;
}
// defines units allowed for a certain property, used in parseUnit
enum Units
{
FUnknown = 0x0000,
FInteger = 0x0001,
FNumber = 0x0002, // Real Numbers
FPercent = 0x0004,
FLength = 0x0008,
FAngle = 0x0010,
FTime = 0x0020,
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -