📄 cssparser.cpp
字号:
/* * This file is part of the DOM implementation for KDE. * * Copyright (C) 2003 Lars Knoll (knoll@kde.org) * * $Id: cssparser.cpp,v 1.2 2004/09/23 13:04:27 p3salmi Exp $ * * 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 "csshelper.h"using namespace DOM;#include <stdlib.h>#if APPLE_CHANGESvoid qFatal ( const char * msg ) {}#endifValueList::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 > 0extern int cssyydebug;#endifextern 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; 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::parseSheet( CSSStyleSheetImpl *sheet, const DOMString &string ){ styleElement = sheet; defaultNamespace = anyNamespace; // Reset the default namespace. int length = string.length() + 3; data = (unsigned short *)malloc( length *sizeof( unsigned short ) ); memcpy( data, string.unicode(), string.length()*sizeof( unsigned short) ); data[length-1] = 0; data[length-2] = 0; data[length-3] = ' '; yy_hold_char = 0; yyleng = 0; yytext = yy_c_buf_p = data; yy_hold_char = *yy_c_buf_p;#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; const char khtml_rule[] = "@-khtml-rule{"; int length = string.length() + 4 + strlen(khtml_rule); data = (unsigned short *)malloc( length *sizeof( unsigned short ) ); for ( unsigned int i = 0; i < strlen(khtml_rule); i++ ) data[i] = khtml_rule[i]; memcpy( data + strlen( khtml_rule ), string.unicode(), string.length()*sizeof( unsigned short) ); // qDebug("parse string = '%s'", QConstString( (const QChar *)data, length ).string().latin1() ); data[length-1] = 0; data[length-2] = 0; data[length-3] = ' '; data[length-4] = '}'; yy_hold_char = 0; yyleng = 0; yytext = yy_c_buf_p = data; yy_hold_char = *yy_c_buf_p; CSSParser *old = currentParser; currentParser = this; cssyyparse( this ); currentParser = old; CSSRuleImpl *result = rule; rule = 0; return result;}bool CSSParser::parseValue( DOM::CSSStyleDeclarationImpl *declaration, int _id, const DOM::DOMString &string, bool _important){#ifdef CSS_DEBUG kdDebug( 6080 ) << "CSSParser::parseValue: id=" << _id << " important=" << _important << " value='" << string.string() << "'" << endl;#endif styleElement = declaration->stylesheet(); const char khtml_value[] = "@-khtml-value{"; int length = string.length() + 4 + strlen(khtml_value); data = (unsigned short *)malloc( length *sizeof( unsigned short ) ); for ( unsigned int i = 0; i < strlen(khtml_value); i++ ) data[i] = khtml_value[i]; memcpy( data + strlen( khtml_value ), string.unicode(), string.length()*sizeof( unsigned short) ); data[length-1] = 0; data[length-2] = 0; data[length-3] = ' '; data[length-4] = '}'; // qDebug("parse string = '%s'", QConstString( (const QChar *)data, length ).string().latin1() ); yy_hold_char = 0; yyleng = 0; yytext = yy_c_buf_p = data; yy_hold_char = *yy_c_buf_p; id = _id; important = _important; CSSParser *old = currentParser; currentParser = this; cssyyparse( this ); currentParser = old; delete rule; rule = 0; bool ok = false; if ( numParsedProperties ) { ok = true; for ( int i = 0; i < numParsedProperties; i++ ) { declaration->removeProperty(parsedProperties[i]->m_id); declaration->values()->append( parsedProperties[i] ); } numParsedProperties = 0; } return ok;}bool CSSParser::parseDeclaration( DOM::CSSStyleDeclarationImpl *declaration, const DOM::DOMString &string ){#ifdef CSS_DEBUG kdDebug( 6080 ) << "CSSParser::parseDeclaration:value='" << string.string() << "'" << endl;#endif styleElement = declaration->stylesheet(); const char khtml_decls[] = "@-khtml-decls{"; int length = string.length() + 4 + strlen(khtml_decls); data = (unsigned short *)malloc( length *sizeof( unsigned short ) ); for ( unsigned int i = 0; i < strlen(khtml_decls); i++ ) data[i] = khtml_decls[i]; memcpy( data + strlen( khtml_decls ), string.unicode(), string.length()*sizeof( unsigned short) ); data[length-1] = 0; data[length-2] = 0; data[length-3] = ' '; data[length-4] = '}'; // qDebug("parse string = '%s'", QConstString( (const QChar *)data, length ).string().latin1() ); yy_hold_char = 0; yyleng = 0; yytext = yy_c_buf_p = data; yy_hold_char = *yy_c_buf_p; CSSParser *old = currentParser; currentParser = this; cssyyparse( this ); currentParser = old; delete rule; rule = 0; bool ok = false; if ( numParsedProperties ) { ok = true; for ( int i = 0; i < numParsedProperties; i++ ) { declaration->removeProperty(parsedProperties[i]->m_id); declaration->values()->append( parsedProperties[i] ); } numParsedProperties = 0; } 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;}CSSStyleDeclarationImpl *CSSParser::createStyleDeclaration( CSSStyleRuleImpl *rule ){ QPtrList<CSSProperty> *propList = new QPtrList<CSSProperty>; propList->setAutoDelete( true ); for ( int i = 0; i < numParsedProperties; i++ ) propList->append( parsedProperties[i] ); numParsedProperties = 0; return new CSSStyleDeclarationImpl(rule, propList);}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 parseUnitenum Units{ FUnknown = 0x0000, FInteger = 0x0001, FNumber = 0x0002, // Real Numbers FPercent = 0x0004, FLength = 0x0008, FAngle = 0x0010, FTime = 0x0020, FFrequency = 0x0040, FRelative = 0x0100, FNonNeg = 0x0200};static bool validUnit( Value *value, int unitflags, bool strict ){ if ( unitflags & FNonNeg && value->fValue < 0 ) return false; bool b = false; switch( value->unit ) { case CSSPrimitiveValue::CSS_NUMBER: b = (unitflags & FNumber); if ( !b && ( (unitflags & FLength) && (value->fValue == 0 || !strict ) ) ) { value->unit = CSSPrimitiveValue::CSS_PX; b = true; } if ( !b && ( unitflags & FInteger ) && (value->fValue - (int)value->fValue) < 0.001 ) b = true; break; case CSSPrimitiveValue::CSS_PERCENTAGE: b = (unitflags & FPercent); break; case Value::Q_EMS: case CSSPrimitiveValue::CSS_EMS: case CSSPrimitiveValue::CSS_EXS: case CSSPrimitiveValue::CSS_PX: case CSSPrimitiveValue::CSS_CM: case CSSPrimitiveValue::CSS_MM: case CSSPrimitiveValue::CSS_IN: case CSSPrimitiveValue::CSS_PT: case CSSPrimitiveValue::CSS_PC: b = (unitflags & FLength); break; case CSSPrimitiveValue::CSS_MS: case CSSPrimitiveValue::CSS_S: b = (unitflags & FTime);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -