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

📄 cssstyleselector.cpp

📁 khtml在gtk上的移植版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/** * This file is part of the CSS implementation for KDE. * * Copyright (C) 1999 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. */#include "css/cssstyleselector.h"#include "rendering/render_style.h"#include "css/css_stylesheetimpl.h"#include "css/css_ruleimpl.h"#include "css/css_valueimpl.h"#include "css/csshelper.h"#include "rendering/render_object.h"#include "html/html_documentimpl.h"#include "html/html_elementimpl.h"#include "xml/dom_elementimpl.h"#include "dom/css_rule.h"#include "dom/css_value.h"#include "khtml_factory.h"#include "khtmlpart_p.h"using namespace khtml;using namespace DOM;#include "css/cssproperties.h"#include "css/cssvalues.h"#include "misc/khtmllayout.h"#include "khtml_settings.h"#include "misc/htmlhashes.h"#include "misc/helper.h"#include "misc/loader.h"#include "rendering/font.h"#include "khtmlview.h"#include "khtml_part.h"#include <kstandarddirs.h>#include <kcharsets.h>#include <kglobal.h>#include <qfile.h>#include <qfontdatabase.h>#include <qfontinfo.h>#include <qvaluelist.h>#include <qstring.h>#include <kdebug.h>#include <kurl.h>#include <qdatetime.h>#include <assert.h>#include <qpaintdevicemetrics.h>#include <qintcache.h>#include <stdlib.h>// #define STYLE_SHARING_STATS 1#define HANDLE_INHERIT(prop, Prop) \if (isInherit) \{\    style->set##Prop(parentStyle->prop());\    return;\}#define HANDLE_INHERIT_AND_INITIAL(prop, Prop) \HANDLE_INHERIT(prop, Prop) \else if (isInitial) \    style->set##Prop(RenderStyle::initial##Prop());#define HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(prop, Prop, Value) \HANDLE_INHERIT(prop, Prop) \else if (isInitial) \    style->set##Prop(RenderStyle::initial##Value());#define HANDLE_INHERIT_COND(propID, prop, Prop) \if (id == propID) \{\    style->set##Prop(parentStyle->prop());\    return;\}#define HANDLE_INITIAL_COND(propID, Prop) \if (id == propID) \{\    style->set##Prop(RenderStyle::initial##Prop());\    return;\}#define HANDLE_INITIAL_COND_WITH_VALUE(propID, Prop, Value) \if (id == propID) \{\    style->set##Prop(RenderStyle::initial##Value());\    return;\}namespace khtml {CSSRuleSet *CSSStyleSelector::defaultStyle = 0;CSSRuleSet *CSSStyleSelector::defaultQuirksStyle = 0;CSSRuleSet *CSSStyleSelector::defaultPrintStyle = 0;CSSStyleSheetImpl *CSSStyleSelector::defaultSheet = 0;RenderStyle* CSSStyleSelector::styleNotYetAvailable = 0;CSSStyleSheetImpl *CSSStyleSelector::quirksSheet = 0;static CSSStyleSelector::Encodedurl *encodedurl = 0;static PseudoState pseudoState;CSSStyleSelector::CSSStyleSelector( DocumentImpl* doc, QString userStyleSheet, StyleSheetListImpl *styleSheets,                                    const KURL &url, bool _strictParsing ){    init();    view = doc->view();    strictParsing = _strictParsing;    settings = view ? view->part()->settings() : 0;    if(!defaultStyle) loadDefaultStyle(settings);    m_medium = view ? view->mediaType() : QString("all");    m_userStyle = 0;    m_userSheet = 0;    paintDeviceMetrics = doc->paintDeviceMetrics();    // FIXME: This sucks! The user sheet is reparsed every time!    if ( !userStyleSheet.isEmpty() ) {        m_userSheet = new DOM::CSSStyleSheetImpl(doc);        m_userSheet->parseString( DOMString( userStyleSheet ) );        m_userStyle = new CSSRuleSet();        m_userStyle->addRulesFromSheet( m_userSheet, m_medium );    }    // add stylesheets from document    m_authorStyle = new CSSRuleSet();    QPtrListIterator<StyleSheetImpl> it(styleSheets->styleSheets);    for (; it.current(); ++it)        if (it.current()->isCSSStyleSheet())            m_authorStyle->addRulesFromSheet(static_cast<CSSStyleSheetImpl*>(it.current()), m_medium);    //kdDebug( 6080 ) << "number of style sheets in document " << authorStyleSheets.count() << endl;    //kdDebug( 6080 ) << "CSSStyleSelector: author style has " << authorStyle->count() << " elements"<< endl;    KURL u = url;    u.setQuery( QString::null );    u.setRef( QString::null );    encodedurl.file = u.url();    int pos = encodedurl.file.findRev('/');    encodedurl.path = encodedurl.file;    if ( pos > 0 ) {	encodedurl.path.truncate( pos );	encodedurl.path += '/';    }    u.setPath( QString::null );    encodedurl.host = u.url();    //kdDebug() << "CSSStyleSelector::CSSStyleSelector encoded url " << encodedurl.path << endl;}CSSStyleSelector::CSSStyleSelector( CSSStyleSheetImpl *sheet ){    init();    if(!defaultStyle) loadDefaultStyle();    KHTMLView *view = sheet->doc()->view();    m_medium =  view ? view->mediaType() : QString("all");    m_authorStyle = new CSSRuleSet();    m_authorStyle->addRulesFromSheet( sheet, m_medium );}void CSSStyleSelector::init(){    element = 0;    settings = 0;    paintDeviceMetrics = 0;    m_matchedRuleCount = m_matchedDeclCount = m_tmpRuleCount = 0;}CSSStyleSelector::~CSSStyleSelector(){    delete m_authorStyle;    delete m_userStyle;    delete m_userSheet;}void CSSStyleSelector::loadDefaultStyle(const KHTMLSettings *s){    if(defaultStyle) return;    {        QFile f(locate( "data", "khtml/css/html4.css" ) );        f.open(IO_ReadOnly);        QCString file( f.size()+1 );        int readbytes = f.readBlock( file.data(), f.size() );        f.close();        if ( readbytes >= 0 )            file[readbytes] = '\0';        QString style = QString::fromLatin1( file.data() );        if(s)            style += s->settingsToCSS();        DOMString str(style);        defaultSheet = new DOM::CSSStyleSheetImpl((DOM::CSSStyleSheetImpl * ) 0);        defaultSheet->parseString( str );        // Collect only strict-mode rules.        defaultStyle = new CSSRuleSet();        defaultStyle->addRulesFromSheet( defaultSheet, "screen" );                defaultPrintStyle = new CSSRuleSet();        defaultPrintStyle->addRulesFromSheet( defaultSheet, "print" );    }    {        QFile f(locate( "data", "khtml/css/quirks.css" ) );        f.open(IO_ReadOnly);        QCString file( f.size()+1 );        int readbytes = f.readBlock( file.data(), f.size() );        f.close();        if ( readbytes >= 0 )            file[readbytes] = '\0';        QString style = QString::fromLatin1( file.data() );        DOMString str(style);        quirksSheet = new DOM::CSSStyleSheetImpl((DOM::CSSStyleSheetImpl * ) 0);        quirksSheet->parseString( str );        // Collect only quirks-mode rules.        defaultQuirksStyle = new CSSRuleSet();        defaultQuirksStyle->addRulesFromSheet( quirksSheet, "screen" );    }    //kdDebug() << "CSSStyleSelector: default style has " << defaultStyle->count() << " elements"<< endl;}void CSSStyleSelector::addMatchedRule(CSSRuleData* rule){    if (m_matchedRules.size() <= m_matchedRuleCount)        m_matchedRules.resize(2*m_matchedRules.size()+1);    m_matchedRules[m_matchedRuleCount++] = rule;}void CSSStyleSelector::addMatchedDeclaration(CSSStyleDeclarationImpl* decl){    if (m_matchedDecls.size() <= m_matchedDeclCount)        m_matchedDecls.resize(2*m_matchedDecls.size()+1);    m_matchedDecls[m_matchedDeclCount++] = decl;}void CSSStyleSelector::matchRules(CSSRuleSet* rules, int& firstRuleIndex, int& lastRuleIndex){    m_matchedRuleCount = 0;    firstRuleIndex = lastRuleIndex = -1;    if (!rules || !element) return;        // We need to collect the rules for id, class, tag, and everything else into a buffer and    // then sort the buffer.    if (element->hasID())        matchRulesForList(rules->getIDRules(element->getIDAttribute().implementation()),                          firstRuleIndex, lastRuleIndex);    if (element->hasClass()) {        for (const AtomicStringList* singleClass = element->getClassList();             singleClass; singleClass = singleClass->next())            matchRulesForList(rules->getClassRules(singleClass->string().implementation()),                                                   firstRuleIndex, lastRuleIndex);    }    matchRulesForList(rules->getTagRules((void*)(int)localNamePart(element->id())),                      firstRuleIndex, lastRuleIndex);    matchRulesForList(rules->getUniversalRules(), firstRuleIndex, lastRuleIndex);        // If we didn't match any rules, we're done.    if (m_matchedRuleCount == 0) return;        // Sort the set of matched rules.    sortMatchedRules(0, m_matchedRuleCount);        // Now transfer the set of matched rules over to our list of decls.    for (unsigned i = 0; i < m_matchedRuleCount; i++)        addMatchedDeclaration(m_matchedRules[i]->rule()->declaration());}void CSSStyleSelector::matchRulesForList(CSSRuleDataList* rules,                                         int& firstRuleIndex, int& lastRuleIndex){    if (!rules) return;    for (CSSRuleData* d = rules->first(); d; d = d->next()) {        CSSStyleRuleImpl* rule = d->rule();        Q_UINT16 cssTagId = localNamePart(element->id());        Q_UINT16 tag = localNamePart(d->selector()->tag);        if ((cssTagId == tag || tag == anyLocalName) && checkSelector(d->selector(), element)) {            // If the rule has no properties to apply, then ignore it.            CSSStyleDeclarationImpl* decl = rule->declaration();            if (!decl) continue;                        // If we're matching normal rules, set a pseudo bit if             // we really just matched a pseudo-element.            if (dynamicPseudo != RenderStyle::NOPSEUDO && pseudoStyle == RenderStyle::NOPSEUDO)                style->setHasPseudoStyle(dynamicPseudo);            else  {                // Update our first/last rule indices in the matched rules array.                lastRuleIndex = m_matchedDeclCount + m_matchedRuleCount;                if (firstRuleIndex == -1) firstRuleIndex = m_matchedDeclCount + m_matchedRuleCount;                // Add this rule to our list of matched rules.                addMatchedRule(d);            }        }    }}bool operator >(CSSRuleData& r1, CSSRuleData& r2){    int spec1 = r1.selector()->specificity();    int spec2 = r2.selector()->specificity();    return (spec1 == spec2) ? r1.position() > r2.position() : spec1 > spec2; }bool operator <=(CSSRuleData& r1, CSSRuleData& r2){    return !(r1 > r2);}void CSSStyleSelector::sortMatchedRules(uint start, uint end){    if (start >= end || (end-start == 1))        return; // Sanity check.        if (end - start <= 6) {        // Apply a bubble sort for smaller lists.        for (uint i = end-1; i > start; i--) {            bool sorted = true;            for (uint j = start; j < i; j++) {                CSSRuleData* elt = m_matchedRules[j];

⌨️ 快捷键说明

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