⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cssparser.cpp

📁 手机浏览器源码程序,功能强大
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*
 * 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 + -