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

📄 cssparser.cpp

📁 monqueror一个很具有参考价值的源玛
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/** * This file is part of the DOM implementation for KDE. * * Copyright (C) 1999 Lars Knoll (knoll@kde.org) *               1999 Waldo Bastian (bastian@kde.org) * * 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. * * $Id: cssparser.cpp,v 1.2 2002/01/28 04:31:02 leon Exp $ *///#define CSS_DEBUG#include "render_interface.h"#include "render_style.h"#include "css_stylesheetimpl.h"#include "css_stylesheet.h"#include "css_rule.h"#include "css_ruleimpl.h"#include "css_valueimpl.h"#include "csshelper.h"#include "dom_string.h"#include "dom_nodeimpl.h"#include "html_documentimpl.h"#include "dom_exception.h"#include "kdebug.h"#include "htmlhashes.h"#include "cssproperties.h"#include "cssvalues.h"using namespace DOM;//// The following file defines the function//     const struct props *findProp(const char *word, int len)//// with 'props->id' a CSS property in the range from CSS_PROP_MIN to// (and including) CSS_PROP_TOTAL-1#include "cssproperties.c"#include "cssvalues.c"int DOM::getPropertyID(const char *tagStr, int len){    const struct props *propsPtr = findProp(tagStr, len);    if (!propsPtr)        return 0;    return propsPtr->id;}// ------------------------------------------------------------------------------------------------------bool StyleBaseImpl::deleteMe(){    if(!m_parent && _ref <= 0) return true;    return false;}void StyleBaseImpl::setParent(StyleBaseImpl *parent){    m_parent = parent;}void StyleBaseImpl::checkLoaded(){    if(m_parent) m_parent->checkLoaded();}DOMString StyleBaseImpl::baseUrl(){    // try to find the style sheet. If found look for it's url.    // If it has none, look for the parentsheet, or the parentNode and    // try to find out about their url    StyleBaseImpl *b = this;    while(b && !b->isStyleSheet())        b = b->parent();    if(!b) return 0;    StyleSheetImpl *sheet = static_cast<StyleSheetImpl *>(b);    if(!sheet->href().isNull())        return sheet->href();    // find parent    if(sheet->parent()) return sheet->parent()->baseUrl();    if(!sheet->ownerNode()) return 0;    DocumentImpl *doc = static_cast<DocumentImpl*>(sheet->ownerNode()->nodeType() == Node::DOCUMENT_NODE ? sheet->ownerNode() : sheet->ownerNode()->ownerDocument());    if(!doc->isHTMLDocument()) return 0;    HTMLDocumentImpl *htmldoc = static_cast<HTMLDocumentImpl *>(doc);    return htmldoc->baseURL();}/* * parsing functions for stylesheets */inline bool isspace(const QChar &c){     return (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\r' || c == QChar(0xa0));}const QChar *StyleBaseImpl::parseSpace(const QChar *curP, const QChar *endP){  bool sc = false;     // possible start comment?  bool ec = false;     // possible end comment?  bool ic = false;     // in comment?  while (curP < endP)  {      if (ic)      {          if (ec && (*curP == '/'))              ic = false;          else if (*curP == '*')              ec = true;          else              ec = false;      }      else if (sc && (*curP == '*'))      {          ic = true;      }      else if (*curP == '/')      {          sc = true;      }      else if (!isspace(*curP))      {          return(curP);      }      else      {          sc = false;      }      curP++;  }  return(0);}/* * ParseToChar * * Search for an expected character.  Deals with escaped characters, * quoted strings, and pairs of braces/parens/brackets. */const QChar *StyleBaseImpl::parseToChar(const QChar *curP, const QChar *endP, QChar c, bool chkws, bool endAtBlock){    //kdDebug( 6080 ) << "parsetochar: \"" << QString(curP, endP-curP) << "\" searching " << c << " ws=" << chkws << endl;    bool sq = false; /* in single quote? */    bool dq = false; /* in double quote? */    bool esc = false; /* escape mode? */    while (curP < endP)    {        if (esc)            esc = false;        else if (*curP == '\\')            esc = true;        else if (!sq && (*curP == '"'))            dq = !dq;        else if (!dq && (*curP == '\''))            sq = !sq;        else if (!sq && !dq && *curP == c)            return(curP);        else if (!sq && !dq && chkws && isspace(*curP))            return(curP);        else if(!sq && !dq ) {            if (*curP == '{') {                if(endAtBlock)                    return curP;                curP = parseToChar(curP + 1, endP, '}', false);                if (!curP)                    return(0);            } else if (*curP == '(') {                curP = parseToChar(curP + 1, endP, ')', false);                if (!curP)                    return(0);            } else if (*curP == '[') {                curP = parseToChar(curP + 1, endP, ']', false);                if (!curP)                    return(0);            }        }        curP++;    }    return(0);}CSSRuleImpl *StyleBaseImpl::parseAtRule(const QChar *&curP, const QChar *endP){    curP++;    const QChar *startP = curP;    while( *curP != ' ' && *curP != '{' && *curP != '\'')        curP++;    QString rule(startP, curP-startP);    rule = rule.lower();    //kdDebug( 6080 ) << "rule = '" << rule << "'" << endl;    if(rule == "import")    {        // load stylesheet and pass it over        curP = parseSpace(curP, endP);        if(!curP) return 0;        startP = curP++;        curP = parseToChar(startP, endP, ';', true);        // Do not allow @import statements after explicity inlined        // declarations.  They should simply be ignored per CSS-1        // specification section 3.0.        if( !curP || hasInlinedDecl ) return 0;        DOMString url = khtml::parseURL(DOMString(startP, curP - startP));        startP = curP;        if(*curP != ';')            curP = parseToChar(startP, endP, ';', false, true);        if(!curP) return 0;        QString media(startP, curP - startP);        // ### check if at the beginning of the stylesheet (no style rule        //     before the import rule)#ifdef CSS_DEBUG//        kdDebug( 6080 ) << "at rule: url = " << url.string()                        << " media = " << media << endl;#endif        // ignore block following @import rule        if( *curP == '{' ) {            curP++;            curP = parseToChar(curP, endP, '}', false);            if(curP)                curP++;        }        // ### only media="", "screen and "all" are imported for the moment...        if( !media.isEmpty() && !(media.contains("all") || media.contains("screen")) )            return 0;        if(!this->isCSSStyleSheet()) return 0;        return new CSSImportRuleImpl(this, url, 0);    }    else if(rule == "charset")    {        // ### invoke decoder        startP = curP++;        curP = parseToChar(startP, endP, ';', false);#ifdef CSS_DEBUG//        kdDebug( 6080 ) << "charset = " << QString(startP, curP - startP) << endl;#endif    }    else if(rule == "font-face")    {        startP = curP++;        curP = parseToChar(startP, endP, '}', false);#ifdef CSS_DEBUG//        kdDebug( 6080 ) << "font rule = " << QString(startP, curP - startP) << endl;#endif    }    else if(rule == "media")    {        startP = curP++;        curP = parseToChar(startP, endP, '}', false);#ifdef CSS_DEBUG//        kdDebug( 6080 ) << "media rule = " << QString(startP, curP - startP) << endl;#endif    }    else if(rule == "page")    {        startP = curP++;        curP = parseToChar(startP, endP, '}', false);#ifdef CSS_DEBUG//        kdDebug( 6080 ) << "page rule = " << QString(startP, curP - startP) << endl;#endif    }    return 0;}static DOMString getValue( const QChar *curP, const QChar *endP, const QChar *&endVal){    //QString selecString( curP, endP - curP );    //kdDebug( 6080 ) << "getValue = \"" << selecString << "\"" << endl;    endVal = curP;    endVal++; // ignore first char (could be the ':' form the pseudo classes)    while( endVal < endP && *endVal != '.' && *endVal != ':' && *endVal != '[' )	endVal++;    const QChar *end = endVal;    if(endVal == endP)	endVal = 0;    return DOMString( curP, end - curP);}CSSSelector *StyleBaseImpl::parseSelector2(const QChar *curP, const QChar *endP, CSSSelector *stack,			      CSSSelector::Relation relation){    CSSSelector *cs = new CSSSelector();#ifdef CSS_DEBUG    QString selecString( curP, endP - curP );//    kdDebug( 6080 ) << "selectString = \"" << selecString << "\"" << endl;#endif    const QChar *endVal = 0;    if (*curP == '#' && (curP < endP && !((*(curP+1)).isDigit())))    {        cs->tag = -1;        cs->attr = ATTR_ID;        cs->match = CSSSelector::Exact;        cs->value = getValue( curP+1, endP, endVal);    }    else if (*curP == '.' && (curP < endP && !((*(curP+1)).isDigit())))    {        cs->tag = -1;        cs->attr = ATTR_CLASS;        cs->match = CSSSelector::List;        cs->value = getValue( curP+1, endP, endVal);    }    else if (*curP == ':')    {        cs->tag = -1;        cs->value = getValue(curP, endP, endVal);        cs->match = CSSSelector::Pseudo;    }    else    {        const QChar *startP = curP;        QString tag;        while (curP < endP)        {            if (*curP =='#' && (curP < endP && !((*(curP+1)).isDigit())))            {                tag = QString( startP, curP-startP );                cs->attr = ATTR_ID;                cs->match = CSSSelector::Exact;                cs->value = getValue(curP+1, endP, endVal);                break;            }            else if (*curP == '.' && (curP < endP && !((*(curP+1)).isDigit())))            {                tag = QString( startP, curP - startP );                cs->attr = ATTR_CLASS;                cs->match = CSSSelector::List;                cs->value = getValue(curP+1, endP, endVal);                break;            }            else if (*curP == ':')            {                // pseudo attributes (:link, :hover, ...)                tag = QString( startP, curP - startP );                cs->value = getValue(curP, endP, endVal);                cs->match = CSSSelector::Pseudo;                break;            }            else if (*curP == '[')            {                tag = QString( startP, curP - startP );                curP++;                if ( curP >= endP ) {                    delete cs;                    return 0;                }#ifdef CSS_DEBUG//                kdDebug( 6080 ) << "tag = " << tag << endl;#endif                const QChar *equal = parseToChar(curP, endP, '=', false);                QString attr;                if(!equal)                {                    attr = QString( curP, endP - curP - 1 );                    attr = attr.stripWhiteSpace();#ifdef CSS_DEBUG//                    kdDebug( 6080 ) << "attr = '" << attr << "'" << endl;#endif                    cs->match = CSSSelector::Set;                }                else                {                    // check relation: = / ~= / |=                    if(*(equal-1) == '~')                    {                        attr = QString( curP, equal - curP - 1 );                        cs->match = CSSSelector::List;                    }                    else if(*(equal-1) == '|')                    {                        attr = QString( curP, equal - curP - 1 );                        cs->match = CSSSelector::Hyphen;                    }                    else                    {                        attr = QString(curP, equal - curP );                        cs->match = CSSSelector::Exact;                    }                }                attr = attr.stripWhiteSpace();                cs->attr = khtml::getAttrID(attr.ascii(), attr.length());                if(equal)                {                    equal++;                    while(equal < endP && *equal == ' ')                        equal++;                    if(equal >= endP ) {                        delete cs;                        return 0;                    }		    endVal = equal;		    bool hasQuote = false;                    if(*equal == '\'') {                        equal++;			endVal++;                        while(endVal < endP && *endVal != '\'')                            endVal++;			hasQuote = true;                    } else if(*equal == '\"') {                        equal++;			endVal++;                        while(endVal < endP && *endVal != '\"')                            endVal++;			hasQuote = true;                    } else {		      while(endVal < endP && *endVal != ']')			endVal++;		    }                    cs->value = DOMString(equal, endVal - equal);		    if ( hasQuote ) {		      while( endVal < endP - 1 && *endVal != ']' )			endVal++;		    }		    endVal++;		    // ### fixme we ignore everything after [..]		    if( endVal == endP )			endVal = 0;                }                break;            }            else            {                curP++;            }        }        if (curP == endP)        {            tag = QString( startP, curP - startP );        }        if(tag == "*")        {            //kdDebug( 6080 ) << "found '*' selector" << endl;            cs->tag = -1;        }        else            cs->tag = khtml::getTagID(tag.lower().ascii(), tag.length());   }   if (cs->tag == 0)   {       delete cs;       delete stack;       return(0);   }#ifdef CSS_DEBUG//   kdDebug( 6080 ) << "[Selector: tag=" << cs->tag << " Attribute=" << cs->attr << " match=" << (int)cs->match << " value=" << cs->value.string() << " specificity=" << cs->specificity() << "]" << endl;#endif   cs->tagHistory = stack;   cs->relation = relation;   relation = CSSSelector::SubSelector;   stack = cs;   //stack->print();   if( endVal ) {       // lets be recursive       stack = parseSelector2(endVal, endP, stack, relation);   }   return(stack);}CSSSelector *StyleBaseImpl::parseSelector1(const QChar *curP, const QChar *endP){#ifdef CSS_DEBUG//    kdDebug( 6080 ) << "selector1 is \'" << QString(curP, endP-curP) << "\'" << endl;#endif    CSSSelector *selecStack=0;    curP = parseSpace(curP, endP);    if (!curP)        return(0);    CSSSelector::Relation relation = CSSSelector::Descendant;    const QChar *startP = curP;    while (curP <= endP)    {        if ((curP == endP) || isspace(*curP) || *curP == '+' || *curP == '>')        {            selecStack = parseSelector2(startP, curP, selecStack, relation);            if (!selecStack)                return 0;            curP = parseSpace(curP, endP);            if (!curP)                return(selecStack);            relation = CSSSelector::Descendant;            if(*curP == '+')            {                relation = CSSSelector::Sibling;                curP++;                curP = parseSpace(curP, endP);            }            else if(*curP == '>')            {#ifdef CSS_DEBUG//                kdDebug( 6080 ) << "child selector" << endl;#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -