cssstyleselector.cpp

来自「konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版」· C++ 代码 · 共 1,879 行 · 第 1/5 页

CPP
1,879
字号
/** * This file is part of the CSS implementation for KDE. * * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) *           (C) 2003-2004 Apple Computer, Inc. *           (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) *           (C) 2004 Germain Garand (germain@ebooksfrance.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., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, 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 <kconfig.h>#include <qfile.h>#include <qvaluelist.h>#include <qstring.h>#include <qtooltip.h>#include <kdebug.h>#include <kurl.h>#include <assert.h>#include <qpaintdevicemetrics.h>#include <stdlib.h>#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());\    return;\}#define HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(prop, Prop, Value) \HANDLE_INHERIT(prop, Prop) \else if (isInitial) \{\    style->set##Prop(RenderStyle::initial##Value());\    return;\}#define HANDLE_BACKGROUND_INHERIT_AND_INITIAL(prop, Prop) \if (isInherit) { \    BackgroundLayer* currChild = style->accessBackgroundLayers(); \    BackgroundLayer* prevChild = 0; \    const BackgroundLayer* currParent = parentStyle->backgroundLayers(); \    while (currParent && currParent->is##Prop##Set()) { \        if (!currChild) { \            /* Need to make a new layer.*/ \            currChild = new BackgroundLayer(); \            prevChild->setNext(currChild); \        } \        currChild->set##Prop(currParent->prop()); \        prevChild = currChild; \        currChild = prevChild->next(); \        currParent = currParent->next(); \    } \    \    while (currChild) { \        /* Reset any remaining layers to not have the property set. */ \        currChild->clear##Prop(); \        currChild = currChild->next(); \    } \    return; \} \if (isInitial) { \    BackgroundLayer* currChild = style->accessBackgroundLayers(); \    currChild->set##Prop(RenderStyle::initial##Prop()); \    for (currChild = currChild->next(); currChild; currChild = currChild->next()) \        currChild->clear##Prop(); \    return; \}#define HANDLE_BACKGROUND_VALUE(prop, Prop, value) { \HANDLE_BACKGROUND_INHERIT_AND_INITIAL(prop, Prop) \if (!value->isPrimitiveValue() && !value->isValueList()) \    return; \BackgroundLayer* currChild = style->accessBackgroundLayers(); \BackgroundLayer* prevChild = 0; \if (value->isPrimitiveValue()) { \    map##Prop(currChild, value); \    currChild = currChild->next(); \} \else { \    /* Walk each value and put it into a layer, creating new layers as needed. */ \    CSSValueListImpl* valueList = static_cast<CSSValueListImpl*>(value); \    for (unsigned int i = 0; i < valueList->length(); i++) { \        if (!currChild) { \            /* Need to make a new layer to hold this value */ \            currChild = new BackgroundLayer(); \            prevChild->setNext(currChild); \        } \        map##Prop(currChild, valueList->item(i)); \        prevChild = currChild; \        currChild = currChild->next(); \    } \} \while (currChild) { \    /* Reset all remaining layers to not have the property set. */ \    currChild->clear##Prop(); \    currChild = currChild->next(); \} }#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 {CSSStyleSelectorList *CSSStyleSelector::s_defaultStyle;CSSStyleSelectorList *CSSStyleSelector::s_defaultQuirksStyle;CSSStyleSelectorList *CSSStyleSelector::s_defaultPrintStyle;CSSStyleSheetImpl *CSSStyleSelector::s_defaultSheet;RenderStyle* CSSStyleSelector::styleNotYetAvailable;CSSStyleSheetImpl *CSSStyleSelector::s_quirksSheet;enum PseudoState { PseudoUnknown, PseudoNone, PseudoLink, PseudoVisited};static PseudoState pseudoState;CSSStyleSelector::CSSStyleSelector( DocumentImpl* doc, QString userStyleSheet, StyleSheetListImpl *styleSheets,                                    const KURL &url, bool _strictParsing ){    KHTMLView* view = doc->view();    init(view ? view->part()->settings() : 0);    strictParsing = _strictParsing;    m_medium = view ? view->mediaType() : QString("all");    selectors = 0;    selectorCache = 0;    properties = 0;    userStyle = 0;    userSheet = 0;    paintDeviceMetrics = doc->paintDeviceMetrics();    if(paintDeviceMetrics) // this may be null, not everyone uses khtmlview (Niko)        computeFontSizes(paintDeviceMetrics, view ? view->part()->zoomFactor() : 100);    if ( !userStyleSheet.isEmpty() ) {        userSheet = new DOM::CSSStyleSheetImpl(doc);        userSheet->parseString( DOMString( userStyleSheet ) );        userStyle = new CSSStyleSelectorList();        userStyle->append( userSheet, m_medium );    }    // add stylesheets from document    authorStyle = new CSSStyleSelectorList();    QPtrListIterator<StyleSheetImpl> it( styleSheets->styleSheets );    for ( ; it.current(); ++it ) {        if ( it.current()->isCSSStyleSheet() && !it.current()->disabled()) {            authorStyle->append( static_cast<CSSStyleSheetImpl*>( it.current() ), m_medium );        }    }    buildLists();    //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(0L);    KHTMLView *view = sheet->doc()->view();    m_medium = view ? view->mediaType() : "screen";    authorStyle = new CSSStyleSelectorList();    authorStyle->append( sheet, m_medium );}void CSSStyleSelector::init(const KHTMLSettings* _settings){    element = 0;    settings = _settings;    paintDeviceMetrics = 0;    propsToApply = (CSSOrderedProperty **)malloc(128*sizeof(CSSOrderedProperty *));    pseudoProps = (CSSOrderedProperty **)malloc(128*sizeof(CSSOrderedProperty *));    propsToApplySize = 128;    pseudoPropsSize = 128;    if(!s_defaultStyle) loadDefaultStyle(settings);    defaultStyle = s_defaultStyle;    defaultPrintStyle = s_defaultPrintStyle;    defaultQuirksStyle = s_defaultQuirksStyle;}CSSStyleSelector::~CSSStyleSelector(){    clearLists();    delete authorStyle;    delete userStyle;    delete userSheet;    free(propsToApply);    free(pseudoProps);}void CSSStyleSelector::addSheet( CSSStyleSheetImpl *sheet ){    KHTMLView *view = sheet->doc()->view();    m_medium = view ? view->mediaType() : "screen";    authorStyle->append( sheet, m_medium );}void CSSStyleSelector::loadDefaultStyle(const KHTMLSettings *s){    if(s_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);	s_defaultSheet = new DOM::CSSStyleSheetImpl((DOM::CSSStyleSheetImpl * ) 0);	s_defaultSheet->parseString( str );	// Collect only strict-mode rules.	s_defaultStyle = new CSSStyleSelectorList();	s_defaultStyle->append( s_defaultSheet, "screen" );	s_defaultPrintStyle = new CSSStyleSelectorList();	s_defaultPrintStyle->append( s_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);	s_quirksSheet = new DOM::CSSStyleSheetImpl((DOM::CSSStyleSheetImpl * ) 0);	s_quirksSheet->parseString( str );	// Collect only quirks-mode rules.	s_defaultQuirksStyle = new CSSStyleSelectorList();	s_defaultQuirksStyle->append( s_quirksSheet, "screen" );    }    //kdDebug() << "CSSStyleSelector: default style has " << defaultStyle->count() << " elements"<< endl;}void CSSStyleSelector::clear(){    delete s_defaultStyle;    delete s_defaultQuirksStyle;    delete s_defaultPrintStyle;    delete s_defaultSheet;    delete styleNotYetAvailable;    s_defaultStyle = 0;    s_defaultQuirksStyle = 0;    s_defaultPrintStyle = 0;    s_defaultSheet = 0;    styleNotYetAvailable = 0;}void CSSStyleSelector::reparseConfiguration(){    // nice leak, but best we can do right now. hopefully its only rare.    s_defaultStyle = 0;    s_defaultQuirksStyle = 0;    s_defaultPrintStyle = 0;    s_defaultSheet = 0;}#define MAXFONTSIZES 8void CSSStyleSelector::computeFontSizes(QPaintDeviceMetrics* paintDeviceMetrics,  int zoomFactor){    computeFontSizesFor(paintDeviceMetrics, zoomFactor, m_fontSizes, false);    computeFontSizesFor(paintDeviceMetrics, zoomFactor, m_fixedFontSizes, true);}

⌨️ 快捷键说明

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