cssparser.cpp
来自「将konqueror浏览器移植到ARM9 2410中」· C++ 代码 · 共 2,040 行 · 第 1/5 页
CPP
2,040 行
/** * 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.158.2.3 2001/11/01 20:06:20 mueller Exp $ *///#define CSS_DEBUG//#define CSS_AURAL//#define CSS_DEBUG_BCKGR#include <assert.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 "xml/dom_nodeimpl.h"#include "html/html_documentimpl.h"#include "dom_exception.h"using namespace DOM;#include <kdebug.h>#include <kglobal.h>#include <kglobalsettings.h> // For system fonts#include <kapp.h>#include "htmlhashes.h"#include "misc/helper.h"//// 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::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 DOMString(); 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 DOMString(); DocumentImpl *doc = static_cast<DocumentImpl*>(sheet->ownerNode()->nodeType() == Node::DOCUMENT_NODE ? sheet->ownerNode() : sheet->ownerNode()->ownerDocument()); return doc->baseURL();}/* * parsing functions for stylesheets */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)) else if (!(curP->isSpace())) { 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 && curP->isSpace()) //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); media = media.stripWhiteSpace(); // ### 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... // ### add at least "print" here once the MediaList class is implemented 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); if ( !curP || curP >= endP ) return 0; curP++; curP = parseToChar(curP, 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); //qDebug("mediaList = '%s'", mediaList.latin1() ); if ( !curP || curP >= endP ) return 0; QString mediaList = QString( startP, curP - startP); curP++; startP = curP; if ( curP >= endP ) return 0; curP = parseToChar(curP, endP, '}', false); if ( !curP || startP >= curP ) return 0;#ifdef CSS_DEBUG kdDebug( 6080 ) << "media rule = " << QString(startP, curP - startP) << endl;#endif if ( mediaList.contains( "screen" ) || mediaList.contains( "all" ) ) return parseStyleRule(startP, curP); } else if(rule == "page") { startP = curP++; curP = parseToChar(startP, endP, '{', false); if ( !curP || curP >= endP ) return 0; curP++; curP = parseToChar(curP, 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::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 == ':' && (curP < endP && !((*(curP+1)).isDigit()))) { // pseudo attributes (:link, :hover, ...), they are case insensitive. cs->tag = -1; cs->match = CSSSelector::Pseudo; cs->value = getValue(curP+1, endP, endVal); cs->value = cs->value.implementation()->lower(); } 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 == ':' && (curP < endP && !((*(curP+1)).isDigit()))) { // pseudo attributes (:link, :hover, ...), they are case insensitive. tag = QString( startP, curP - startP ); cs->match = CSSSelector::Pseudo; cs->value = getValue(curP+1, endP, endVal); cs->value = cs->value.implementation()->lower(); 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 *closebracket = parseToChar(curP, endP, ']', false); if (!closebracket) { kdWarning()<<"error in css: closing bracket not found!"<<endl; return 0; } QString attr; const QChar *equal = parseToChar(curP, closebracket, '=', false); if(!equal)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?