cssparser.cpp

来自「将konqueror浏览器移植到ARM9 2410中」· C++ 代码 · 共 2,040 行 · 第 1/5 页

CPP
2,040
字号
                {                    attr = QString( curP, closebracket - curP );                    attr = attr.stripWhiteSpace();#ifdef CSS_DEBUG                    kdDebug( 6080 ) << "attr = '" << attr << "'" << endl;#endif                    cs->match = CSSSelector::Set;                    endVal = closebracket + 1;                    // ### fixme we ignore everything after [..]                    if( endVal == endP )                        endVal = 0;                }                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 {            StyleBaseImpl *root = this;            DocumentImpl *doc = 0;            while (root->parent())                root = root->parent();            if (root->isCSSStyleSheet())                doc = static_cast<CSSStyleSheetImpl*>(root)->doc();            if (doc && !doc->isHTMLDocument()) {                const DOMString s = tag;                cs->tag = doc->elementId(s.implementation());            } else {		int tagID = khtml::getTagID(tag.lower().ascii(), tag.length());		if (tagID != 0) {		    cs->tag = tagID;		} else if (!(tag.isEmpty())) {                    const DOMString s = tag;                    cs->tag = doc->elementId(s.implementation());		} else {		    kdWarning() << "Error in CSS" << endl;		}	    }        }   }#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   //stack->print();   if( endVal ) {       // lets be recursive       relation = CSSSelector::SubSelector;       CSSSelector *stack = parseSelector2(endVal, endP, relation);       cs->tagHistory = stack;       cs->relation = relation;   }   return cs;}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 && curP <= endP)    {        if ((curP == endP) || curP->isSpace() || *curP == '+' || *curP == '>')        {            CSSSelector *newsel = parseSelector2(startP, curP, relation);            if (!newsel) {                delete selecStack;                return 0;            }            CSSSelector *end = newsel;            while( end->tagHistory )                end = end->tagHistory;            end->tagHistory = selecStack;            end->relation = relation;            selecStack = newsel;            curP = parseSpace(curP, endP);            if (!curP) {#ifdef CSS_DEBUG                kdDebug( 6080 ) << "selector stack is:" << endl;                selecStack->print();                kdDebug( 6080 ) << endl;#endif                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                relation = CSSSelector::Child;                curP++;                curP = parseSpace(curP, endP);            }            //if(selecStack)            //    selecStack->print();            startP = curP;        }        else        {            curP++;        }    }#ifdef CSS_DEBUG    selecStack->print();#endif    return(selecStack);}QList<CSSSelector> *StyleBaseImpl::parseSelector(const QChar *curP, const QChar *endP){#ifdef CSS_DEBUG    kdDebug( 6080 ) << "selector is \'" << QString(curP, endP-curP) << "\'" << endl;#endif    QList<CSSSelector> *slist  = 0;    const QChar *startP;    while (curP < endP)    {        startP = curP;        curP = parseToChar(curP, endP, ',', false);        if (!curP)            curP = endP;        CSSSelector *selector = parseSelector1(startP, curP);        if (selector)        {            if (!slist)            {                slist = new QList<CSSSelector>;                slist->setAutoDelete(true);            }            slist->append(selector);        }        else        {#ifdef CSS_DEBUG            kdDebug( 6080 ) << "invalid selector" << endl;#endif            // invalid selector, delete            delete slist;            return 0;        }        curP++;    }    return slist;}void StyleBaseImpl::parseProperty(const QChar *curP, const QChar *endP){    m_bImportant = false;    // Get rid of space in front of the declaration    curP = parseSpace(curP, endP);    if (!curP)        return;    // Search for the required colon or white space    const QChar *colon = parseToChar(curP, endP, ':', true);    if (!colon)        return;    const QString propName( curP, colon - curP );#ifdef CSS_DEBUG    kdDebug( 6080 ) << "Property-name = \"" << propName << "\"" << endl;#endif    // May have only reached white space before    if (*colon != ':')    {        // Search for the required colon        colon = parseToChar(curP, endP, ':', false);        if (!colon)            return;    }    curP = colon+1;    // remove space in front of the value    while(curP < endP && *curP == ' ')        curP++;    if ( curP >= endP )        return;    // search for !important    const QChar *exclam = parseToChar(curP, endP, '!', false);    if(exclam)    {        //const QChar *imp = parseSpace(exclam+1, endP);        QString s(exclam+1, endP - exclam - 1);        s = s.stripWhiteSpace();        s = s.lower();        if(s != "important")            return;        m_bImportant = true;        endP = exclam;#ifdef CSS_DEBUG        kdDebug( 6080 ) << "important property!" << endl;#endif    }    // remove space after the value;    while (endP > curP)    {        //if (!isspace(*(endP-1)))        if (!((endP-1)->isSpace()))            break;        endP--;    }#ifdef CSS_DEBUG    QString propVal( curP , endP - curP );    kdDebug( 6080 ) << "Property-value = \"" << propVal.latin1() << "\"" << endl;#endif    const struct props *propPtr = findProp(propName.lower().ascii(), propName.length());    if (!propPtr)    {#ifdef CSS_DEBUG        kdDebug( 6080 ) << "Unknown property" << propName << endl;#endif         return;    }    unsigned int numProps = m_propList->count();    if(!parseValue(curP, endP, propPtr->id)) {#ifdef CSS_DEBUG        kdDebug(6080) << "invalid property, removing added properties from m_propList" << endl;#endif        while(m_propList->count() > numProps)            m_propList->removeLast();    }}QList<CSSProperty> *StyleBaseImpl::parseProperties(const QChar *curP, const QChar *endP){    m_propList = new QList<CSSProperty>;    m_propList->setAutoDelete(true);    while (curP < endP)    {        const QChar *startP = curP;        curP = parseToChar(curP, endP, ';', false);        if (!curP)            curP = endP;#ifdef CSS_DEBUG        QString propVal( startP , curP - startP );        kdDebug( 6080 ) << "Property = \"" << propVal.latin1() << "\"" << endl;#endif        parseProperty(startP, curP);        curP++;    }    if(!m_propList->isEmpty()) {        return m_propList;    } else {#ifdef CSS_DEBUG        kdDebug( 6080 ) << "empty property list" << endl;#endif        delete m_propList;        return 0;    }}static const QChar *getNext( const QChar *curP, const QChar *endP, bool &last ){    last = false;    const QChar *nextP = curP;    bool ignoreSpace = false;    while(nextP <= endP) {	if ( *nextP == '(' ) {	    ignoreSpace = true;	} else if ( *nextP == ')' ) {	    ignoreSpace = false;	}	if ( *nextP == ' ' && !ignoreSpace ) {	    if (nextP == endP) {		last = true;	    }	    break;	}	if ( *nextP == ';' || nextP == endP ) {	    last = true;	    break;	}	nextP++;    }    return nextP;}// ------------------- begin font property ---------------------/*  Parser for the font property of CSS.  See  http://www.w3.org/TR/REC-CSS2/fonts.html#propdef-font for details.  Written by Jasmin Blanchette (jasmin@trolltech.com) on 2000-08-16.*/class FontParser {public:    enum { TOK_NONE, TOK_EOI, TOK_SLASH, TOK_COMMA, TOK_STRING, TOK_SYMBOL };    QChar m_yyChar;    QString m_yyIn, m_yyStr;    unsigned int m_yyPos;    int m_yyTok;    bool strictParsing;    int getChar() {      return ( m_yyPos == m_yyIn.length() ) ? QChar('\0') : QChar(m_yyIn[m_yyPos++]);    }    void startTokenizer( const QString& str, bool _strictParsing ) {      m_yyIn = str.simplifyWhiteSpace();#ifdef CSS_DEBUG      kdDebug( 6080 ) << "startTokenizer: [" << m_yyIn << "]" << endl;#endif      m_yyPos = 0;      m_yyChar = getChar();

⌨️ 快捷键说明

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