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 + -
显示快捷键?