cssparser.cpp
来自「konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版」· C++ 代码 · 共 1,746 行 · 第 1/5 页
CPP
1,746 行
/* * This file is part of the DOM implementation for KDE. * * Copyright (C) 2003 Lars Knoll (knoll@kde.org) * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) * * 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., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. *///#define CSS_DEBUG//#define TOKEN_DEBUG#define YYDEBUG 0#include <kdebug.h>#include <kglobal.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>#include <assert.h>// used to promote background: left to left center#define BACKGROUND_SKIP_CENTER( num ) \ if ( !pos_ok[ num ] && expected != 1 ) { \ pos_ok[num] = true; \ pos[num] = 0; \ skip_next = false; \ }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->args; 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; data = 0; valueList = 0; rule = 0; id = 0; important = false; nonCSSHint = 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 CSSParser::runParser(int length){ data[length-1] = 0; data[length-2] = 0; data[length-3] = ' '; yyTok = -1; block_nesting = 0; 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;}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) );#ifdef CSS_DEBUG kdDebug( 6080 ) << ">>>>>>> start parsing style sheet" << endl;#endif runParser(length);#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); assert( !data ); 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-4] = '}'; runParser(length); CSSRuleImpl *result = rule; rule = 0; return result;}bool CSSParser::parseValue( DOM::CSSStyleDeclarationImpl *declaration, int _id, const DOM::DOMString &string, bool _important, bool _nonCSSHint ){#ifdef CSS_DEBUG kdDebug( 6080 ) << "CSSParser::parseValue: id=" << _id << " important=" << _important << " nonCSSHint=" << _nonCSSHint << " value='" << string.string() << "'" << endl;#endif styleElement = declaration->stylesheet(); const char khtml_value[] = "@-khtml-value{"; int length = string.length() + 4 + strlen(khtml_value); assert( !data ); 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-4] = '}'; // qDebug("parse string = '%s'", QConstString( (const QChar *)data, length ).string().latin1() ); id = _id; important = _important; nonCSSHint = _nonCSSHint; runParser(length); delete rule; rule = 0; bool ok = false; if ( numParsedProperties ) { ok = true; for ( int i = 0; i < numParsedProperties; i++ ) { declaration->removeProperty(parsedProperties[i]->m_id, nonCSSHint); declaration->values()->append( parsedProperties[i] ); } numParsedProperties = 0; } return ok;}bool CSSParser::parseDeclaration( DOM::CSSStyleDeclarationImpl *declaration, const DOM::DOMString &string, bool _nonCSSHint ){#ifdef CSS_DEBUG kdDebug( 6080 ) << "CSSParser::parseDeclaration: nonCSSHint=" << nonCSSHint << " value='" << string.string() << "'" << endl;#endif styleElement = declaration->stylesheet(); const char khtml_decls[] = "@-khtml-decls{"; int length = string.length() + 4 + strlen(khtml_decls); assert( !data ); 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-4] = '}'; nonCSSHint = _nonCSSHint; runParser(length); delete rule; rule = 0; bool ok = false; if ( numParsedProperties ) { ok = true; for ( int i = 0; i < numParsedProperties; i++ ) { declaration->removeProperty(parsedProperties[i]->m_id, false); 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; prop->nonCSSHint = nonCSSHint; 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{ const StyleBaseImpl* root = styleElement; DocumentImpl *doc = 0; while (root->parent()) root = root->parent(); if (root->isCSSStyleSheet()) doc = static_cast<const 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:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?