diff options
Diffstat (limited to 'khtml/css')
34 files changed, 21714 insertions, 0 deletions
diff --git a/khtml/css/Makefile.am b/khtml/css/Makefile.am new file mode 100644 index 000000000..c9f61b8b6 --- /dev/null +++ b/khtml/css/Makefile.am @@ -0,0 +1,60 @@ +# This file is part of the KDE libraries +# Copyright (C) 1997 Martin Jones (mjones@kde.org) +# (C) 1997 Torben Weis (weis@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., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. + +KDE_CXXFLAGS = $(WOVERLOADED_VIRTUAL) + +YACC=bison + +noinst_LTLIBRARIES = libkhtmlcss.la +libkhtmlcss_la_SOURCES = \ + css_stylesheetimpl.cpp css_ruleimpl.cpp css_valueimpl.cpp css_base.cpp \ + cssparser.cpp cssstyleselector.cpp csshelper.cpp parser.cpp \ + css_renderstyledeclarationimpl.cpp + +#libkhtmlcss_la_LDFLAGS = -no-undefined +libkhtmlcss_la_METASOURCES = AUTO + +noinst_HEADERS = \ + css_extensionsimpl.h css_stylesheetimpl.h cssparser.h \ + css_ruleimpl.h css_valueimpl.h css_base.h \ + cssstyleselector.h csshelper.h parser.h \ + css_renderstyledeclarationimpl.h + +INCLUDES = -I$(top_srcdir)/kimgio -I$(top_srcdir)/kio -I$(top_srcdir)/dcop \ + -I$(top_srcdir)/khtml -I$(top_srcdir)/libltdl -I$(top_srcdir) \ + -I$(top_srcdir)/kwallet/client -I$(top_srcdir)/kutils \ + $(all_includes) + +cssdir = $(kde_datadir)/khtml/css +css_DATA = html4.css quirks.css + +SRCDOC_DEST=$(kde_htmldir)/en/kdelibs/khtml + +EXTRA_DIST = parser.y + +parser: $(srcdir)/parser.y + cd $(srcdir); \ + $(YACC) -v -d -p cssyy parser.y && mv parser.tab.c parser.cpp; \ + if test -f parser.tab.h; then \ + if cmp -s parser.tab.h parser.h; then rm -f parser.tab.h; \ + else mv parser.tab.h parser.h; fi \ + else :; fi + +.PHONY: parser + diff --git a/khtml/css/css_base.cpp b/khtml/css/css_base.cpp new file mode 100644 index 000000000..9cca21761 --- /dev/null +++ b/khtml/css/css_base.cpp @@ -0,0 +1,419 @@ +/* + * This file is part of the DOM implementation for KDE. + * + * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) + * 1999 Waldo Bastian (bastian@kde.org) + * 2001 Andreas Schlapbach (schlpbch@iam.unibe.ch) + * 2001-2003 Dirk Mueller (mueller@kde.org) + * 2002 Apple Computer, Inc. + * 2004 Allan Sandfeld Jensen (kde@carewolf.com) + * + * 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. + */ + +//#define CSS_DEBUG + +#include <assert.h> +#include <kdebug.h> + +#include "css_base.h" + +#ifdef CSS_DEBUG +#include "cssproperties.h" +#endif + +#include "css_stylesheetimpl.h" +#include "xml/dom_docimpl.h" +#include "misc/htmlhashes.h" +#include "css_valueimpl.h" +using namespace DOM; + +void StyleBaseImpl::checkLoaded() const +{ + if(m_parent) m_parent->checkLoaded(); +} + +StyleSheetImpl* StyleBaseImpl::stylesheet() +{ + StyleBaseImpl* b = this; + while(b && !b->isStyleSheet()) + b = b->m_parent; + return static_cast<StyleSheetImpl *>(b); +} + +KURL StyleBaseImpl::baseURL() +{ + // try to find the style sheet. If found look for its url. + // If it has none, look for the parentsheet, or the parentNode and + // try to find out about their url + + StyleSheetImpl *sheet = stylesheet(); + + if(!sheet) return KURL(); + + if(!sheet->href().isNull()) + return KURL( sheet->href().string() ); + + // find parent + if(sheet->parent()) return sheet->parent()->baseURL(); + + if(!sheet->ownerNode()) return KURL(); + + return sheet->ownerNode()->getDocument()->baseURL(); +} + +void StyleBaseImpl::setParsedValue(int propId, const CSSValueImpl *parsedValue, + bool important, bool nonCSSHint, QPtrList<CSSProperty> *propList) +{ + QPtrListIterator<CSSProperty> propIt(*propList); + propIt.toLast(); // just remove the top one - not sure what should happen if we have multiple instances of the property + while (propIt.current() && + ( propIt.current()->m_id != propId || propIt.current()->nonCSSHint != nonCSSHint || + propIt.current()->m_important != important) ) + --propIt; + if (propIt.current()) + propList->removeRef(propIt.current()); + + CSSProperty *prop = new CSSProperty(); + prop->m_id = propId; + prop->setValue((CSSValueImpl *) parsedValue); + prop->m_important = important; + prop->nonCSSHint = nonCSSHint; + + propList->append(prop); +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "added property: " << getPropertyName(propId).string() + // non implemented yet << ", value: " << parsedValue->cssText().string() + << " important: " << prop->m_important + << " nonCSS: " << prop->nonCSSHint << endl; +#endif +} + +// ------------------------------------------------------------------------------ + +StyleListImpl::~StyleListImpl() +{ + StyleBaseImpl *n; + + if(!m_lstChildren) return; + + for( n = m_lstChildren->first(); n != 0; n = m_lstChildren->next() ) + { + n->setParent(0); + if( !n->refCount() ) delete n; + } + delete m_lstChildren; +} + +// -------------------------------------------------------------------------------- + +void CSSSelector::print(void) +{ + kdDebug( 6080 ) << "[Selector: tag = " << QString::number(tag,16) << ", attr = \"" << attr << "\", match = \"" << match + << "\" value = \"" << value.string().latin1() << "\" relation = " << (int)relation + << "]" << endl; + if ( tagHistory ) + tagHistory->print(); + kdDebug( 6080 ) << " specificity = " << specificity() << endl; +} + +unsigned int CSSSelector::specificity() const +{ + if ( nonCSSHint ) + return 0; + + int s = ((localNamePart(tag) == anyLocalName) ? 0 : 1); + switch(match) + { + case Id: + s += 0x10000; + break; + case Exact: + case Set: + case List: + case Class: + case Hyphen: + case PseudoClass: + case PseudoElement: + case Contain: + case Begin: + case End: + s += 0x100; + case None: + break; + } + if(tagHistory) + s += tagHistory->specificity(); + // make sure it doesn't overflow + return s & 0xffffff; +} + +void CSSSelector::extractPseudoType() const +{ + if (match != PseudoClass && match != PseudoElement) + return; + _pseudoType = PseudoOther; + bool element = false; + bool compat = false; + if (!value.isEmpty()) { + value = value.lower(); + switch (value[0]) { + case '-': + if (value == "-khtml-replaced") + _pseudoType = PseudoReplaced; + else + if (value == "-khtml-marker") + _pseudoType = PseudoMarker; + element = true; + break; + case 'a': + if (value == "active") + _pseudoType = PseudoActive; + else if (value == "after") { + _pseudoType = PseudoAfter; + element = compat = true; + } + break; + case 'b': + if (value == "before") { + _pseudoType = PseudoBefore; + element = compat = true; + } + break; + case 'c': + if (value == "checked") + _pseudoType = PseudoChecked; + else if (value == "contains(") + _pseudoType = PseudoContains; + break; + case 'd': + if (value == "disabled") + _pseudoType = PseudoDisabled; + break; + case 'e': + if (value == "empty") + _pseudoType = PseudoEmpty; + else if (value == "enabled") + _pseudoType = PseudoEnabled; + break; + case 'f': + if (value == "first-child") + _pseudoType = PseudoFirstChild; + else if (value == "first-letter") { + _pseudoType = PseudoFirstLetter; + element = compat = true; + } + else if (value == "first-line") { + _pseudoType = PseudoFirstLine; + element = compat = true; + } + else if (value == "first-of-type") + _pseudoType = PseudoFirstOfType; + else if (value == "focus") + _pseudoType = PseudoFocus; + break; + case 'h': + if (value == "hover") + _pseudoType = PseudoHover; + break; + case 'i': + if (value == "indeterminate") + _pseudoType = PseudoIndeterminate; + break; + case 'l': + if (value == "link") + _pseudoType = PseudoLink; + else if (value == "lang(") + _pseudoType = PseudoLang; + else if (value == "last-child") + _pseudoType = PseudoLastChild; + else if (value == "last-of-type") + _pseudoType = PseudoLastOfType; + break; + case 'n': + if (value == "not(") + _pseudoType = PseudoNot; + else if (value == "nth-child(") + _pseudoType = PseudoNthChild; + else if (value == "nth-last-child(") + _pseudoType = PseudoNthLastChild; + else if (value == "nth-of-type(") + _pseudoType = PseudoNthOfType; + else if (value == "nth-last-of-type(") + _pseudoType = PseudoNthLastOfType; + break; + case 'o': + if (value == "only-child") + _pseudoType = PseudoOnlyChild; + else if (value == "only-of-type") + _pseudoType = PseudoOnlyOfType; + break; + case 'r': + if (value == "root") + _pseudoType = PseudoRoot; + break; + case 's': + if (value == "selection") { + _pseudoType = PseudoSelection; + element = true; + } + break; + case 't': + if (value == "target") + _pseudoType = PseudoTarget; + break; + case 'v': + if (value == "visited") + _pseudoType = PseudoVisited; + break; + } + } + if (match == PseudoClass && element) + if (!compat) _pseudoType = PseudoOther; + else match = PseudoElement; + else + if (match == PseudoElement && !element) + _pseudoType = PseudoOther; +} + + +bool CSSSelector::operator == ( const CSSSelector &other ) const +{ + const CSSSelector *sel1 = this; + const CSSSelector *sel2 = &other; + + while ( sel1 && sel2 ) { + //assert(sel1->_pseudoType != PseudoNotParsed); + //assert(sel2->_pseudoType != PseudoNotParsed); + if ( sel1->tag != sel2->tag || sel1->attr != sel2->attr || + sel1->relation != sel2->relation || sel1->match != sel2->match || + sel1->nonCSSHint != sel2->nonCSSHint || + sel1->value != sel2->value || + sel1->pseudoType() != sel2->pseudoType() || + sel1->string_arg != sel2->string_arg) + return false; + sel1 = sel1->tagHistory; + sel2 = sel2->tagHistory; + } + if ( sel1 || sel2 ) + return false; + return true; +} + +DOMString CSSSelector::selectorText() const +{ + // FIXME: Support namespaces when dumping the selector text. This requires preserving + // the original namespace prefix used. Ugh. -dwh + DOMString str; + const CSSSelector* cs = this; + Q_UINT16 tag = localNamePart(cs->tag); + if (tag == anyLocalName && cs->match == CSSSelector::None) + str = "*"; + else if (tag != anyLocalName) + str = getTagName( cs->tag ); + + const CSSSelector* op = 0; + while (true) { + if ( cs->attr == ATTR_ID && cs->match == CSSSelector::Id ) + { + str += "#"; + str += cs->value; + } + else if ( cs->match == CSSSelector::Class ) + { + str += "."; + str += cs->value; + } + else if ( cs->match == CSSSelector::PseudoClass ) + { + str += ":"; + str += cs->value; + if (!cs->string_arg.isEmpty()) { // e.g :nth-child(...) + str += cs->string_arg; + str += ")"; + } else if (cs->simpleSelector && !op) { // :not(...) + op = cs; + cs = cs->simpleSelector; + continue; + } + } + else if ( cs->match == CSSSelector::PseudoElement ) + { + str += "::"; + str += cs->value; + } + // optional attribute + else if ( cs->attr ) { + DOMString attrName = getAttrName( cs->attr ); + str += "["; + str += attrName; + switch (cs->match) { + case CSSSelector::Exact: + str += "="; + break; + case CSSSelector::Set: + break; + case CSSSelector::List: + str += "~="; + break; + case CSSSelector::Hyphen: + str += "|="; + break; + case CSSSelector::Begin: + str += "^="; + break; + case CSSSelector::End: + str += "$="; + break; + case CSSSelector::Contain: + str += "*="; + break; + default: + kdWarning(6080) << "Unhandled case in CSSStyleRuleImpl::selectorText : match=" << cs->match << endl; + } + if (cs->match != CSSSelector::Set) { + str += "\""; + str += cs->value; + str += "\""; + } + str += "]"; + } + if (op && !cs->tagHistory) { + cs=op; + op=0; + str += ")"; + } + + if ((cs->relation != CSSSelector::SubSelector && !op) || !cs->tagHistory) + break; + cs = cs->tagHistory; + } + + if ( cs->tagHistory ) { + DOMString tagHistoryText = cs->tagHistory->selectorText(); + if ( cs->relation == DirectAdjacent ) + str = tagHistoryText + " + " + str; + else if ( cs->relation == IndirectAdjacent ) + str = tagHistoryText + " ~ " + str; + else if ( cs->relation == Child ) + str = tagHistoryText + " > " + str; + else // Descendant + str = tagHistoryText + " " + str; + } + return str; +} + +// ---------------------------------------------------------------------------- diff --git a/khtml/css/css_base.h b/khtml/css/css_base.h new file mode 100644 index 000000000..f8b520423 --- /dev/null +++ b/khtml/css/css_base.h @@ -0,0 +1,271 @@ +/* + * This file is part of the CSS implementation for KDE. + * + * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) + * 1999 Waldo Bastian (bastian@kde.org) + * 2002 Apple Computer, Inc. + * 2004 Allan Sandfeld Jensen (kde@carewolf.com) + * + * 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. + * + */ +#ifndef _CSS_BASE_H +#define _CSS_BASE_H + +#include "dom/dom_string.h" +#include "dom/dom_misc.h" +#include "xml/dom_nodeimpl.h" +#include "misc/shared.h" +#include <kdemacros.h> +#include <qdatetime.h> +#include <qptrlist.h> + +namespace DOM { + + class StyleSheetImpl; + class MediaList; + + class CSSSelector; + class CSSProperty; + class CSSValueImpl; + class CSSPrimitiveValueImpl; + class CSSStyleDeclarationImpl; + class CSSRuleImpl; + class CSSStyleRuleImpl; + + class DocumentImpl; + + struct CSSNamespace { + DOMString m_prefix; + DOMString m_uri; + CSSNamespace* m_parent; + + CSSNamespace(const DOMString& p, const DOMString& u, CSSNamespace* parent) + :m_prefix(p), m_uri(u), m_parent(parent) {} + ~CSSNamespace() { delete m_parent; } + + const DOMString& uri() { return m_uri; } + const DOMString& prefix() { return m_prefix; } + + CSSNamespace* namespaceForPrefix(const DOMString& prefix) { + if (prefix == m_prefix) + return this; + if (m_parent) + return m_parent->namespaceForPrefix(prefix); + return 0; + } + }; + +// this class represents a selector for a StyleRule + class CSSSelector + { + public: + CSSSelector() + : tagHistory(0), simpleSelector(0), attr(0), tag(anyQName), relation( Descendant ), + match( None ), nonCSSHint( false ), pseudoId( 0 ), _pseudoType(PseudoNotParsed) + {} + + ~CSSSelector() { + delete tagHistory; + delete simpleSelector; + } + + /** + * Print debug output for this selector + */ + void print(); + + /** + * Re-create selector text from selector's data + */ + DOMString selectorText() const; + + // checks if the 2 selectors (including sub selectors) agree. + bool operator == ( const CSSSelector &other ) const; + + // tag == -1 means apply to all elements (Selector = *) + + unsigned int specificity() const; + + /* how the attribute value has to match.... Default is Exact */ + enum Match + { + None = 0, + Id, + Exact, + Set, + Class, + List, + Hyphen, + PseudoClass, + PseudoElement, + Contain, // css3: E[foo*="bar"] + Begin, // css3: E[foo^="bar"] + End // css3: E[foo$="bar"] + }; + + enum Relation + { + Descendant = 0, + Child, + DirectAdjacent, + IndirectAdjacent, + SubSelector + }; + + enum PseudoType + { + PseudoNotParsed = 0, + PseudoOther, + PseudoEmpty, + PseudoFirstChild, + PseudoLastChild, + PseudoNthChild, + PseudoNthLastChild, + PseudoOnlyChild, + PseudoFirstOfType, + PseudoLastOfType, + PseudoNthOfType, + PseudoNthLastOfType, + PseudoOnlyOfType, + PseudoLink, + PseudoVisited, + PseudoHover, + PseudoFocus, + PseudoActive, + PseudoTarget, + PseudoLang, + PseudoNot, + PseudoContains, + PseudoRoot, + PseudoEnabled, + PseudoDisabled, + PseudoChecked, + PseudoIndeterminate, +// pseudo-elements: + // inherited: + PseudoFirstLine, + PseudoFirstLetter, + PseudoSelection, + // generated: + PseudoBefore, + PseudoAfter, + PseudoMarker, + PseudoReplaced + }; + + PseudoType pseudoType() const { + if (_pseudoType == PseudoNotParsed) + extractPseudoType(); + return _pseudoType; + } + + mutable DOM::DOMString value; + CSSSelector *tagHistory; + CSSSelector* simpleSelector; // Used by :not + DOM::DOMString string_arg; // Used by :contains, :lang and :nth-* + DOM::NodeImpl::Id attr; + DOM::NodeImpl::Id tag; + + Relation relation : 3; + mutable Match match : 4; + bool nonCSSHint : 1; + unsigned int pseudoId : 4; + mutable PseudoType _pseudoType : 6; + + private: + void extractPseudoType() const; + }; + + // a style class which has a parent (almost all have) + class StyleBaseImpl : public khtml::TreeShared<StyleBaseImpl> + { + public: + StyleBaseImpl() { m_parent = 0; hasInlinedDecl = false; strictParsing = true; multiLength = false; } + StyleBaseImpl(StyleBaseImpl *p) { + m_parent = p; hasInlinedDecl = false; + strictParsing = (m_parent ? m_parent->useStrictParsing() : true); + multiLength = false; + } + + virtual ~StyleBaseImpl() {} + + // returns the url of the style sheet this object belongs to + // not const + KURL baseURL(); + + virtual bool isStyleSheet() const { return false; } + virtual bool isCSSStyleSheet() const { return false; } + virtual bool isStyleSheetList() const { return false; } + virtual bool isMediaList() const { return false; } + virtual bool isRuleList() const { return false; } + virtual bool isRule() const { return false; } + virtual bool isStyleRule() const { return false; } + virtual bool isCharetRule() const { return false; } + virtual bool isImportRule() const { return false; } + virtual bool isMediaRule() const { return false; } + virtual bool isFontFaceRule() const { return false; } + virtual bool isPageRule() const { return false; } + virtual bool isUnknownRule() const { return false; } + virtual bool isStyleDeclaration() const { return false; } + virtual bool isValue() const { return false; } + virtual bool isPrimitiveValue() const { return false; } + virtual bool isValueList() const { return false; } + virtual bool isValueCustom() const { return false; } + + void setParent(StyleBaseImpl *parent) { m_parent = parent; } + + static void setParsedValue(int propId, const CSSValueImpl *parsedValue, + bool important, bool nonCSSHint, QPtrList<CSSProperty> *propList); + + virtual bool parseString(const DOMString &/*cssString*/, bool = false) { return false; } + + virtual void checkLoaded() const; + + void setStrictParsing( bool b ) { strictParsing = b; } + bool useStrictParsing() const { return strictParsing; } + + // not const + StyleSheetImpl* stylesheet(); + + protected: + bool hasInlinedDecl : 1; + bool strictParsing : 1; + bool multiLength : 1; + }; + + // a style class which has a list of children (StyleSheets for example) + class StyleListImpl : public StyleBaseImpl + { + public: + StyleListImpl() : StyleBaseImpl() { m_lstChildren = 0; } + StyleListImpl(StyleBaseImpl *parent) : StyleBaseImpl(parent) { m_lstChildren = 0; } + virtual ~StyleListImpl(); + + unsigned long length() const { return m_lstChildren->count(); } + StyleBaseImpl *item(unsigned long num) const { return m_lstChildren->at(num); } + + void append(StyleBaseImpl *item) { m_lstChildren->append(item); } + + protected: + QPtrList<StyleBaseImpl> *m_lstChildren; + }; + + KDE_NO_EXPORT int getPropertyID(const char *tagStr, int len); + +} + +#endif diff --git a/khtml/css/css_extensionsimpl.cpp b/khtml/css/css_extensionsimpl.cpp new file mode 100644 index 000000000..e0e17e207 --- /dev/null +++ b/khtml/css/css_extensionsimpl.cpp @@ -0,0 +1,366 @@ +/** + * This file is part of the DOM implementation for KDE. + * + * (C) 1999 Lars Knoll (knoll@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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ +#include "DOMException.h" +#include "DOMString.h" + +#include "CSS2AzimuthImpl.h" +using namespace DOM; + +CSS2AzimuthImpl::CSS2AzimuthImpl(DocumentImpl *doc) : CSSValueImpl(doc) +{ +} + +CSS2AzimuthImpl::~CSS2AzimuthImpl() +{ +} + +unsigned short CSS2AzimuthImpl::azimuthType() const +{ +} + +DOMString CSS2AzimuthImpl::identifier() const +{ +} + +bool CSS2AzimuthImpl::behind() const +{ +} + +void CSS2AzimuthImpl::setAngleValue( const unsigned short &unitType, const float &floatValue ) +{ +} + +float CSS2AzimuthImpl::getAngleValue( const unsigned short &unitType ) +{ +} + +void CSS2AzimuthImpl::setIdentifier( const DOMString &identifier, const bool &behind ) +{ +} + + + + + +#include "CSS2BackgroundPositionImpl.h" +CSS2BackgroundPositionImpl::CSS2BackgroundPositionImpl(DocumentImpl *doc) : CSSValueImpl(doc) +{ +} + +CSS2BackgroundPositionImpl::~CSS2BackgroundPositionImpl() +{ +} + +unsigned short CSS2BackgroundPositionImpl::horizontalType() const +{ +} + +unsigned short CSS2BackgroundPositionImpl::verticalType() const +{ +} + +DOMString CSS2BackgroundPositionImpl::horizontalIdentifier() const +{ +} + +DOMString CSS2BackgroundPositionImpl::verticalIdentifier() const +{ +} + +float CSS2BackgroundPositionImpl::getHorizontalPosition( const float &horizontalType ) +{ +} + +float CSS2BackgroundPositionImpl::getVerticalPosition( const float &verticalType ) +{ +} + +void CSS2BackgroundPositionImpl::setHorizontalPosition( const unsigned short &horizontalType, const float &value ) +{ +} + +void CSS2BackgroundPositionImpl::setVerticalPosition( const unsigned short &verticalType, const float &value ) +{ +} + +void CSS2BackgroundPositionImpl::setPositionIdentifier( const DOMString &horizontalIdentifier, const DOMString &verticalIdentifier ) +{ +} + + + + + +#include "CSS2BorderSpacingImpl.h" +CSS2BorderSpacingImpl::CSS2BorderSpacingImpl(DocumentImpl *doc) : CSSValueImpl(doc) +{ +} + +CSS2BorderSpacingImpl::~CSS2BorderSpacingImpl() +{ +} + +unsigned short CSS2BorderSpacingImpl::horizontalType() const +{ +} + +unsigned short CSS2BorderSpacingImpl::verticalType() const +{ +} + +float CSS2BorderSpacingImpl::getHorizontalSpacing( const float &horizontalType ) +{ +} + +float CSS2BorderSpacingImpl::getVerticalSpacing( const float &verticalType ) +{ +} + +void CSS2BorderSpacingImpl::setHorizontalSpacing( const unsigned short &horizontalType, const float &value ) +{ +} + +void CSS2BorderSpacingImpl::setVerticalSpacing( const unsigned short &verticalType, const float &value ) +{ +} + +void CSS2BorderSpacingImpl::setInherit() +{ +} + + + + + +#include "CSS2CounterIncrementImpl.h" +CSS2CounterIncrementImpl::CSS2CounterIncrementImpl(DocumentImpl *doc) +{ +} + +CSS2CounterIncrementImpl::~CSS2CounterIncrementImpl() +{ +} + +short CSS2CounterIncrementImpl::increment() const +{ +} + +void CSS2CounterIncrementImpl::setIncrement( const short & ) +{ +} + + + + + +#include "CSS2CounterResetImpl.h" +CSS2CounterResetImpl::CSS2CounterResetImpl(DocumentImpl *doc) +{ +} + +CSS2CounterResetImpl::~CSS2CounterResetImpl() +{ +} + +short CSS2CounterResetImpl::reset() const +{ +} + +void CSS2CounterResetImpl::setReset( const short & ) +{ +} + + + + +#include "CSSValueList.h" +#include "CSS2CursorImpl.h" +CSS2CursorImpl::CSS2CursorImpl(DocumentImpl *doc) : CSSValueImpl(doc) +{ +} + +CSS2CursorImpl::~CSS2CursorImpl() +{ +} + +unsigned short CSS2CursorImpl::cursorType() const +{ +} + +void CSS2CursorImpl::setCursorType( const unsigned short & ) +{ +} + +CSSValueList CSS2CursorImpl::uris() const +{ +} + +#include "CSS2FontFaceSrcImpl.h" +CSS2FontFaceSrcImpl::CSS2FontFaceSrcImpl(DocumentImpl *doc) +{ +} + +CSS2FontFaceSrcImpl::~CSS2FontFaceSrcImpl() +{ +} + +CSSValueList CSS2FontFaceSrcImpl::format() const +{ +} + + + + +#include "CSS2FontFaceWidthsImpl.h" +CSS2FontFaceWidthsImpl::CSS2FontFaceWidthsImpl(DocumentImpl *doc) +{ +} + +CSS2FontFaceWidthsImpl::~CSS2FontFaceWidthsImpl() +{ +} + +CSSValueList CSS2FontFaceWidthsImpl::numbers() const +{ +} + + + + +#include "CSS2PageSizeImpl.h" +CSS2PageSizeImpl::CSS2PageSizeImpl(DocumentImpl *doc) : CSSValueImpl(doc) +{ +} + +CSS2PageSizeImpl::~CSS2PageSizeImpl() +{ +} + +unsigned short CSS2PageSizeImpl::widthType() const +{ +} + +unsigned short CSS2PageSizeImpl::heightType() const +{ +} + +DOMString CSS2PageSizeImpl::identifier() const +{ +} + +float CSS2PageSizeImpl::getWidth( const float &widthType ) +{ +} + +float CSS2PageSizeImpl::getHeightSize( const float &heightType ) +{ +} + +void CSS2PageSizeImpl::setWidthSize( const unsigned short &widthType, const float &value ) +{ +} + +void CSS2PageSizeImpl::setHeightSize( const unsigned short &heightType, const float &value ) +{ +} + +void CSS2PageSizeImpl::setIdentifier( const DOMString &identifier ) +{ +} + + + + +#include "CSS2PlayDuringImpl.h" +CSS2PlayDuringImpl::CSS2PlayDuringImpl(DocumentImpl *doc) : CSSValueImpl(doc) +{ +} + +CSS2PlayDuringImpl::~CSS2PlayDuringImpl() +{ +} + +unsigned short CSS2PlayDuringImpl::playDuringType() const +{ +} + +bool CSS2PlayDuringImpl::mix() const +{ +} + +void CSS2PlayDuringImpl::setMix( const bool & ) +{ +} + +bool CSS2PlayDuringImpl::repeat() const +{ +} + +void CSS2PlayDuringImpl::setRepeat( const bool & ) +{ +} + + + + + +#include "CSS2PropertiesImpl.h" +CSS2PropertiesImpl::CSS2PropertiesImpl(DocumentImpl *doc) +{ +} + +CSS2PropertiesImpl::~CSS2PropertiesImpl() +{ +} + + + + +#include "CSSValue.h" + +#include "CSS2TextShadowImpl.h" +CSS2TextShadowImpl::CSS2TextShadowImpl(DocumentImpl *doc) +{ +} + +CSS2TextShadowImpl::~CSS2TextShadowImpl() +{ +} + +CSSValue CSS2TextShadowImpl::color() const +{ +} + +CSSValue CSS2TextShadowImpl::horizontal() const +{ +} + +CSSValue CSS2TextShadowImpl::vertical() const +{ +} + +CSSValue CSS2TextShadowImpl::blur() const +{ +} + + + diff --git a/khtml/css/css_extensionsimpl.h b/khtml/css/css_extensionsimpl.h new file mode 100644 index 000000000..dba74e217 --- /dev/null +++ b/khtml/css/css_extensionsimpl.h @@ -0,0 +1,205 @@ +/* + * This file is part of the DOM implementation for KDE. + * + * (C) 1999 Lars Knoll (knoll@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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ +#ifndef _CSS_css_extensionsimpl_h_ +#define _CSS_css_extensionsimpl_h_ + +#include "css_valueimpl.h" +#include "dom_string.h" + +namespace DOM { + +class CSS2AzimuthImpl : public CSSValueImpl +{ +public: + CSS2AzimuthImpl(DocumentImpl *doc); + + ~CSS2AzimuthImpl(); + + unsigned short azimuthType() const; + DOM::DOMString identifier() const; + bool behind() const; + void setAngleValue ( const unsigned short &unitType, const float &floatValue ); + float getAngleValue ( const unsigned short &unitType ); + void setIdentifier ( const DOM::DOMString &identifier, const bool &behind ); +}; + + +class DOM::DOMString; + +class CSS2BackgroundPositionImpl : public CSSValueImpl +{ +public: + CSS2BackgroundPositionImpl(DocumentImpl *doc); + + ~CSS2BackgroundPositionImpl(); + + unsigned short horizontalType() const; + unsigned short verticalType() const; + DOM::DOMString horizontalIdentifier() const; + DOM::DOMString verticalIdentifier() const; + float getHorizontalPosition ( const float &horizontalType ); + float getVerticalPosition ( const float &verticalType ); + void setHorizontalPosition ( const unsigned short &horizontalType, const float &value ); + void setVerticalPosition ( const unsigned short &verticalType, const float &value ); + void setPositionIdentifier ( const DOM::DOMString &horizontalIdentifier, const DOM::DOMString &verticalIdentifier ); +}; + + + +class CSS2BorderSpacingImpl : public CSSValueImpl +{ +public: + CSS2BorderSpacingImpl(DocumentImpl *doc); + + ~CSS2BorderSpacingImpl(); + + unsigned short horizontalType() const; + unsigned short verticalType() const; + float getHorizontalSpacing ( const float &horizontalType ); + float getVerticalSpacing ( const float &verticalType ); + void setHorizontalSpacing ( const unsigned short &horizontalType, const float &value ); + void setVerticalSpacing ( const unsigned short &verticalType, const float &value ); + void setInherit(); +}; + + +class CSS2CounterIncrementImpl +{ +public: + CSS2CounterIncrementImpl(DocumentImpl *doc); + + ~CSS2CounterIncrementImpl(); + + short increment() const; + void setIncrement( const short & ); +}; + + +class CSS2CounterResetImpl +{ +public: + CSS2CounterResetImpl(DocumentImpl *doc); + + ~CSS2CounterResetImpl(); + + short reset() const; + void setReset( const short & ); +}; + + +class CSS2CursorImpl : public CSSValueImpl +{ +public: + CSS2CursorImpl(DocumentImpl *doc); + + ~CSS2CursorImpl(); + + unsigned short cursorType() const; + void setCursorType( const unsigned short & ); + + CSSValueList uris() const; +}; + + +class CSS2FontFaceSrcImpl +{ +public: + CSS2FontFaceSrcImpl(DocumentImpl *doc); + + ~CSS2FontFaceSrcImpl(); + + CSSValueList format() const; +}; + + +class CSS2FontFaceWidthsImpl +{ +public: + CSS2FontFaceWidthsImpl(DocumentImpl *doc); + + ~CSS2FontFaceWidthsImpl(); + + CSSValueList numbers() const; +}; + + +class CSS2PageSizeImpl : public CSSValueImpl +{ +public: + CSS2PageSizeImpl(DocumentImpl *doc); + + ~CSS2PageSizeImpl(); + + unsigned short widthType() const; + unsigned short heightType() const; + DOM::DOMString identifier() const; + float getWidth ( const float &widthType ); + float getHeightSize ( const float &heightType ); + void setWidthSize ( const unsigned short &widthType, const float &value ); + void setHeightSize ( const unsigned short &heightType, const float &value ); + void setIdentifier ( const DOM::DOMString &identifier ); +}; + + +class CSS2PlayDuringImpl : public CSSValueImpl +{ +public: + CSS2PlayDuringImpl(DocumentImpl *doc); + + ~CSS2PlayDuringImpl(); + + unsigned short playDuringType() const; + bool mix() const; + + void setMix( const bool & ); + bool repeat() const; + + void setRepeat( const bool & ); +}; + + +class CSS2PropertiesImpl +{ +public: + CSS2PropertiesImpl(DocumentImpl *doc); + + ~CSS2PropertiesImpl(); +}; + + +class CSS2TextShadowImpl +{ +public: + CSS2TextShadowImpl(DocumentImpl *doc); + + ~CSS2TextShadowImpl(); + + CSSValue color() const; + CSSValue horizontal() const; + CSSValue vertical() const; + CSSValue blur() const; +}; + + +}; // namespace + +#endif diff --git a/khtml/css/css_renderstyledeclarationimpl.cpp b/khtml/css/css_renderstyledeclarationimpl.cpp new file mode 100644 index 000000000..25de55f4a --- /dev/null +++ b/khtml/css/css_renderstyledeclarationimpl.cpp @@ -0,0 +1,1147 @@ +/** + * css_renderstyledeclarationimpl.cpp + * + * Copyright (C) 2004 Zack Rusin <zack@kde.org> + * Copyright (C) 2004,2005 Apple Computer, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#include "css_renderstyledeclarationimpl.h" + +#include "rendering/render_style.h" +#include "rendering/render_object.h" + +#include "cssproperties.h" +#include "cssvalues.h" + +using namespace DOM; +using namespace khtml; + +// List of all properties we know how to compute, omitting shorthands. +static const int computedProperties[] = { + CSS_PROP_BACKGROUND_COLOR, + CSS_PROP_BACKGROUND_IMAGE, + CSS_PROP_BACKGROUND_REPEAT, + CSS_PROP_BACKGROUND_ATTACHMENT, + CSS_PROP_BACKGROUND_POSITION, + CSS_PROP_BACKGROUND_POSITION_X, + CSS_PROP_BACKGROUND_POSITION_Y, + CSS_PROP_BORDER_COLLAPSE, + CSS_PROP_BORDER_SPACING, + CSS_PROP__KHTML_BORDER_HORIZONTAL_SPACING, + CSS_PROP__KHTML_BORDER_VERTICAL_SPACING, + CSS_PROP_BORDER_TOP_COLOR, + CSS_PROP_BORDER_RIGHT_COLOR, + CSS_PROP_BORDER_BOTTOM_COLOR, + CSS_PROP_BORDER_LEFT_COLOR, + CSS_PROP_BORDER_TOP_STYLE, + CSS_PROP_BORDER_RIGHT_STYLE, + CSS_PROP_BORDER_BOTTOM_STYLE, + CSS_PROP_BORDER_LEFT_STYLE, + CSS_PROP_BORDER_TOP_WIDTH, + CSS_PROP_BORDER_RIGHT_WIDTH, + CSS_PROP_BORDER_BOTTOM_WIDTH, + CSS_PROP_BORDER_LEFT_WIDTH, + CSS_PROP_BOTTOM, + CSS_PROP_CAPTION_SIDE, + CSS_PROP_CLEAR, + CSS_PROP_COLOR, + CSS_PROP_CURSOR, + CSS_PROP_DIRECTION, + CSS_PROP_DISPLAY, + CSS_PROP_EMPTY_CELLS, + CSS_PROP_FLOAT, + CSS_PROP_FONT_FAMILY, + CSS_PROP_FONT_SIZE, + CSS_PROP_FONT_STYLE, + CSS_PROP_FONT_VARIANT, + CSS_PROP_FONT_WEIGHT, + CSS_PROP_HEIGHT, + CSS_PROP_LEFT, + CSS_PROP_LETTER_SPACING, + CSS_PROP_LINE_HEIGHT, + CSS_PROP_LIST_STYLE_IMAGE, + CSS_PROP_LIST_STYLE_POSITION, + CSS_PROP_LIST_STYLE_TYPE, + CSS_PROP_MARGIN_TOP, + CSS_PROP_MARGIN_RIGHT, + CSS_PROP_MARGIN_BOTTOM, + CSS_PROP_MARGIN_LEFT, + CSS_PROP__KHTML_MARQUEE_DIRECTION, + CSS_PROP__KHTML_MARQUEE_INCREMENT, + CSS_PROP__KHTML_MARQUEE_REPETITION, + CSS_PROP__KHTML_MARQUEE_STYLE, + CSS_PROP_MAX_HEIGHT, + CSS_PROP_MAX_WIDTH, + CSS_PROP_MIN_HEIGHT, + CSS_PROP_MIN_WIDTH, + CSS_PROP_OPACITY, + CSS_PROP_ORPHANS, + CSS_PROP_OUTLINE_STYLE, + CSS_PROP_OVERFLOW, + CSS_PROP_OVERFLOW_X, + CSS_PROP_OVERFLOW_Y, + CSS_PROP_PADDING_TOP, + CSS_PROP_PADDING_RIGHT, + CSS_PROP_PADDING_BOTTOM, + CSS_PROP_PADDING_LEFT, + CSS_PROP_PAGE_BREAK_AFTER, + CSS_PROP_PAGE_BREAK_BEFORE, + CSS_PROP_PAGE_BREAK_INSIDE, + CSS_PROP_POSITION, + CSS_PROP_RIGHT, + CSS_PROP_TABLE_LAYOUT, + CSS_PROP_TEXT_ALIGN, + CSS_PROP_TEXT_DECORATION, + CSS_PROP_TEXT_INDENT, + CSS_PROP_TEXT_SHADOW, + CSS_PROP_TEXT_TRANSFORM, + CSS_PROP_TOP, + CSS_PROP_UNICODE_BIDI, + CSS_PROP_VERTICAL_ALIGN, + CSS_PROP_VISIBILITY, + CSS_PROP_WHITE_SPACE, + CSS_PROP_WIDOWS, + CSS_PROP_WIDTH, + CSS_PROP_WORD_SPACING, + CSS_PROP_Z_INDEX, +}; + +const unsigned numComputedProperties = sizeof(computedProperties) / sizeof(computedProperties[0]); + + +static CSSValueImpl *valueForLength(const Length &length, int max) +{ + if (length.isPercent()) { + return new CSSPrimitiveValueImpl(length.value(), CSSPrimitiveValue::CSS_PERCENTAGE); + } + else { + return new CSSPrimitiveValueImpl(length.minWidth(max), CSSPrimitiveValue::CSS_PX); + } +} + +static CSSValueImpl *valueForBorderStyle(EBorderStyle style) +{ + switch (style) { + case khtml::BNATIVE: + return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_NATIVE); + case khtml::BNONE: + return new CSSPrimitiveValueImpl(CSS_VAL_NONE); + case khtml::BHIDDEN: + return new CSSPrimitiveValueImpl(CSS_VAL_HIDDEN); + case khtml::INSET: + return new CSSPrimitiveValueImpl(CSS_VAL_INSET); + case khtml::GROOVE: + return new CSSPrimitiveValueImpl(CSS_VAL_GROOVE); + case khtml::RIDGE: + return new CSSPrimitiveValueImpl(CSS_VAL_RIDGE); + case khtml::OUTSET: + return new CSSPrimitiveValueImpl(CSS_VAL_OUTSET); + case khtml::DOTTED: + return new CSSPrimitiveValueImpl(CSS_VAL_DOTTED); + case khtml::DASHED: + return new CSSPrimitiveValueImpl(CSS_VAL_DASHED); + case khtml::SOLID: + return new CSSPrimitiveValueImpl(CSS_VAL_SOLID); + case khtml::DOUBLE: + return new CSSPrimitiveValueImpl(CSS_VAL_DOUBLE); + } + Q_ASSERT( 0 ); + return 0; +} + +static CSSValueImpl *valueForTextAlign(ETextAlign align) +{ + switch (align) { + case khtml::TAAUTO: + return new CSSPrimitiveValueImpl(CSS_VAL_AUTO); + case khtml::LEFT: + return new CSSPrimitiveValueImpl(CSS_VAL_LEFT); + case khtml::RIGHT: + return new CSSPrimitiveValueImpl(CSS_VAL_RIGHT); + case khtml::CENTER: + return new CSSPrimitiveValueImpl(CSS_VAL_CENTER); + case khtml::JUSTIFY: + return new CSSPrimitiveValueImpl(CSS_VAL_JUSTIFY); + case khtml::KHTML_LEFT: + return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_LEFT); + case khtml::KHTML_RIGHT: + return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_RIGHT); + case khtml::KHTML_CENTER: + return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_CENTER); + } + Q_ASSERT( 0 ); + return 0; +} + +DOMString khtml::stringForListStyleType(EListStyleType type) +{ + switch (type) { + case khtml::LDISC: + return "disc"; + case khtml::LCIRCLE: + return "circle"; + case khtml::LSQUARE: + return "square"; + case khtml::LBOX: + return "box"; + case khtml::LDIAMOND: + return "-khtml-diamond"; + case khtml::LDECIMAL: + return "decimal"; + case khtml::DECIMAL_LEADING_ZERO: + return "decimal-leading-zero"; + case khtml::ARABIC_INDIC: + return "-khtml-arabic-indic"; + case khtml::LAO: + return "-khtml-lao"; + case khtml::PERSIAN: + return "-khtml-persian"; + case khtml::URDU: + return "-khtml-urdu"; + case khtml::THAI: + return "-khtml-thai"; + case khtml::TIBETAN: + return "-khtml-tibetan"; + case khtml::LOWER_ROMAN: + return "lower-roman"; + case khtml::UPPER_ROMAN: + return "upper-roman"; + case khtml::HEBREW: + return "hebrew"; + case khtml::ARMENIAN: + return "armenian"; + case khtml::GEORGIAN: + return "georgian"; + case khtml::CJK_IDEOGRAPHIC: + return "cjk-ideographic"; + case khtml::JAPANESE_FORMAL: + return "-khtml-japanese-formal"; + case khtml::JAPANESE_INFORMAL: + return "-khtml-japanese-informal"; + case khtml::SIMP_CHINESE_FORMAL: + return "-khtml-simp-chinese-formal"; + case khtml::SIMP_CHINESE_INFORMAL: + return "-khtml-simp-chinese-informal"; + case khtml::TRAD_CHINESE_FORMAL: + return "-khtml-trad-chinese-formal"; + case khtml::TRAD_CHINESE_INFORMAL: + return "-khtml-trad-chinese-informal"; + case khtml::LOWER_GREEK: + return "lower-greek"; + case khtml::UPPER_GREEK: + return "-khtml-upper-greek"; + case khtml::LOWER_ALPHA: + return "lower-alpha"; + case khtml::UPPER_ALPHA: + return "upper-alpha"; + case khtml::LOWER_LATIN: + return "lower-latin"; + case khtml::UPPER_LATIN: + return "upper-latin"; + case khtml::HIRAGANA: + return "hiragana"; + case khtml::KATAKANA: + return "katakana"; + case khtml::HIRAGANA_IROHA: + return "hiragana-iroha"; + case khtml::KATAKANA_IROHA: + return "katakana_iroha"; + case khtml::LNONE: + return "none"; + } + Q_ASSERT( 0 ); + return ""; +} + +static CSSPrimitiveValueImpl* valueForColor(QColor color) +{ + if (color.isValid()) + return new CSSPrimitiveValueImpl(color.rgb());//### KDE4: use rgba! + else + return new CSSPrimitiveValueImpl(khtml::transparentColor); +} + +static CSSValueImpl* valueForShadow(const ShadowData *shadow) +{ + if (!shadow) + return new CSSPrimitiveValueImpl(CSS_VAL_NONE); + CSSValueListImpl *list = new CSSValueListImpl; + for (const ShadowData *s = shadow; s; s = s->next) { + CSSPrimitiveValueImpl *x = new CSSPrimitiveValueImpl(s->x, CSSPrimitiveValue::CSS_PX); + CSSPrimitiveValueImpl *y = new CSSPrimitiveValueImpl(s->y, CSSPrimitiveValue::CSS_PX); + CSSPrimitiveValueImpl *blur = new CSSPrimitiveValueImpl(s->blur, CSSPrimitiveValue::CSS_PX); + CSSPrimitiveValueImpl *color = valueForColor(s->color); + list->append(new ShadowValueImpl(x, y, blur, color)); + } + return list; +} + +static CSSValueImpl *getPositionOffsetValue(RenderObject *renderer, int propertyID) +{ + if (!renderer) + return 0; + + RenderStyle *style = renderer->style(); + if (!style) + return 0; + + Length l; + switch (propertyID) { + case CSS_PROP_LEFT: + l = style->left(); + break; + case CSS_PROP_RIGHT: + l = style->right(); + break; + case CSS_PROP_TOP: + l = style->top(); + break; + case CSS_PROP_BOTTOM: + l = style->bottom(); + break; + default: + return 0; + } + + if (renderer->isPositioned()) + return valueForLength(l, renderer->contentWidth()); + + if (renderer->isRelPositioned()) + // FIXME: It's not enough to simply return "auto" values for one offset if the other side is defined. + // In other words if left is auto and right is not auto, then left's computed value is negative right. + // So we should get the opposite length unit and see if it is auto. + return valueForLength(l, renderer->contentWidth()); + + return new CSSPrimitiveValueImpl(CSS_VAL_AUTO); + } + +RenderStyleDeclarationImpl::RenderStyleDeclarationImpl( DOM::NodeImpl *node ) + : CSSStyleDeclarationImpl(0), m_node(node) +{ + //kdDebug() << "Render Style Declaration created" << endl; +} + +RenderStyleDeclarationImpl::~RenderStyleDeclarationImpl() +{ + //kdDebug() << "Render Style Declaration destroyed" << endl; +} + +DOM::DOMString RenderStyleDeclarationImpl::cssText() const +{ + DOMString result; + + for (unsigned i = 0; i < numComputedProperties; i++) { + if (i != 0) + result += " "; + result += getPropertyName(computedProperties[i]); + result += ": "; + result += getPropertyValue(computedProperties[i]); + result += ";"; + } + + return result; +} + +void RenderStyleDeclarationImpl::setCssText( DOM::DOMString ) +{ + // ### report that this sucka is read only +} + +CSSValueImpl *RenderStyleDeclarationImpl::getPropertyCSSValue( int propertyID ) const +{ + NodeImpl *node = m_node.get(); + if (!node) + return 0; + + // Make sure our layout is up to date before we allow a query on these attributes. + DocumentImpl* docimpl = node->getDocument(); + if (docimpl) { + docimpl->updateLayout(); + } + + RenderObject *renderer = m_node->renderer(); + if (!renderer) + return 0; + RenderStyle *style = renderer->style(); + if (!style) + return 0; + + switch(propertyID) + { + case CSS_PROP_BACKGROUND_COLOR: + return valueForColor(style->backgroundColor()); + case CSS_PROP_BACKGROUND_IMAGE: + if (style->backgroundImage()) + return new CSSPrimitiveValueImpl(style->backgroundImage()->url(), + CSSPrimitiveValue::CSS_URI); + return new CSSPrimitiveValueImpl(CSS_VAL_NONE); + case CSS_PROP_BACKGROUND_REPEAT: + switch (style->backgroundRepeat()) { + case khtml::REPEAT: + return new CSSPrimitiveValueImpl(CSS_VAL_REPEAT); + case khtml::REPEAT_X: + return new CSSPrimitiveValueImpl(CSS_VAL_REPEAT_X); + case khtml::REPEAT_Y: + return new CSSPrimitiveValueImpl(CSS_VAL_REPEAT_Y); + case khtml::NO_REPEAT: + return new CSSPrimitiveValueImpl(CSS_VAL_NO_REPEAT); + default: + Q_ASSERT( 0 ); + } + case CSS_PROP_BACKGROUND_ATTACHMENT: + if (style->backgroundAttachment()) + return new CSSPrimitiveValueImpl(CSS_VAL_SCROLL); + else + return new CSSPrimitiveValueImpl(CSS_VAL_FIXED); + case CSS_PROP_BACKGROUND_POSITION: + { + DOMString string; + Length length(style->backgroundXPosition()); + if (length.isPercent()) + string = QString::number(length.value()) + "%"; + else + string = QString::number(length.minWidth(renderer->contentWidth())); + string += " "; + length = style->backgroundYPosition(); + if (length.isPercent()) + string += QString::number(length.value()) + "%"; + else + string += QString::number(length.minWidth(renderer->contentWidth())); + return new CSSPrimitiveValueImpl(string, CSSPrimitiveValue::CSS_STRING); + } + case CSS_PROP_BACKGROUND_POSITION_X: + return valueForLength(style->backgroundXPosition(), renderer->contentWidth()); + case CSS_PROP_BACKGROUND_POSITION_Y: + return valueForLength(style->backgroundYPosition(), renderer->contentHeight()); + case CSS_PROP_BORDER_COLLAPSE: + if (style->borderCollapse()) + return new CSSPrimitiveValueImpl(CSS_VAL_COLLAPSE); + else + return new CSSPrimitiveValueImpl(CSS_VAL_SEPARATE); + case CSS_PROP_BORDER_SPACING: + { + QString string(QString::number(style->borderHorizontalSpacing()) + + "px " + + QString::number(style->borderVerticalSpacing()) + + "px"); + return new CSSPrimitiveValueImpl(string, CSSPrimitiveValue::CSS_STRING); + } + case CSS_PROP__KHTML_BORDER_HORIZONTAL_SPACING: + return new CSSPrimitiveValueImpl(style->borderHorizontalSpacing(), + CSSPrimitiveValue::CSS_PX); + case CSS_PROP__KHTML_BORDER_VERTICAL_SPACING: + return new CSSPrimitiveValueImpl(style->borderVerticalSpacing(), + CSSPrimitiveValue::CSS_PX); + case CSS_PROP_BORDER_TOP_COLOR: + return valueForColor(style->borderTopColor()); + case CSS_PROP_BORDER_RIGHT_COLOR: + return valueForColor(style->borderRightColor()); + case CSS_PROP_BORDER_BOTTOM_COLOR: + return valueForColor(style->borderBottomColor()); + case CSS_PROP_BORDER_LEFT_COLOR: + return valueForColor(style->borderLeftColor()); + case CSS_PROP_BORDER_TOP_STYLE: + return valueForBorderStyle(style->borderTopStyle()); + case CSS_PROP_BORDER_RIGHT_STYLE: + return valueForBorderStyle(style->borderRightStyle()); + case CSS_PROP_BORDER_BOTTOM_STYLE: + return valueForBorderStyle(style->borderBottomStyle()); + case CSS_PROP_BORDER_LEFT_STYLE: + return valueForBorderStyle(style->borderLeftStyle()); + case CSS_PROP_BORDER_TOP_WIDTH: + return new CSSPrimitiveValueImpl( style->borderTopWidth(), CSSPrimitiveValue::CSS_PX ); + case CSS_PROP_BORDER_RIGHT_WIDTH: + return new CSSPrimitiveValueImpl( style->borderRightWidth(), CSSPrimitiveValue::CSS_PX ); + case CSS_PROP_BORDER_BOTTOM_WIDTH: + return new CSSPrimitiveValueImpl( style->borderBottomWidth(), CSSPrimitiveValue::CSS_PX ); + case CSS_PROP_BORDER_LEFT_WIDTH: + return new CSSPrimitiveValueImpl( style->borderLeftWidth(), CSSPrimitiveValue::CSS_PX ); + case CSS_PROP_BOTTOM: + return getPositionOffsetValue(renderer, CSS_PROP_BOTTOM); + case CSS_PROP_CAPTION_SIDE: + switch (style->captionSide()) { + case CAPLEFT: + return new CSSPrimitiveValueImpl(CSS_VAL_LEFT); + case CAPRIGHT: + return new CSSPrimitiveValueImpl(CSS_VAL_RIGHT); + case CAPTOP: + return new CSSPrimitiveValueImpl(CSS_VAL_TOP); + case CAPBOTTOM: + return new CSSPrimitiveValueImpl(CSS_VAL_BOTTOM); + } + Q_ASSERT(0); + break; + case CSS_PROP_CLEAR: + switch (style->clear()) { + case CNONE: + return new CSSPrimitiveValueImpl(CSS_VAL_NONE); + case CLEFT: + return new CSSPrimitiveValueImpl(CSS_VAL_LEFT); + case CRIGHT: + return new CSSPrimitiveValueImpl(CSS_VAL_RIGHT); + case CBOTH: + return new CSSPrimitiveValueImpl(CSS_VAL_BOTH); + } + Q_ASSERT(0); + break; + case CSS_PROP_CLIP: + break; + case CSS_PROP_COLOR: + return valueForColor(style->color()); + case CSS_PROP_CONTENT: + break; + case CSS_PROP_COUNTER_INCREMENT: + break; + case CSS_PROP_COUNTER_RESET: + break; + case CSS_PROP_CURSOR: + switch (style->cursor()) { + case CURSOR_AUTO: + return new CSSPrimitiveValueImpl(CSS_VAL_AUTO); + case CURSOR_CROSS: + return new CSSPrimitiveValueImpl(CSS_VAL_CROSSHAIR); + case CURSOR_DEFAULT: + return new CSSPrimitiveValueImpl(CSS_VAL_DEFAULT); + case CURSOR_POINTER: + return new CSSPrimitiveValueImpl(CSS_VAL_POINTER); + case CURSOR_MOVE: + return new CSSPrimitiveValueImpl(CSS_VAL_MOVE); + case CURSOR_PROGRESS: + return new CSSPrimitiveValueImpl(CSS_VAL_PROGRESS); + case CURSOR_E_RESIZE: + return new CSSPrimitiveValueImpl(CSS_VAL_E_RESIZE); + case CURSOR_NE_RESIZE: + return new CSSPrimitiveValueImpl(CSS_VAL_NE_RESIZE); + case CURSOR_NW_RESIZE: + return new CSSPrimitiveValueImpl(CSS_VAL_NW_RESIZE); + case CURSOR_N_RESIZE: + return new CSSPrimitiveValueImpl(CSS_VAL_N_RESIZE); + case CURSOR_SE_RESIZE: + return new CSSPrimitiveValueImpl(CSS_VAL_SE_RESIZE); + case CURSOR_SW_RESIZE: + return new CSSPrimitiveValueImpl(CSS_VAL_SW_RESIZE); + case CURSOR_S_RESIZE: + return new CSSPrimitiveValueImpl(CSS_VAL_S_RESIZE); + case CURSOR_W_RESIZE: + return new CSSPrimitiveValueImpl(CSS_VAL_W_RESIZE); + case CURSOR_TEXT: + return new CSSPrimitiveValueImpl(CSS_VAL_TEXT); + case CURSOR_WAIT: + return new CSSPrimitiveValueImpl(CSS_VAL_WAIT); + case CURSOR_HELP: + return new CSSPrimitiveValueImpl(CSS_VAL_HELP); + } + Q_ASSERT(0); + break; + case CSS_PROP_DIRECTION: + switch (style->direction()) { + case LTR: + return new CSSPrimitiveValueImpl(CSS_VAL_LTR); + case RTL: + return new CSSPrimitiveValueImpl(CSS_VAL_RTL); + } + Q_ASSERT(0); + break; + case CSS_PROP_DISPLAY: + switch (style->display()) { + case INLINE: + return new CSSPrimitiveValueImpl(CSS_VAL_INLINE); + case BLOCK: + return new CSSPrimitiveValueImpl(CSS_VAL_BLOCK); + case LIST_ITEM: + return new CSSPrimitiveValueImpl(CSS_VAL_LIST_ITEM); + case RUN_IN: + return new CSSPrimitiveValueImpl(CSS_VAL_RUN_IN); + case COMPACT: + return new CSSPrimitiveValueImpl(CSS_VAL_COMPACT); + case INLINE_BLOCK: + return new CSSPrimitiveValueImpl(CSS_VAL_INLINE_BLOCK); + case TABLE: + return new CSSPrimitiveValueImpl(CSS_VAL_TABLE); + case INLINE_TABLE: + return new CSSPrimitiveValueImpl(CSS_VAL_INLINE_TABLE); + case TABLE_ROW_GROUP: + return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_ROW_GROUP); + case TABLE_HEADER_GROUP: + return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_HEADER_GROUP); + case TABLE_FOOTER_GROUP: + return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_FOOTER_GROUP); + case TABLE_ROW: + return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_ROW); + case TABLE_COLUMN_GROUP: + return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_COLUMN_GROUP); + case TABLE_COLUMN: + return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_COLUMN); + case TABLE_CELL: + return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_CELL); + case TABLE_CAPTION: + return new CSSPrimitiveValueImpl(CSS_VAL_TABLE_CAPTION); + case NONE: + return new CSSPrimitiveValueImpl(CSS_VAL_NONE); + } + Q_ASSERT( 0 ); + break; + case CSS_PROP_EMPTY_CELLS: + switch (style->emptyCells()) { + case SHOW: + return new CSSPrimitiveValueImpl(CSS_VAL_SHOW); + case HIDE: + return new CSSPrimitiveValueImpl(CSS_VAL_HIDE); + } + Q_ASSERT( 0 ); + break; + case CSS_PROP_FLOAT: + { + switch (style->floating()) { + case FNONE: + return new CSSPrimitiveValueImpl(CSS_VAL_NONE); + case FLEFT: + return new CSSPrimitiveValueImpl(CSS_VAL_LEFT); + case FRIGHT: + return new CSSPrimitiveValueImpl(CSS_VAL_RIGHT); + case FLEFT_ALIGN: + return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_LEFT); + case FRIGHT_ALIGN: + return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_RIGHT); + } + } + case CSS_PROP_FONT_FAMILY: + { + FontDef def = style->htmlFont().getFontDef(); + return new CSSPrimitiveValueImpl(def.family, CSSPrimitiveValue::CSS_STRING); + } + case CSS_PROP_FONT_SIZE: + { + FontDef def = style->htmlFont().getFontDef(); + return new CSSPrimitiveValueImpl(def.size, CSSPrimitiveValue::CSS_PX); + } + case CSS_PROP_FONT_STYLE: + { + // FIXME: handle oblique + FontDef def = style->htmlFont().getFontDef(); + if (def.italic) + return new CSSPrimitiveValueImpl(CSS_VAL_ITALIC); + else + return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL); + } + case CSS_PROP_FONT_VARIANT: + { + FontDef def = style->htmlFont().getFontDef(); + if (def.smallCaps) + return new CSSPrimitiveValueImpl(CSS_VAL_SMALL_CAPS); + else + return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL); + } + case CSS_PROP_FONT_WEIGHT: + { + // FIXME: this does not reflect the full range of weights + // that can be expressed with CSS + FontDef def = style->htmlFont().getFontDef(); + if (def.weight == QFont::Bold) + return new CSSPrimitiveValueImpl(CSS_VAL_BOLD); + else + return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL); + } + case CSS_PROP_HEIGHT: + return new CSSPrimitiveValueImpl(renderer->contentHeight(), CSSPrimitiveValue::CSS_PX); + case CSS_PROP_LEFT: + return getPositionOffsetValue(renderer, CSS_PROP_LEFT); + case CSS_PROP_LETTER_SPACING: + if (style->letterSpacing() == 0) + return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL); + return new CSSPrimitiveValueImpl(style->letterSpacing(), CSSPrimitiveValue::CSS_PX); + case CSS_PROP_LINE_HEIGHT: + { + // Note: internally a specified <number> value gets encoded as a percentage, + // so the isPercent() case corresponds to the <number> case; + // values < 0 are used to mark "normal"; and specified %% + // get computed down to px by the time they get to RenderStyle + // already + Length length(style->lineHeight()); + if (length.value() < 0) + return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL); + if (length.isPercent()) { + //XXX: merge from webcore the computedStyle/specifiedStyle distinction in rendering/font.h + float computedSize = style->htmlFont().getFontDef().size; + return new CSSPrimitiveValueImpl((int)(length.value() * computedSize) / 100, CSSPrimitiveValue::CSS_PX); + } + else { + return new CSSPrimitiveValueImpl(length.value(), CSSPrimitiveValue::CSS_PX); + } + } + case CSS_PROP_LIST_STYLE_IMAGE: + if (style->listStyleImage()) + return new CSSPrimitiveValueImpl(style->listStyleImage()->url(), CSSPrimitiveValue::CSS_URI); + return new CSSPrimitiveValueImpl(CSS_VAL_NONE); + case CSS_PROP_LIST_STYLE_POSITION: + switch (style->listStylePosition()) { + case OUTSIDE: + return new CSSPrimitiveValueImpl(CSS_VAL_OUTSIDE); + case INSIDE: + return new CSSPrimitiveValueImpl(CSS_VAL_INSIDE); + } + Q_ASSERT( 0 ); + break; + case CSS_PROP_LIST_STYLE_TYPE: + return new CSSPrimitiveValueImpl(stringForListStyleType(style->listStyleType()), CSSPrimitiveValue::CSS_STRING); + case CSS_PROP_MARGIN_TOP: + return valueForLength(style->marginTop(), renderer->contentHeight()); + case CSS_PROP_MARGIN_RIGHT: + return valueForLength(style->marginRight(), renderer->contentWidth()); + case CSS_PROP_MARGIN_BOTTOM: + return valueForLength(style->marginBottom(), renderer->contentHeight()); + case CSS_PROP_MARGIN_LEFT: + return valueForLength(style->marginLeft(), renderer->contentWidth()); + case CSS_PROP__KHTML_MARQUEE: + // FIXME: unimplemented + break; + case CSS_PROP__KHTML_MARQUEE_DIRECTION: + switch (style->marqueeDirection()) { + case MFORWARD: + return new CSSPrimitiveValueImpl(CSS_VAL_FORWARDS); + case MBACKWARD: + return new CSSPrimitiveValueImpl(CSS_VAL_BACKWARDS); + case MAUTO: + return new CSSPrimitiveValueImpl(CSS_VAL_AUTO); + case MUP: + return new CSSPrimitiveValueImpl(CSS_VAL_UP); + case MDOWN: + return new CSSPrimitiveValueImpl(CSS_VAL_DOWN); + case MLEFT: + return new CSSPrimitiveValueImpl(CSS_VAL_LEFT); + case MRIGHT: + return new CSSPrimitiveValueImpl(CSS_VAL_RIGHT); + } + Q_ASSERT(0); + return 0; + case CSS_PROP__KHTML_MARQUEE_INCREMENT: + return valueForLength(style->marqueeIncrement(), renderer->contentWidth()); + case CSS_PROP__KHTML_MARQUEE_REPETITION: + if (style->marqueeLoopCount() < 0) + return new CSSPrimitiveValueImpl(CSS_VAL_INFINITE); + return new CSSPrimitiveValueImpl(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER); + case CSS_PROP__KHTML_MARQUEE_SPEED: + // FIXME: unimplemented + break; + case CSS_PROP__KHTML_MARQUEE_STYLE: + switch (style->marqueeBehavior()) { + case MNONE: + return new CSSPrimitiveValueImpl(CSS_VAL_NONE); + case MSCROLL: + return new CSSPrimitiveValueImpl(CSS_VAL_SCROLL); + case MSLIDE: + return new CSSPrimitiveValueImpl(CSS_VAL_SLIDE); + case MALTERNATE: + return new CSSPrimitiveValueImpl(CSS_VAL_ALTERNATE); + case MUNFURL: + return new CSSPrimitiveValueImpl(CSS_VAL_UNFURL); + } + Q_ASSERT(0); + return 0; + case CSS_PROP_MAX_HEIGHT: + return new CSSPrimitiveValueImpl( renderer->availableHeight(), + CSSPrimitiveValue::CSS_PX ); + break; + case CSS_PROP_MAX_WIDTH: + return new CSSPrimitiveValueImpl( renderer->maxWidth(), + CSSPrimitiveValue::CSS_PX ); + break; + case CSS_PROP_MIN_HEIGHT: + return new CSSPrimitiveValueImpl( renderer->contentHeight(), + CSSPrimitiveValue::CSS_PX ); + break; + case CSS_PROP_MIN_WIDTH: + return new CSSPrimitiveValueImpl( renderer->minWidth(), + CSSPrimitiveValue::CSS_PX ); + break; + case CSS_PROP_OPACITY: + return new CSSPrimitiveValueImpl(style->opacity(), CSSPrimitiveValue::CSS_NUMBER); + case CSS_PROP_ORPHANS: + return new CSSPrimitiveValueImpl(style->orphans(), CSSPrimitiveValue::CSS_NUMBER); + case CSS_PROP_OUTLINE_COLOR: + break; + case CSS_PROP_OUTLINE_OFFSET: + break; + case CSS_PROP_OUTLINE_STYLE: + if (style->outlineStyleIsAuto()) + return new CSSPrimitiveValueImpl(CSS_VAL_AUTO); + return valueForBorderStyle(style->outlineStyle()); + case CSS_PROP_OUTLINE_WIDTH: + break; + case CSS_PROP_OVERFLOW: + case CSS_PROP_OVERFLOW_X: + case CSS_PROP_OVERFLOW_Y: { + EOverflow overflow; + switch (propertyID) { + case CSS_PROP_OVERFLOW_X: + overflow = style->overflowX(); + break; + case CSS_PROP_OVERFLOW_Y: + overflow = style->overflowY(); + break; + default: + overflow = kMax(style->overflowX(), style->overflowY()); + } + switch (overflow) { + case OVISIBLE: + return new CSSPrimitiveValueImpl(CSS_VAL_VISIBLE); + case OHIDDEN: + return new CSSPrimitiveValueImpl(CSS_VAL_HIDDEN); + case OSCROLL: + return new CSSPrimitiveValueImpl(CSS_VAL_SCROLL); + case OAUTO: + return new CSSPrimitiveValueImpl(CSS_VAL_AUTO); + case OMARQUEE: + return new CSSPrimitiveValueImpl(CSS_VAL_MARQUEE); + } + Q_ASSERT(0); + return 0; + } + case CSS_PROP_PADDING_TOP: + return valueForLength(style->paddingTop(), renderer->contentHeight()); + case CSS_PROP_PADDING_RIGHT: + return valueForLength(style->paddingRight(), renderer->contentWidth()); + case CSS_PROP_PADDING_BOTTOM: + return valueForLength(style->paddingBottom(), renderer->contentHeight()); + case CSS_PROP_PADDING_LEFT: + return valueForLength(style->paddingLeft(), renderer->contentWidth()); + case CSS_PROP_PAGE_BREAK_AFTER: + switch (style->pageBreakAfter()) { + case PBAUTO: + return new CSSPrimitiveValueImpl(CSS_VAL_AUTO); + case PBALWAYS: + return new CSSPrimitiveValueImpl(CSS_VAL_ALWAYS); + case PBAVOID: + return new CSSPrimitiveValueImpl(CSS_VAL_AVOID); + case PBLEFT: + return new CSSPrimitiveValueImpl(CSS_VAL_LEFT); + case PBRIGHT: + return new CSSPrimitiveValueImpl(CSS_VAL_RIGHT); + } + Q_ASSERT(0); + break; + case CSS_PROP_PAGE_BREAK_BEFORE: + switch (style->pageBreakBefore()) { + case PBAUTO: + return new CSSPrimitiveValueImpl(CSS_VAL_AUTO); + case PBALWAYS: + return new CSSPrimitiveValueImpl(CSS_VAL_ALWAYS); + case PBAVOID: + return new CSSPrimitiveValueImpl(CSS_VAL_AVOID); + case PBLEFT: + return new CSSPrimitiveValueImpl(CSS_VAL_LEFT); + case PBRIGHT: + return new CSSPrimitiveValueImpl(CSS_VAL_RIGHT); + } + Q_ASSERT(0); + break; + case CSS_PROP_PAGE_BREAK_INSIDE: + if (style->pageBreakInside()) + return new CSSPrimitiveValueImpl(CSS_VAL_AUTO); + else + return new CSSPrimitiveValueImpl(CSS_VAL_AVOID); + Q_ASSERT(0); + break; + case CSS_PROP_POSITION: + switch (style->position()) { + case STATIC: + return new CSSPrimitiveValueImpl(CSS_VAL_STATIC); + case RELATIVE: + return new CSSPrimitiveValueImpl(CSS_VAL_RELATIVE); + case ABSOLUTE: + return new CSSPrimitiveValueImpl(CSS_VAL_ABSOLUTE); + case FIXED: + return new CSSPrimitiveValueImpl(CSS_VAL_FIXED); + } + Q_ASSERT(0); + break; + case CSS_PROP_QUOTES: + break; + case CSS_PROP_RIGHT: + return getPositionOffsetValue(renderer, CSS_PROP_RIGHT); + case CSS_PROP_SIZE: + break; + case CSS_PROP_TABLE_LAYOUT: + switch (style->tableLayout()) { + case TAUTO: + return new CSSPrimitiveValueImpl(CSS_VAL_AUTO); + case TFIXED: + return new CSSPrimitiveValueImpl(CSS_VAL_FIXED); + } + Q_ASSERT(0); + break; + case CSS_PROP_TEXT_ALIGN: + return valueForTextAlign(style->textAlign()); + case CSS_PROP_TEXT_DECORATION: + { + QString string; + if (style->textDecoration() & khtml::UNDERLINE) + string += "underline"; + if (style->textDecoration() & khtml::OVERLINE) { + if (string.length() > 0) + string += " "; + string += "overline"; + } + if (style->textDecoration() & khtml::LINE_THROUGH) { + if (string.length() > 0) + string += " "; + string += "line-through"; + } + if (style->textDecoration() & khtml::BLINK) { + if (string.length() > 0) + string += " "; + string += "blink"; + } + if (string.length() == 0) + string = "none"; + return new CSSPrimitiveValueImpl(string, CSSPrimitiveValue::CSS_STRING); + } + case CSS_PROP_TEXT_INDENT: + return valueForLength(style->textIndent(), renderer->contentWidth()); + case CSS_PROP_TEXT_SHADOW: + return valueForShadow(style->textShadow()); + case CSS_PROP_TEXT_TRANSFORM: + switch (style->textTransform()) { + case CAPITALIZE: + return new CSSPrimitiveValueImpl(CSS_VAL_CAPITALIZE); + case UPPERCASE: + return new CSSPrimitiveValueImpl(CSS_VAL_UPPERCASE); + case LOWERCASE: + return new CSSPrimitiveValueImpl(CSS_VAL_LOWERCASE); + case TTNONE: + return new CSSPrimitiveValueImpl(CSS_VAL_NONE); + } + Q_ASSERT(0); + break; + case CSS_PROP_TOP: + return getPositionOffsetValue(renderer, CSS_PROP_TOP); + case CSS_PROP_UNICODE_BIDI: + switch (style->unicodeBidi()) { + case UBNormal: + return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL); + case Embed: + return new CSSPrimitiveValueImpl(CSS_VAL_EMBED); + case Override: + return new CSSPrimitiveValueImpl(CSS_VAL_BIDI_OVERRIDE); + } + Q_ASSERT(0); + break; + case CSS_PROP_VERTICAL_ALIGN: + { + switch (style->verticalAlign()) { + case BASELINE: + return new CSSPrimitiveValueImpl(CSS_VAL_BASELINE); + case MIDDLE: + return new CSSPrimitiveValueImpl(CSS_VAL_MIDDLE); + case SUB: + return new CSSPrimitiveValueImpl(CSS_VAL_SUB); + case SUPER: + return new CSSPrimitiveValueImpl(CSS_VAL_SUPER); + case TEXT_TOP: + return new CSSPrimitiveValueImpl(CSS_VAL_TEXT_TOP); + case TEXT_BOTTOM: + return new CSSPrimitiveValueImpl(CSS_VAL_TEXT_BOTTOM); + case TOP: + return new CSSPrimitiveValueImpl(CSS_VAL_TOP); + case BOTTOM: + return new CSSPrimitiveValueImpl(CSS_VAL_BOTTOM); + case BASELINE_MIDDLE: + return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_BASELINE_MIDDLE); + case LENGTH: + return valueForLength(style->verticalAlignLength(), renderer->contentWidth()); + } + Q_ASSERT(0); + break; + } + case CSS_PROP_VISIBILITY: + switch (style->visibility()) { + case khtml::VISIBLE: + return new CSSPrimitiveValueImpl(CSS_VAL_VISIBLE); + case khtml::HIDDEN: + return new CSSPrimitiveValueImpl(CSS_VAL_HIDDEN); + case khtml::COLLAPSE: + return new CSSPrimitiveValueImpl(CSS_VAL_COLLAPSE); + } + Q_ASSERT(0); + break; + case CSS_PROP_WHITE_SPACE: + { + switch (style->whiteSpace()) { + case NORMAL: + return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL); + case PRE: + return new CSSPrimitiveValueImpl(CSS_VAL_PRE); + case PRE_WRAP: + return new CSSPrimitiveValueImpl(CSS_VAL_PRE_WRAP); + case PRE_LINE: + return new CSSPrimitiveValueImpl(CSS_VAL_PRE_LINE); + case NOWRAP: + return new CSSPrimitiveValueImpl(CSS_VAL_NOWRAP); + case KHTML_NOWRAP: + return new CSSPrimitiveValueImpl(CSS_VAL__KHTML_NOWRAP); + } + Q_ASSERT(0); + break; + } + case CSS_PROP_WIDOWS: + return new CSSPrimitiveValueImpl(style->widows(), CSSPrimitiveValue::CSS_NUMBER); + case CSS_PROP_WIDTH: + return new CSSPrimitiveValueImpl( renderer->contentWidth(), + CSSPrimitiveValue::CSS_PX ); + case CSS_PROP_WORD_SPACING: + return new CSSPrimitiveValueImpl(style->wordSpacing(), CSSPrimitiveValue::CSS_PX); + case CSS_PROP_Z_INDEX: + if (style->hasAutoZIndex()) + return new CSSPrimitiveValueImpl(CSS_VAL_NORMAL); + return new CSSPrimitiveValueImpl(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER); + case CSS_PROP_BACKGROUND: + break; + case CSS_PROP_BORDER: + break; + case CSS_PROP_BORDER_COLOR: + break; + case CSS_PROP_BORDER_STYLE: + break; + case CSS_PROP_BORDER_TOP: + return new CSSPrimitiveValueImpl( renderer->borderTop(), + CSSPrimitiveValue::CSS_PX ); + break; + case CSS_PROP_BORDER_RIGHT: + return new CSSPrimitiveValueImpl( renderer->borderRight(), + CSSPrimitiveValue::CSS_PX ); + break; + case CSS_PROP_BORDER_BOTTOM: + return new CSSPrimitiveValueImpl( renderer->borderBottom(), + CSSPrimitiveValue::CSS_PX ); + break; + case CSS_PROP_BORDER_LEFT: + return new CSSPrimitiveValueImpl( renderer->borderLeft(), + CSSPrimitiveValue::CSS_PX ); + break; + case CSS_PROP_BORDER_WIDTH: + break; + case CSS_PROP_FONT: + break; + case CSS_PROP_LIST_STYLE: + break; + case CSS_PROP_MARGIN: + break; + case CSS_PROP_OUTLINE: + break; + case CSS_PROP_PADDING: + break; + case CSS_PROP_SCROLLBAR_BASE_COLOR: + break; + case CSS_PROP_SCROLLBAR_FACE_COLOR: + break; + case CSS_PROP_SCROLLBAR_SHADOW_COLOR: + break; + case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR: + break; + case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR: + break; + case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR: + break; + case CSS_PROP_SCROLLBAR_TRACK_COLOR: + break; + case CSS_PROP_SCROLLBAR_ARROW_COLOR: + break; + case CSS_PROP__KHTML_FLOW_MODE: + break; + case CSS_PROP__KHTML_USER_INPUT: + break; + default: + Q_ASSERT( 0 ); + break; + } + return 0; +} + +DOMString RenderStyleDeclarationImpl::getPropertyValue( int propertyID ) const +{ + CSSValueImpl* value = getPropertyCSSValue(propertyID); + if (value) { + DOMString val = value->cssText(); + delete value; + return val; + } + return ""; +} + +bool RenderStyleDeclarationImpl::getPropertyPriority( int ) const +{ + // All computed styles have a priority of false (not "important"). + return false; +} + +DOM::DOMString RenderStyleDeclarationImpl::removeProperty( int, bool ) +{ + // ### emit error since we're read-only + return DOMString(); +} + +bool RenderStyleDeclarationImpl::setProperty ( int, const DOM::DOMString&, bool, + bool ) +{ + // ### emit error since we're read-only + return false; +} + +void RenderStyleDeclarationImpl::setProperty ( int, int, bool, + bool ) +{ + // ### emit error since we're read-only +} + +void RenderStyleDeclarationImpl::setLengthProperty( int, const DOM::DOMString&, bool, + bool, bool ) +{ + // ### emit error since we're read-only +} + +void RenderStyleDeclarationImpl::setProperty( const DOMString& ) +{ + // ### emit error since we're read-only +} + +unsigned long RenderStyleDeclarationImpl::length() const +{ + return numComputedProperties; +} + +DOM::DOMString RenderStyleDeclarationImpl::item( unsigned long i ) const +{ + if (i >= numComputedProperties) + return DOMString(); + + return getPropertyName(computedProperties[i]); +} + +CSSProperty RenderStyleDeclarationImpl::property( int id ) const +{ + CSSProperty prop; + prop.m_id = id; + prop.m_important = false; + prop.nonCSSHint = false; + + CSSValueImpl* v = getPropertyCSSValue( id ); + if ( !v ) + v = new CSSPrimitiveValueImpl; + prop.setValue( v ); + return prop; +} + diff --git a/khtml/css/css_renderstyledeclarationimpl.h b/khtml/css/css_renderstyledeclarationimpl.h new file mode 100644 index 000000000..d35983993 --- /dev/null +++ b/khtml/css/css_renderstyledeclarationimpl.h @@ -0,0 +1,75 @@ +/* + * css_renderstyleimpl.h + * + * Copyright (C) 2004 Zack Rusin <zack@kde.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef CSS_RENDERSTYLEIMPL_H +#define CSS_RENDERSTYLEIMPL_H + +#include "css/css_valueimpl.h" +#include "dom/dom_string.h" +#include "rendering/render_style.h" + + +namespace DOM { + class NodeImpl; +} + +namespace khtml { + +class RenderObject; + + +// Used by DOM::Counter::listStyle() +DOM::DOMString stringForListStyleType(khtml::EListStyleType type); + +class RenderStyleDeclarationImpl : public DOM::CSSStyleDeclarationImpl +{ +public: + RenderStyleDeclarationImpl( DOM::NodeImpl *node ); + virtual ~RenderStyleDeclarationImpl(); + + DOM::DOMString cssText() const; + void setCssText( DOM::DOMString str ); + + DOM::CSSValueImpl *getPropertyCSSValue( int propertyID ) const; + DOM::DOMString getPropertyValue( int propertyID ) const; + bool getPropertyPriority( int propertyID ) const; + unsigned long length() const; + + DOM::DOMString removeProperty( int propertyID, bool NonCSSHints = false ); + bool setProperty ( int propertyId, const DOM::DOMString &value, bool important = false, + bool nonCSSHint = false); + void setProperty ( int propertyId, int value, bool important = false, bool nonCSSHint = false); + void setLengthProperty(int id, const DOM::DOMString &value, bool important, + bool nonCSSHint = true, bool multiLength = false); + + void setProperty ( const DOM::DOMString &propertyString); + DOM::DOMString item ( unsigned long index ) const; + +protected: + DOM::CSSProperty property( int id ) const; + +protected: + SharedPtr<DOM::NodeImpl> m_node; +}; + + +} + +#endif diff --git a/khtml/css/css_ruleimpl.cpp b/khtml/css/css_ruleimpl.cpp new file mode 100644 index 000000000..ff927e061 --- /dev/null +++ b/khtml/css/css_ruleimpl.cpp @@ -0,0 +1,391 @@ +/** + * This file is part of the DOM implementation for KDE. + * + * (C) 1999-2003 Lars Knoll (knoll@kde.org) + * (C) 2002-2003 Dirk Mueller (mueller@kde.org) + * Copyright (C) 2002 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#include "dom/css_rule.h" +#include "dom/css_stylesheet.h" +#include "dom/dom_exception.h" +#include "dom/dom_string.h" + +#include "css/css_stylesheetimpl.h" +#include "css/css_valueimpl.h" +#include "css/cssparser.h" +#include "css/css_ruleimpl.h" + +#include "misc/loader.h" +#include "misc/htmltags.h" +#include "misc/htmlattrs.h" +#include "xml/dom_docimpl.h" + +using namespace DOM; + +#include <kdebug.h> + +CSSStyleSheetImpl *CSSRuleImpl::parentStyleSheet() const +{ + return ( m_parent && m_parent->isCSSStyleSheet() ) ? + static_cast<CSSStyleSheetImpl *>(m_parent) : 0; +} + +CSSRuleImpl *CSSRuleImpl::parentRule() const +{ + return ( m_parent && m_parent->isRule() ) ? + static_cast<CSSRuleImpl *>(m_parent) : 0; +} + +DOM::DOMString CSSRuleImpl::cssText() const +{ + // ### + return DOMString(); +} + +void CSSRuleImpl::setCssText(DOM::DOMString /*str*/) +{ + // ### +} + +// --------------------------------------------------------------------------- + +CSSFontFaceRuleImpl::CSSFontFaceRuleImpl(StyleBaseImpl *parent) + : CSSRuleImpl(parent) +{ + m_type = CSSRule::FONT_FACE_RULE; + m_style = 0; +} + +CSSFontFaceRuleImpl::~CSSFontFaceRuleImpl() +{ + if(m_style) m_style->deref(); +} + +// -------------------------------------------------------------------------- + +CSSImportRuleImpl::CSSImportRuleImpl( StyleBaseImpl *parent, + const DOM::DOMString &href, + MediaListImpl *media ) + : CSSRuleImpl(parent) +{ + m_type = CSSRule::IMPORT_RULE; + + m_lstMedia = media; + if ( !m_lstMedia ) + m_lstMedia = new MediaListImpl( this, DOMString() ); + m_lstMedia->setParent( this ); + m_lstMedia->ref(); + + m_strHref = href; + m_styleSheet = 0; + + m_cachedSheet = 0; + + init(); +} +CSSImportRuleImpl::CSSImportRuleImpl( StyleBaseImpl *parent, + const DOM::DOMString &href, + const DOM::DOMString &media ) + : CSSRuleImpl(parent) +{ + m_type = CSSRule::IMPORT_RULE; + + m_lstMedia = new MediaListImpl( this, media ); + m_lstMedia->ref(); + + m_strHref = href; + m_styleSheet = 0; + + m_cachedSheet = 0; + + init(); +} + +CSSImportRuleImpl::~CSSImportRuleImpl() +{ + if( m_lstMedia ) { + m_lstMedia->setParent( 0 ); + m_lstMedia->deref(); + } + if(m_styleSheet) { + m_styleSheet->setParent(0); + m_styleSheet->deref(); + } + + if(m_cachedSheet) m_cachedSheet->deref(this); +} + +void CSSImportRuleImpl::setStyleSheet(const DOM::DOMString &url, const DOM::DOMString &sheet, const DOM::DOMString &charset) +{ + if ( m_styleSheet ) { + m_styleSheet->setParent(0); + m_styleSheet->deref(); + } + m_styleSheet = new CSSStyleSheetImpl(this, url); + m_styleSheet->setCharset(charset); + m_styleSheet->ref(); + + CSSStyleSheetImpl *parent = parentStyleSheet(); + m_styleSheet->parseString( sheet, parent ? parent->useStrictParsing() : true ); + m_loading = false; + m_done = true; + + checkLoaded(); +} + +void CSSImportRuleImpl::error(int /*err*/, const QString &/*text*/) +{ + if ( m_styleSheet ) { + m_styleSheet->setParent(0); + m_styleSheet->deref(); + } + m_styleSheet = 0; + + m_loading = false; + m_done = true; + + checkLoaded(); +} + +bool CSSImportRuleImpl::isLoading() +{ + return ( m_loading || (m_styleSheet && m_styleSheet->isLoading()) ); +} + +void CSSImportRuleImpl::init() +{ + m_loading = 0; + m_done = false; + khtml::DocLoader *docLoader = 0; + StyleBaseImpl *root = this; + StyleBaseImpl *parent; + while ( ( parent = root->parent()) ) + root = parent; + if (root->isCSSStyleSheet()) + docLoader = static_cast<CSSStyleSheetImpl*>(root)->docLoader(); + + DOMString absHref = m_strHref; + CSSStyleSheetImpl *parentSheet = parentStyleSheet(); + if (!parentSheet->href().isNull()) { + // use parent styleheet's URL as the base URL + absHref = KURL(KURL( parentSheet->href().string() ),m_strHref.string()).url(); + } +/* + else { + // use documents's URL as the base URL + DocumentImpl *doc = static_cast<CSSStyleSheetImpl*>(root)->doc(); + absHref = KURL(doc->URL(),m_strHref.string()).url(); + } +*/ + // Check for a cycle in our import chain. If we encounter a stylesheet + // in our parent chain with the same URL, then just bail. + for ( parent = static_cast<StyleBaseImpl*>( this )->parent(); + parent; + parent = parent->parent() ) + if ( absHref == parent->baseURL().url() ) + return; + + m_cachedSheet = docLoader->requestStyleSheet(absHref, parentStyleSheet()->charset().string()); + + if (m_cachedSheet) + { + m_cachedSheet->ref(this); + + // If the imported sheet is in the cache, then setStyleSheet gets called, + // and the sheet even gets parsed (via parseString). In this case we have + // loaded (even if our subresources haven't), so if we have stylesheet after + // checking the cache, then we've clearly loaded. -dwh + // This can also happen when error() is called from within ref(). In either case, + // m_done is set to true. + if (!m_done) + m_loading = true; + } +} + +// -------------------------------------------------------------------------- +CSSMediaRuleImpl::CSSMediaRuleImpl( StyleBaseImpl *parent, MediaListImpl *mediaList, CSSRuleListImpl *ruleList ) + : CSSRuleImpl( parent ) +{ + m_type = CSSRule::MEDIA_RULE; + m_lstMedia = mediaList; + m_lstMedia->ref(); + m_lstCSSRules = ruleList; + m_lstCSSRules->ref(); +} + +CSSMediaRuleImpl::CSSMediaRuleImpl(StyleBaseImpl *parent) + : CSSRuleImpl( parent ) +{ + m_type = CSSRule::MEDIA_RULE; + m_lstMedia = 0; + m_lstCSSRules = new CSSRuleListImpl(); + m_lstCSSRules->ref(); +} + +CSSMediaRuleImpl::CSSMediaRuleImpl( StyleBaseImpl *parent, const DOM::DOMString &media ) +: CSSRuleImpl( parent ) +{ + m_type = CSSRule::MEDIA_RULE; + m_lstMedia = new MediaListImpl( this, media ); + m_lstMedia->ref(); + m_lstCSSRules = new CSSRuleListImpl(); + m_lstCSSRules->ref(); +} + +CSSMediaRuleImpl::~CSSMediaRuleImpl() +{ + if( m_lstMedia ) { + m_lstMedia->setParent( 0 ); + m_lstMedia->deref(); + } + for ( unsigned int i = 0; i < m_lstCSSRules->length(); ++i ) + m_lstCSSRules->item( i )->setParent( 0 ); + m_lstCSSRules->deref(); +} + +unsigned long CSSMediaRuleImpl::append( CSSRuleImpl *rule ) +{ + return rule ? m_lstCSSRules->insertRule( rule, m_lstCSSRules->length() ) : 0; +} + +unsigned long CSSMediaRuleImpl::insertRule( const DOMString &rule, + unsigned long index ) +{ + CSSParser p( strictParsing ); + CSSRuleImpl *newRule = p.parseRule( parentStyleSheet(), rule ); + + return newRule ? m_lstCSSRules->insertRule( newRule, index ) : 0; +} + +CSSRuleListImpl::~CSSRuleListImpl() +{ + CSSRuleImpl* rule; + while ( !m_lstCSSRules.isEmpty() && ( rule = m_lstCSSRules.take( 0 ) ) ) + rule->deref(); +} + +// --------------------------------------------------------------------------- + +CSSPageRuleImpl::CSSPageRuleImpl(StyleBaseImpl *parent) + : CSSRuleImpl(parent) +{ + m_type = CSSRule::PAGE_RULE; + m_style = 0; +} + +CSSPageRuleImpl::~CSSPageRuleImpl() +{ + if(m_style) m_style->deref(); +} + +DOM::DOMString CSSPageRuleImpl::selectorText() const +{ + // ### + return DOMString(); +} + +void CSSPageRuleImpl::setSelectorText(DOM::DOMString /*str*/) +{ + // ### +} + +// -------------------------------------------------------------------------- + +CSSStyleRuleImpl::CSSStyleRuleImpl(StyleBaseImpl *parent) + : CSSRuleImpl(parent) +{ + m_type = CSSRule::STYLE_RULE; + m_style = 0; + m_selector = 0; +} + +CSSStyleRuleImpl::~CSSStyleRuleImpl() +{ + if(m_style) { + m_style->setParent( 0 ); + m_style->deref(); + } + delete m_selector; +} + +DOM::DOMString CSSStyleRuleImpl::selectorText() const +{ + if (m_selector) { + DOMString str; + for (CSSSelector *s = m_selector->first(); s; s = m_selector->next()) { + if (s != m_selector->getFirst()) + str += ", "; + str += s->selectorText(); + } + return str; + } + return DOMString(); +} + +void CSSStyleRuleImpl::setSelectorText(DOM::DOMString /*str*/) +{ + // ### +} + +bool CSSStyleRuleImpl::parseString( const DOMString &/*string*/, bool ) +{ + // ### + return false; +} + +void CSSStyleRuleImpl::setDeclaration( CSSStyleDeclarationImpl *style) +{ + if ( m_style != style ) { + if(m_style) m_style->deref(); + m_style = style; + if(m_style) m_style->ref(); + } +} + +void CSSStyleRuleImpl::setNonCSSHints() +{ + CSSSelector *s = m_selector->first(); + while ( s ) { + s->nonCSSHint = true; + s = m_selector->next(); + } +} + +void CSSRuleListImpl::deleteRule ( unsigned long index ) +{ + CSSRuleImpl *rule = m_lstCSSRules.take( index ); + if( rule ) + rule->deref(); + else { + // ### Throw INDEX_SIZE_ERR exception here (TODO) + } +} + +unsigned long CSSRuleListImpl::insertRule( CSSRuleImpl *rule, + unsigned long index ) +{ + if( rule && m_lstCSSRules.insert( index, rule ) ) + { + rule->ref(); + return index; + } + + // ### Should throw INDEX_SIZE_ERR exception instead! (TODO) + return 0; +} + diff --git a/khtml/css/css_ruleimpl.h b/khtml/css/css_ruleimpl.h new file mode 100644 index 000000000..0db6e97ba --- /dev/null +++ b/khtml/css/css_ruleimpl.h @@ -0,0 +1,237 @@ +/* + * This file is part of the DOM implementation for KDE. + * + * (C) 1999-2003 Lars Knoll (knoll@kde.org) + * (C) 2002-2003 Dirk Mueller (mueller@kde.org) + * Copyright (C) 2002 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ +#ifndef _CSS_css_ruleimpl_h_ +#define _CSS_css_ruleimpl_h_ + +#include "dom/dom_string.h" +#include "dom/css_rule.h" +#include "css/css_base.h" +#include "misc/loader_client.h" +#include "misc/shared.h" + +namespace khtml { + class CachedCSSStyleSheet; +} + +namespace DOM { + +class CSSRule; +class CSSStyleSheet; +class CSSStyleSheetImpl; +class CSSStyleDeclarationImpl; +class MediaListImpl; + +class CSSRuleImpl : public StyleBaseImpl +{ +public: + CSSRuleImpl(StyleBaseImpl *parent) + : StyleBaseImpl(parent), m_type(CSSRule::UNKNOWN_RULE) {} + + virtual bool isRule() const { return true; } + unsigned short type() const { return m_type; } + + CSSStyleSheetImpl *parentStyleSheet() const; + CSSRuleImpl *parentRule() const; + + DOM::DOMString cssText() const; + void setCssText(DOM::DOMString str); + virtual void init() {} + +protected: + CSSRule::RuleType m_type; +}; + + +class CSSCharsetRuleImpl : public CSSRuleImpl +{ +public: + CSSCharsetRuleImpl(StyleBaseImpl *parent) + : CSSRuleImpl(parent) { m_type = CSSRule::CHARSET_RULE; } + + virtual bool isCharsetRule() const { return true; } + + DOMString encoding() const { return m_encoding; } + void setEncoding(DOMString _encoding) { m_encoding = _encoding; } + +protected: + DOMString m_encoding; +}; + + +class CSSFontFaceRuleImpl : public CSSRuleImpl +{ +public: + CSSFontFaceRuleImpl(StyleBaseImpl *parent); + + virtual ~CSSFontFaceRuleImpl(); + + CSSStyleDeclarationImpl *style() const { return m_style; } + + virtual bool isFontFaceRule() const { return true; } + +protected: + CSSStyleDeclarationImpl *m_style; +}; + + +class CSSImportRuleImpl : public khtml::CachedObjectClient, public CSSRuleImpl +{ +public: + CSSImportRuleImpl( StyleBaseImpl *parent, const DOM::DOMString &href, + const DOM::DOMString &media ); + CSSImportRuleImpl( StyleBaseImpl *parent, const DOM::DOMString &href, + MediaListImpl *media ); + + virtual ~CSSImportRuleImpl(); + + DOM::DOMString href() const { return m_strHref; } + MediaListImpl *media() const { return m_lstMedia; } + CSSStyleSheetImpl *styleSheet() const { return m_styleSheet; } + + virtual bool isImportRule() const { return true; } + + // from CachedObjectClient + virtual void setStyleSheet(const DOM::DOMString &url, const DOM::DOMString &sheet, const DOM::DOMString &charset); + virtual void error(int err, const QString &text); + + bool isLoading(); + virtual void init(); + +protected: + DOMString m_strHref; + MediaListImpl *m_lstMedia; + CSSStyleSheetImpl *m_styleSheet; + khtml::CachedCSSStyleSheet *m_cachedSheet; + bool m_loading; + bool m_done; +}; + +class MediaList; + +class CSSRuleListImpl : public khtml::Shared<CSSRuleListImpl> +{ +public: + CSSRuleListImpl() {} + + ~CSSRuleListImpl(); + + unsigned long length() const { return m_lstCSSRules.count(); } + CSSRuleImpl *item ( unsigned long index ) { return m_lstCSSRules.at( index ); } + + + /* not part of the DOM */ + unsigned long insertRule ( CSSRuleImpl *rule, unsigned long index ); + void deleteRule ( unsigned long index ); + + void append( CSSRuleImpl *rule ) { m_lstCSSRules.append( rule ); } +protected: + QPtrList<CSSRuleImpl> m_lstCSSRules; +}; + +class CSSMediaRuleImpl : public CSSRuleImpl +{ +public: + CSSMediaRuleImpl( StyleBaseImpl *parent ); + CSSMediaRuleImpl( StyleBaseImpl *parent, const DOM::DOMString &media ); + CSSMediaRuleImpl( StyleBaseImpl *parent, MediaListImpl *mediaList, CSSRuleListImpl *ruleList ); + + virtual ~CSSMediaRuleImpl(); + + MediaListImpl *media() const { return m_lstMedia; } + CSSRuleListImpl *cssRules() { return m_lstCSSRules; } + + unsigned long insertRule ( const DOM::DOMString &rule, unsigned long index ); + void deleteRule ( unsigned long index ) { m_lstCSSRules->deleteRule( index ); } + + virtual bool isMediaRule() const { return true; } + + /* Not part of the DOM */ + unsigned long append( CSSRuleImpl *rule ); +protected: + MediaListImpl *m_lstMedia; + CSSRuleListImpl *m_lstCSSRules; +}; + + +class CSSPageRuleImpl : public CSSRuleImpl +{ +public: + CSSPageRuleImpl(StyleBaseImpl *parent); + + virtual ~CSSPageRuleImpl(); + + CSSStyleDeclarationImpl *style() const { return m_style; } + + virtual bool isPageRule() const { return true; } + + DOM::DOMString selectorText() const; + void setSelectorText(DOM::DOMString str); + +protected: + CSSStyleDeclarationImpl *m_style; +}; + + +class CSSStyleRuleImpl : public CSSRuleImpl +{ +public: + CSSStyleRuleImpl(StyleBaseImpl *parent); + + virtual ~CSSStyleRuleImpl(); + + CSSStyleDeclarationImpl *style() const { return m_style; } + + virtual bool isStyleRule() const { return true; } + + DOM::DOMString selectorText() const; + void setSelectorText(DOM::DOMString str); + + virtual bool parseString( const DOMString &string, bool = false ); + + void setSelector( QPtrList<CSSSelector> *selector) { m_selector = selector; } + void setDeclaration( CSSStyleDeclarationImpl *style); + + QPtrList<CSSSelector> *selector() { return m_selector; } + CSSStyleDeclarationImpl *declaration() { return m_style; } + + void setNonCSSHints(); + +protected: + CSSStyleDeclarationImpl *m_style; + QPtrList<CSSSelector> *m_selector; +}; + + +class CSSUnknownRuleImpl : public CSSRuleImpl +{ +public: + CSSUnknownRuleImpl(StyleBaseImpl *parent) : CSSRuleImpl(parent) {} + + virtual bool isUnknownRule() const { return true; } +}; + + +} // namespace + +#endif diff --git a/khtml/css/css_stylesheetimpl.cpp b/khtml/css/css_stylesheetimpl.cpp new file mode 100644 index 000000000..4743cd2e4 --- /dev/null +++ b/khtml/css/css_stylesheetimpl.cpp @@ -0,0 +1,436 @@ +/** + * This file is part of the DOM implementation for KDE. + * + * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) + * (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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +//#define CSS_STYLESHEET_DEBUG + +#include "dom/dom_string.h" +#include "dom/dom_exception.h" +#include "dom/css_stylesheet.h" +#include "dom/css_rule.h" + +#include "css/css_ruleimpl.h" +#include "css/css_valueimpl.h" +#include "css/cssparser.h" +#include "css/css_stylesheetimpl.h" + +#include "xml/dom_nodeimpl.h" +#include "html/html_documentimpl.h" +#include "misc/loader.h" + +#include <kdebug.h> + +using namespace DOM; +using namespace khtml; +// -------------------------------------------------------------------------------- + +StyleSheetImpl::StyleSheetImpl(StyleSheetImpl *parentSheet, DOMString href) + : StyleListImpl(parentSheet) +{ + m_disabled = false; + m_media = 0; + m_parentNode = 0; + m_strHref = href; +} + + +StyleSheetImpl::StyleSheetImpl(DOM::NodeImpl *parentNode, DOMString href) + : StyleListImpl() +{ + m_parentNode = parentNode; + m_disabled = false; + m_media = 0; + m_strHref = href; +} + +StyleSheetImpl::StyleSheetImpl(StyleBaseImpl *owner, DOMString href) + : StyleListImpl(owner) +{ + m_disabled = false; + m_media = 0; + m_parentNode = 0; + m_strHref = href; +} + +StyleSheetImpl::~StyleSheetImpl() +{ + if(m_media) { + m_media->setParent( 0 ); + m_media->deref(); + } +} + +StyleSheetImpl *StyleSheetImpl::parentStyleSheet() const +{ + if( !m_parent ) return 0; + if( m_parent->isStyleSheet() ) return static_cast<StyleSheetImpl *>(m_parent); + if( m_parent->isRule() ) return m_parent->stylesheet(); + return 0; +} + +void StyleSheetImpl::setMedia( MediaListImpl *media ) +{ + if( media ) + media->ref(); + if( m_media ) + m_media->deref(); + m_media = media; +} + +void StyleSheetImpl::setDisabled( bool disabled ) +{ + bool updateStyle = isCSSStyleSheet() && m_parentNode && disabled != m_disabled; + m_disabled = disabled; + if (updateStyle) + m_parentNode->getDocument()->updateStyleSelector(); +} + +// ----------------------------------------------------------------------- + + +CSSStyleSheetImpl::CSSStyleSheetImpl(CSSStyleSheetImpl *parentSheet, DOMString href) + : StyleSheetImpl(parentSheet, href) +{ + m_lstChildren = new QPtrList<StyleBaseImpl>; + m_doc = parentSheet ? parentSheet->doc() : 0; + m_implicit = false; + m_namespaces = 0; + m_defaultNamespace = anyNamespace; +} + +CSSStyleSheetImpl::CSSStyleSheetImpl(DOM::NodeImpl *parentNode, DOMString href, bool _implicit) + : StyleSheetImpl(parentNode, href) +{ + m_lstChildren = new QPtrList<StyleBaseImpl>; + m_doc = parentNode->getDocument(); + m_implicit = _implicit; + m_namespaces = 0; + m_defaultNamespace = anyNamespace; +} + +CSSStyleSheetImpl::CSSStyleSheetImpl(CSSRuleImpl *ownerRule, DOMString href) + : StyleSheetImpl(ownerRule, href) +{ + m_lstChildren = new QPtrList<StyleBaseImpl>; + m_doc = static_cast<CSSStyleSheetImpl*>(ownerRule->stylesheet())->doc(); + m_implicit = false; + m_namespaces = 0; + m_defaultNamespace = anyNamespace; +} + +CSSStyleSheetImpl::CSSStyleSheetImpl(DOM::NodeImpl *parentNode, CSSStyleSheetImpl *orig) + : StyleSheetImpl(parentNode, orig->m_strHref) +{ + m_lstChildren = new QPtrList<StyleBaseImpl>; + StyleBaseImpl *rule; + for ( rule = orig->m_lstChildren->first(); rule != 0; rule = orig->m_lstChildren->next() ) + { + m_lstChildren->append(rule); + rule->setParent(this); + } + m_doc = parentNode->getDocument(); + m_implicit = false; + m_namespaces = 0; + m_defaultNamespace = anyNamespace; +} + +CSSStyleSheetImpl::CSSStyleSheetImpl(CSSRuleImpl *ownerRule, CSSStyleSheetImpl *orig) + : StyleSheetImpl(ownerRule, orig->m_strHref) +{ + // m_lstChildren is deleted in StyleListImpl + m_lstChildren = new QPtrList<StyleBaseImpl>; + StyleBaseImpl *rule; + for ( rule = orig->m_lstChildren->first(); rule != 0; rule = orig->m_lstChildren->next() ) + { + m_lstChildren->append(rule); + rule->setParent(this); + } + m_doc = static_cast<CSSStyleSheetImpl*>(ownerRule->stylesheet())->doc(); + m_implicit = false; + m_namespaces = 0; + m_defaultNamespace = anyNamespace; +} + +CSSRuleImpl *CSSStyleSheetImpl::ownerRule() const +{ + if( !m_parent ) return 0; + if( m_parent->isRule() ) return static_cast<CSSRuleImpl *>(m_parent); + return 0; +} + +unsigned long CSSStyleSheetImpl::insertRule( const DOMString &rule, unsigned long index, int &exceptioncode ) +{ + exceptioncode = 0; + if(index > m_lstChildren->count()) { + exceptioncode = DOMException::INDEX_SIZE_ERR; + return 0; + } + CSSParser p( strictParsing ); + CSSRuleImpl *r = p.parseRule( this, rule ); + + if(!r) { + exceptioncode = CSSException::SYNTAX_ERR + CSSException::_EXCEPTION_OFFSET; + return 0; + } + // ### + // HIERARCHY_REQUEST_ERR: Raised if the rule cannot be inserted at the specified index e.g. if an + //@import rule is inserted after a standard rule set or other at-rule. + m_lstChildren->insert(index, r); + if (m_doc) + m_doc->updateStyleSelector(true /*shallow*/); + return index; +} + +CSSRuleList CSSStyleSheetImpl::cssRules() +{ + return this; +} + +void CSSStyleSheetImpl::deleteRule( unsigned long index, int &exceptioncode ) +{ + exceptioncode = 0; + StyleBaseImpl *b = m_lstChildren->take(index); + if(!b) { + exceptioncode = DOMException::INDEX_SIZE_ERR; + return; + } + // TreeShared requires delete not deref when removed from tree + b->setParent(0); + if( !b->refCount() ) delete b; + if (m_doc) + m_doc->updateStyleSelector(true /*shallow*/); +} + +void CSSStyleSheetImpl::addNamespace(CSSParser* p, const DOM::DOMString& prefix, const DOM::DOMString& uri) +{ + int exceptioncode = 0; + if (uri.isEmpty()) + return; + + m_namespaces = new CSSNamespace(prefix, uri, m_namespaces); + + if (prefix.isEmpty()) { + Q_ASSERT(m_doc != 0); + + m_defaultNamespace = m_doc->getId(NodeImpl::NamespaceId, uri.implementation(), false, false, &exceptioncode); + } +} + +void CSSStyleSheetImpl::determineNamespace(Q_UINT32& id, const DOM::DOMString& prefix) +{ + // If the stylesheet has no namespaces we can just return. There won't be any need to ever check + // namespace values in selectors. + if (!m_namespaces) + return; + + if (prefix.isEmpty()) + id = makeId(emptyNamespace, localNamePart(id)); // No namespace. If an element/attribute has a namespace, we won't match it. + else if (prefix == "*") + id = makeId(anyNamespace, localNamePart(id)); // We'll match any namespace. + else { + int exceptioncode = 0; + CSSNamespace* ns = m_namespaces->namespaceForPrefix(prefix); + if (ns) { + Q_ASSERT(m_doc != 0); + + // Look up the id for this namespace URI. + Q_UINT16 nsid = m_doc->getId(NodeImpl::NamespaceId, 0, 0, ns->uri().implementation(), false, false, &exceptioncode); + id = makeId(nsid, localNamePart(id)); + } + } +} + +bool CSSStyleSheetImpl::parseString(const DOMString &string, bool strict) +{ +#ifdef CSS_STYLESHEET_DEBUG + kdDebug( 6080 ) << "parsing sheet, len=" << string.length() << ", sheet is " << string.string() << endl; +#endif + + strictParsing = strict; + CSSParser p( strict ); + p.parseSheet( this, string ); + return true; +} + +bool CSSStyleSheetImpl::isLoading() const +{ + StyleBaseImpl *rule; + for ( rule = m_lstChildren->first(); rule != 0; rule = m_lstChildren->next() ) + { + if(rule->isImportRule()) + { + CSSImportRuleImpl *import = static_cast<CSSImportRuleImpl *>(rule); +#ifdef CSS_STYLESHEET_DEBUG + kdDebug( 6080 ) << "found import" << endl; +#endif + if(import->isLoading()) + { +#ifdef CSS_STYLESHEET_DEBUG + kdDebug( 6080 ) << "--> not loaded" << endl; +#endif + return true; + } + } + } + return false; +} + +void CSSStyleSheetImpl::checkLoaded() const +{ + if(isLoading()) return; + if(m_parent) m_parent->checkLoaded(); + if(m_parentNode) m_parentNode->sheetLoaded(); +} + +void CSSStyleSheetImpl::setNonCSSHints() +{ + StyleBaseImpl *rule = m_lstChildren->first(); + while(rule) { + if(rule->isStyleRule()) { + static_cast<CSSStyleRuleImpl *>(rule)->setNonCSSHints(); + } + rule = m_lstChildren->next(); + } +} + + +// --------------------------------------------------------------------------- + + +StyleSheetListImpl::~StyleSheetListImpl() +{ + for ( QPtrListIterator<StyleSheetImpl> it ( styleSheets ); it.current(); ++it ) + it.current()->deref(); +} + +void StyleSheetListImpl::add( StyleSheetImpl* s ) +{ + if ( !styleSheets.containsRef( s ) ) { + s->ref(); + styleSheets.append( s ); + } +} + +void StyleSheetListImpl::remove( StyleSheetImpl* s ) +{ + if ( styleSheets.removeRef( s ) ) + s->deref(); +} + +unsigned long StyleSheetListImpl::length() const +{ + // hack so implicit BODY stylesheets don't get counted here + unsigned long l = 0; + QPtrListIterator<StyleSheetImpl> it(styleSheets); + for (; it.current(); ++it) { + if (!it.current()->isCSSStyleSheet() || !static_cast<CSSStyleSheetImpl*>(it.current())->implicit()) + ++l; + } + return l; +} + +StyleSheetImpl *StyleSheetListImpl::item ( unsigned long index ) +{ + unsigned long l = 0; + QPtrListIterator<StyleSheetImpl> it(styleSheets); + for (; it.current(); ++it) { + if (!it.current()->isCSSStyleSheet() || !static_cast<CSSStyleSheetImpl*>(it.current())->implicit()) { + if (l == index) + return it.current(); + ++l; + } + } + return 0; +} + +// -------------------------------------------------------------------------------------------- + +MediaListImpl::MediaListImpl( CSSStyleSheetImpl *parentSheet, + const DOMString &media ) + : StyleBaseImpl( parentSheet ) +{ + setMediaText( media ); +} + +MediaListImpl::MediaListImpl( CSSRuleImpl *parentRule, const DOMString &media ) + : StyleBaseImpl(parentRule) +{ + setMediaText( media ); +} + +bool MediaListImpl::contains( const DOMString &medium ) const +{ + return m_lstMedia.empty() || m_lstMedia.contains( medium ) || + m_lstMedia.contains( "all" ); +} + +CSSStyleSheetImpl *MediaListImpl::parentStyleSheet() const +{ + if( m_parent->isCSSStyleSheet() ) return static_cast<CSSStyleSheetImpl *>(m_parent); + return 0; +} + +CSSRuleImpl *MediaListImpl::parentRule() const +{ + if( m_parent->isRule() ) return static_cast<CSSRuleImpl *>(m_parent); + return 0; +} + +void MediaListImpl::deleteMedium( const DOMString &oldMedium ) +{ + const QValueList<DOMString>::Iterator itEnd = m_lstMedia.end(); + + for ( QValueList<DOMString>::Iterator it = m_lstMedia.begin(); it != itEnd; ++it ) { + if( (*it) == oldMedium ) { + m_lstMedia.remove( it ); + return; + } + } +} + +DOM::DOMString MediaListImpl::mediaText() const +{ + DOMString text; + const QValueList<DOMString>::ConstIterator itEnd = m_lstMedia.end(); + + for ( QValueList<DOMString>::ConstIterator it = m_lstMedia.begin(); it != itEnd; ++it ) { + text += *it; + text += ", "; + } + return text; +} + +void MediaListImpl::setMediaText(const DOM::DOMString &value) +{ + m_lstMedia.clear(); + const QString val = value.string(); + const QStringList list = QStringList::split( ',', val ); + + const QStringList::ConstIterator itEnd = list.end(); + + for ( QStringList::ConstIterator it = list.begin(); it != itEnd; ++it ) + { + const DOMString medium = (*it).stripWhiteSpace(); + if( !medium.isEmpty() ) + m_lstMedia.append( medium ); + } +} diff --git a/khtml/css/css_stylesheetimpl.h b/khtml/css/css_stylesheetimpl.h new file mode 100644 index 000000000..0b35c2104 --- /dev/null +++ b/khtml/css/css_stylesheetimpl.h @@ -0,0 +1,192 @@ +/* + * This file is part of the DOM implementation for KDE. + * + * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) + * (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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ +#ifndef _CSS_css_stylesheetimpl_h_ +#define _CSS_css_stylesheetimpl_h_ + +#include <qvaluelist.h> +#include <qptrlist.h> + +#include "dom/dom_string.h" +#include "css/css_base.h" +#include "misc/loader_client.h" +#include "xml/dom_docimpl.h" + +namespace khtml { + class CachedCSSStyleSheet; + class DocLoader; +} + +namespace DOM { + +class StyleSheet; +class CSSStyleSheet; +class CSSParser; +class MediaListImpl; +class CSSRuleImpl; +class CSSRuleList; +class CSSStyleRuleImpl; +class CSSValueImpl; +class NodeImpl; +class DocumentImpl; + +class StyleSheetImpl : public StyleListImpl +{ +public: + StyleSheetImpl(DOM::NodeImpl *ownerNode, DOM::DOMString href = DOMString()); + StyleSheetImpl(StyleSheetImpl *parentSheet, DOM::DOMString href = DOMString()); + StyleSheetImpl(StyleBaseImpl *owner, DOM::DOMString href = DOMString()); + StyleSheetImpl(khtml::CachedCSSStyleSheet *cached, DOM::DOMString href = DOMString()); + virtual ~StyleSheetImpl(); + + virtual bool isStyleSheet() const { return true; } + + virtual DOM::DOMString type() const { return DOMString(); } + + bool disabled() const { return m_disabled; } + void setDisabled( bool disabled ); + DOM::NodeImpl *ownerNode() const { return m_parentNode; } + StyleSheetImpl *parentStyleSheet() const; + DOM::DOMString href() const { return m_strHref; } + DOM::DOMString title() const { return m_strTitle; } + MediaListImpl *media() const { return m_media; } + void setMedia( MediaListImpl *media ); + +protected: + DOM::NodeImpl *m_parentNode; + DOM::DOMString m_strHref; + DOM::DOMString m_strTitle; + MediaListImpl *m_media; + bool m_disabled; +}; + +class CSSStyleSheetImpl : public StyleSheetImpl +{ +public: + CSSStyleSheetImpl(DOM::NodeImpl *parentNode, DOM::DOMString href = DOMString(), bool _implicit = false); + CSSStyleSheetImpl(CSSStyleSheetImpl *parentSheet, DOM::DOMString href = DOMString()); + CSSStyleSheetImpl(CSSRuleImpl *ownerRule, DOM::DOMString href = DOMString()); + // clone from a cached version of the sheet + CSSStyleSheetImpl(DOM::NodeImpl *parentNode, CSSStyleSheetImpl *orig); + CSSStyleSheetImpl(CSSRuleImpl *ownerRule, CSSStyleSheetImpl *orig); + + ~CSSStyleSheetImpl() { delete m_namespaces; } + + virtual bool isCSSStyleSheet() const { return true; } + + virtual DOM::DOMString type() const { return "text/css"; } + + CSSRuleImpl *ownerRule() const; + CSSRuleList cssRules(); + unsigned long insertRule ( const DOM::DOMString &rule, unsigned long index, int &exceptioncode ); + void deleteRule ( unsigned long index, int &exceptioncode ); + + void addNamespace(CSSParser* p, const DOM::DOMString& prefix, const DOM::DOMString& uri); + void determineNamespace(Q_UINT32& id, const DOM::DOMString& prefix); + Q_UINT32 defaultNamespace() { return m_defaultNamespace; }; + + void setCharset(const DOMString &charset) { m_charset = charset; } + const DOMString& charset() const { return m_charset; } + + virtual bool parseString( const DOMString &string, bool strict = true ); + + bool isLoading() const; + void setNonCSSHints(); + + virtual void checkLoaded() const; + + // ### remove? (clients should use sheet->doc()->docLoader()) + khtml::DocLoader *docLoader() const + { return m_doc ? m_doc->docLoader() : 0; } + + DocumentImpl *doc() const { return m_doc; } + bool implicit() const { return m_implicit; } +protected: + DocumentImpl *m_doc; + bool m_implicit; + Q_UINT32 m_defaultNamespace; + CSSNamespace* m_namespaces; + DOMString m_charset; +}; + +// ---------------------------------------------------------------------------- + +class StyleSheetListImpl : public khtml::Shared<StyleSheetListImpl> +{ +public: + StyleSheetListImpl() {} + ~StyleSheetListImpl(); + + // the following two ignore implicit stylesheets + unsigned long length() const; + StyleSheetImpl *item ( unsigned long index ); + + void add(StyleSheetImpl* s); + void remove(StyleSheetImpl* s); + + QPtrList<StyleSheetImpl> styleSheets; +}; + +// ---------------------------------------------------------------------------- + +class MediaListImpl : public StyleBaseImpl +{ +public: + MediaListImpl() + : StyleBaseImpl( 0 ) {} + MediaListImpl( CSSStyleSheetImpl *parentSheet ) + : StyleBaseImpl(parentSheet) {} + MediaListImpl( CSSStyleSheetImpl *parentSheet, + const DOM::DOMString &media ); + MediaListImpl( CSSRuleImpl *parentRule, const DOM::DOMString &media ); + + virtual bool isMediaList() const { return true; } + + CSSStyleSheetImpl *parentStyleSheet() const; + CSSRuleImpl *parentRule() const; + unsigned long length() const { return m_lstMedia.count(); } + DOM::DOMString item ( unsigned long index ) const { return m_lstMedia[index]; } + void deleteMedium ( const DOM::DOMString &oldMedium ); + void appendMedium ( const DOM::DOMString &newMedium ) { m_lstMedia.append(newMedium); } + + DOM::DOMString mediaText() const; + void setMediaText(const DOM::DOMString &value); + + /** + * Check if the list contains either the requested medium, or the + * catch-all "all" media type. Returns true when found, false otherwise. + * Since not specifying media types should be treated as "all" according + * to DOM specs, an empty list always returns true. + * + * _NOT_ part of the DOM! + */ + bool contains( const DOM::DOMString &medium ) const; + +protected: + QValueList<DOM::DOMString> m_lstMedia; +}; + + +} // namespace + +#endif + diff --git a/khtml/css/css_valueimpl.cpp b/khtml/css/css_valueimpl.cpp new file mode 100644 index 000000000..531cb88bf --- /dev/null +++ b/khtml/css/css_valueimpl.cpp @@ -0,0 +1,1071 @@ +/** + * This file is part of the DOM implementation for KDE. + * + * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) + * (C) 2004, 2005, 2006 Apple Computer, Inc. + * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) + * + * 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 "dom/css_value.h" +#include "dom/dom_exception.h" +#include "dom/dom_string.h" + +#include "css/css_valueimpl.h" +#include "css/css_ruleimpl.h" +#include "css/css_stylesheetimpl.h" +#include "css/cssparser.h" +#include "css/cssproperties.h" +#include "css/cssvalues.h" + +#include "xml/dom_stringimpl.h" +#include "xml/dom_docimpl.h" + +#include "misc/loader.h" + +#include "rendering/font.h" +#include "rendering/render_style.h" + +#include <kdebug.h> +#include <qregexp.h> +#include <qpaintdevice.h> +#include <qpaintdevicemetrics.h> + +// Hack for debugging purposes +extern DOM::DOMString getPropertyName(unsigned short id); + +using khtml::FontDef; + +using namespace DOM; + +// Quotes the string if it needs quoting. +static DOMString quoteStringIfNeeded(const DOMString &string) +{ + // FIXME: Also need to transform control characters into \ sequences. + QString s = string.string(); + s.replace('\\', "\\\\"); + s.replace('\'', "\\'"); + return '\'' + s + '\''; +} + + +CSSStyleDeclarationImpl::CSSStyleDeclarationImpl(CSSRuleImpl *parent) + : StyleBaseImpl(parent) +{ + m_lstValues = 0; + m_node = 0; +} + +CSSStyleDeclarationImpl::CSSStyleDeclarationImpl(CSSRuleImpl *parent, QPtrList<CSSProperty> *lstValues) + : StyleBaseImpl(parent) +{ + m_lstValues = lstValues; + m_node = 0; +} + +CSSStyleDeclarationImpl& CSSStyleDeclarationImpl::operator= (const CSSStyleDeclarationImpl& o) +{ + // don't attach it to the same node, just leave the current m_node value + delete m_lstValues; + m_lstValues = 0; + if (o.m_lstValues) { + m_lstValues = new QPtrList<CSSProperty>; + m_lstValues->setAutoDelete( true ); + + QPtrListIterator<CSSProperty> lstValuesIt(*o.m_lstValues); + for (lstValuesIt.toFirst(); lstValuesIt.current(); ++lstValuesIt) + m_lstValues->append(new CSSProperty(*lstValuesIt.current())); + } + + return *this; +} + +CSSStyleDeclarationImpl::~CSSStyleDeclarationImpl() +{ + delete m_lstValues; + // we don't use refcounting for m_node, to avoid cyclic references (see ElementImpl) +} + +DOMString CSSStyleDeclarationImpl::getPropertyValue( int propertyID ) const +{ + if(!m_lstValues) return DOMString(); + CSSValueImpl* value = getPropertyCSSValue( propertyID ); + if ( value ) + return value->cssText(); + + // Shorthand and 4-values properties + switch ( propertyID ) { + case CSS_PROP_BACKGROUND_POSITION: + { + // ## Is this correct? The code in cssparser.cpp is confusing + const int properties[2] = { CSS_PROP_BACKGROUND_POSITION_X, + CSS_PROP_BACKGROUND_POSITION_Y }; + return getShortHandValue( properties, 2 ); + } + case CSS_PROP_BACKGROUND: + { + const int properties[5] = { CSS_PROP_BACKGROUND_IMAGE, CSS_PROP_BACKGROUND_REPEAT, + CSS_PROP_BACKGROUND_ATTACHMENT, CSS_PROP_BACKGROUND_POSITION, + CSS_PROP_BACKGROUND_COLOR }; + return getShortHandValue( properties, 5 ); + } + case CSS_PROP_BORDER: + { + const int properties[3] = { CSS_PROP_BORDER_WIDTH, CSS_PROP_BORDER_STYLE, + CSS_PROP_BORDER_COLOR }; + return getShortHandValue( properties, 3 ); + } + case CSS_PROP_BORDER_TOP: + { + const int properties[3] = { CSS_PROP_BORDER_TOP_WIDTH, CSS_PROP_BORDER_TOP_STYLE, + CSS_PROP_BORDER_TOP_COLOR}; + return getShortHandValue( properties, 3 ); + } + case CSS_PROP_BORDER_RIGHT: + { + const int properties[3] = { CSS_PROP_BORDER_RIGHT_WIDTH, CSS_PROP_BORDER_RIGHT_STYLE, + CSS_PROP_BORDER_RIGHT_COLOR}; + return getShortHandValue( properties, 3 ); + } + case CSS_PROP_BORDER_BOTTOM: + { + const int properties[3] = { CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_PROP_BORDER_BOTTOM_STYLE, + CSS_PROP_BORDER_BOTTOM_COLOR}; + return getShortHandValue( properties, 3 ); + } + case CSS_PROP_BORDER_LEFT: + { + const int properties[3] = { CSS_PROP_BORDER_LEFT_WIDTH, CSS_PROP_BORDER_LEFT_STYLE, + CSS_PROP_BORDER_LEFT_COLOR}; + return getShortHandValue( properties, 3 ); + } + case CSS_PROP_OUTLINE: + { + const int properties[3] = { CSS_PROP_OUTLINE_WIDTH, CSS_PROP_OUTLINE_STYLE, + CSS_PROP_OUTLINE_COLOR }; + return getShortHandValue( properties, 3 ); + } + case CSS_PROP_BORDER_COLOR: + { + const int properties[4] = { CSS_PROP_BORDER_TOP_COLOR, CSS_PROP_BORDER_RIGHT_COLOR, + CSS_PROP_BORDER_BOTTOM_COLOR, CSS_PROP_BORDER_LEFT_COLOR }; + return get4Values( properties ); + } + case CSS_PROP_BORDER_WIDTH: + { + const int properties[4] = { CSS_PROP_BORDER_TOP_WIDTH, CSS_PROP_BORDER_RIGHT_WIDTH, + CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_PROP_BORDER_LEFT_WIDTH }; + return get4Values( properties ); + } + case CSS_PROP_BORDER_STYLE: + { + const int properties[4] = { CSS_PROP_BORDER_TOP_STYLE, CSS_PROP_BORDER_RIGHT_STYLE, + CSS_PROP_BORDER_BOTTOM_STYLE, CSS_PROP_BORDER_LEFT_STYLE }; + return get4Values( properties ); + } + case CSS_PROP_MARGIN: + { + const int properties[4] = { CSS_PROP_MARGIN_TOP, CSS_PROP_MARGIN_RIGHT, + CSS_PROP_MARGIN_BOTTOM, CSS_PROP_MARGIN_LEFT }; + return get4Values( properties ); + } + case CSS_PROP_PADDING: + { + const int properties[4] = { CSS_PROP_PADDING_TOP, CSS_PROP_PADDING_RIGHT, + CSS_PROP_PADDING_BOTTOM, CSS_PROP_PADDING_LEFT }; + return get4Values( properties ); + } + case CSS_PROP_LIST_STYLE: + { + const int properties[3] = { CSS_PROP_LIST_STYLE_TYPE, CSS_PROP_LIST_STYLE_POSITION, + CSS_PROP_LIST_STYLE_IMAGE }; + return getShortHandValue( properties, 3 ); + } + } + //kdDebug() << k_funcinfo << "property not found:" << propertyID << endl; + return DOMString(); +} + +DOMString CSSStyleDeclarationImpl::get4Values( const int* properties ) const +{ + DOMString res; + for ( int i = 0 ; i < 4 ; ++i ) { + CSSValueImpl* value = getPropertyCSSValue( properties[i] ); + if ( !value ) { // apparently all 4 properties must be specified. + return DOMString(); + } + if ( i > 0 ) + res += " "; + res += value->cssText(); + } + return res; +} + +DOMString CSSStyleDeclarationImpl::getShortHandValue( const int* properties, int number ) const +{ + DOMString res; + for ( int i = 0 ; i < number ; ++i ) { + CSSValueImpl* value = getPropertyCSSValue( properties[i] ); + if ( value ) { // TODO provide default value if !value + if ( !res.isNull() ) + res += " "; + res += value->cssText(); + } + } + return res; +} + + CSSValueImpl *CSSStyleDeclarationImpl::getPropertyCSSValue( int propertyID ) const +{ + if(!m_lstValues) return 0; + + QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues); + CSSProperty *current; + for ( lstValuesIt.toLast(); (current = lstValuesIt.current()); --lstValuesIt ) + if (current->m_id == propertyID && !current->nonCSSHint) + return current->value(); + return 0; +} + +DOMString CSSStyleDeclarationImpl::removeProperty( int propertyID, bool NonCSSHint ) +{ + if(!m_lstValues) return DOMString(); + DOMString value; + + QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues); + CSSProperty *current; + for ( lstValuesIt.toLast(); (current = lstValuesIt.current()); --lstValuesIt ) { + if (current->m_id == propertyID && NonCSSHint == current->nonCSSHint) { + value = current->value()->cssText(); + m_lstValues->removeRef(current); + setChanged(); + break; + } + } + + return value; +} + +void CSSStyleDeclarationImpl::setChanged() +{ + if (m_node) { + m_node->setChanged(); + return; + } + + // ### quick&dirty hack for KDE 3.0... make this MUCH better! (Dirk) + for (StyleBaseImpl* stylesheet = this; stylesheet; stylesheet = stylesheet->parent()) + if (stylesheet->isCSSStyleSheet()) { + static_cast<CSSStyleSheetImpl*>(stylesheet)->doc()->updateStyleSelector(); + break; + } +} + +void CSSStyleDeclarationImpl::removeCSSHints() +{ + if (!m_lstValues) + return; + + for (int i = (int)m_lstValues->count()-1; i >= 0; i--) { + if (!m_lstValues->at(i)->nonCSSHint) + m_lstValues->remove(i); + } +} + +bool CSSStyleDeclarationImpl::getPropertyPriority( int propertyID ) const +{ + if ( m_lstValues) { + QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues); + CSSProperty *current; + for ( lstValuesIt.toFirst(); (current = lstValuesIt.current()); ++lstValuesIt ) { + if( propertyID == current->m_id ) + return current->m_important; + } + } + return false; +} + +bool CSSStyleDeclarationImpl::setProperty(int id, const DOMString &value, bool important, bool nonCSSHint) +{ + if(!m_lstValues) { + m_lstValues = new QPtrList<CSSProperty>; + m_lstValues->setAutoDelete(true); + } + + CSSParser parser( strictParsing ); + bool success = parser.parseValue( this, id, value, important, nonCSSHint ); + if(!success) + kdDebug( 6080 ) << "CSSStyleDeclarationImpl::setProperty invalid property: [" << getPropertyName(id).string() + << "] value: [" << value.string() << "]"<< endl; + else + setChanged(); + return success; +} + +void CSSStyleDeclarationImpl::setProperty(int id, int value, bool important, bool nonCSSHint) +{ + if(!m_lstValues) { + m_lstValues = new QPtrList<CSSProperty>; + m_lstValues->setAutoDelete(true); + } + removeProperty(id, nonCSSHint ); + + CSSValueImpl * cssValue = new CSSPrimitiveValueImpl(value); + setParsedValue(id, cssValue, important, nonCSSHint, m_lstValues); + setChanged(); +} + +void CSSStyleDeclarationImpl::setLengthProperty(int id, const DOM::DOMString &value, bool important, bool nonCSSHint, bool _multiLength ) +{ + bool parseMode = strictParsing; + strictParsing = false; + multiLength = _multiLength; + setProperty( id, value, important, nonCSSHint); + strictParsing = parseMode; + multiLength = false; +} + +void CSSStyleDeclarationImpl::setProperty ( const DOMString &propertyString) +{ + if(!m_lstValues) { + m_lstValues = new QPtrList<CSSProperty>; + m_lstValues->setAutoDelete( true ); + } + + CSSParser parser( strictParsing ); + parser.parseDeclaration( this, propertyString, false ); + setChanged(); +} + +unsigned long CSSStyleDeclarationImpl::length() const +{ + return m_lstValues ? m_lstValues->count() : 0; +} + +DOMString CSSStyleDeclarationImpl::item( unsigned long index ) const +{ + if(m_lstValues && index < m_lstValues->count() && m_lstValues->at(index)) + return getPropertyName(m_lstValues->at(index)->m_id); + return DOMString(); +} + +CSSRuleImpl *CSSStyleDeclarationImpl::parentRule() const +{ + return (m_parent && m_parent->isRule() ) ? + static_cast<CSSRuleImpl *>(m_parent) : 0; +} + +DOM::DOMString CSSStyleDeclarationImpl::cssText() const +{ + DOMString result; + + if ( m_lstValues) { + QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues); + CSSProperty *current; + for ( lstValuesIt.toFirst(); (current = lstValuesIt.current()); ++lstValuesIt ) { + result += current->cssText(); + } + } + + return result; +} + +void CSSStyleDeclarationImpl::setCssText(DOM::DOMString text) +{ + if (m_lstValues) { + m_lstValues->clear(); + } else { + m_lstValues = new QPtrList<CSSProperty>; + m_lstValues->setAutoDelete( true ); + } + + CSSParser parser( strictParsing ); + parser.parseDeclaration( this, text, false ); + setChanged(); +} + +bool CSSStyleDeclarationImpl::parseString( const DOMString &/*string*/, bool ) +{ + kdDebug() << "WARNING: CSSStyleDeclarationImpl::parseString, unimplemented, was called" << endl; + return false; + // ### +} + + +// -------------------------------------------------------------------------------------- + +unsigned short CSSInheritedValueImpl::cssValueType() const +{ + return CSSValue::CSS_INHERIT; +} + +DOM::DOMString CSSInheritedValueImpl::cssText() const +{ + return DOMString("inherit"); +} + +unsigned short CSSInitialValueImpl::cssValueType() const +{ + return CSSValue::CSS_INITIAL; +} + +DOM::DOMString CSSInitialValueImpl::cssText() const +{ + return DOMString("initial"); +} + +// ---------------------------------------------------------------------------------------- + +CSSValueListImpl::~CSSValueListImpl() +{ + CSSValueImpl *val = m_values.first(); + while( val ) { + val->deref(); + val = m_values.next(); + } +} + +unsigned short CSSValueListImpl::cssValueType() const +{ + return CSSValue::CSS_VALUE_LIST; +} + +void CSSValueListImpl::append(CSSValueImpl *val) +{ + m_values.append(val); + val->ref(); +} + +DOM::DOMString CSSValueListImpl::cssText() const +{ + DOMString result = ""; + + for (QPtrListIterator<CSSValueImpl> iterator(m_values); iterator.current(); ++iterator) { + result += iterator.current()->cssText(); + } + + return result; +} + +// ------------------------------------------------------------------------------------- + +CSSPrimitiveValueImpl::CSSPrimitiveValueImpl() + : CSSValueImpl() +{ + m_type = 0; +} + +CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(int ident) + : CSSValueImpl() +{ + m_value.ident = ident; + m_type = CSSPrimitiveValue::CSS_IDENT; +} + +CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(double num, CSSPrimitiveValue::UnitTypes type) +{ + m_value.num = num; + m_type = type; +} + +CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(const DOMString &str, CSSPrimitiveValue::UnitTypes type) +{ + m_value.string = str.implementation(); + if(m_value.string) m_value.string->ref(); + m_type = type; +} + +CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(CounterImpl *c) +{ + m_value.counter = c; + if (m_value.counter) + m_value.counter->ref(); + m_type = CSSPrimitiveValue::CSS_COUNTER; +} + +CSSPrimitiveValueImpl::CSSPrimitiveValueImpl( RectImpl *r) +{ + m_value.rect = r; + if (m_value.rect) + m_value.rect->ref(); + m_type = CSSPrimitiveValue::CSS_RECT; +} + +CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(QRgb color) +{ + m_value.rgbcolor = color; + m_type = CSSPrimitiveValue::CSS_RGBCOLOR; +} + +CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(PairImpl *p) +{ + m_value.pair = p; + if (m_value.pair) + m_value.pair->ref(); + m_type = CSSPrimitiveValue::CSS_PAIR; +} + + +CSSPrimitiveValueImpl::~CSSPrimitiveValueImpl() +{ + cleanup(); +} + +void CSSPrimitiveValueImpl::cleanup() +{ + switch(m_type) { + case CSSPrimitiveValue::CSS_STRING: + case CSSPrimitiveValue::CSS_URI: + case CSSPrimitiveValue::CSS_ATTR: + if(m_value.string) m_value.string->deref(); + break; + case CSSPrimitiveValue::CSS_COUNTER: + m_value.counter->deref(); + break; + case CSSPrimitiveValue::CSS_RECT: + m_value.rect->deref(); + break; + case CSSPrimitiveValue::CSS_PAIR: + m_value.pair->deref(); + break; + default: + break; + } + + m_type = 0; +} + +int CSSPrimitiveValueImpl::computeLength( khtml::RenderStyle *style, QPaintDeviceMetrics *devMetrics ) +{ + double result = computeLengthFloat( style, devMetrics ); + // This conversion is imprecise, often resulting in values of, e.g., 44.99998. We + // need to go ahead and round if we're really close to the next integer value. + int intResult = (int)(result + (result < 0 ? -0.01 : +0.01)); + return intResult; +} + +double CSSPrimitiveValueImpl::computeLengthFloat( khtml::RenderStyle *style, QPaintDeviceMetrics *devMetrics ) +{ + unsigned short type = primitiveType(); + + double dpiY = 72.; // fallback + if ( devMetrics ) + dpiY = devMetrics->logicalDpiY(); + if ( !khtml::printpainter && dpiY < 96 ) + dpiY = 96.; + + double factor = 1.; + switch(type) + { + case CSSPrimitiveValue::CSS_EMS: + factor = style->font().pixelSize(); + break; + case CSSPrimitiveValue::CSS_EXS: + { + QFontMetrics fm = style->fontMetrics(); +#ifdef APPLE_CHANGES + factor = fm.xHeight(); +#else + QRect b = fm.boundingRect('x'); + factor = b.height(); +#endif + break; + } + case CSSPrimitiveValue::CSS_PX: + break; + case CSSPrimitiveValue::CSS_CM: + factor = dpiY/2.54; //72dpi/(2.54 cm/in) + break; + case CSSPrimitiveValue::CSS_MM: + factor = dpiY/25.4; + break; + case CSSPrimitiveValue::CSS_IN: + factor = dpiY; + break; + case CSSPrimitiveValue::CSS_PT: + factor = dpiY/72.; + break; + case CSSPrimitiveValue::CSS_PC: + // 1 pc == 12 pt + factor = dpiY*12./72.; + break; + default: + return -1; + } + + return floatValue(type)*factor; +} + +void CSSPrimitiveValueImpl::setFloatValue( unsigned short unitType, double floatValue, int &exceptioncode ) +{ + exceptioncode = 0; + cleanup(); + // ### check if property supports this type + if(m_type > CSSPrimitiveValue::CSS_DIMENSION) { + exceptioncode = CSSException::SYNTAX_ERR + CSSException::_EXCEPTION_OFFSET; + return; + } + //if(m_type > CSSPrimitiveValue::CSS_DIMENSION) throw DOMException(DOMException::INVALID_ACCESS_ERR); + m_value.num = floatValue; + m_type = unitType; +} + +void CSSPrimitiveValueImpl::setStringValue( unsigned short stringType, const DOMString &stringValue, int &exceptioncode ) +{ + exceptioncode = 0; + cleanup(); + //if(m_type < CSSPrimitiveValue::CSS_STRING) throw DOMException(DOMException::INVALID_ACCESS_ERR); + //if(m_type > CSSPrimitiveValue::CSS_ATTR) throw DOMException(DOMException::INVALID_ACCESS_ERR); + if(m_type < CSSPrimitiveValue::CSS_STRING || m_type > CSSPrimitiveValue::CSS_ATTR) { + exceptioncode = CSSException::SYNTAX_ERR + CSSException::_EXCEPTION_OFFSET; + return; + } + if(stringType != CSSPrimitiveValue::CSS_IDENT) + { + m_value.string = stringValue.implementation(); + m_value.string->ref(); + m_type = stringType; + } + // ### parse ident +} + +unsigned short CSSPrimitiveValueImpl::cssValueType() const +{ + return CSSValue::CSS_PRIMITIVE_VALUE; +} + +bool CSSPrimitiveValueImpl::parseString( const DOMString &/*string*/, bool ) +{ + // ### + kdDebug() << "WARNING: CSSPrimitiveValueImpl::parseString, unimplemented, was called" << endl; + return false; +} + +int CSSPrimitiveValueImpl::getIdent() +{ + if(m_type != CSSPrimitiveValue::CSS_IDENT) return 0; + return m_value.ident; +} + +DOM::DOMString CSSPrimitiveValueImpl::cssText() const +{ + // ### return the original value instead of a generated one (e.g. color + // name if it was specified) - check what spec says about this + DOMString text; + switch ( m_type ) { + case CSSPrimitiveValue::CSS_UNKNOWN: + // ### + break; + case CSSPrimitiveValue::CSS_NUMBER: + text = DOMString(QString::number( (int)m_value.num )); + break; + case CSSPrimitiveValue::CSS_PERCENTAGE: + text = DOMString(QString::number( m_value.num ) + "%"); + break; + case CSSPrimitiveValue::CSS_EMS: + text = DOMString(QString::number( m_value.num ) + "em"); + break; + case CSSPrimitiveValue::CSS_EXS: + text = DOMString(QString::number( m_value.num ) + "ex"); + break; + case CSSPrimitiveValue::CSS_PX: + text = DOMString(QString::number( m_value.num ) + "px"); + break; + case CSSPrimitiveValue::CSS_CM: + text = DOMString(QString::number( m_value.num ) + "cm"); + break; + case CSSPrimitiveValue::CSS_MM: + text = DOMString(QString::number( m_value.num ) + "mm"); + break; + case CSSPrimitiveValue::CSS_IN: + text = DOMString(QString::number( m_value.num ) + "in"); + break; + case CSSPrimitiveValue::CSS_PT: + text = DOMString(QString::number( m_value.num ) + "pt"); + break; + case CSSPrimitiveValue::CSS_PC: + text = DOMString(QString::number( m_value.num ) + "pc"); + break; + case CSSPrimitiveValue::CSS_DEG: + text = DOMString(QString::number( m_value.num ) + "deg"); + break; + case CSSPrimitiveValue::CSS_RAD: + text = DOMString(QString::number( m_value.num ) + "rad"); + break; + case CSSPrimitiveValue::CSS_GRAD: + text = DOMString(QString::number( m_value.num ) + "grad"); + break; + case CSSPrimitiveValue::CSS_MS: + text = DOMString(QString::number( m_value.num ) + "ms"); + break; + case CSSPrimitiveValue::CSS_S: + text = DOMString(QString::number( m_value.num ) + "s"); + break; + case CSSPrimitiveValue::CSS_HZ: + text = DOMString(QString::number( m_value.num ) + "hz"); + break; + case CSSPrimitiveValue::CSS_KHZ: + text = DOMString(QString::number( m_value.num ) + "khz"); + break; + case CSSPrimitiveValue::CSS_DIMENSION: + // ### + break; + case CSSPrimitiveValue::CSS_STRING: + text = quoteStringIfNeeded(m_value.string); + break; + case CSSPrimitiveValue::CSS_URI: + text = "url("; + text += DOMString( m_value.string ); + text += ")"; + break; + case CSSPrimitiveValue::CSS_IDENT: + text = getValueName(m_value.ident); + break; + case CSSPrimitiveValue::CSS_ATTR: + // ### + break; + case CSSPrimitiveValue::CSS_COUNTER: + text = "counter("; + text += m_value.counter->m_identifier; + text += ")"; + // ### add list-style and separator + break; + case CSSPrimitiveValue::CSS_RECT: + { + RectImpl* rectVal = getRectValue(); + text = "rect("; + text += rectVal->top()->cssText() + " "; + text += rectVal->right()->cssText() + " "; + text += rectVal->bottom()->cssText() + " "; + text += rectVal->left()->cssText() + ")"; + break; + } + case CSSPrimitiveValue::CSS_RGBCOLOR: + if (qAlpha(m_value.rgbcolor) != 0xFF) { + if (m_value.rgbcolor == khtml::transparentColor) + text = "transparent"; + else + text = "rgba(" + QString::number(qRed (m_value.rgbcolor)) + "," + + QString::number(qBlue (m_value.rgbcolor)) + "," + + QString::number(qGreen(m_value.rgbcolor)) + "," + + QString::number(qAlpha(m_value.rgbcolor)/255.0) + ")"; + } else { + text = QColor(m_value.rgbcolor).name(); + } + break; + case CSSPrimitiveValue::CSS_PAIR: + text = m_value.pair->first()->cssText(); + text += " "; + text += m_value.pair->second()->cssText(); + break; + default: + break; + } + return text; +} + +// ----------------------------------------------------------------- + +RectImpl::RectImpl() +{ + m_top = 0; + m_right = 0; + m_bottom = 0; + m_left = 0; +} + +RectImpl::~RectImpl() +{ + if (m_top) m_top->deref(); + if (m_right) m_right->deref(); + if (m_bottom) m_bottom->deref(); + if (m_left) m_left->deref(); +} + +void RectImpl::setTop( CSSPrimitiveValueImpl *top ) +{ + if( top ) top->ref(); + if ( m_top ) m_top->deref(); + m_top = top; +} + +void RectImpl::setRight( CSSPrimitiveValueImpl *right ) +{ + if( right ) right->ref(); + if ( m_right ) m_right->deref(); + m_right = right; +} + +void RectImpl::setBottom( CSSPrimitiveValueImpl *bottom ) +{ + if( bottom ) bottom->ref(); + if ( m_bottom ) m_bottom->deref(); + m_bottom = bottom; +} + +void RectImpl::setLeft( CSSPrimitiveValueImpl *left ) +{ + if( left ) left->ref(); + if ( m_left ) m_left->deref(); + m_left = left; +} + +// ----------------------------------------------------------------- + +PairImpl::~PairImpl() +{ + if (m_first) m_first->deref(); if (m_second) m_second->deref(); +} + +void PairImpl::setFirst(CSSPrimitiveValueImpl* first) +{ + if (first == m_first) return; + if (m_first) m_first->deref(); + m_first = first; + if (m_first) m_first->ref(); +} + +void PairImpl::setSecond(CSSPrimitiveValueImpl* second) +{ + if (second == m_second) return; + if (m_second) m_second->deref(); + m_second = second; + if (m_second) m_second->ref(); +} + +// ----------------------------------------------------------------- + +CSSImageValueImpl::CSSImageValueImpl(const DOMString &url, const StyleBaseImpl* style) + : CSSPrimitiveValueImpl(url, CSSPrimitiveValue::CSS_URI) +{ + khtml::DocLoader *docLoader = 0; + const StyleBaseImpl *root = style; + while (root->parent()) + root = root->parent(); + if (root->isCSSStyleSheet()) + docLoader = static_cast<const CSSStyleSheetImpl*>(root)->docLoader(); + + m_image = docLoader->requestImage(url); + if(m_image) m_image->ref(this); +} + +CSSImageValueImpl::CSSImageValueImpl() + : CSSPrimitiveValueImpl(CSS_VAL_NONE) +{ + m_image = 0; +} + +CSSImageValueImpl::~CSSImageValueImpl() +{ + if(m_image) m_image->deref(this); +} + +// ------------------------------------------------------------------------ + +FontFamilyValueImpl::FontFamilyValueImpl( const QString &string) +: CSSPrimitiveValueImpl( DOMString(string), CSSPrimitiveValue::CSS_STRING) +{ + static const QRegExp parenReg(" \\(.*\\)$"); + static const QRegExp braceReg(" \\[.*\\]$"); + + parsedFontName = string; + // a language tag is often added in braces at the end. Remove it. + parsedFontName.replace(parenReg, QString::null); + // remove [Xft] qualifiers + parsedFontName.replace(braceReg, QString::null); + +#ifndef APPLE_CHANGES + const QString &available = KHTMLSettings::availableFamilies(); + + parsedFontName = parsedFontName.lower(); + // kdDebug(0) << "searching for face '" << parsedFontName << "'" << endl; + + int pos = available.find( ',' + parsedFontName + ',', 0, false ); + if ( pos == -1 ) { + // many pages add extra MSs to make sure it's windows only ;( + if ( parsedFontName.startsWith( "ms " ) ) + parsedFontName = parsedFontName.mid( 3 ); + if ( parsedFontName.endsWith( " ms" ) ) + parsedFontName.truncate( parsedFontName.length() - 3 ); + pos = available.find( ",ms " + parsedFontName + ',', 0, false ); + if ( pos == -1 ) + pos = available.find( ',' + parsedFontName + " ms,", 0, false ); + } + + if ( pos != -1 ) { + ++pos; + int p = available.find(',', pos); + assert( p != -1 ); // available is supposed to start and end with , + parsedFontName = available.mid( pos, p - pos); + // kdDebug(0) << "going for '" << parsedFontName << "'" << endl; + } else + parsedFontName = QString::null; + +#endif // !APPLE_CHANGES +} + +FontValueImpl::FontValueImpl() + : style(0), variant(0), weight(0), size(0), lineHeight(0), family(0) +{ +} + +FontValueImpl::~FontValueImpl() +{ + delete style; + delete variant; + delete weight; + delete size; + delete lineHeight; + delete family; +} + +DOMString FontValueImpl::cssText() const +{ + // font variant weight size / line-height family + + DOMString result(""); + + if (style) { + result += style->cssText(); + } + if (variant) { + if (result.length() > 0) { + result += " "; + } + result += variant->cssText(); + } + if (weight) { + if (result.length() > 0) { + result += " "; + } + result += weight->cssText(); + } + if (size) { + if (result.length() > 0) { + result += " "; + } + result += size->cssText(); + } + if (lineHeight) { + if (!size) { + result += " "; + } + result += "/"; + result += lineHeight->cssText(); + } + if (family) { + if (result.length() > 0) { + result += " "; + } + result += family->cssText(); + } + + return result; +} + +QuotesValueImpl::QuotesValueImpl() + : levels(0) +{ +} + +DOMString QuotesValueImpl::cssText() const +{ + return "\"" + data.join("\" \"") + "\""; +} + +void QuotesValueImpl::addLevel(const QString& open, const QString& close) +{ + data.append(open); + data.append(close); + levels++; +} + +QString QuotesValueImpl::openQuote(int level) const +{ + if (levels == 0) return ""; + level--; // increments are calculated before openQuote is called +// kdDebug( 6080 ) << "Open quote level:" << level << endl; + if (level < 0) level = 0; + else + if (level >= (int) levels) level = (int) (levels-1); + return data[level*2]; +} + +QString QuotesValueImpl::closeQuote(int level) const +{ + if (levels == 0) return ""; +// kdDebug( 6080 ) << "Close quote level:" << level << endl; + if (level < 0) level = 0; + else + if (level >= (int) levels) level = (int) (levels-1); + return data[level*2+1]; +} + +// Used for text-shadow and box-shadow +ShadowValueImpl::ShadowValueImpl(CSSPrimitiveValueImpl* _x, CSSPrimitiveValueImpl* _y, + CSSPrimitiveValueImpl* _blur, CSSPrimitiveValueImpl* _color) + :x(_x), y(_y), blur(_blur), color(_color) +{} + +ShadowValueImpl::~ShadowValueImpl() +{ + delete x; + delete y; + delete blur; + delete color; +} + +DOMString ShadowValueImpl::cssText() const +{ + DOMString text(""); + if (color) { + text += color->cssText(); + } + if (x) { + if (text.length() > 0) { + text += " "; + } + text += x->cssText(); + } + if (y) { + if (text.length() > 0) { + text += " "; + } + text += y->cssText(); + } + if (blur) { + if (text.length() > 0) { + text += " "; + } + text += blur->cssText(); + } + + return text; +} + +DOMString CounterActImpl::cssText() const +{ + DOMString text(m_counter); + text += DOMString(QString::number(m_value)); + + return text; +} + +DOMString CSSProperty::cssText() const +{ + return getPropertyName(m_id) + DOMString(": ") + m_value->cssText() + (m_important ? DOMString(" !important") : DOMString()) + DOMString("; "); +} diff --git a/khtml/css/css_valueimpl.h b/khtml/css/css_valueimpl.h new file mode 100644 index 000000000..5b4207149 --- /dev/null +++ b/khtml/css/css_valueimpl.h @@ -0,0 +1,461 @@ +/* + * This file is part of the DOM implementation for KDE. + * + * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) + * (C) 2004, 2005, 2006 Apple Computer, Inc. + * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) + * + * 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. + * + */ +#ifndef _CSS_css_valueimpl_h_ +#define _CSS_css_valueimpl_h_ + +#include "dom/css_value.h" +#include "dom/dom_string.h" +#include "css/css_base.h" +#include "misc/loader_client.h" +#include "misc/shared.h" + +#include <qintdict.h> + +namespace khtml { + class RenderStyle; + class CachedImage; +} + + +namespace DOM { + +class CSSRuleImpl; +class CSSValueImpl; +class NodeImpl; +class CounterImpl; +class PairImpl; + + +class CSSStyleDeclarationImpl : public StyleBaseImpl +{ +public: + CSSStyleDeclarationImpl(CSSRuleImpl *parentRule); + CSSStyleDeclarationImpl(CSSRuleImpl *parentRule, QPtrList<CSSProperty> *lstValues); + virtual ~CSSStyleDeclarationImpl(); + + CSSStyleDeclarationImpl& operator=( const CSSStyleDeclarationImpl&); + + virtual unsigned long length() const; + CSSRuleImpl *parentRule() const; + virtual DOM::DOMString removeProperty( int propertyID, bool NonCSSHints = false ); + virtual bool setProperty ( int propertyId, const DOM::DOMString &value, bool important = false, bool nonCSSHint = false); + virtual void setProperty ( int propertyId, int value, bool important = false, bool nonCSSHint = false); + // this treats integers as pixels! + // needed for conversion of html attributes + virtual void setLengthProperty(int id, const DOM::DOMString &value, bool important, bool nonCSSHint = true, bool multiLength = false); + + // add a whole, unparsed property + virtual void setProperty ( const DOMString &propertyString); + virtual DOM::DOMString item ( unsigned long index ) const; + + DOM::DOMString cssText() const; + void setCssText(DOM::DOMString str); + + virtual bool isStyleDeclaration() const { return true; } + virtual bool parseString( const DOMString &string, bool = false ); + + virtual CSSValueImpl *getPropertyCSSValue( int propertyID ) const; + virtual DOMString getPropertyValue( int propertyID ) const; + virtual bool getPropertyPriority( int propertyID ) const; + + QPtrList<CSSProperty> *values() const { return m_lstValues; } + void setNode(NodeImpl *_node) { m_node = _node; } + + void setChanged(); + + void removeCSSHints(); + +protected: + DOMString getShortHandValue( const int* properties, int number ) const; + DOMString get4Values( const int* properties ) const; + + QPtrList<CSSProperty> *m_lstValues; + NodeImpl *m_node; + +private: + // currently not needed - make sure its not used + CSSStyleDeclarationImpl(const CSSStyleDeclarationImpl& o); +}; + +class CSSValueImpl : public StyleBaseImpl +{ +public: + CSSValueImpl() : StyleBaseImpl() {} + + virtual unsigned short cssValueType() const = 0; + + virtual DOM::DOMString cssText() const = 0; + + virtual bool isValue() const { return true; } + virtual bool isFontValue() const { return false; } +}; + +class CSSInheritedValueImpl : public CSSValueImpl +{ +public: + CSSInheritedValueImpl() : CSSValueImpl() {} + virtual ~CSSInheritedValueImpl() {} + + virtual unsigned short cssValueType() const; + virtual DOM::DOMString cssText() const; +}; + +class CSSInitialValueImpl : public CSSValueImpl +{ +public: + virtual unsigned short cssValueType() const; + virtual DOM::DOMString cssText() const; +}; + +class CSSValueListImpl : public CSSValueImpl +{ +public: + CSSValueListImpl() : CSSValueImpl() {} + + virtual ~CSSValueListImpl(); + + unsigned long length() const { return m_values.count(); } + CSSValueImpl *item ( unsigned long index ) { return m_values.at(index); } + + virtual bool isValueList() const { return true; } + + virtual unsigned short cssValueType() const; + + void append(CSSValueImpl *val); + virtual DOM::DOMString cssText() const; + +protected: + QPtrList<CSSValueImpl> m_values; +}; + + +class Counter; +class RGBColor; +class Rect; + +class CSSPrimitiveValueImpl : public CSSValueImpl +{ +public: + CSSPrimitiveValueImpl(); + CSSPrimitiveValueImpl(int ident); + CSSPrimitiveValueImpl(double num, CSSPrimitiveValue::UnitTypes type); + CSSPrimitiveValueImpl(const DOMString &str, CSSPrimitiveValue::UnitTypes type); + CSSPrimitiveValueImpl(CounterImpl *c); + CSSPrimitiveValueImpl( RectImpl *r); + CSSPrimitiveValueImpl(QRgb color); + CSSPrimitiveValueImpl(PairImpl *p); + + virtual ~CSSPrimitiveValueImpl(); + + void cleanup(); + + unsigned short primitiveType() const { return m_type; } + + /* + * computes a length in pixels out of the given CSSValue. Need the RenderStyle to get + * the fontinfo in case val is defined in em or ex. + * + * The metrics have to be a bit different for screen and printer output. + * For screen output we assume 1 inch == 72 px, for printer we assume 300 dpi + * + * this is screen/printer dependent, so we probably need a config option for this, + * and some tool to calibrate. + */ + int computeLength( khtml::RenderStyle *style, QPaintDeviceMetrics *devMetrics ); + + double computeLengthFloat( khtml::RenderStyle *style, QPaintDeviceMetrics *devMetrics ); + + // use with care!!! + void setPrimitiveType(unsigned short type) { m_type = type; } + void setFloatValue ( unsigned short unitType, double floatValue, int &exceptioncode ); + double floatValue ( unsigned short/* unitType */) const { return m_value.num; } + + void setStringValue ( unsigned short stringType, const DOM::DOMString &stringValue, int &exceptioncode ); + DOM::DOMStringImpl *getStringValue () const { + return ( ( m_type < CSSPrimitiveValue::CSS_STRING || + m_type > CSSPrimitiveValue::CSS_ATTR || + m_type == CSSPrimitiveValue::CSS_IDENT ) ? // fix IDENT + 0 : m_value.string ); + } + CounterImpl *getCounterValue () const { + return ( m_type != CSSPrimitiveValue::CSS_COUNTER ? 0 : m_value.counter ); + } + + RectImpl *getRectValue () const { + return ( m_type != CSSPrimitiveValue::CSS_RECT ? 0 : m_value.rect ); + } + + QRgb getRGBColorValue () const { + return ( m_type != CSSPrimitiveValue::CSS_RGBCOLOR ? 0 : m_value.rgbcolor ); + } + + PairImpl* getPairValue() const { + return (m_type != CSSPrimitiveValue::CSS_PAIR ? 0 : m_value.pair); + } + + virtual bool isPrimitiveValue() const { return true; } + virtual unsigned short cssValueType() const; + + int getIdent(); + + virtual bool parseString( const DOMString &string, bool = false); + virtual DOM::DOMString cssText() const; + + virtual bool isQuirkValue() const { return false; } + +protected: + int m_type; + union { + int ident; + double num; + DOM::DOMStringImpl *string; + CounterImpl *counter; + RectImpl *rect; + QRgb rgbcolor; + PairImpl* pair; + } m_value; +}; + +// This value is used to handle quirky margins in reflow roots (body, td, and th) like WinIE. +// The basic idea is that a stylesheet can use the value __qem (for quirky em) instead of em +// in a stylesheet. When the quirky value is used, if you're in quirks mode, the margin will +// collapse away inside a table cell. +class CSSQuirkPrimitiveValueImpl : public CSSPrimitiveValueImpl +{ +public: + CSSQuirkPrimitiveValueImpl(double num, CSSPrimitiveValue::UnitTypes type) + :CSSPrimitiveValueImpl(num, type) {} + + virtual ~CSSQuirkPrimitiveValueImpl() {} + + virtual bool isQuirkValue() const { return true; } +}; + +class CounterImpl : public khtml::Shared<CounterImpl> { +public: + CounterImpl() : m_listStyle(0) { } + DOMString identifier() const { return m_identifier; } + unsigned int listStyle() const { return m_listStyle; } + DOMString separator() const { return m_separator; } + + DOMString m_identifier; + unsigned int m_listStyle; + DOMString m_separator; +}; + +class RectImpl : public khtml::Shared<RectImpl> { +public: + RectImpl(); + ~RectImpl(); + + CSSPrimitiveValueImpl *top() const { return m_top; } + CSSPrimitiveValueImpl *right() const { return m_right; } + CSSPrimitiveValueImpl *bottom() const { return m_bottom; } + CSSPrimitiveValueImpl *left() const { return m_left; } + + void setTop( CSSPrimitiveValueImpl *top ); + void setRight( CSSPrimitiveValueImpl *right ); + void setBottom( CSSPrimitiveValueImpl *bottom ); + void setLeft( CSSPrimitiveValueImpl *left ); +protected: + CSSPrimitiveValueImpl *m_top; + CSSPrimitiveValueImpl *m_right; + CSSPrimitiveValueImpl *m_bottom; + CSSPrimitiveValueImpl *m_left; +}; + +// A primitive value representing a pair. This is useful for properties like border-radius, background-size/position, +// and border-spacing (all of which are space-separated sets of two values). At the moment we are only using it for +// border-radius and background-size, but (FIXME) border-spacing and background-position could be converted over to use +// it (eliminating some extra -webkit- internal properties). +class PairImpl : public khtml::Shared<PairImpl> { +public: + PairImpl() : m_first(0), m_second(0) { } + PairImpl(CSSPrimitiveValueImpl* first, CSSPrimitiveValueImpl* second) + : m_first(first), m_second(second) { if (first) first->ref(); if (second) second->ref(); } + virtual ~PairImpl(); + + CSSPrimitiveValueImpl* first() const { return m_first; } + CSSPrimitiveValueImpl* second() const { return m_second; } + + void setFirst(CSSPrimitiveValueImpl* first); + void setSecond(CSSPrimitiveValueImpl* second); + +protected: + CSSPrimitiveValueImpl* m_first; + CSSPrimitiveValueImpl* m_second; +}; + + +class CSSImageValueImpl : public CSSPrimitiveValueImpl, public khtml::CachedObjectClient +{ +public: + CSSImageValueImpl(const DOMString &url, const StyleBaseImpl *style); + CSSImageValueImpl(); + virtual ~CSSImageValueImpl(); + + khtml::CachedImage *image() { return m_image; } +protected: + khtml::CachedImage *m_image; +}; + +class FontFamilyValueImpl : public CSSPrimitiveValueImpl +{ +public: + FontFamilyValueImpl( const QString &string); + const QString &fontName() const { return parsedFontName; } + int genericFamilyType() const { return _genericFamilyType; } +protected: + QString parsedFontName; +private: + int _genericFamilyType; +}; + +class FontValueImpl : public CSSValueImpl +{ +public: + FontValueImpl(); + virtual ~FontValueImpl(); + + virtual unsigned short cssValueType() const { return CSSValue::CSS_CUSTOM; } + + virtual DOM::DOMString cssText() const; + + virtual bool isFontValue() const { return true; } + + CSSPrimitiveValueImpl *style; + CSSPrimitiveValueImpl *variant; + CSSPrimitiveValueImpl *weight; + CSSPrimitiveValueImpl *size; + CSSPrimitiveValueImpl *lineHeight; + CSSValueListImpl *family; +}; + +// Used for quotes +class QuotesValueImpl : public CSSValueImpl +{ +public: + QuotesValueImpl(); +// virtual ~QuotesValueImpl(); + + virtual unsigned short cssValueType() const { return CSSValue::CSS_CUSTOM; } + virtual DOM::DOMString cssText() const; + + void addLevel(const QString& open, const QString& close); + QString openQuote(int level) const; + QString closeQuote(int level) const; + + unsigned int levels; + QStringList data; +}; + +// Used for text-shadow and box-shadow +class ShadowValueImpl : public CSSValueImpl +{ +public: + ShadowValueImpl(CSSPrimitiveValueImpl* _x, CSSPrimitiveValueImpl* _y, + CSSPrimitiveValueImpl* _blur, CSSPrimitiveValueImpl* _color); + virtual ~ShadowValueImpl(); + + virtual unsigned short cssValueType() const { return CSSValue::CSS_CUSTOM; } + + virtual DOM::DOMString cssText() const; + + CSSPrimitiveValueImpl* x; + CSSPrimitiveValueImpl* y; + CSSPrimitiveValueImpl* blur; + CSSPrimitiveValueImpl* color; +}; + +// Used for counter-reset and counter-increment +class CounterActImpl : public CSSValueImpl { + public: + CounterActImpl(const DOMString &c, short v) : m_counter(c), m_value(v) { } + virtual ~CounterActImpl() {}; + + virtual unsigned short cssValueType() const { return CSSValue::CSS_CUSTOM; } + virtual DOM::DOMString cssText() const; + + const DOMString& counter() const { return m_counter; } + short value() const { return m_value; } + void setValue( const short v ) { m_value = v; } + + DOM::DOMString m_counter; + short m_value; +}; + + +// ------------------------------------------------------------------------------ + +// another helper class +class CSSProperty +{ +public: + CSSProperty() + { + m_id = -1; + m_important = false; + nonCSSHint = false; + m_value = 0; + } + CSSProperty(const CSSProperty& o) + { + m_id = o.m_id; + m_important = o.m_important; + nonCSSHint = o.nonCSSHint; + m_value = o.m_value; + if (m_value) m_value->ref(); + } + ~CSSProperty() { + if(m_value) m_value->deref(); + } + + void setValue(CSSValueImpl *val) { + if ( val != m_value ) { + if(m_value) m_value->deref(); + m_value = val; + if(m_value) m_value->ref(); + } + } + + int id() const { return m_id; } + + bool isImportant() const { return m_important; } + + CSSValueImpl *value() const { return m_value; } + + DOM::DOMString cssText() const; + + // make sure the following fits in 4 bytes. + signed int m_id : 29; + bool m_important : 1; + bool nonCSSHint : 1; +protected: + CSSValueImpl *m_value; +}; + + +} // namespace + +#endif diff --git a/khtml/css/csshelper.cpp b/khtml/css/csshelper.cpp new file mode 100644 index 000000000..7b7a464f4 --- /dev/null +++ b/khtml/css/csshelper.cpp @@ -0,0 +1,87 @@ +/* + * This file is part of the CSS implementation for KDE. + * + * Copyright (C) 1999 Lars Knoll (knoll@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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ +#include "csshelper.h" + +#include <qfontmetrics.h> +#include <qfontinfo.h> +#include <qpaintdevice.h> +#include <qpaintdevicemetrics.h> +#include <qfontdatabase.h> + +#include <kcharsets.h> +#include <kglobal.h> +#include <kdebug.h> + +#include "rendering/render_style.h" +#include "css_valueimpl.h" +#include "dom/css_value.h" +#include "misc/helper.h" +#include "xml/dom_stringimpl.h" +#include "khtml_settings.h" + +using namespace DOM; +using namespace khtml; + + +DOMString khtml::parseURL(const DOMString &url) +{ + DOMStringImpl* i = url.implementation(); + if(!i) return DOMString(); + + int o = 0; + int l = i->l; + while(o < l && (i->s[o] <= ' ')) { o++; l--; } + while(l > 0 && (i->s[o+l-1] <= ' ')) l--; + + if(l >= 5 && + (i->s[o].lower() == 'u') && + (i->s[o+1].lower() == 'r') && + (i->s[o+2].lower() == 'l') && + i->s[o+3].latin1() == '(' && + i->s[o+l-1].latin1() == ')') { + o += 4; + l -= 5; + } + + while(o < l && (i->s[o] <= ' ')) { o++; l--; } + while(l > 0 && (i->s[o+l-1] <= ' ')) l--; + + if(l >= 2 && i->s[o] == i->s[o+l-1] && + (i->s[o].latin1() == '\'' || i->s[o].latin1() == '\"')) { + o++; + l -= 2; + } + + while(o < l && (i->s[o] <= ' ')) { o++; l--; } + while(l > 0 && (i->s[o+l-1] <= ' ')) l--; + + DOMStringImpl* j = new DOMStringImpl(i->s+o,l); + + int nl = 0; + for(int k = o; k < o+l; k++) + if(i->s[k].unicode() > '\r') + j->s[nl++] = i->s[k]; + + j->l = nl; + + return j; +} diff --git a/khtml/css/csshelper.h b/khtml/css/csshelper.h new file mode 100644 index 000000000..68793421b --- /dev/null +++ b/khtml/css/csshelper.h @@ -0,0 +1,51 @@ +/* + * This file is part of the CSS implementation for KDE. + * + * Copyright (C) 1999 Lars Knoll (knoll@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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ +#ifndef css_helper_h +#define css_helper_h + +#include <qcolor.h> +#include <qfont.h> + +#include "dom/dom_string.h" + +class QPaintDeviceMetrics; +class KHTMLSettings; + +namespace DOM +{ + class CSSPrimitiveValueImpl; +} + +namespace khtml +{ + class RenderStyle; + + /* + * mostly just removes the url("...") brace + */ + DOM::DOMString parseURL(const DOM::DOMString &url); + +} + + + +#endif diff --git a/khtml/css/cssparser.cpp b/khtml/css/cssparser.cpp new file mode 100644 index 000000000..6ec9a4ec7 --- /dev/null +++ b/khtml/css/cssparser.cpp @@ -0,0 +1,2598 @@ +/* + * This file is part of the DOM implementation for KDE. + * + * Copyright (C) 2003 Lars Knoll (knoll@kde.org) + * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) + * Copyright (C) 2004, 2005, 2006 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +// #define CSS_DEBUG +// #define TOKEN_DEBUG +#define YYDEBUG 0 + +#include <kdebug.h> +#include <kglobal.h> +#include <kurl.h> + +#include "cssparser.h" +#include "css_valueimpl.h" +#include "css_ruleimpl.h" +#include "css_stylesheetimpl.h" +#include "cssproperties.h" +#include "cssvalues.h" +#include "misc/helper.h" +#include "csshelper.h" +using namespace DOM; + +#include <stdlib.h> +#include <assert.h> + +// used to promote background: left to left center +#define BACKGROUND_SKIP_CENTER( num ) \ + if ( !pos_ok[ num ] && expected != 1 ) { \ + pos_ok[num] = true; \ + pos[num] = 0; \ + skip_next = false; \ + } + +ValueList::~ValueList() +{ + unsigned numValues = m_values.size(); + for (unsigned i = 0; i < numValues; i++) + if (m_values[i].unit == Value::Function) + delete m_values[i].function; +} + +namespace { + class ShorthandScope { + public: + ShorthandScope(CSSParser* parser, int propId) : m_parser(parser) + { + if (!(m_parser->m_inParseShorthand++)) + m_parser->m_currentShorthand = propId; + } + ~ShorthandScope() + { + if (!(--m_parser->m_inParseShorthand)) + m_parser->m_currentShorthand = 0; + } + + private: + CSSParser* m_parser; + }; +} + +using namespace DOM; + +#if YYDEBUG > 0 +extern int cssyydebug; +#endif + +extern int cssyyparse( void * parser ); + +CSSParser *CSSParser::currentParser = 0; + +CSSParser::CSSParser( bool strictParsing ) +{ +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "CSSParser::CSSParser this=" << this << endl; +#endif + strict = strictParsing; + + parsedProperties = (CSSProperty **) malloc( 32 * sizeof( CSSProperty * ) ); + numParsedProperties = 0; + maxParsedProperties = 32; + + data = 0; + valueList = 0; + rule = 0; + id = 0; + important = false; + nonCSSHint = false; + + m_inParseShorthand = 0; + m_currentShorthand = 0; + m_implicitShorthand = false; + + yy_start = 1; + +#if YYDEBUG > 0 + cssyydebug = 1; +#endif + +} + +CSSParser::~CSSParser() +{ + if ( numParsedProperties ) + clearProperties(); + free( parsedProperties ); + + delete valueList; + +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "CSSParser::~CSSParser this=" << this << endl; +#endif + + free( data ); + +} + +unsigned int CSSParser::defaultNamespace() +{ + if (styleElement && styleElement->isCSSStyleSheet()) + return static_cast<CSSStyleSheetImpl*>(styleElement)->defaultNamespace(); + else + return anyNamespace; +} + +void CSSParser::runParser(int length) +{ + data[length-1] = 0; + data[length-2] = 0; + data[length-3] = ' '; + + yyTok = -1; + block_nesting = 0; + yy_hold_char = 0; + yyleng = 0; + yytext = yy_c_buf_p = data; + yy_hold_char = *yy_c_buf_p; + + CSSParser *old = currentParser; + currentParser = this; + cssyyparse( this ); + currentParser = old; +} + +void CSSParser::parseSheet( CSSStyleSheetImpl *sheet, const DOMString &string ) +{ + styleElement = sheet; + + int length = string.length() + 3; + data = (unsigned short *)malloc( length *sizeof( unsigned short ) ); + memcpy( data, string.unicode(), string.length()*sizeof( unsigned short) ); + +#ifdef CSS_DEBUG + kdDebug( 6080 ) << ">>>>>>> start parsing style sheet" << endl; +#endif + runParser(length); +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "<<<<<<< done parsing style sheet" << endl; +#endif + + delete rule; + rule = 0; +} + +CSSRuleImpl *CSSParser::parseRule( DOM::CSSStyleSheetImpl *sheet, const DOM::DOMString &string ) +{ + styleElement = sheet; + + const char khtml_rule[] = "@-khtml-rule{"; + int length = string.length() + 4 + strlen(khtml_rule); + assert( !data ); + data = (unsigned short *)malloc( length *sizeof( unsigned short ) ); + for ( unsigned int i = 0; i < strlen(khtml_rule); i++ ) + data[i] = khtml_rule[i]; + memcpy( data + strlen( khtml_rule ), string.unicode(), string.length()*sizeof( unsigned short) ); + // qDebug("parse string = '%s'", QConstString( (const QChar *)data, length ).string().latin1() ); + data[length-4] = '}'; + + runParser(length); + + CSSRuleImpl *result = rule; + rule = 0; + + return result; +} + +bool CSSParser::parseValue( DOM::CSSStyleDeclarationImpl *declaration, int _id, const DOM::DOMString &string, + bool _important, bool _nonCSSHint ) +{ +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "CSSParser::parseValue: id=" << _id << " important=" << _important + << " nonCSSHint=" << _nonCSSHint << " value='" << string.string() << "'" << endl; +#endif + + styleElement = declaration->stylesheet(); + + const char khtml_value[] = "@-khtml-value{"; + int length = string.length() + 4 + strlen(khtml_value); + assert( !data ); + data = (unsigned short *)malloc( length *sizeof( unsigned short ) ); + for ( unsigned int i = 0; i < strlen(khtml_value); i++ ) + data[i] = khtml_value[i]; + memcpy( data + strlen( khtml_value ), string.unicode(), string.length()*sizeof( unsigned short) ); + data[length-4] = '}'; + // qDebug("parse string = '%s'", QConstString( (const QChar *)data, length ).string().latin1() ); + + id = _id; + important = _important; + nonCSSHint = _nonCSSHint; + + runParser(length); + + delete rule; + rule = 0; + + bool ok = false; + if ( numParsedProperties ) { + ok = true; + for ( int i = 0; i < numParsedProperties; i++ ) { + declaration->removeProperty(parsedProperties[i]->m_id, nonCSSHint); + declaration->values()->append( parsedProperties[i] ); + } + numParsedProperties = 0; + } + + return ok; +} + +bool CSSParser::parseDeclaration( DOM::CSSStyleDeclarationImpl *declaration, const DOM::DOMString &string, + bool _nonCSSHint ) +{ +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "CSSParser::parseDeclaration: nonCSSHint=" << nonCSSHint + << " value='" << string.string() << "'" << endl; +#endif + + styleElement = declaration->stylesheet(); + + const char khtml_decls[] = "@-khtml-decls{"; + int length = string.length() + 4 + strlen(khtml_decls); + assert( !data ); + data = (unsigned short *)malloc( length *sizeof( unsigned short ) ); + for ( unsigned int i = 0; i < strlen(khtml_decls); i++ ) + data[i] = khtml_decls[i]; + memcpy( data + strlen( khtml_decls ), string.unicode(), string.length()*sizeof( unsigned short) ); + data[length-4] = '}'; + + nonCSSHint = _nonCSSHint; + + runParser(length); + + delete rule; + rule = 0; + + bool ok = false; + if ( numParsedProperties ) { + ok = true; + for ( int i = 0; i < numParsedProperties; i++ ) { + declaration->removeProperty(parsedProperties[i]->m_id, false); + declaration->values()->append( parsedProperties[i] ); + } + numParsedProperties = 0; + } + + return ok; +} + +void CSSParser::addProperty( int propId, CSSValueImpl *value, bool important ) +{ + CSSProperty *prop = new CSSProperty; + prop->m_id = propId; + prop->setValue( value ); + prop->m_important = important; + prop->nonCSSHint = nonCSSHint; + + if ( numParsedProperties >= maxParsedProperties ) { + maxParsedProperties += 32; + parsedProperties = (CSSProperty **) realloc( parsedProperties, + maxParsedProperties*sizeof( CSSProperty * ) ); + } + parsedProperties[numParsedProperties++] = prop; +} + +CSSStyleDeclarationImpl *CSSParser::createStyleDeclaration( CSSStyleRuleImpl *rule ) +{ + QPtrList<CSSProperty> *propList = new QPtrList<CSSProperty>; + propList->setAutoDelete( true ); + for ( int i = 0; i < numParsedProperties; i++ ) + propList->append( parsedProperties[i] ); + + numParsedProperties = 0; + return new CSSStyleDeclarationImpl(rule, propList); +} + +void CSSParser::clearProperties() +{ + for ( int i = 0; i < numParsedProperties; i++ ) + delete parsedProperties[i]; + numParsedProperties = 0; +} + +DOM::DocumentImpl *CSSParser::document() const +{ + const StyleBaseImpl* root = styleElement; + DocumentImpl *doc = 0; + while (root->parent()) + root = root->parent(); + if (root->isCSSStyleSheet()) + doc = static_cast<const CSSStyleSheetImpl*>(root)->doc(); + return doc; +} + + +// defines units allowed for a certain property, used in parseUnit +enum Units +{ + FUnknown = 0x0000, + FInteger = 0x0001, + FNumber = 0x0002, // Real Numbers + FPercent = 0x0004, + FLength = 0x0008, + FAngle = 0x0010, + FTime = 0x0020, + FFrequency = 0x0040, + FRelative = 0x0100, + FNonNeg = 0x0200 +}; + +static bool validUnit( Value *value, int unitflags, bool strict ) +{ + if ( unitflags & FNonNeg && value->fValue < 0 ) + return false; + + bool b = false; + switch( value->unit ) { + case CSSPrimitiveValue::CSS_NUMBER: + b = (unitflags & FNumber); + if ( !b && ( (unitflags & FLength) && (value->fValue == 0 || !strict ) ) ) { + value->unit = CSSPrimitiveValue::CSS_PX; + b = true; + } + if (!b && (unitflags & FInteger) && value->isInt) + b = true; + break; + case CSSPrimitiveValue::CSS_PERCENTAGE: + b = (unitflags & FPercent); + break; + case Value::Q_EMS: + case CSSPrimitiveValue::CSS_EMS: + case CSSPrimitiveValue::CSS_EXS: + case CSSPrimitiveValue::CSS_PX: + case CSSPrimitiveValue::CSS_CM: + case CSSPrimitiveValue::CSS_MM: + case CSSPrimitiveValue::CSS_IN: + case CSSPrimitiveValue::CSS_PT: + case CSSPrimitiveValue::CSS_PC: + b = (unitflags & FLength); + break; + case CSSPrimitiveValue::CSS_MS: + case CSSPrimitiveValue::CSS_S: + b = (unitflags & FTime); + break; + case CSSPrimitiveValue::CSS_DEG: + case CSSPrimitiveValue::CSS_RAD: + case CSSPrimitiveValue::CSS_GRAD: + case CSSPrimitiveValue::CSS_HZ: + case CSSPrimitiveValue::CSS_KHZ: + case CSSPrimitiveValue::CSS_DIMENSION: + default: + break; + } + return b; +} + +bool CSSParser::parseValue( int propId, bool important ) +{ + if ( !valueList ) return false; + + Value *value = valueList->current(); + + if ( !value ) + return false; + + int id = value->id; + + int num = inShorthand() ? 1 : valueList->size(); + + if ( id == CSS_VAL_INHERIT ) { + if (num != 1) + return false; + addProperty( propId, new CSSInheritedValueImpl(), important ); + return true; + } else if (id == CSS_VAL_INITIAL ) { + if (num != 1) + return false; + addProperty(propId, new CSSInitialValueImpl(), important); + return true; + } + + bool valid_primitive = false; + CSSValueImpl *parsedValue = 0; + + switch(propId) { + /* The comment to the left defines all valid value of this properties as defined + * in CSS 2, Appendix F. Property index + */ + + /* All the CSS properties are not supported by the renderer at the moment. + * Note that all the CSS2 Aural properties are only checked, if CSS_AURAL is defined + * (see parseAuralValues). As we don't support them at all this seems reasonable. + */ + + case CSS_PROP_SIZE: // <length>{1,2} | auto | portrait | landscape | inherit +// case CSS_PROP_PAGE: // <identifier> | auto // ### CHECK + // ### To be done + if (id) + valid_primitive = true; + break; + case CSS_PROP_UNICODE_BIDI: // normal | embed | bidi-override | inherit + if ( id == CSS_VAL_NORMAL || + id == CSS_VAL_EMBED || + id == CSS_VAL_BIDI_OVERRIDE ) + valid_primitive = true; + break; + + case CSS_PROP_POSITION: // static | relative | absolute | fixed | inherit + if ( id == CSS_VAL_STATIC || + id == CSS_VAL_RELATIVE || + id == CSS_VAL_ABSOLUTE || + id == CSS_VAL_FIXED ) + valid_primitive = true; + break; + + case CSS_PROP_PAGE_BREAK_AFTER: // auto | always | avoid | left | right | inherit + case CSS_PROP_PAGE_BREAK_BEFORE: // auto | always | avoid | left | right | inherit + if ( id == CSS_VAL_AUTO || + id == CSS_VAL_ALWAYS || + id == CSS_VAL_AVOID || + id == CSS_VAL_LEFT || + id == CSS_VAL_RIGHT ) + valid_primitive = true; + break; + + case CSS_PROP_PAGE_BREAK_INSIDE: // avoid | auto | inherit + if ( id == CSS_VAL_AUTO || + id == CSS_VAL_AVOID ) + valid_primitive = true; + break; + + case CSS_PROP_EMPTY_CELLS: // show | hide | inherit + if ( id == CSS_VAL_SHOW || + id == CSS_VAL_HIDE ) + valid_primitive = true; + break; + + case CSS_PROP_QUOTES: // [<string> <string>]+ | none | inherit + if (id == CSS_VAL_NONE) { + valid_primitive = true; + } else { + QuotesValueImpl *quotes = new QuotesValueImpl; + bool is_valid = true; + QString open, close; + Value *val=valueList->current(); + while (val) { + if (val->unit == CSSPrimitiveValue::CSS_STRING) + open = qString(val->string); + else { + is_valid = false; + break; + } + valueList->next(); + val=valueList->current(); + if (val && val->unit == CSSPrimitiveValue::CSS_STRING) + close = qString(val->string); + else { + is_valid = false; + break; + } + quotes->addLevel(open, close); + valueList->next(); + val=valueList->current(); + } + if (is_valid) + parsedValue = quotes; + else + delete quotes; + } + break; + + case CSS_PROP_CONTENT: // normal | none | inherit | + // [ <string> | <uri> | <counter> | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ + if ( id == CSS_VAL_NORMAL || id == CSS_VAL_NONE) + valid_primitive = true; + else + return parseContent( propId, important ); + break; + + case CSS_PROP_WHITE_SPACE: // normal | pre | nowrap | pre-wrap | pre-line | inherit + if ( id == CSS_VAL_NORMAL || + id == CSS_VAL_PRE || + id == CSS_VAL_PRE_WRAP || + id == CSS_VAL_PRE_LINE || + id == CSS_VAL_NOWRAP ) + valid_primitive = true; + break; + + case CSS_PROP_CLIP: // <shape> | auto | inherit + if ( id == CSS_VAL_AUTO ) + valid_primitive = true; + else if ( value->unit == Value::Function ) + return parseShape( propId, important ); + break; + + /* Start of supported CSS properties with validation. This is needed for parseShortHand to work + * correctly and allows optimization in khtml::applyRule(..) + */ + case CSS_PROP_CAPTION_SIDE: // top | bottom | left | right | inherit + // Left and right were deprecated in CSS 2.1 and never supported by KHTML + if ( /* id == CSS_VAL_LEFT || id == CSS_VAL_RIGHT || */ + id == CSS_VAL_TOP || id == CSS_VAL_BOTTOM) + valid_primitive = true; + break; + + case CSS_PROP_BORDER_COLLAPSE: // collapse | separate | inherit + if ( id == CSS_VAL_COLLAPSE || id == CSS_VAL_SEPARATE ) + valid_primitive = true; + break; + + case CSS_PROP_VISIBILITY: // visible | hidden | collapse | inherit + if (id == CSS_VAL_VISIBLE || id == CSS_VAL_HIDDEN || id == CSS_VAL_COLLAPSE) + valid_primitive = true; + break; + + case CSS_PROP_OVERFLOW: // visible | hidden | scroll | auto | marquee | inherit + case CSS_PROP_OVERFLOW_X: + case CSS_PROP_OVERFLOW_Y: + if (id == CSS_VAL_VISIBLE || id == CSS_VAL_HIDDEN || id == CSS_VAL_SCROLL || id == CSS_VAL_AUTO || + id == CSS_VAL_MARQUEE) + valid_primitive = true; + break; + + case CSS_PROP_LIST_STYLE_POSITION: // inside | outside | inherit + if ( id == CSS_VAL_INSIDE || id == CSS_VAL_OUTSIDE ) + valid_primitive = true; + break; + + case CSS_PROP_LIST_STYLE_TYPE: + // disc | circle | square | decimal | decimal-leading-zero | lower-roman | + // upper-roman | lower-greek | lower-alpha | lower-latin | upper-alpha | + // upper-latin | hebrew | armenian | georgian | cjk-ideographic | hiragana | + // katakana | hiragana-iroha | katakana-iroha | none | inherit + if ((id >= CSS_VAL_DISC && id <= CSS_VAL__KHTML_CLOSE_QUOTE) || id == CSS_VAL_NONE) + valid_primitive = true; + break; + + case CSS_PROP_DISPLAY: + // inline | block | list-item | run-in | inline-block | -khtml-ruler | table | + // inline-table | table-row-group | table-header-group | table-footer-group | table-row | + // table-column-group | table-column | table-cell | table-caption | none | inherit + if ((id >= CSS_VAL_INLINE && id <= CSS_VAL_TABLE_CAPTION) || id == CSS_VAL_NONE) + valid_primitive = true; + break; + + case CSS_PROP_DIRECTION: // ltr | rtl | inherit + if ( id == CSS_VAL_LTR || id == CSS_VAL_RTL ) + valid_primitive = true; + break; + + case CSS_PROP_TEXT_TRANSFORM: // capitalize | uppercase | lowercase | none | inherit + if ((id >= CSS_VAL_CAPITALIZE && id <= CSS_VAL_LOWERCASE) || id == CSS_VAL_NONE) + valid_primitive = true; + break; + + case CSS_PROP_FLOAT: // left | right | none | khtml_left | khtml_right | inherit + center for buggy CSS + if ( id == CSS_VAL_LEFT || id == CSS_VAL_RIGHT || id == CSS_VAL__KHTML_LEFT || + id == CSS_VAL__KHTML_RIGHT ||id == CSS_VAL_NONE || id == CSS_VAL_CENTER) + valid_primitive = true; + break; + + case CSS_PROP_CLEAR: // none | left | right | both | inherit + if ( id == CSS_VAL_NONE || id == CSS_VAL_LEFT || + id == CSS_VAL_RIGHT|| id == CSS_VAL_BOTH) + valid_primitive = true; + break; + + case CSS_PROP_TEXT_ALIGN: + // left | right | center | justify | khtml_left | khtml_right | khtml_center | <string> | inherit + if ( ( id >= CSS_VAL__KHTML_AUTO && id <= CSS_VAL__KHTML_CENTER ) || + value->unit == CSSPrimitiveValue::CSS_STRING ) + valid_primitive = true; + break; + + case CSS_PROP_OUTLINE_STYLE: // <border-style> | inherit + case CSS_PROP_BORDER_TOP_STYLE: //// <border-style> | inherit + case CSS_PROP_BORDER_RIGHT_STYLE: // Defined as: none | hidden | dotted | dashed | + case CSS_PROP_BORDER_BOTTOM_STYLE: // solid | double | groove | ridge | inset | outset | -khtml-native + case CSS_PROP_BORDER_LEFT_STYLE: //// + if (id >= CSS_VAL__KHTML_NATIVE && id <= CSS_VAL_DOUBLE) + valid_primitive = true; + break; + + case CSS_PROP_FONT_WEIGHT: // normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | + // 500 | 600 | 700 | 800 | 900 | inherit + if (id >= CSS_VAL_NORMAL && id <= CSS_VAL_900) { + // Allready correct id + valid_primitive = true; + } else if ( validUnit( value, FInteger|FNonNeg, false ) ) { + int weight = (int)value->fValue; + if ( (weight % 100) ) + break; + weight /= 100; + if ( weight >= 1 && weight <= 9 ) { + id = CSS_VAL_100 + weight - 1; + valid_primitive = true; + } + } + break; + + case CSS_PROP_BORDER_SPACING: + { + const int properties[2] = { CSS_PROP__KHTML_BORDER_HORIZONTAL_SPACING, + CSS_PROP__KHTML_BORDER_VERTICAL_SPACING }; + if (num == 1) { + ShorthandScope scope(this, CSS_PROP_BORDER_SPACING); + if (!parseValue(properties[0], important)) return false; + CSSValueImpl* value = parsedProperties[numParsedProperties-1]->value(); + addProperty(properties[1], value, important); + return true; + } + else if (num == 2) { + ShorthandScope scope(this, CSS_PROP_BORDER_SPACING); + if (!parseValue(properties[0], important)) return false; + if (!parseValue(properties[1], important)) return false; + return true; + } + return false; + } + case CSS_PROP__KHTML_BORDER_HORIZONTAL_SPACING: + case CSS_PROP__KHTML_BORDER_VERTICAL_SPACING: + valid_primitive = validUnit(value, FLength|FNonNeg, strict&(!nonCSSHint)); + break; + + case CSS_PROP_SCROLLBAR_FACE_COLOR: // IE5.5 + case CSS_PROP_SCROLLBAR_SHADOW_COLOR: // IE5.5 + case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR: // IE5.5 + case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR: // IE5.5 + case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR: // IE5.5 + case CSS_PROP_SCROLLBAR_TRACK_COLOR: // IE5.5 + case CSS_PROP_SCROLLBAR_ARROW_COLOR: // IE5.5 + case CSS_PROP_SCROLLBAR_BASE_COLOR: // IE5.5 + if ( strict ) + break; + /* nobreak */ + case CSS_PROP_OUTLINE_COLOR: // <color> | invert | inherit + // outline has "invert" as additional keyword. + if ( propId == CSS_PROP_OUTLINE_COLOR && id == CSS_VAL_INVERT ) { + valid_primitive = true; + break; + } + /* nobreak */ + case CSS_PROP_BACKGROUND_COLOR: // <color> | inherit + case CSS_PROP_BORDER_TOP_COLOR: // <color> | inherit + case CSS_PROP_BORDER_RIGHT_COLOR: // <color> | inherit + case CSS_PROP_BORDER_BOTTOM_COLOR: // <color> | inherit + case CSS_PROP_BORDER_LEFT_COLOR: // <color> | inherit + case CSS_PROP_COLOR: // <color> | inherit + if ( id == CSS_VAL__KHTML_TEXT || id == CSS_VAL_MENU || + (id >= CSS_VAL_AQUA && id <= CSS_VAL_WINDOWTEXT ) || + id == CSS_VAL_TRANSPARENT || + (id >= CSS_VAL_GREY && id < CSS_VAL__KHTML_TEXT && (nonCSSHint|!strict) ) ) { + valid_primitive = true; + } else { + parsedValue = parseColor(); + if ( parsedValue ) + valueList->next(); + } + break; + + case CSS_PROP_CURSOR: + // [ auto | crosshair | default | pointer | progress | move | e-resize | ne-resize | + // nw-resize | n-resize | se-resize | sw-resize | s-resize | w-resize | text | + // wait | help ] ] | inherit + // MSIE 5 compatibility :/ + if ( !strict && id == CSS_VAL_HAND ) { + id = CSS_VAL_POINTER; + valid_primitive = true; + } else if ( id >= CSS_VAL_AUTO && id <= CSS_VAL_HELP ) + valid_primitive = true; + break; + + case CSS_PROP_BACKGROUND_ATTACHMENT: + case CSS_PROP__KHTML_BACKGROUND_CLIP: + case CSS_PROP_BACKGROUND_IMAGE: + case CSS_PROP__KHTML_BACKGROUND_ORIGIN: + case CSS_PROP_BACKGROUND_POSITION: + case CSS_PROP_BACKGROUND_POSITION_X: + case CSS_PROP_BACKGROUND_POSITION_Y: + case CSS_PROP__KHTML_BACKGROUND_SIZE: + case CSS_PROP_BACKGROUND_REPEAT: { + CSSValueImpl *val1 = 0, *val2 = 0; + int propId1, propId2; + if (parseBackgroundProperty(propId, propId1, propId2, val1, val2)) { + addProperty(propId1, val1, important); + if (val2) + addProperty(propId2, val2, important); + return true; + } + return false; + } + case CSS_PROP_LIST_STYLE_IMAGE: // <uri> | none | inherit + if (id == CSS_VAL_NONE) { + parsedValue = new CSSImageValueImpl(); + valueList->next(); + } + else if (value->unit == CSSPrimitiveValue::CSS_URI ) { + // ### allow string in non strict mode? + DOMString uri = khtml::parseURL( domString( value->string ) ); + if (!uri.isEmpty()) { + parsedValue = new CSSImageValueImpl( + DOMString(KURL( styleElement->baseURL(), uri.string()).url()), + styleElement ); + valueList->next(); + } + } + break; + + case CSS_PROP_OUTLINE_WIDTH: // <border-width> | inherit + case CSS_PROP_BORDER_TOP_WIDTH: //// <border-width> | inherit + case CSS_PROP_BORDER_RIGHT_WIDTH: // Which is defined as + case CSS_PROP_BORDER_BOTTOM_WIDTH: // thin | medium | thick | <length> + case CSS_PROP_BORDER_LEFT_WIDTH: //// + if (id == CSS_VAL_THIN || id == CSS_VAL_MEDIUM || id == CSS_VAL_THICK) + valid_primitive = true; + else + valid_primitive = ( validUnit( value, FLength, strict&(!nonCSSHint) ) ); + break; + + case CSS_PROP_LETTER_SPACING: // normal | <length> | inherit + case CSS_PROP_WORD_SPACING: // normal | <length> | inherit + if ( id == CSS_VAL_NORMAL ) + valid_primitive = true; + else + valid_primitive = validUnit( value, FLength, strict&(!nonCSSHint) ); + break; + + case CSS_PROP_TEXT_INDENT: // <length> | <percentage> | inherit + valid_primitive = ( !id && validUnit( value, FLength|FPercent, strict&(!nonCSSHint) ) ); + break; + + case CSS_PROP_PADDING_TOP: // <length> | <percentage> | inherit + case CSS_PROP_PADDING_RIGHT: // <padding-width> | inherit + case CSS_PROP_PADDING_BOTTOM: // Which is defined as + case CSS_PROP_PADDING_LEFT: // <length> | <percentage> + case CSS_PROP__KHTML_PADDING_START: + valid_primitive = ( !id && validUnit( value, FLength|FPercent|FNonNeg, strict&(!nonCSSHint) ) ); + break; + + case CSS_PROP_MAX_HEIGHT: // <length> | <percentage> | none | inherit + case CSS_PROP_MAX_WIDTH: // <length> | <percentage> | none | inherit + if ( id == CSS_VAL_NONE ) { + valid_primitive = true; + break; + } + /* nobreak */ + case CSS_PROP_MIN_HEIGHT: // <length> | <percentage> | inherit + case CSS_PROP_MIN_WIDTH: // <length> | <percentage> | inherit + valid_primitive = ( !id && validUnit( value, FLength|FPercent|FNonNeg, strict&(!nonCSSHint) ) ); + break; + + case CSS_PROP_FONT_SIZE: + // <absolute-size> | <relative-size> | <length> | <percentage> | inherit + if (id >= CSS_VAL_XX_SMALL && id <= CSS_VAL_LARGER) + valid_primitive = true; + else + valid_primitive = ( validUnit( value, FLength|FPercent, strict&(!nonCSSHint) ) ); + break; + + case CSS_PROP_FONT_STYLE: // normal | italic | oblique | inherit + if ( id == CSS_VAL_NORMAL || id == CSS_VAL_ITALIC || id == CSS_VAL_OBLIQUE) + valid_primitive = true; + break; + + case CSS_PROP_FONT_VARIANT: // normal | small-caps | inherit + if ( id == CSS_VAL_NORMAL || id == CSS_VAL_SMALL_CAPS) + valid_primitive = true; + break; + + case CSS_PROP_VERTICAL_ALIGN: + // baseline | sub | super | top | text-top | middle | bottom | text-bottom | + // <percentage> | <length> | inherit + + if ( id >= CSS_VAL_BASELINE && id <= CSS_VAL__KHTML_BASELINE_MIDDLE ) + valid_primitive = true; + else + valid_primitive = ( !id && validUnit( value, FLength|FPercent, strict&(!nonCSSHint) ) ); + break; + + case CSS_PROP_HEIGHT: // <length> | <percentage> | auto | inherit + case CSS_PROP_WIDTH: // <length> | <percentage> | auto | inherit + if ( id == CSS_VAL_AUTO ) + valid_primitive = true; + else + // ### handle multilength case where we allow relative units + valid_primitive = ( !id && validUnit( value, FLength|FPercent|FNonNeg, strict&(!nonCSSHint) ) ); + break; + + case CSS_PROP_BOTTOM: // <length> | <percentage> | auto | inherit + case CSS_PROP_LEFT: // <length> | <percentage> | auto | inherit + case CSS_PROP_RIGHT: // <length> | <percentage> | auto | inherit + case CSS_PROP_TOP: // <length> | <percentage> | auto | inherit + case CSS_PROP_MARGIN_TOP: //// <margin-width> | inherit + case CSS_PROP_MARGIN_RIGHT: // Which is defined as + case CSS_PROP_MARGIN_BOTTOM: // <length> | <percentage> | auto | inherit + case CSS_PROP_MARGIN_LEFT: //// + case CSS_PROP__KHTML_MARGIN_START: + if ( id == CSS_VAL_AUTO ) + valid_primitive = true; + else + valid_primitive = ( !id && validUnit( value, FLength|FPercent, strict&(!nonCSSHint) ) ); + break; + + case CSS_PROP_Z_INDEX: // auto | <integer> | inherit + // qDebug("parsing z-index: id=%d, fValue=%f", id, value->fValue ); + if ( id == CSS_VAL_AUTO ) { + valid_primitive = true; + break; + } + /* nobreak */ + case CSS_PROP_ORPHANS: // <integer> | inherit + case CSS_PROP_WIDOWS: // <integer> | inherit + // ### not supported later on + valid_primitive = ( !id && validUnit( value, FInteger, false ) ); + break; + + case CSS_PROP_LINE_HEIGHT: // normal | <number> | <length> | <percentage> | inherit + if ( id == CSS_VAL_NORMAL ) + valid_primitive = true; + else + valid_primitive = ( !id && validUnit( value, FNumber|FLength|FPercent, strict&(!nonCSSHint) ) ); + break; + case CSS_PROP_COUNTER_INCREMENT: // [ <identifier> <integer>? ]+ | none | inherit + if ( id == CSS_VAL_NONE ) + valid_primitive = true; + else + return parseCounter(propId, true, important); + break; + case CSS_PROP_COUNTER_RESET: // [ <identifier> <integer>? ]+ | none | inherit + if ( id == CSS_VAL_NONE ) + valid_primitive = true; + else + return parseCounter(propId, false, important); + break; + + case CSS_PROP_FONT_FAMILY: + // [[ <family-name> | <generic-family> ],]* [<family-name> | <generic-family>] | inherit + { + parsedValue = parseFontFamily(); + break; + } + + case CSS_PROP_TEXT_DECORATION: + // none | [ underline || overline || line-through || blink ] | inherit + if (id == CSS_VAL_NONE) { + valid_primitive = true; + } else { + CSSValueListImpl *list = new CSSValueListImpl; + bool is_valid = true; + while( is_valid && value ) { + switch ( value->id ) { + case CSS_VAL_BLINK: + break; + case CSS_VAL_UNDERLINE: + case CSS_VAL_OVERLINE: + case CSS_VAL_LINE_THROUGH: + list->append( new CSSPrimitiveValueImpl( value->id ) ); + break; + default: + is_valid = false; + } + value = valueList->next(); + } + //kdDebug( 6080 ) << "got " << list->length() << "d decorations" << endl; + if(list->length() && is_valid) { + parsedValue = list; + valueList->next(); + } else { + delete list; + } + } + break; + + case CSS_PROP_TABLE_LAYOUT: // auto | fixed | inherit + if ( id == CSS_VAL_AUTO || id == CSS_VAL_FIXED ) + valid_primitive = true; + break; + + case CSS_PROP__KHTML_FLOW_MODE: + if ( id == CSS_VAL__KHTML_NORMAL || id == CSS_VAL__KHTML_AROUND_FLOATS ) + valid_primitive = true; + break; + + /* CSS3 properties */ + case CSS_PROP_BOX_SIZING: // border-box | content-box | inherit + if ( id == CSS_VAL_BORDER_BOX || id == CSS_VAL_CONTENT_BOX ) + valid_primitive = true; + break; + case CSS_PROP_OUTLINE_OFFSET: + valid_primitive = validUnit(value, FLength, strict); + break; + case CSS_PROP_TEXT_SHADOW: // CSS2 property, dropped in CSS2.1, back in CSS3, so treat as CSS3 + if (id == CSS_VAL_NONE) + valid_primitive = true; + else + return parseShadow(propId, important); + break; + case CSS_PROP_OPACITY: + valid_primitive = validUnit(value, FNumber, strict); + break; + case CSS_PROP__KHTML_USER_INPUT: // none | enabled | disabled | inherit + if ( id == CSS_VAL_NONE || id == CSS_VAL_ENABLED || id == CSS_VAL_DISABLED ) + valid_primitive = true; +// kdDebug(6080) << "CSS_PROP__KHTML_USER_INPUT: " << valid_primitive << endl; + break; + case CSS_PROP__KHTML_MARQUEE: { + const int properties[5] = { CSS_PROP__KHTML_MARQUEE_DIRECTION, CSS_PROP__KHTML_MARQUEE_INCREMENT, + CSS_PROP__KHTML_MARQUEE_REPETITION, + CSS_PROP__KHTML_MARQUEE_STYLE, CSS_PROP__KHTML_MARQUEE_SPEED }; + return parseShortHand(propId, properties, 5, important); + } + case CSS_PROP__KHTML_MARQUEE_DIRECTION: + if (id == CSS_VAL_FORWARDS || id == CSS_VAL_BACKWARDS || id == CSS_VAL_AHEAD || + id == CSS_VAL_REVERSE || id == CSS_VAL_LEFT || id == CSS_VAL_RIGHT || id == CSS_VAL_DOWN || + id == CSS_VAL_UP || id == CSS_VAL_AUTO) + valid_primitive = true; + break; + case CSS_PROP__KHTML_MARQUEE_INCREMENT: + if (id == CSS_VAL_SMALL || id == CSS_VAL_LARGE || id == CSS_VAL_MEDIUM) + valid_primitive = true; + else + valid_primitive = validUnit(value, FLength|FPercent, strict&(!nonCSSHint)); + break; + case CSS_PROP__KHTML_MARQUEE_STYLE: + if (id == CSS_VAL_NONE || id == CSS_VAL_SLIDE || id == CSS_VAL_SCROLL || id == CSS_VAL_ALTERNATE || + id == CSS_VAL_UNFURL) + valid_primitive = true; + break; + case CSS_PROP__KHTML_MARQUEE_REPETITION: + if (id == CSS_VAL_INFINITE) + valid_primitive = true; + else + valid_primitive = validUnit(value, FInteger|FNonNeg, strict&(!nonCSSHint)); + break; + case CSS_PROP__KHTML_MARQUEE_SPEED: + if (id == CSS_VAL_NORMAL || id == CSS_VAL_SLOW || id == CSS_VAL_FAST) + valid_primitive = true; + else + valid_primitive = validUnit(value, FTime|FInteger|FNonNeg, strict&(!nonCSSHint)); + break; + case CSS_PROP_TEXT_OVERFLOW: // clip | ellipsis + if (id == CSS_VAL_CLIP || id == CSS_VAL_ELLIPSIS) + valid_primitive = true; + break; + // End of CSS3 properties + + /* shorthand properties */ + case CSS_PROP_BACKGROUND: + // ['background-color' || 'background-image' ||'background-repeat' || + // 'background-attachment' || 'background-position'] | inherit + return parseBackgroundShorthand(important); + case CSS_PROP_BORDER: + // [ 'border-width' || 'border-style' || <color> ] | inherit + { + const int properties[3] = { CSS_PROP_BORDER_WIDTH, CSS_PROP_BORDER_STYLE, + CSS_PROP_BORDER_COLOR }; + return parseShortHand(propId, properties, 3, important); + } + case CSS_PROP_BORDER_TOP: + // [ 'border-top-width' || 'border-style' || <color> ] | inherit + { + const int properties[3] = { CSS_PROP_BORDER_TOP_WIDTH, CSS_PROP_BORDER_TOP_STYLE, + CSS_PROP_BORDER_TOP_COLOR}; + return parseShortHand(propId, properties, 3, important); + } + case CSS_PROP_BORDER_RIGHT: + // [ 'border-right-width' || 'border-style' || <color> ] | inherit + { + const int properties[3] = { CSS_PROP_BORDER_RIGHT_WIDTH, CSS_PROP_BORDER_RIGHT_STYLE, + CSS_PROP_BORDER_RIGHT_COLOR }; + return parseShortHand(propId, properties, 3, important); + } + case CSS_PROP_BORDER_BOTTOM: + // [ 'border-bottom-width' || 'border-style' || <color> ] | inherit + { + const int properties[3] = { CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_PROP_BORDER_BOTTOM_STYLE, + CSS_PROP_BORDER_BOTTOM_COLOR }; + return parseShortHand(propId, properties, 3, important); + } + case CSS_PROP_BORDER_LEFT: + // [ 'border-left-width' || 'border-style' || <color> ] | inherit + { + const int properties[3] = { CSS_PROP_BORDER_LEFT_WIDTH, CSS_PROP_BORDER_LEFT_STYLE, + CSS_PROP_BORDER_LEFT_COLOR }; + return parseShortHand(propId, properties, 3, important); + } + case CSS_PROP_OUTLINE: + // [ 'outline-color' || 'outline-style' || 'outline-width' ] | inherit + { + const int properties[3] = { CSS_PROP_OUTLINE_WIDTH, CSS_PROP_OUTLINE_STYLE, + CSS_PROP_OUTLINE_COLOR }; + return parseShortHand(propId, properties, 3, important); + } + case CSS_PROP_BORDER_COLOR: + // <color>{1,4} | inherit + { + const int properties[4] = { CSS_PROP_BORDER_TOP_COLOR, CSS_PROP_BORDER_RIGHT_COLOR, + CSS_PROP_BORDER_BOTTOM_COLOR, CSS_PROP_BORDER_LEFT_COLOR }; + return parse4Values(propId, properties, important); + } + case CSS_PROP_BORDER_WIDTH: + // <border-width>{1,4} | inherit + { + const int properties[4] = { CSS_PROP_BORDER_TOP_WIDTH, CSS_PROP_BORDER_RIGHT_WIDTH, + CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_PROP_BORDER_LEFT_WIDTH }; + return parse4Values(propId, properties, important); + } + case CSS_PROP_BORDER_STYLE: + // <border-style>{1,4} | inherit + { + const int properties[4] = { CSS_PROP_BORDER_TOP_STYLE, CSS_PROP_BORDER_RIGHT_STYLE, + CSS_PROP_BORDER_BOTTOM_STYLE, CSS_PROP_BORDER_LEFT_STYLE }; + return parse4Values(propId, properties, important); + } + case CSS_PROP_MARGIN: + // <margin-width>{1,4} | inherit + { + const int properties[4] = { CSS_PROP_MARGIN_TOP, CSS_PROP_MARGIN_RIGHT, + CSS_PROP_MARGIN_BOTTOM, CSS_PROP_MARGIN_LEFT }; + return parse4Values(propId, properties, important); + } + case CSS_PROP_PADDING: + // <padding-width>{1,4} | inherit + { + const int properties[4] = { CSS_PROP_PADDING_TOP, CSS_PROP_PADDING_RIGHT, + CSS_PROP_PADDING_BOTTOM, CSS_PROP_PADDING_LEFT }; + return parse4Values(propId, properties, important); + } + case CSS_PROP_FONT: + // [ [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]? + // 'font-family' ] | caption | icon | menu | message-box | small-caption | status-bar | inherit + if ( id >= CSS_VAL_CAPTION && id <= CSS_VAL_STATUS_BAR ) + valid_primitive = true; + else + return parseFont(important); + + case CSS_PROP_LIST_STYLE: + { + const int properties[3] = { CSS_PROP_LIST_STYLE_TYPE, CSS_PROP_LIST_STYLE_POSITION, + CSS_PROP_LIST_STYLE_IMAGE }; + return parseShortHand(propId, properties, 3, important); + } + default: +// #ifdef CSS_DEBUG +// kdDebug( 6080 ) << "illegal or CSS2 Aural property: " << val << endl; +// #endif + break; + } + + if ( valid_primitive ) { + + if ( id != 0 ) { + parsedValue = new CSSPrimitiveValueImpl( id ); + } else if ( value->unit == CSSPrimitiveValue::CSS_STRING ) + parsedValue = new CSSPrimitiveValueImpl( domString( value->string ), + (CSSPrimitiveValue::UnitTypes) value->unit ); + else if ( value->unit >= CSSPrimitiveValue::CSS_NUMBER && + value->unit <= CSSPrimitiveValue::CSS_KHZ ) { + parsedValue = new CSSPrimitiveValueImpl( value->fValue, + (CSSPrimitiveValue::UnitTypes) value->unit ); + } else if ( value->unit >= Value::Q_EMS ) { + parsedValue = new CSSQuirkPrimitiveValueImpl( value->fValue, CSSPrimitiveValue::CSS_EMS ); + } + valueList->next(); + } + if ( parsedValue ) { + if (!valueList->current() || inShorthand()) { + addProperty( propId, parsedValue, important ); + return true; + } + delete parsedValue; + } + return false; +} + +void CSSParser::addBackgroundValue(CSSValueImpl*& lval, CSSValueImpl* rval) +{ + if (lval) { + if (lval->isValueList()) + static_cast<CSSValueListImpl*>(lval)->append(rval); + else { + CSSValueImpl* oldVal = lval; + CSSValueListImpl* list = new CSSValueListImpl(); + lval = list; + list->append(oldVal); + list->append(rval); + } + } + else + lval = rval; +} + +bool CSSParser::parseBackgroundShorthand(bool important) +{ + // Position must come before color in this array because a plain old "0" is a legal color + // in quirks mode but it's usually the X coordinate of a position. + // FIXME: Add CSS_PROP__KHTML_BACKGROUND_SIZE to the shorthand. + const int numProperties = 7; + const int properties[numProperties] = { CSS_PROP_BACKGROUND_IMAGE, CSS_PROP_BACKGROUND_REPEAT, + CSS_PROP_BACKGROUND_ATTACHMENT, CSS_PROP_BACKGROUND_POSITION, CSS_PROP__KHTML_BACKGROUND_CLIP, + CSS_PROP__KHTML_BACKGROUND_ORIGIN, CSS_PROP_BACKGROUND_COLOR }; + + ShorthandScope scope(this, CSS_PROP_BACKGROUND); + + bool parsedProperty[numProperties] = { false }; // compiler will repeat false as necessary + CSSValueImpl* values[numProperties] = { 0 }; // compiler will repeat 0 as necessary + CSSValueImpl* positionYValue = 0; + int i; + + while (valueList->current()) { + Value* val = valueList->current(); + if (val->unit == Value::Operator && val->iValue == ',') { + // We hit the end. Fill in all remaining values with the initial value. + valueList->next(); + for (i = 0; i < numProperties; ++i) { + if (properties[i] == CSS_PROP_BACKGROUND_COLOR && parsedProperty[i]) + // Color is not allowed except as the last item in a list. Reject the entire + // property. + goto fail; + + if (!parsedProperty[i] && properties[i] != CSS_PROP_BACKGROUND_COLOR) { + addBackgroundValue(values[i], new CSSInitialValueImpl()); + if (properties[i] == CSS_PROP_BACKGROUND_POSITION) + addBackgroundValue(positionYValue, new CSSInitialValueImpl()); + } + parsedProperty[i] = false; + } + if (!valueList->current()) + break; + } + + bool found = false; + for (i = 0; !found && i < numProperties; ++i) { + if (!parsedProperty[i]) { + CSSValueImpl *val1 = 0, *val2 = 0; + int propId1, propId2; + if (parseBackgroundProperty(properties[i], propId1, propId2, val1, val2)) { + parsedProperty[i] = found = true; + addBackgroundValue(values[i], val1); + if (properties[i] == CSS_PROP_BACKGROUND_POSITION) + addBackgroundValue(positionYValue, val2); + } + } + } + + // if we didn't find at least one match, this is an + // invalid shorthand and we have to ignore it + if (!found) + goto fail; + } + + // Fill in any remaining properties with the initial value. + for (i = 0; i < numProperties; ++i) { + if (!parsedProperty[i]) { + addBackgroundValue(values[i], new CSSInitialValueImpl()); + if (properties[i] == CSS_PROP_BACKGROUND_POSITION) + addBackgroundValue(positionYValue, new CSSInitialValueImpl()); + } + } + + // Now add all of the properties we found. + for (i = 0; i < numProperties; i++) { + if (properties[i] == CSS_PROP_BACKGROUND_POSITION) { + addProperty(CSS_PROP_BACKGROUND_POSITION_X, values[i], important); + addProperty(CSS_PROP_BACKGROUND_POSITION_Y, positionYValue, important); + } + else + addProperty(properties[i], values[i], important); + } + + return true; + +fail: + for (int k = 0; k < numProperties; k++) + delete values[k]; + delete positionYValue; + return false; +} + +bool CSSParser::parseShortHand(int propId, const int *properties, int numProperties, bool important ) +{ + /* We try to match as many properties as possible + * We setup an array of booleans to mark which property has been found, + * and we try to search for properties until it makes no longer any sense + */ + ShorthandScope scope(this, propId); + + bool found = false; + bool fnd[6]; //Trust me ;) + for( int i = 0; i < numProperties; i++ ) + fnd[i] = false; + + while ( valueList->current() ) { + found = false; + for (int propIndex = 0; !found && propIndex < numProperties; ++propIndex) { + if (!fnd[propIndex]) { + if ( parseValue( properties[propIndex], important ) ) { + fnd[propIndex] = found = true; + } + } + } + + // if we didn't find at least one match, this is an + // invalid shorthand and we have to ignore it + if (!found) + return false; + } + + // Fill in any remaining properties with the initial value. + m_implicitShorthand = true; + for (int i = 0; i < numProperties; ++i) { + if (!fnd[i]) + addProperty(properties[i], new CSSInitialValueImpl(), important); + } + m_implicitShorthand = false; + + return true; +} + +bool CSSParser::parse4Values(int propId, const int *properties, bool important ) +{ + /* From the CSS 2 specs, 8.3 + * If there is only one value, it applies to all sides. If there are two values, the top and + * bottom margins are set to the first value and the right and left margins are set to the second. + * If there are three values, the top is set to the first value, the left and right are set to the + * second, and the bottom is set to the third. If there are four values, they apply to the top, + * right, bottom, and left, respectively. + */ + + int num = inShorthand() ? 1 : valueList->size(); + //qDebug("parse4Values: num=%d %d", num, valueList->numValues ); + + ShorthandScope scope(this, propId); + + // the order is top, right, bottom, left + switch (num) { + case 1: { + if (!parseValue(properties[0], important)) + return false; + CSSValueImpl *value = parsedProperties[numParsedProperties-1]->value(); + m_implicitShorthand = true; + addProperty(properties[1], value, important); + addProperty(properties[2], value, important); + addProperty(properties[3], value, important); + m_implicitShorthand = false; + break; + } + case 2: { + if (!parseValue(properties[0], important) || !parseValue(properties[1], important)) + return false; + CSSValueImpl *value = parsedProperties[numParsedProperties-2]->value(); + m_implicitShorthand = true; + addProperty(properties[2], value, important); + value = parsedProperties[numParsedProperties-2]->value(); + addProperty(properties[3], value, important); + m_implicitShorthand = false; + break; + } + case 3: { + if (!parseValue(properties[0], important) || !parseValue(properties[1], important) || !parseValue(properties[2], important)) + return false; + CSSValueImpl *value = parsedProperties[numParsedProperties-2]->value(); + m_implicitShorthand = true; + addProperty(properties[3], value, important); + m_implicitShorthand = false; + break; + } + case 4: { + if (!parseValue(properties[0], important) || !parseValue(properties[1], important) || + !parseValue(properties[2], important) || !parseValue(properties[3], important)) + return false; + break; + } + default: { + return false; + } + } + + return true; +} + +// [ <string> | <uri> | <counter> | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit +// in CSS 2.1 this got somewhat reduced: +// [ <string> | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit +bool CSSParser::parseContent( int propId, bool important ) +{ + CSSValueListImpl* values = new CSSValueListImpl(); + + bool isValid = true; + Value *val; + CSSValueImpl *parsedValue = 0; + while ( (val = valueList->current()) ) { + parsedValue = 0; + if ( val->unit == CSSPrimitiveValue::CSS_URI ) { + // url + DOMString value = khtml::parseURL(domString(val->string)); + parsedValue = new CSSImageValueImpl( + DOMString(KURL( styleElement->baseURL(), value.string()).url() ), styleElement ); +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "content, url=" << value.string() << " base=" << styleElement->baseURL().url( ) << endl; +#endif + } else if ( val->unit == Value::Function ) { + // attr( X ) | counter( X [,Y] ) | counters( X, Y, [,Z] ) + ValueList *args = val->function->args; + QString fname = qString( val->function->name ).lower(); + if (!args) return false; + if (fname == "attr(") { + if ( args->size() != 1) + return false; + Value *a = args->current(); + parsedValue = new CSSPrimitiveValueImpl(domString(a->string), CSSPrimitiveValue::CSS_ATTR); + } + else + if (fname == "counter(") { + parsedValue = parseCounterContent(args, false); + if (!parsedValue) return false; + } else + if (fname == "counters(") { + parsedValue = parseCounterContent(args, true); + if (!parsedValue) return false; + } + else + return false; + + } else if ( val->unit == CSSPrimitiveValue::CSS_IDENT ) { + // open-quote | close-quote | no-open-quote | no-close-quote + if ( val->id == CSS_VAL_OPEN_QUOTE || + val->id == CSS_VAL_CLOSE_QUOTE || + val->id == CSS_VAL_NO_OPEN_QUOTE || + val->id == CSS_VAL_NO_CLOSE_QUOTE ) { + parsedValue = new CSSPrimitiveValueImpl(val->id); + } + } else if ( val->unit == CSSPrimitiveValue::CSS_STRING ) { + parsedValue = new CSSPrimitiveValueImpl(domString(val->string), CSSPrimitiveValue::CSS_STRING); + } + + if (parsedValue) + values->append(parsedValue); + else { + isValid = false; + break; + } + valueList->next(); + } + if ( isValid && values->length() ) { + addProperty( propId, values, important ); + valueList->next(); + return true; + } + + delete values; // also frees any content by deref + return false; +} + +CSSValueImpl* CSSParser::parseCounterContent(ValueList *args, bool counters) +{ + if (counters || (args->size() != 1 && args->size() != 3)) + if (!counters || (args->size() != 3 && args->size() != 5)) + return 0; + + CounterImpl *counter = new CounterImpl; + Value *i = args->current(); +// if (i->unit != CSSPrimitiveValue::CSS_IDENT) goto invalid; + counter->m_identifier = domString(i->string); + if (counters) { + i = args->next(); + if (i->unit != Value::Operator || i->iValue != ',') goto invalid; + i = args->next(); + if (i->unit != CSSPrimitiveValue::CSS_STRING) goto invalid; + counter->m_separator = domString(i->string); + } + counter->m_listStyle = CSS_VAL_DECIMAL - CSS_VAL_DISC; + i = args->next(); + if (i) { + if (i->unit != Value::Operator || i->iValue != ',') goto invalid; + i = args->next(); + if (i->unit != CSSPrimitiveValue::CSS_IDENT) goto invalid; + if (i->id < CSS_VAL_DISC || i->id > CSS_VAL__KHTML_CLOSE_QUOTE) goto invalid; + counter->m_listStyle = i->id - CSS_VAL_DISC; + } + return new CSSPrimitiveValueImpl(counter); +invalid: + delete counter; + return 0; +} + +CSSValueImpl* CSSParser::parseBackgroundColor() +{ + int id = valueList->current()->id; + if (id == CSS_VAL__KHTML_TEXT || id == CSS_VAL_TRANSPARENT || + (id >= CSS_VAL_AQUA && id <= CSS_VAL_WINDOWTEXT) || id == CSS_VAL_MENU || + (id >= CSS_VAL_GREY && id < CSS_VAL__KHTML_TEXT && !strict)) + return new CSSPrimitiveValueImpl(id); + return parseColor(); +} + +CSSValueImpl* CSSParser::parseBackgroundImage() +{ + if (valueList->current()->id == CSS_VAL_NONE) + return new CSSImageValueImpl(); + if (valueList->current()->unit == CSSPrimitiveValue::CSS_URI) { + DOMString uri = khtml::parseURL(domString(valueList->current()->string)); + if (!uri.isEmpty()) + return new CSSImageValueImpl(DOMString(KURL(styleElement->baseURL(), uri.string()).url()), + styleElement); + } + return 0; +} + +CSSValueImpl* CSSParser::parseBackgroundPositionXY(bool& xFound, bool& yFound) +{ + int id = valueList->current()->id; + if (id == CSS_VAL_LEFT || id == CSS_VAL_TOP || id == CSS_VAL_RIGHT || id == CSS_VAL_BOTTOM || id == CSS_VAL_CENTER) { + int percent = 0; + if (id == CSS_VAL_LEFT || id == CSS_VAL_RIGHT) { + if (xFound) + return 0; + xFound = true; + if (id == CSS_VAL_RIGHT) + percent = 100; + } + else if (id == CSS_VAL_TOP || id == CSS_VAL_BOTTOM) { + if (yFound) + return 0; + yFound = true; + if (id == CSS_VAL_BOTTOM) + percent = 100; + } + else if (id == CSS_VAL_CENTER) + // Center is ambiguous, so we're not sure which position we've found yet, an x or a y. + percent = 50; + return new CSSPrimitiveValueImpl(percent, CSSPrimitiveValue::CSS_PERCENTAGE); + } + if (validUnit(valueList->current(), FPercent|FLength, strict)) + return new CSSPrimitiveValueImpl(valueList->current()->fValue, + (CSSPrimitiveValue::UnitTypes)valueList->current()->unit); + + return 0; +} + +void CSSParser::parseBackgroundPosition(CSSValueImpl*& value1, CSSValueImpl*& value2) +{ + value1 = value2 = 0; + Value* value = valueList->current(); + + // Parse the first value. We're just making sure that it is one of the valid keywords or a percentage/length. + bool value1IsX = false, value1IsY = false; + value1 = parseBackgroundPositionXY(value1IsX, value1IsY); + if (!value1) + return; + + // It only takes one value for background-position to be correctly parsed if it was specified in a shorthand (since we + // can assume that any other values belong to the rest of the shorthand). If we're not parsing a shorthand, though, the + // value was explicitly specified for our property. + value = valueList->next(); + + // First check for the comma. If so, we are finished parsing this value or value pair. + if (value && value->unit == Value::Operator && value->iValue == ',') + value = 0; + + bool value2IsX = false, value2IsY = false; + if (value) { + value2 = parseBackgroundPositionXY(value2IsX, value2IsY); + if (value2) + valueList->next(); + else { + if (!inShorthand()) { + delete value1; + value1 = 0; + return; + } + } + } + + if (!value2) + // Only one value was specified. If that value was not a keyword, then it sets the x position, and the y position + // is simply 50%. This is our default. + // For keywords, the keyword was either an x-keyword (left/right), a y-keyword (top/bottom), or an ambiguous keyword (center). + // For left/right/center, the default of 50% in the y is still correct. + value2 = new CSSPrimitiveValueImpl(50, CSSPrimitiveValue::CSS_PERCENTAGE); + + if (value1IsY || value2IsX) { + // Swap our two values. + CSSValueImpl* val = value2; + value2 = value1; + value1 = val; + } +} + +CSSValueImpl* CSSParser::parseBackgroundSize() +{ + Value* value = valueList->current(); + CSSPrimitiveValueImpl* parsedValue1; + + if (value->id == CSS_VAL_AUTO) + parsedValue1 = new CSSPrimitiveValueImpl(0, CSSPrimitiveValue::CSS_UNKNOWN); + else { + if (!validUnit(value, FLength|FPercent, strict)) + return 0; + parsedValue1 = new CSSPrimitiveValueImpl(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); + } + + CSSPrimitiveValueImpl* parsedValue2 = parsedValue1; + if ((value = valueList->next())) { + if (value->id == CSS_VAL_AUTO) + parsedValue2 = new CSSPrimitiveValueImpl(0, CSSPrimitiveValue::CSS_UNKNOWN); + else { + if (!validUnit(value, FLength|FPercent, strict)) { + delete parsedValue1; + return 0; + } + parsedValue2 = new CSSPrimitiveValueImpl(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); + } + } + + PairImpl* pair = new PairImpl(parsedValue1, parsedValue2); + return new CSSPrimitiveValueImpl(pair); +} + +bool CSSParser::parseBackgroundProperty(int propId, int& propId1, int& propId2, + CSSValueImpl*& retValue1, CSSValueImpl*& retValue2) +{ +#ifdef CSS_DEBUG + kdDebug(6080) << "parseBackgroundProperty()" << endl; + kdDebug(6080) << "LOOKING FOR: " << getPropertyName(propId).string() << endl; +#endif + CSSValueListImpl *values = 0, *values2 = 0; + Value* val; + CSSValueImpl *value = 0, *value2 = 0; + bool allowComma = false; + + retValue1 = retValue2 = 0; + propId1 = propId; + propId2 = propId; + if (propId == CSS_PROP_BACKGROUND_POSITION) { + propId1 = CSS_PROP_BACKGROUND_POSITION_X; + propId2 = CSS_PROP_BACKGROUND_POSITION_Y; + } + + while ((val = valueList->current())) { + CSSValueImpl *currValue = 0, *currValue2 = 0; + if (allowComma) { + if (val->unit != Value::Operator || val->iValue != ',') + goto failed; + valueList->next(); + allowComma = false; + } + else { + switch (propId) { + case CSS_PROP_BACKGROUND_ATTACHMENT: + if (val->id == CSS_VAL_SCROLL || val->id == CSS_VAL_FIXED) { + currValue = new CSSPrimitiveValueImpl(val->id); + valueList->next(); + } + break; + case CSS_PROP_BACKGROUND_COLOR: + currValue = parseBackgroundColor(); + if (currValue) + valueList->next(); + break; + case CSS_PROP_BACKGROUND_IMAGE: + currValue = parseBackgroundImage(); + if (currValue) + valueList->next(); + break; + case CSS_PROP__KHTML_BACKGROUND_CLIP: + case CSS_PROP__KHTML_BACKGROUND_ORIGIN: + if (val->id == CSS_VAL_BORDER || val->id == CSS_VAL_PADDING || val->id == CSS_VAL_CONTENT) { + currValue = new CSSPrimitiveValueImpl(val->id); + valueList->next(); + } + break; + case CSS_PROP_BACKGROUND_POSITION: + parseBackgroundPosition(currValue, currValue2); + // unlike the other functions, parseBackgroundPosition advances the valueList pointer + break; + case CSS_PROP_BACKGROUND_POSITION_X: { + bool xFound = false, yFound = true; + currValue = parseBackgroundPositionXY(xFound, yFound); + if (currValue) + valueList->next(); + break; + } + case CSS_PROP_BACKGROUND_POSITION_Y: { + bool xFound = true, yFound = false; + currValue = parseBackgroundPositionXY(xFound, yFound); + if (currValue) + valueList->next(); + break; + } + case CSS_PROP_BACKGROUND_REPEAT: + if (val->id >= CSS_VAL_REPEAT && val->id <= CSS_VAL_NO_REPEAT) { + currValue = new CSSPrimitiveValueImpl(val->id); + valueList->next(); + } + break; + case CSS_PROP__KHTML_BACKGROUND_SIZE: + currValue = parseBackgroundSize(); + if (currValue) + valueList->next(); + break; + } + + if (!currValue) + goto failed; + + if (value && !values) { + values = new CSSValueListImpl(); + values->append(value); + value = 0; + } + + if (value2 && !values2) { + values2 = new CSSValueListImpl(); + values2->append(value2); + value2 = 0; + } + + if (values) + values->append(currValue); + else + value = currValue; + if (currValue2) { + if (values2) + values2->append(currValue2); + else + value2 = currValue2; + } + allowComma = true; + } + + // When parsing the 'background' shorthand property, we let it handle building up the lists for all + // properties. + if (inShorthand()) + break; + } + + if (values && values->length()) { + retValue1 = values; + if (values2 && values2->length()) + retValue2 = values2; + return true; + } + if (value) { + retValue1 = value; + retValue2 = value2; + return true; + } + +failed: + delete values; delete values2; + delete value; delete value2; + return false; +} + +bool CSSParser::parseShape( int propId, bool important ) +{ + Value *value = valueList->current(); + ValueList *args = value->function->args; + QString fname = qString( value->function->name ).lower(); + //qDebug( "parseShape: fname: %d", fname.latin1() ); + if ( fname != "rect(" || !args ) + return false; + + // rect( t, r, b, l ) || rect( t r b l ) + if ( args->size() != 4 && args->size() != 7 ) + return false; + RectImpl *rect = new RectImpl(); + bool valid = true; + int i = 0; + Value *a = args->current(); + while ( a ) { + valid = validUnit( a, FLength, strict ); + if ( !valid ) + break; + CSSPrimitiveValueImpl *length = + new CSSPrimitiveValueImpl( a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit ); + if ( i == 0 ) + rect->setTop( length ); + else if ( i == 1 ) + rect->setRight( length ); + else if ( i == 2 ) + rect->setBottom( length ); + else + rect->setLeft( length ); + a = args->next(); + if ( a && args->size() == 7 ) { + if ( a->unit == Value::Operator && a->iValue == ',' ) { + a = args->next(); + } else { + valid = false; + break; + } + } + i++; + } + if ( valid ) { + addProperty( propId, new CSSPrimitiveValueImpl( rect ), important ); + valueList->next(); + return true; + } + delete rect; + return false; +} + +// [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]? 'font-family' +bool CSSParser::parseFont( bool important ) +{ +// kdDebug(6080) << "parsing font property current=" << valueList->currentValue << endl; + bool valid = true; + Value *value = valueList->current(); + CSSValueListImpl* family = 0; + CSSPrimitiveValueImpl *style = 0, *variant = 0, *weight = 0, *size = 0, *lineHeight = 0; + // optional font-style, font-variant and font-weight + while ( value ) { +// kdDebug( 6080 ) << "got value " << value->id << " / " << (value->unit == CSSPrimitiveValue::CSS_STRING || + // value->unit == CSSPrimitiveValue::CSS_IDENT ? qString( value->string ) : QString::null ) +// << endl; + int id = value->id; + if ( id ) { + if ( id == CSS_VAL_NORMAL ) { + // do nothing, it's the initial value for all three + } + /* + else if ( id == CSS_VAL_INHERIT ) { + // set all non set ones to inherit + // This is not that simple as the inherit could also apply to the following font-size. + // very ahrd to tell without looking ahead. + inherit = true; + } */ + else if ( id == CSS_VAL_ITALIC || id == CSS_VAL_OBLIQUE ) { + if ( style ) + goto invalid; + style = new CSSPrimitiveValueImpl( id ); + } else if ( id == CSS_VAL_SMALL_CAPS ) { + if ( variant ) + goto invalid; + variant = new CSSPrimitiveValueImpl( id ); + } else if ( id >= CSS_VAL_BOLD && id <= CSS_VAL_LIGHTER ) { + if ( weight ) + goto invalid; + weight = new CSSPrimitiveValueImpl( id ); + } else { + valid = false; + } + } else if ( !weight && validUnit( value, FInteger|FNonNeg, true ) ) { + int w = (int)value->fValue; + int val = 0; + if ( w == 100 ) + val = CSS_VAL_100; + else if ( w == 200 ) + val = CSS_VAL_200; + else if ( w == 300 ) + val = CSS_VAL_300; + else if ( w == 400 ) + val = CSS_VAL_400; + else if ( w == 500 ) + val = CSS_VAL_500; + else if ( w == 600 ) + val = CSS_VAL_600; + else if ( w == 700 ) + val = CSS_VAL_700; + else if ( w == 800 ) + val = CSS_VAL_800; + else if ( w == 900 ) + val = CSS_VAL_900; + + if ( val ) + weight = new CSSPrimitiveValueImpl( val ); + else + valid = false; + } else { + valid = false; + } + if ( !valid ) + break; + value = valueList->next(); + } + if ( !value ) + goto invalid; + + // set undefined values to default + if ( !style ) + style = new CSSPrimitiveValueImpl( CSS_VAL_NORMAL ); + if ( !variant ) + variant = new CSSPrimitiveValueImpl( CSS_VAL_NORMAL ); + if ( !weight ) + weight = new CSSPrimitiveValueImpl( CSS_VAL_NORMAL ); + +// kdDebug( 6080 ) << " got style, variant and weight current=" << valueList->currentValue << endl; + + // now a font size _must_ come + // <absolute-size> | <relative-size> | <length> | <percentage> | inherit + if ( value->id >= CSS_VAL_XX_SMALL && value->id <= CSS_VAL_LARGER ) + size = new CSSPrimitiveValueImpl( value->id ); + else if ( validUnit( value, FLength|FPercent, strict ) ) { + size = new CSSPrimitiveValueImpl( value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit ); + } + value = valueList->next(); + if ( !size || !value ) + goto invalid; + + // kdDebug( 6080 ) << " got size" << endl; + + if ( value->unit == Value::Operator && value->iValue == '/' ) { + // line-height + value = valueList->next(); + if ( !value ) + goto invalid; + if ( value->id == CSS_VAL_NORMAL ) { + // default value, nothing to do + } else if ( validUnit( value, FNumber|FLength|FPercent, strict ) ) { + lineHeight = new CSSPrimitiveValueImpl( value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit ); + } else { + goto invalid; + } + value = valueList->next(); + if ( !value ) + goto invalid; + } + if ( !lineHeight ) + lineHeight = new CSSPrimitiveValueImpl( CSS_VAL_NORMAL ); + +// kdDebug( 6080 ) << " got line height current=" << valueList->currentValue << endl; + // font family must come now + family = parseFontFamily(); + + if ( valueList->current() || !family ) + goto invalid; + //kdDebug( 6080 ) << " got family, parsing ok!" << endl; + + addProperty( CSS_PROP_FONT_FAMILY, family, important ); + addProperty( CSS_PROP_FONT_STYLE, style, important ); + addProperty( CSS_PROP_FONT_VARIANT, variant, important ); + addProperty( CSS_PROP_FONT_WEIGHT, weight, important ); + addProperty( CSS_PROP_FONT_SIZE, size, important ); + addProperty( CSS_PROP_LINE_HEIGHT, lineHeight, important ); + return true; + + invalid: + //kdDebug(6080) << " -> invalid" << endl; + delete family; + delete style; + delete variant; + delete weight; + delete size; + delete lineHeight; + + return false; +} + +CSSValueListImpl *CSSParser::parseFontFamily() +{ +// kdDebug( 6080 ) << "CSSParser::parseFontFamily current=" << valueList->currentValue << endl; + CSSValueListImpl *list = new CSSValueListImpl; + Value *value = valueList->current(); + QString currFace; + + while ( value ) { +// kdDebug( 6080 ) << "got value " << value->id << " / " +// << (value->unit == CSSPrimitiveValue::CSS_STRING || +// value->unit == CSSPrimitiveValue::CSS_IDENT ? qString( value->string ) : QString::null ) +// << endl; + Value* nextValue = valueList->next(); + bool nextValBreaksFont = !nextValue || + (nextValue->unit == Value::Operator && nextValue->iValue == ','); + bool nextValIsFontName = nextValue && + ((nextValue->id >= CSS_VAL_SERIF && nextValue->id <= CSS_VAL_MONOSPACE) || + (nextValue->unit == CSSPrimitiveValue::CSS_STRING || + nextValue->unit == CSSPrimitiveValue::CSS_IDENT)); + + if (value->id >= CSS_VAL_SERIF && value->id <= CSS_VAL_MONOSPACE) { + if (!currFace.isNull()) { + currFace += ' '; + currFace += qString(value->string); + } + else if (nextValBreaksFont || !nextValIsFontName) { + if ( !currFace.isNull() ) { + list->append( new FontFamilyValueImpl( currFace ) ); + currFace = QString::null; + } + list->append(new CSSPrimitiveValueImpl(value->id)); + } + else { + currFace = qString( value->string ); + } + } + else if (value->unit == CSSPrimitiveValue::CSS_STRING) { + // Strings never share in a family name. + currFace = QString::null; + list->append(new FontFamilyValueImpl(qString( value->string) ) ); + } + else if (value->unit == CSSPrimitiveValue::CSS_IDENT) { + if (!currFace.isNull()) { + currFace += ' '; + currFace += qString(value->string); + } + else if (nextValBreaksFont || !nextValIsFontName) { + if ( !currFace.isNull() ) { + list->append( new FontFamilyValueImpl( currFace ) ); + currFace = QString::null; + } + list->append(new FontFamilyValueImpl( qString( value->string ) ) ); + } + else { + currFace = qString( value->string); + } + } + else { + //kdDebug( 6080 ) << "invalid family part" << endl; + break; + } + + if (!nextValue) + break; + + if (nextValBreaksFont) { + value = valueList->next(); + if ( !currFace.isNull() ) + list->append( new FontFamilyValueImpl( currFace ) ); + currFace = QString::null; + } + else if (nextValIsFontName) + value = nextValue; + else + break; + } + + if ( !currFace.isNull() ) + list->append( new FontFamilyValueImpl( currFace ) ); + + if ( !list->length() ) { + delete list; + list = 0; + } + return list; +} + + +bool CSSParser::parseColorParameters(Value* value, int* colorArray, bool parseAlpha) +{ + ValueList* args = value->function->args; + Value* v = args->current(); + // Get the first value + if (!validUnit(v, FInteger | FPercent, true)) + return false; + colorArray[0] = static_cast<int>(v->fValue * (v->unit == CSSPrimitiveValue::CSS_PERCENTAGE ? 256.0 / 100.0 : 1.0)); + for (int i = 1; i < 3; i++) { + v = args->next(); + if (v->unit != Value::Operator && v->iValue != ',') + return false; + v = args->next(); + if (!validUnit(v, FInteger | FPercent, true)) + return false; + colorArray[i] = static_cast<int>(v->fValue * (v->unit == CSSPrimitiveValue::CSS_PERCENTAGE ? 256.0 / 100.0 : 1.0)); + } + if (parseAlpha) { + v = args->next(); + if (v->unit != Value::Operator && v->iValue != ',') + return false; + v = args->next(); + if (!validUnit(v, FNumber, true)) + return false; + colorArray[3] = static_cast<int>(kMax(0.0, kMin(1.0, v->fValue)) * 255); + } + return true; +} + +// CSS3 specification defines the format of a HSL color as +// hsl(<number>, <percent>, <percent>) +// and with alpha, the format is +// hsla(<number>, <percent>, <percent>, <number>) +// The first value, HUE, is in an angle with a value between 0 and 360 +bool CSSParser::parseHSLParameters(Value* value, double* colorArray, bool parseAlpha) +{ + ValueList* args = value->function->args; + Value* v = args->current(); + // Get the first value + if (!validUnit(v, FInteger, true)) + return false; + // normalize the Hue value and change it to be between 0 and 1.0 + colorArray[0] = (((static_cast<int>(v->fValue) % 360) + 360) % 360) / 360.0; + for (int i = 1; i < 3; i++) { + v = args->next(); + if (v->unit != Value::Operator && v->iValue != ',') + return false; + v = args->next(); + if (!validUnit(v, FPercent, true)) + return false; + colorArray[i] = kMax(0.0, kMin(100.0, v->fValue)) / 100.0; // needs to be value between 0 and 1.0 + } + if (parseAlpha) { + v = args->next(); + if (v->unit != Value::Operator && v->iValue != ',') + return false; + v = args->next(); + if (!validUnit(v, FNumber, true)) + return false; + colorArray[3] = kMax(0.0, kMin(1.0, v->fValue)); + } + return true; +} + +static bool parseColor(int unit, const QString &name, QRgb& rgb) +{ + int len = name.length(); + + if ( !len ) + return false; + + + bool ok; + + if ( len == 3 || len == 6 ) { + int val = name.toInt(&ok, 16); + if ( ok ) { + if (len == 6) { + rgb = (0xff << 24) | val; + return true; + } + else if ( len == 3 ) { + // #abc converts to #aabbcc according to the specs + rgb = (0xff << 24) | + (val&0xf00)<<12 | (val&0xf00)<<8 | + (val&0xf0)<<8 | (val&0xf0)<<4 | + (val&0xf)<<4 | (val&0xf); + return true; + } + } + } + + if ( unit == CSSPrimitiveValue::CSS_IDENT ) { + // try a little harder + QColor tc; + tc.setNamedColor(name.lower()); + if ( tc.isValid() ) { + rgb = tc.rgb(); + return true; + } + } + + return false; +} + +CSSPrimitiveValueImpl *CSSParser::parseColor() +{ + return parseColorFromValue(valueList->current()); +} + +CSSPrimitiveValueImpl *CSSParser::parseColorFromValue(Value* value) +{ + QRgb c = khtml::transparentColor; + if ( !strict && value->unit == CSSPrimitiveValue::CSS_NUMBER && + value->fValue >= 0. && value->fValue < 1000000. ) { + QString str; + str.sprintf( "%06d", (int)(value->fValue+.5) ); + if ( !::parseColor( value->unit, str, c ) ) + return 0; + } + else if (value->unit == CSSPrimitiveValue::CSS_RGBCOLOR || + value->unit == CSSPrimitiveValue::CSS_IDENT || + (!strict && value->unit == CSSPrimitiveValue::CSS_DIMENSION)) { + if ( !::parseColor( value->unit, qString( value->string ), c) ) + return 0; + } + else if ( value->unit == Value::Function && + value->function->args != 0 && + value->function->args->size() == 5 /* rgb + two commas */ && + qString( value->function->name ).lower() == "rgb(" ) { + int colorValues[3]; + if (!parseColorParameters(value, colorValues, false)) + return 0; + colorValues[0] = kMax( 0, kMin( 255, colorValues[0] ) ); + colorValues[1] = kMax( 0, kMin( 255, colorValues[1] ) ); + colorValues[2] = kMax( 0, kMin( 255, colorValues[2] ) ); + c = qRgb(colorValues[0], colorValues[1], colorValues[2]); + } else if (value->unit == Value::Function && + value->function->args != 0 && + value->function->args->size() == 7 /* rgba + three commas */ && + domString(value->function->name).lower() == "rgba(") { + int colorValues[4]; + if (!parseColorParameters(value, colorValues, true)) + return 0; + colorValues[0] = kMax( 0, kMin( 255, colorValues[0] ) ); + colorValues[1] = kMax( 0, kMin( 255, colorValues[1] ) ); + colorValues[2] = kMax( 0, kMin( 255, colorValues[2] ) ); + c = qRgba(colorValues[0], colorValues[1], colorValues[2], colorValues[3]); + } else if (value->unit == Value::Function && + value->function->args != 0 && + value->function->args->size() == 5 /* hsl + two commas */ && + domString(value->function->name).lower() == "hsl(") { + double colorValues[3]; + if (!parseHSLParameters(value, colorValues, false)) + return 0; + c = khtml::qRgbaFromHsla(colorValues[0], colorValues[1], colorValues[2], 1.0); + } else if (value->unit == Value::Function && + value->function->args != 0 && + value->function->args->size() == 7 /* hsla + three commas */ && + domString(value->function->name).lower() == "hsla(") { + double colorValues[4]; + if (!parseHSLParameters(value, colorValues, true)) + return 0; + c = khtml::qRgbaFromHsla(colorValues[0], colorValues[1], colorValues[2], colorValues[3]); + } + else + return 0; + + return new CSSPrimitiveValueImpl(c); +} + +// This class tracks parsing state for shadow values. If it goes out of scope (e.g., due to an early return) +// without the allowBreak bit being set, then it will clean up all of the objects and destroy them. +struct ShadowParseContext { + ShadowParseContext() + :values(0), x(0), y(0), blur(0), color(0), + allowX(true), allowY(false), allowBlur(false), allowColor(true), + allowBreak(true) + {} + + ~ShadowParseContext() { + if (!allowBreak) { + delete values; + delete x; + delete y; + delete blur; + delete color; + } + } + + bool allowLength() { return allowX || allowY || allowBlur; } + + bool failed() { return allowBreak = false; } + + void commitValue() { + // Handle the ,, case gracefully by doing nothing. + if (x || y || blur || color) { + if (!values) + values = new CSSValueListImpl(); + + // Construct the current shadow value and add it to the list. + values->append(new ShadowValueImpl(x, y, blur, color)); + } + + // Now reset for the next shadow value. + x = y = blur = color = 0; + allowX = allowColor = allowBreak = true; + allowY = allowBlur = false; + } + + void commitLength(Value* v) { + CSSPrimitiveValueImpl* val = new CSSPrimitiveValueImpl(v->fValue, + (CSSPrimitiveValue::UnitTypes)v->unit); + if (allowX) { + x = val; + allowX = false; allowY = true; allowColor = false; allowBreak = false; + } + else if (allowY) { + y = val; + allowY = false; allowBlur = true; allowColor = true; allowBreak = true; + } + else if (allowBlur) { + blur = val; + allowBlur = false; + } + else + delete val; + } + + void commitColor(CSSPrimitiveValueImpl* val) { + color = val; + allowColor = false; + if (allowX) + allowBreak = false; + else + allowBlur = false; + } + + CSSValueListImpl* values; + CSSPrimitiveValueImpl* x; + CSSPrimitiveValueImpl* y; + CSSPrimitiveValueImpl* blur; + CSSPrimitiveValueImpl* color; + + bool allowX; + bool allowY; + bool allowBlur; + bool allowColor; + bool allowBreak; +}; + +bool CSSParser::parseShadow(int propId, bool important) +{ + ShadowParseContext context; + Value* val; + while ((val = valueList->current())) { + // Check for a comma break first. + if (val->unit == Value::Operator) { + if (val->iValue != ',' || !context.allowBreak) + // Other operators aren't legal or we aren't done with the current shadow + // value. Treat as invalid. + return context.failed(); + + // The value is good. Commit it. + context.commitValue(); + } + // Check to see if we're a length. + else if (validUnit(val, FLength, true)) { + // We required a length and didn't get one. Invalid. + if (!context.allowLength()) + return context.failed(); + + // A length is allowed here. Construct the value and add it. + context.commitLength(val); + } + else { + // The only other type of value that's ok is a color value. + CSSPrimitiveValueImpl* parsedColor = 0; + bool isColor = (val->id >= CSS_VAL_AQUA && val->id <= CSS_VAL_WINDOWTEXT || val->id == CSS_VAL_MENU || + (val->id >= CSS_VAL_GREY && val->id <= CSS_VAL__KHTML_TEXT && !strict)); + if (!context.allowColor) + return context.failed(); + + if (isColor) + parsedColor = new CSSPrimitiveValueImpl(val->id); + + if (!parsedColor) + // It's not built-in. Try to parse it as a color. + parsedColor = parseColorFromValue(val); + + if (!parsedColor) + return context.failed(); + + context.commitColor(parsedColor); + } + + valueList->next(); + } + + if (context.allowBreak) { + context.commitValue(); + if (context.values->length()) { + addProperty(propId, context.values, important); + valueList->next(); + return true; + } + } + + return context.failed(); +} + +bool CSSParser::parseCounter(int propId, bool increment, bool important) +{ + enum { ID, VAL, COMMA } state = ID; + + CSSValueListImpl *list = new CSSValueListImpl; + DOMString c; + Value* val; + while (true) { + val = valueList->current(); + switch (state) { + // Commas are not allowed according to the standard, but Opera allows them and being the only + // other browser with counter support we need to match their behavior to work with current use + case COMMA: + state = ID; + if (val && val->unit == Value::Operator && val->iValue == ',') { + valueList->next(); + continue; + } + // no break + case ID: + if (val && val->unit == CSSPrimitiveValue::CSS_IDENT) { + c = qString(val->string); + state = VAL; + valueList->next(); + continue; + } + break; + case VAL: { + short i = 0; + if (val && val->unit == CSSPrimitiveValue::CSS_NUMBER) { + i = (short)val->fValue; + valueList->next(); + } else + i = (increment) ? 1 : 0; + + CounterActImpl *cv = new CounterActImpl(c,i); + list->append(cv); + state = COMMA; + continue; + } + } + break; + } + if(list->length() > 0) { + addProperty( propId, list, important ); + return true; + } + delete list; + return false; +} + +static inline int yyerror( const char *str ) { +// assert( 0 ); +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "CSS parse error " << str << endl; +#else + Q_UNUSED( str ); +#endif + return 1; +} + +#define END 0 + +#include "parser.h" + +int DOM::CSSParser::lex( void *_yylval ) +{ + YYSTYPE *yylval = (YYSTYPE *)_yylval; + int token = lex(); + int length; + unsigned short *t = text( &length ); + +#ifdef TOKEN_DEBUG + qDebug("CSSTokenizer: got token %d: '%s'", token, token == END ? "" : QString( (QChar *)t, length ).latin1() ); +#endif + switch( token ) { + case '{': + block_nesting++; + break; + case '}': + if ( block_nesting ) + block_nesting--; + break; + case END: + if ( block_nesting ) { + block_nesting--; + return '}'; + } + break; + case S: + case SGML_CD: + case INCLUDES: + case DASHMATCH: + break; + + case URI: + case STRING: + case IDENT: + case NTH: + case HASH: + case DIMEN: + case UNICODERANGE: + case NOTFUNCTION: + case FUNCTION: + yylval->string.string = t; + yylval->string.length = length; + break; + + case IMPORT_SYM: + case PAGE_SYM: + case MEDIA_SYM: + case FONT_FACE_SYM: + case CHARSET_SYM: + case NAMESPACE_SYM: + + case IMPORTANT_SYM: + break; + + case QEMS: + length--; + case GRADS: + length--; + case DEGS: + case RADS: + case KHERZ: + length--; + case MSECS: + case HERZ: + case EMS: + case EXS: + case PXS: + case CMS: + case MMS: + case INS: + case PTS: + case PCS: + length--; + case SECS: + case PERCENTAGE: + length--; + case FLOAT: + case INTEGER: + yylval->val = QString( (QChar *)t, length ).toDouble(); + //qDebug("value = %s, converted=%.2f", QString( (QChar *)t, length ).latin1(), yylval->val ); + break; + + default: + break; + } + + return token; +} + +static inline int toHex( char c ) { + if ( '0' <= c && c <= '9' ) + return c - '0'; + if ( 'a' <= c && c <= 'f' ) + return c - 'a' + 10; + if ( 'A' <= c && c<= 'F' ) + return c - 'A' + 10; + return 0; +} + +unsigned short *DOM::CSSParser::text(int *length) +{ + unsigned short *start = yytext; + int l = yyleng; + switch( yyTok ) { + case STRING: + l--; + /* nobreak */ + case HASH: + start++; + l--; + break; + case URI: + // "url("{w}{string}{w}")" + // "url("{w}{url}{w}")" + + // strip "url(" and ")" + start += 4; + l -= 5; + // strip {w} + while ( l && + (*start == ' ' || *start == '\t' || *start == '\r' || + *start == '\n' || *start == '\f' ) ) { + start++; l--; + } + if ( *start == '"' || *start == '\'' ) { + start++; l--; + } + while ( l && + (start[l-1] == ' ' || start[l-1] == '\t' || start[l-1] == '\r' || + start[l-1] == '\n' || start[l-1] == '\f' ) ) { + l--; + } + if ( l && (start[l-1] == '\"' || start[l-1] == '\'' ) ) + l--; + + default: + break; + } + + // process escapes + unsigned short *out = start; + unsigned short *escape = 0; + + for ( int i = 0; i < l; i++ ) { + unsigned short *current = start+i; + if ( escape == current - 1 ) { + if ( ( *current >= '0' && *current <= '9' ) || + ( *current >= 'a' && *current <= 'f' ) || + ( *current >= 'A' && *current <= 'F' ) ) + continue; + if ( yyTok == STRING && + ( *current == '\n' || *current == '\r' || *current == '\f' ) ) { + // ### handle \r\n case + if ( *current != '\r' ) + escape = 0; + continue; + } + // in all other cases copy the char to output + // ### + *out++ = *current; + escape = 0; + continue; + } + if ( escape == current - 2 && yyTok == STRING && + *(current-1) == '\r' && *current == '\n' ) { + escape = 0; + continue; + } + if ( escape > current - 7 && + ( ( *current >= '0' && *current <= '9' ) || + ( *current >= 'a' && *current <= 'f' ) || + ( *current >= 'A' && *current <= 'F' ) ) ) + continue; + if ( escape ) { + // add escaped char + int uc = 0; + escape++; + while ( escape < current ) { +// qDebug("toHex( %c = %x", (char)*escape, toHex( *escape ) ); + uc *= 16; + uc += toHex( *escape ); + escape++; + } +// qDebug(" converting escape: string='%s', value=0x%x", QString( (QChar *)e, current-e ).latin1(), uc ); + // can't handle chars outside ucs2 + if ( uc > 0xffff ) + uc = 0xfffd; + *(out++) = (unsigned short)uc; + escape = 0; + if ( *current == ' ' || + *current == '\t' || + *current == '\r' || + *current == '\n' || + *current == '\f' ) + continue; + } + if ( !escape && *current == '\\' ) { + escape = current; + continue; + } + *(out++) = *current; + } + if ( escape ) { + // add escaped char + int uc = 0; + escape++; + while ( escape < start+l ) { + // qDebug("toHex( %c = %x", (char)*escape, toHex( *escape ) ); + uc *= 16; + uc += toHex( *escape ); + escape++; + } + // qDebug(" converting escape: string='%s', value=0x%x", QString( (QChar *)e, current-e ).latin1(), uc ); + // can't handle chars outside ucs2 + if ( uc > 0xffff ) + uc = 0xfffd; + *(out++) = (unsigned short)uc; + } + + *length = out - start; + return start; +} + + +#define YY_DECL int DOM::CSSParser::lex() +#define yyconst const +typedef int yy_state_type; +typedef unsigned int YY_CHAR; +// this line makes sure we treat all Unicode chars correctly. +#define YY_SC_TO_UI(c) (c > 0xff ? 0xff : c) +#define YY_DO_BEFORE_ACTION \ + yytext = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + yy_hold_char = *yy_cp; \ + *yy_cp = 0; \ + yy_c_buf_p = yy_cp; +#define YY_BREAK break; +#define ECHO qDebug( "%s", QString( (QChar *)yytext, yyleng ).latin1() ) +#define YY_RULE_SETUP +#define INITIAL 0 +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) +#define YY_START ((yy_start - 1) / 2) +#define yyterminate() yyTok = END; return yyTok +#define YY_FATAL_ERROR(a) qFatal(a) +#define BEGIN yy_start = 1 + 2 * +#define COMMENT 1 + +#include "tokenizer.cpp" diff --git a/khtml/css/cssparser.h b/khtml/css/cssparser.h new file mode 100644 index 000000000..1c055acd0 --- /dev/null +++ b/khtml/css/cssparser.h @@ -0,0 +1,201 @@ +/* + * This file is part of the DOM implementation for KDE. + * + * Copyright (C) 2003 Lars Knoll (knoll@kde.org) + * Copyright (C) 2004, 2005, 2006 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#ifndef _CSS_cssparser_h_ +#define _CSS_cssparser_h_ + +#include <qstring.h> +#include <qcolor.h> +#include <qvaluevector.h> +#include <dom/dom_string.h> + +namespace DOM { + class StyleListImpl; + class CSSStyleSheetImpl; + class CSSRuleImpl; + class CSSStyleRuleImpl; + class DocumentImpl; + class CSSValueImpl; + class CSSValueListImpl; + class CSSPrimitiveValueImpl; + class CSSStyleDeclarationImpl; + class CSSProperty; + class CSSRuleListImpl; + + + struct ParseString { + unsigned short *string; + int length; + }; + + struct Value; + class ValueList; + + struct Function { + ParseString name; + ValueList *args; + }; + + struct Value { + int id; + bool isInt; + union { + double fValue; + int iValue; + ParseString string; + struct Function *function; + }; + enum { + Operator = 0x100000, + Function = 0x100001, + Q_EMS = 0x100002 + }; + + int unit; + }; + + static inline QString qString( const ParseString &ps ) { + return QString( (QChar *)ps.string, ps.length ); + } + static inline DOMString domString( const ParseString &ps ) { + return DOMString( (QChar *)ps.string, ps.length ); + } + + class ValueList { + public: + ValueList() : m_current(0) { } + ~ValueList(); + void addValue(const Value& v) { m_values.append(v); } + unsigned int size() const { return m_values.size(); } + Value* current() { return m_current < m_values.size() ? &m_values[m_current] : 0; } + Value* next() { ++m_current; return current(); } + private: + QValueVector<Value> m_values; + unsigned int m_current; + }; + + class CSSParser + { + public: + CSSParser( bool strictParsing = true ); + ~CSSParser(); + + void parseSheet( DOM::CSSStyleSheetImpl *sheet, const DOM::DOMString &string ); + DOM::CSSRuleImpl *parseRule( DOM::CSSStyleSheetImpl *sheet, const DOM::DOMString &string ); + bool parseValue( DOM::CSSStyleDeclarationImpl *decls, int id, const DOM::DOMString &string, + bool _important, bool _nonCSSHint ); + bool parseDeclaration( DOM::CSSStyleDeclarationImpl *decls, const DOM::DOMString &string, + bool _nonCSSHint ); + + static CSSParser *current() { return currentParser; } + + + DOM::DocumentImpl *document() const; + + unsigned int defaultNamespace(); + + void addProperty( int propId, CSSValueImpl *value, bool important ); + bool hasProperties() const { return numParsedProperties > 0; } + CSSStyleDeclarationImpl *createStyleDeclaration( CSSStyleRuleImpl *rule ); + void clearProperties(); + + bool parseValue( int propId, bool important ); + bool parseShortHand( int propId, const int *properties, int numProperties, bool important ); + bool parse4Values( int propId, const int *properties, bool important ); + bool parseContent( int propId, bool important ); + + CSSValueImpl* parseBackgroundColor(); + CSSValueImpl* parseBackgroundImage(); + CSSValueImpl* parseBackgroundPositionXY(bool& xFound, bool& yFound); + void parseBackgroundPosition(CSSValueImpl*& value1, CSSValueImpl*& value2); + CSSValueImpl* parseBackgroundSize(); + + bool parseBackgroundProperty(int propId, int& propId1, int& propId2, CSSValueImpl*& retValue1, CSSValueImpl*& retValue2); + bool parseBackgroundShorthand(bool important); + + void addBackgroundValue(CSSValueImpl*& lval, CSSValueImpl* rval); + + bool parseShape( int propId, bool important ); + bool parseFont(bool important); + bool parseCounter(int propId, bool increment, bool important); + + bool parseColorParameters(Value*, int* colorValues, bool parseAlpha); + bool parseHSLParameters(Value*, double* colorValues, bool parseAlpha); + + // returns the found property + // 0 if nothing found (or ok == false) + // @param forward if true, it parses the next in the list + CSSValueListImpl *parseFontFamily(); + CSSPrimitiveValueImpl *parseColor(); + CSSPrimitiveValueImpl *parseColorFromValue(Value* val); + CSSValueImpl* parseCounterContent(ValueList *args, bool counters); + + static bool parseColor(const QString &name, QRgb& rgb); + + // CSS3 Parsing Routines (for properties specific to CSS3) + bool parseShadow(int propId, bool important); + + bool parseBorderImage(int propId, bool important); + + public: + bool strict; + bool important; + bool nonCSSHint; + unsigned int id; + DOM::StyleListImpl* styleElement; + DOM::CSSRuleImpl *rule; + ValueList *valueList; + CSSProperty **parsedProperties; + int numParsedProperties; + int maxParsedProperties; + + int m_inParseShorthand; + int m_currentShorthand; + bool m_implicitShorthand; + + static CSSParser *currentParser; + + // tokenizer methods and data + public: + int lex( void *yylval ); + int token() { return yyTok; } + unsigned short *text( int *length); + int lex(); + private: + int yyparse(); + void runParser(int length); + + bool inShorthand() const { return m_inParseShorthand; } + + unsigned short *data; + unsigned short *yytext; + unsigned short *yy_c_buf_p; + unsigned short yy_hold_char; + int yy_last_accepting_state; + unsigned short *yy_last_accepting_cpos; + int block_nesting; + int yyleng; + int yyTok; + int yy_start; + }; + +} // namespace +#endif diff --git a/khtml/css/cssproperties.c b/khtml/css/cssproperties.c new file mode 100644 index 000000000..df4563a56 --- /dev/null +++ b/khtml/css/cssproperties.c @@ -0,0 +1,679 @@ +/* ANSI-C code produced by gperf version 3.0.1 */ +/* Command-line: gperf -a -L ANSI-C -E -C -c -o -t -k '*' -NfindProp -Hhash_prop -Wwordlist_prop -D -s 2 cssproperties.gperf */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>." +#endif + +#line 1 "cssproperties.gperf" + +/* This file is automatically generated from cssproperties.in by makeprop, do not edit */ +/* Copyright 1999 W. Bastian */ +#include "cssproperties.h" +#line 6 "cssproperties.gperf" +struct props { + const char *name; + int id; +}; + +static const struct props * findProp (register const char *str, register unsigned int len); +/* maximum key range = 508, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +hash_prop (register const char *str, register unsigned int len) +{ + static const unsigned short asso_values[] = + { + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 0, 511, 511, 511, 511, + 511, 0, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 10, 0, 0, + 5, 5, 160, 0, 0, 0, 511, 15, 5, 0, + 25, 0, 0, 15, 0, 30, 0, 40, 5, 190, + 5, 135, 120, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511 + }; + register int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[31]]; + /*FALLTHROUGH*/ + case 31: + hval += asso_values[(unsigned char)str[30]]; + /*FALLTHROUGH*/ + case 30: + hval += asso_values[(unsigned char)str[29]]; + /*FALLTHROUGH*/ + case 29: + hval += asso_values[(unsigned char)str[28]]; + /*FALLTHROUGH*/ + case 28: + hval += asso_values[(unsigned char)str[27]]; + /*FALLTHROUGH*/ + case 27: + hval += asso_values[(unsigned char)str[26]]; + /*FALLTHROUGH*/ + case 26: + hval += asso_values[(unsigned char)str[25]]; + /*FALLTHROUGH*/ + case 25: + hval += asso_values[(unsigned char)str[24]]; + /*FALLTHROUGH*/ + case 24: + hval += asso_values[(unsigned char)str[23]]; + /*FALLTHROUGH*/ + case 23: + hval += asso_values[(unsigned char)str[22]]; + /*FALLTHROUGH*/ + case 22: + hval += asso_values[(unsigned char)str[21]]; + /*FALLTHROUGH*/ + case 21: + hval += asso_values[(unsigned char)str[20]]; + /*FALLTHROUGH*/ + case 20: + hval += asso_values[(unsigned char)str[19]]; + /*FALLTHROUGH*/ + case 19: + hval += asso_values[(unsigned char)str[18]]; + /*FALLTHROUGH*/ + case 18: + hval += asso_values[(unsigned char)str[17]]; + /*FALLTHROUGH*/ + case 17: + hval += asso_values[(unsigned char)str[16]]; + /*FALLTHROUGH*/ + case 16: + hval += asso_values[(unsigned char)str[15]]; + /*FALLTHROUGH*/ + case 15: + hval += asso_values[(unsigned char)str[14]]; + /*FALLTHROUGH*/ + case 14: + hval += asso_values[(unsigned char)str[13]]; + /*FALLTHROUGH*/ + case 13: + hval += asso_values[(unsigned char)str[12]]; + /*FALLTHROUGH*/ + case 12: + hval += asso_values[(unsigned char)str[11]]; + /*FALLTHROUGH*/ + case 11: + hval += asso_values[(unsigned char)str[10]]; + /*FALLTHROUGH*/ + case 10: + hval += asso_values[(unsigned char)str[9]]; + /*FALLTHROUGH*/ + case 9: + hval += asso_values[(unsigned char)str[8]]; + /*FALLTHROUGH*/ + case 8: + hval += asso_values[(unsigned char)str[7]]; + /*FALLTHROUGH*/ + case 7: + hval += asso_values[(unsigned char)str[6]]; + /*FALLTHROUGH*/ + case 6: + hval += asso_values[(unsigned char)str[5]]; + /*FALLTHROUGH*/ + case 5: + hval += asso_values[(unsigned char)str[4]]; + /*FALLTHROUGH*/ + case 4: + hval += asso_values[(unsigned char)str[3]]; + /*FALLTHROUGH*/ + case 3: + hval += asso_values[(unsigned char)str[2]]; + /*FALLTHROUGH*/ + case 2: + hval += asso_values[(unsigned char)str[1]]; + /*FALLTHROUGH*/ + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval; +} + +#ifdef __GNUC__ +__inline +#endif +const struct props * +findProp (register const char *str, register unsigned int len) +{ + enum + { + TOTAL_KEYWORDS = 128, + MIN_WORD_LENGTH = 3, + MAX_WORD_LENGTH = 32, + MIN_HASH_VALUE = 3, + MAX_HASH_VALUE = 510 + }; + + static const struct props wordlist_prop[] = + { +#line 108 "cssproperties.gperf" + {"top", CSS_PROP_TOP}, +#line 99 "cssproperties.gperf" + {"right", CSS_PROP_RIGHT}, +#line 40 "cssproperties.gperf" + {"bottom", CSS_PROP_BOTTOM}, +#line 43 "cssproperties.gperf" + {"clip", CSS_PROP_CLIP}, +#line 44 "cssproperties.gperf" + {"color", CSS_PROP_COLOR}, +#line 58 "cssproperties.gperf" + {"height", CSS_PROP_HEIGHT}, +#line 118 "cssproperties.gperf" + {"border", CSS_PROP_BORDER}, +#line 121 "cssproperties.gperf" + {"border-top", CSS_PROP_BORDER_TOP}, +#line 122 "cssproperties.gperf" + {"border-right", CSS_PROP_BORDER_RIGHT}, +#line 123 "cssproperties.gperf" + {"border-bottom", CSS_PROP_BORDER_BOTTOM}, +#line 42 "cssproperties.gperf" + {"clear", CSS_PROP_CLEAR}, +#line 119 "cssproperties.gperf" + {"border-color", CSS_PROP_BORDER_COLOR}, +#line 76 "cssproperties.gperf" + {"max-height", CSS_PROP_MAX_HEIGHT}, +#line 28 "cssproperties.gperf" + {"border-top-color", CSS_PROP_BORDER_TOP_COLOR}, +#line 29 "cssproperties.gperf" + {"border-right-color", CSS_PROP_BORDER_RIGHT_COLOR}, +#line 30 "cssproperties.gperf" + {"border-bottom-color", CSS_PROP_BORDER_BOTTOM_COLOR}, +#line 78 "cssproperties.gperf" + {"min-height", CSS_PROP_MIN_HEIGHT}, +#line 129 "cssproperties.gperf" + {"margin", CSS_PROP_MARGIN}, +#line 49 "cssproperties.gperf" + {"direction", CSS_PROP_DIRECTION}, +#line 65 "cssproperties.gperf" + {"margin-top", CSS_PROP_MARGIN_TOP}, +#line 66 "cssproperties.gperf" + {"margin-right", CSS_PROP_MARGIN_RIGHT}, +#line 67 "cssproperties.gperf" + {"margin-bottom", CSS_PROP_MARGIN_BOTTOM}, +#line 61 "cssproperties.gperf" + {"line-height", CSS_PROP_LINE_HEIGHT}, +#line 131 "cssproperties.gperf" + {"padding", CSS_PROP_PADDING}, +#line 89 "cssproperties.gperf" + {"padding-top", CSS_PROP_PADDING_TOP}, +#line 90 "cssproperties.gperf" + {"padding-right", CSS_PROP_PADDING_RIGHT}, +#line 91 "cssproperties.gperf" + {"padding-bottom", CSS_PROP_PADDING_BOTTOM}, +#line 102 "cssproperties.gperf" + {"text-align", CSS_PROP_TEXT_ALIGN}, +#line 45 "cssproperties.gperf" + {"content", CSS_PROP_CONTENT}, +#line 97 "cssproperties.gperf" + {"position", CSS_PROP_POSITION}, +#line 103 "cssproperties.gperf" + {"text-decoration", CSS_PROP_TEXT_DECORATION}, +#line 80 "cssproperties.gperf" + {"orphans", CSS_PROP_ORPHANS}, +#line 48 "cssproperties.gperf" + {"cursor", CSS_PROP_CURSOR}, +#line 110 "cssproperties.gperf" + {"vertical-align", CSS_PROP_VERTICAL_ALIGN}, +#line 24 "cssproperties.gperf" + {"border-collapse", CSS_PROP_BORDER_COLLAPSE}, +#line 104 "cssproperties.gperf" + {"text-indent", CSS_PROP_TEXT_INDENT}, +#line 130 "cssproperties.gperf" + {"outline", CSS_PROP_OUTLINE}, +#line 135 "cssproperties.gperf" + {"scrollbar-highlight-color", CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR}, +#line 41 "cssproperties.gperf" + {"caption-side", CSS_PROP_CAPTION_SIDE}, +#line 136 "cssproperties.gperf" + {"scrollbar-3dlight-color", CSS_PROP_SCROLLBAR_3DLIGHT_COLOR}, +#line 25 "cssproperties.gperf" + {"border-spacing", CSS_PROP_BORDER_SPACING}, +#line 109 "cssproperties.gperf" + {"unicode-bidi", CSS_PROP_UNICODE_BIDI}, +#line 82 "cssproperties.gperf" + {"outline-color", CSS_PROP_OUTLINE_COLOR}, +#line 60 "cssproperties.gperf" + {"letter-spacing", CSS_PROP_LETTER_SPACING}, +#line 98 "cssproperties.gperf" + {"quotes", CSS_PROP_QUOTES}, +#line 138 "cssproperties.gperf" + {"scrollbar-track-color", CSS_PROP_SCROLLBAR_TRACK_COLOR}, +#line 117 "cssproperties.gperf" + {"background", CSS_PROP_BACKGROUND}, +#line 70 "cssproperties.gperf" + {"-khtml-marquee", CSS_PROP__KHTML_MARQUEE}, +#line 69 "cssproperties.gperf" + {"-khtml-margin-start", CSS_PROP__KHTML_MARGIN_START}, +#line 14 "cssproperties.gperf" + {"background-color", CSS_PROP_BACKGROUND_COLOR}, +#line 132 "cssproperties.gperf" + {"scrollbar-base-color", CSS_PROP_SCROLLBAR_BASE_COLOR}, +#line 47 "cssproperties.gperf" + {"counter-reset", CSS_PROP_COUNTER_RESET}, +#line 93 "cssproperties.gperf" + {"-khtml-padding-start", CSS_PROP__KHTML_PADDING_START}, +#line 15 "cssproperties.gperf" + {"background-image", CSS_PROP_BACKGROUND_IMAGE}, +#line 96 "cssproperties.gperf" + {"page-break-inside", CSS_PROP_PAGE_BREAK_INSIDE}, +#line 16 "cssproperties.gperf" + {"background-repeat", CSS_PROP_BACKGROUND_REPEAT}, +#line 21 "cssproperties.gperf" + {"-khtml-background-clip", CSS_PROP__KHTML_BACKGROUND_CLIP}, +#line 46 "cssproperties.gperf" + {"counter-increment", CSS_PROP_COUNTER_INCREMENT}, +#line 27 "cssproperties.gperf" + {"-khtml-border-vertical-spacing", CSS_PROP__KHTML_BORDER_VERTICAL_SPACING}, +#line 81 "cssproperties.gperf" + {"opacity", CSS_PROP_OPACITY}, +#line 71 "cssproperties.gperf" + {"-khtml-marquee-direction", CSS_PROP__KHTML_MARQUEE_DIRECTION}, +#line 73 "cssproperties.gperf" + {"-khtml-marquee-repetition", CSS_PROP__KHTML_MARQUEE_REPETITION}, +#line 100 "cssproperties.gperf" + {"size", CSS_PROP_SIZE}, +#line 74 "cssproperties.gperf" + {"-khtml-marquee-speed", CSS_PROP__KHTML_MARQUEE_SPEED}, +#line 22 "cssproperties.gperf" + {"-khtml-background-origin", CSS_PROP__KHTML_BACKGROUND_ORIGIN}, +#line 17 "cssproperties.gperf" + {"background-attachment", CSS_PROP_BACKGROUND_ATTACHMENT}, +#line 116 "cssproperties.gperf" + {"z-index", CSS_PROP_Z_INDEX}, +#line 18 "cssproperties.gperf" + {"background-position", CSS_PROP_BACKGROUND_POSITION}, +#line 59 "cssproperties.gperf" + {"left", CSS_PROP_LEFT}, +#line 19 "cssproperties.gperf" + {"background-position-x", CSS_PROP_BACKGROUND_POSITION_X}, +#line 141 "cssproperties.gperf" + {"-khtml-user-input", CSS_PROP__KHTML_USER_INPUT}, +#line 72 "cssproperties.gperf" + {"-khtml-marquee-increment", CSS_PROP__KHTML_MARQUEE_INCREMENT}, +#line 52 "cssproperties.gperf" + {"float", CSS_PROP_FLOAT}, +#line 111 "cssproperties.gperf" + {"visibility", CSS_PROP_VISIBILITY}, +#line 127 "cssproperties.gperf" + {"font", CSS_PROP_FONT}, +#line 126 "cssproperties.gperf" + {"box-sizing", CSS_PROP_BOX_SIZING}, +#line 124 "cssproperties.gperf" + {"border-left", CSS_PROP_BORDER_LEFT}, +#line 50 "cssproperties.gperf" + {"display", CSS_PROP_DISPLAY}, +#line 51 "cssproperties.gperf" + {"empty-cells", CSS_PROP_EMPTY_CELLS}, +#line 120 "cssproperties.gperf" + {"border-style", CSS_PROP_BORDER_STYLE}, +#line 114 "cssproperties.gperf" + {"width", CSS_PROP_WIDTH}, +#line 32 "cssproperties.gperf" + {"border-top-style", CSS_PROP_BORDER_TOP_STYLE}, +#line 31 "cssproperties.gperf" + {"border-left-color", CSS_PROP_BORDER_LEFT_COLOR}, +#line 33 "cssproperties.gperf" + {"border-right-style", CSS_PROP_BORDER_RIGHT_STYLE}, +#line 34 "cssproperties.gperf" + {"border-bottom-style", CSS_PROP_BORDER_BOTTOM_STYLE}, +#line 68 "cssproperties.gperf" + {"margin-left", CSS_PROP_MARGIN_LEFT}, +#line 125 "cssproperties.gperf" + {"border-width", CSS_PROP_BORDER_WIDTH}, +#line 77 "cssproperties.gperf" + {"max-width", CSS_PROP_MAX_WIDTH}, +#line 128 "cssproperties.gperf" + {"list-style", CSS_PROP_LIST_STYLE}, +#line 36 "cssproperties.gperf" + {"border-top-width", CSS_PROP_BORDER_TOP_WIDTH}, +#line 101 "cssproperties.gperf" + {"table-layout", CSS_PROP_TABLE_LAYOUT}, +#line 37 "cssproperties.gperf" + {"border-right-width", CSS_PROP_BORDER_RIGHT_WIDTH}, +#line 38 "cssproperties.gperf" + {"border-bottom-width", CSS_PROP_BORDER_BOTTOM_WIDTH}, +#line 92 "cssproperties.gperf" + {"padding-left", CSS_PROP_PADDING_LEFT}, +#line 79 "cssproperties.gperf" + {"min-width", CSS_PROP_MIN_WIDTH}, +#line 95 "cssproperties.gperf" + {"page-break-before", CSS_PROP_PAGE_BREAK_BEFORE}, +#line 94 "cssproperties.gperf" + {"page-break-after", CSS_PROP_PAGE_BREAK_AFTER}, +#line 62 "cssproperties.gperf" + {"list-style-image", CSS_PROP_LIST_STYLE_IMAGE}, +#line 56 "cssproperties.gperf" + {"font-variant", CSS_PROP_FONT_VARIANT}, +#line 107 "cssproperties.gperf" + {"text-transform", CSS_PROP_TEXT_TRANSFORM}, +#line 133 "cssproperties.gperf" + {"scrollbar-face-color", CSS_PROP_SCROLLBAR_FACE_COLOR}, +#line 112 "cssproperties.gperf" + {"white-space", CSS_PROP_WHITE_SPACE}, +#line 106 "cssproperties.gperf" + {"text-shadow", CSS_PROP_TEXT_SHADOW}, +#line 84 "cssproperties.gperf" + {"outline-style", CSS_PROP_OUTLINE_STYLE}, +#line 115 "cssproperties.gperf" + {"word-spacing", CSS_PROP_WORD_SPACING}, +#line 139 "cssproperties.gperf" + {"scrollbar-arrow-color", CSS_PROP_SCROLLBAR_ARROW_COLOR}, +#line 85 "cssproperties.gperf" + {"outline-width", CSS_PROP_OUTLINE_WIDTH}, +#line 63 "cssproperties.gperf" + {"list-style-position", CSS_PROP_LIST_STYLE_POSITION}, +#line 26 "cssproperties.gperf" + {"-khtml-border-horizontal-spacing", CSS_PROP__KHTML_BORDER_HORIZONTAL_SPACING}, +#line 75 "cssproperties.gperf" + {"-khtml-marquee-style", CSS_PROP__KHTML_MARQUEE_STYLE}, +#line 23 "cssproperties.gperf" + {"-khtml-background-size", CSS_PROP__KHTML_BACKGROUND_SIZE}, +#line 20 "cssproperties.gperf" + {"background-position-y", CSS_PROP_BACKGROUND_POSITION_Y}, +#line 134 "cssproperties.gperf" + {"scrollbar-shadow-color", CSS_PROP_SCROLLBAR_SHADOW_COLOR}, +#line 137 "cssproperties.gperf" + {"scrollbar-darkshadow-color", CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR}, +#line 54 "cssproperties.gperf" + {"font-size", CSS_PROP_FONT_SIZE}, +#line 64 "cssproperties.gperf" + {"list-style-type", CSS_PROP_LIST_STYLE_TYPE}, +#line 55 "cssproperties.gperf" + {"font-style", CSS_PROP_FONT_STYLE}, +#line 35 "cssproperties.gperf" + {"border-left-style", CSS_PROP_BORDER_LEFT_STYLE}, +#line 86 "cssproperties.gperf" + {"overflow", CSS_PROP_OVERFLOW}, +#line 87 "cssproperties.gperf" + {"overflow-x", CSS_PROP_OVERFLOW_X}, +#line 105 "cssproperties.gperf" + {"text-overflow", CSS_PROP_TEXT_OVERFLOW}, +#line 57 "cssproperties.gperf" + {"font-weight", CSS_PROP_FONT_WEIGHT}, +#line 39 "cssproperties.gperf" + {"border-left-width", CSS_PROP_BORDER_LEFT_WIDTH}, +#line 140 "cssproperties.gperf" + {"-khtml-flow-mode", CSS_PROP__KHTML_FLOW_MODE}, +#line 113 "cssproperties.gperf" + {"widows", CSS_PROP_WIDOWS}, +#line 83 "cssproperties.gperf" + {"outline-offset", CSS_PROP_OUTLINE_OFFSET}, +#line 53 "cssproperties.gperf" + {"font-family", CSS_PROP_FONT_FAMILY}, +#line 88 "cssproperties.gperf" + {"overflow-y", CSS_PROP_OVERFLOW_Y} + }; + + static const signed char lookup[] = + { + -1, -1, -1, 0, -1, 1, 2, -1, -1, 3, + 4, 5, -1, -1, -1, -1, 6, -1, -1, -1, + 7, -1, 8, 9, -1, 10, -1, 11, -1, -1, + 12, 13, -1, 14, 15, -1, -1, -1, -1, -1, + 16, 17, -1, -1, 18, 19, -1, 20, 21, -1, + -1, 22, 23, -1, -1, -1, 24, -1, 25, 26, + 27, -1, 28, 29, -1, -1, -1, -1, -1, -1, + 30, -1, 31, -1, -1, -1, 32, -1, -1, 33, + 34, 35, 36, -1, -1, 37, -1, 38, 39, 40, + -1, -1, 41, 42, 43, -1, 44, -1, -1, -1, + -1, 45, -1, -1, -1, 46, -1, -1, -1, 47, + -1, -1, -1, -1, 48, -1, 49, -1, -1, -1, + 50, -1, -1, 51, -1, 52, 53, 54, -1, -1, + -1, -1, 55, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 56, -1, -1, -1, -1, 57, -1, -1, + 58, -1, 59, -1, 60, 61, -1, -1, -1, 62, + 63, -1, -1, -1, 64, -1, 65, 66, -1, 67, + -1, -1, -1, -1, 68, -1, 69, 70, -1, 71, + 72, -1, -1, -1, -1, 73, -1, -1, -1, 74, + 75, 76, 77, -1, -1, -1, 78, 79, -1, -1, + 80, 81, 82, 83, 84, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 85, 86, -1, 87, + 88, 89, 90, 91, 92, -1, -1, 93, -1, 94, + -1, -1, 95, -1, -1, -1, 96, -1, -1, -1, + -1, 97, -1, -1, -1, -1, -1, 98, -1, 99, + 100, 101, -1, -1, -1, -1, 102, -1, -1, -1, + -1, -1, -1, 103, -1, -1, -1, -1, -1, -1, + -1, -1, 104, -1, -1, -1, 105, -1, -1, -1, + -1, -1, -1, 106, 107, -1, -1, 108, -1, -1, + 109, -1, 110, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 111, -1, -1, -1, + -1, -1, 112, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 113, -1, -1, 114, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 115, -1, -1, -1, -1, + 116, -1, 117, 118, -1, -1, -1, -1, -1, -1, + 119, -1, -1, -1, -1, -1, -1, -1, 120, -1, + -1, 121, 122, -1, -1, -1, -1, -1, -1, -1, + -1, 123, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 124, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 125, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 126, -1, -1, -1, + 127 + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash_prop (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register int index = lookup[key]; + + if (index >= 0) + { + register const char *s = wordlist_prop[index].name; + + if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') + return &wordlist_prop[index]; + } + } + } + return 0; +} +#line 142 "cssproperties.gperf" + +static const char * const propertyList[] = { +"", +"background-color", +"background-image", +"background-repeat", +"background-attachment", +"background-position", +"background-position-x", +"background-position-y", +"-khtml-background-clip", +"-khtml-background-origin", +"-khtml-background-size", +"border-collapse", +"border-spacing", +"-khtml-border-horizontal-spacing", +"-khtml-border-vertical-spacing", +"border-top-color", +"border-right-color", +"border-bottom-color", +"border-left-color", +"border-top-style", +"border-right-style", +"border-bottom-style", +"border-left-style", +"border-top-width", +"border-right-width", +"border-bottom-width", +"border-left-width", +"bottom", +"caption-side", +"clear", +"clip", +"color", +"content", +"counter-increment", +"counter-reset", +"cursor", +"direction", +"display", +"empty-cells", +"float", +"font-family", +"font-size", +"font-style", +"font-variant", +"font-weight", +"height", +"left", +"letter-spacing", +"line-height", +"list-style-image", +"list-style-position", +"list-style-type", +"margin-top", +"margin-right", +"margin-bottom", +"margin-left", +"-khtml-margin-start", +"-khtml-marquee", +"-khtml-marquee-direction", +"-khtml-marquee-increment", +"-khtml-marquee-repetition", +"-khtml-marquee-speed", +"-khtml-marquee-style", +"max-height", +"max-width", +"min-height", +"min-width", +"orphans", +"opacity", +"outline-color", +"outline-offset", +"outline-style", +"outline-width", +"overflow", +"overflow-x", +"overflow-y", +"padding-top", +"padding-right", +"padding-bottom", +"padding-left", +"-khtml-padding-start", +"page-break-after", +"page-break-before", +"page-break-inside", +"position", +"quotes", +"right", +"size", +"table-layout", +"text-align", +"text-decoration", +"text-indent", +"text-overflow", +"text-shadow", +"text-transform", +"top", +"unicode-bidi", +"vertical-align", +"visibility", +"white-space", +"widows", +"width", +"word-spacing", +"z-index", +"background", +"border", +"border-color", +"border-style", +"border-top", +"border-right", +"border-bottom", +"border-left", +"border-width", +"box-sizing", +"font", +"list-style", +"margin", +"outline", +"padding", +"scrollbar-base-color", +"scrollbar-face-color", +"scrollbar-shadow-color", +"scrollbar-highlight-color", +"scrollbar-3dlight-color", +"scrollbar-darkshadow-color", +"scrollbar-track-color", +"scrollbar-arrow-color", +"-khtml-flow-mode", +"-khtml-user-input", + 0 +}; +DOMString getPropertyName(unsigned short id) +{ + if(id >= CSS_PROP_TOTAL || id == 0) + return DOMString(); + else + return DOMString(propertyList[id]); +} + diff --git a/khtml/css/cssproperties.h b/khtml/css/cssproperties.h new file mode 100644 index 000000000..29f7d375b --- /dev/null +++ b/khtml/css/cssproperties.h @@ -0,0 +1,143 @@ +/* This file is automatically generated from cssproperties.in by makeprop, do not edit */ +/* Copyright 1998 W. Bastian */ + +#ifndef CSSPROPERTIES_H +#define CSSPROPERTIES_H + +DOM::DOMString getPropertyName(unsigned short id) KDE_NO_EXPORT; + +#define CSS_PROP_INVALID 0 +#define CSS_PROP_MIN 1 +#define CSS_PROP_BACKGROUND_COLOR 1 +#define CSS_PROP_BACKGROUND_IMAGE 2 +#define CSS_PROP_BACKGROUND_REPEAT 3 +#define CSS_PROP_BACKGROUND_ATTACHMENT 4 +#define CSS_PROP_BACKGROUND_POSITION 5 +#define CSS_PROP_BACKGROUND_POSITION_X 6 +#define CSS_PROP_BACKGROUND_POSITION_Y 7 +#define CSS_PROP__KHTML_BACKGROUND_CLIP 8 +#define CSS_PROP__KHTML_BACKGROUND_ORIGIN 9 +#define CSS_PROP__KHTML_BACKGROUND_SIZE 10 +#define CSS_PROP_BORDER_COLLAPSE 11 +#define CSS_PROP_BORDER_SPACING 12 +#define CSS_PROP__KHTML_BORDER_HORIZONTAL_SPACING 13 +#define CSS_PROP__KHTML_BORDER_VERTICAL_SPACING 14 +#define CSS_PROP_BORDER_TOP_COLOR 15 +#define CSS_PROP_BORDER_RIGHT_COLOR 16 +#define CSS_PROP_BORDER_BOTTOM_COLOR 17 +#define CSS_PROP_BORDER_LEFT_COLOR 18 +#define CSS_PROP_BORDER_TOP_STYLE 19 +#define CSS_PROP_BORDER_RIGHT_STYLE 20 +#define CSS_PROP_BORDER_BOTTOM_STYLE 21 +#define CSS_PROP_BORDER_LEFT_STYLE 22 +#define CSS_PROP_BORDER_TOP_WIDTH 23 +#define CSS_PROP_BORDER_RIGHT_WIDTH 24 +#define CSS_PROP_BORDER_BOTTOM_WIDTH 25 +#define CSS_PROP_BORDER_LEFT_WIDTH 26 +#define CSS_PROP_BOTTOM 27 +#define CSS_PROP_CAPTION_SIDE 28 +#define CSS_PROP_CLEAR 29 +#define CSS_PROP_CLIP 30 +#define CSS_PROP_COLOR 31 +#define CSS_PROP_CONTENT 32 +#define CSS_PROP_COUNTER_INCREMENT 33 +#define CSS_PROP_COUNTER_RESET 34 +#define CSS_PROP_CURSOR 35 +#define CSS_PROP_DIRECTION 36 +#define CSS_PROP_DISPLAY 37 +#define CSS_PROP_EMPTY_CELLS 38 +#define CSS_PROP_FLOAT 39 +#define CSS_PROP_FONT_FAMILY 40 +#define CSS_PROP_FONT_SIZE 41 +#define CSS_PROP_FONT_STYLE 42 +#define CSS_PROP_FONT_VARIANT 43 +#define CSS_PROP_FONT_WEIGHT 44 +#define CSS_PROP_HEIGHT 45 +#define CSS_PROP_LEFT 46 +#define CSS_PROP_LETTER_SPACING 47 +#define CSS_PROP_LINE_HEIGHT 48 +#define CSS_PROP_LIST_STYLE_IMAGE 49 +#define CSS_PROP_LIST_STYLE_POSITION 50 +#define CSS_PROP_LIST_STYLE_TYPE 51 +#define CSS_PROP_MARGIN_TOP 52 +#define CSS_PROP_MARGIN_RIGHT 53 +#define CSS_PROP_MARGIN_BOTTOM 54 +#define CSS_PROP_MARGIN_LEFT 55 +#define CSS_PROP__KHTML_MARGIN_START 56 +#define CSS_PROP__KHTML_MARQUEE 57 +#define CSS_PROP__KHTML_MARQUEE_DIRECTION 58 +#define CSS_PROP__KHTML_MARQUEE_INCREMENT 59 +#define CSS_PROP__KHTML_MARQUEE_REPETITION 60 +#define CSS_PROP__KHTML_MARQUEE_SPEED 61 +#define CSS_PROP__KHTML_MARQUEE_STYLE 62 +#define CSS_PROP_MAX_HEIGHT 63 +#define CSS_PROP_MAX_WIDTH 64 +#define CSS_PROP_MIN_HEIGHT 65 +#define CSS_PROP_MIN_WIDTH 66 +#define CSS_PROP_ORPHANS 67 +#define CSS_PROP_OPACITY 68 +#define CSS_PROP_OUTLINE_COLOR 69 +#define CSS_PROP_OUTLINE_OFFSET 70 +#define CSS_PROP_OUTLINE_STYLE 71 +#define CSS_PROP_OUTLINE_WIDTH 72 +#define CSS_PROP_OVERFLOW 73 +#define CSS_PROP_OVERFLOW_X 74 +#define CSS_PROP_OVERFLOW_Y 75 +#define CSS_PROP_PADDING_TOP 76 +#define CSS_PROP_PADDING_RIGHT 77 +#define CSS_PROP_PADDING_BOTTOM 78 +#define CSS_PROP_PADDING_LEFT 79 +#define CSS_PROP__KHTML_PADDING_START 80 +#define CSS_PROP_PAGE_BREAK_AFTER 81 +#define CSS_PROP_PAGE_BREAK_BEFORE 82 +#define CSS_PROP_PAGE_BREAK_INSIDE 83 +#define CSS_PROP_POSITION 84 +#define CSS_PROP_QUOTES 85 +#define CSS_PROP_RIGHT 86 +#define CSS_PROP_SIZE 87 +#define CSS_PROP_TABLE_LAYOUT 88 +#define CSS_PROP_TEXT_ALIGN 89 +#define CSS_PROP_TEXT_DECORATION 90 +#define CSS_PROP_TEXT_INDENT 91 +#define CSS_PROP_TEXT_OVERFLOW 92 +#define CSS_PROP_TEXT_SHADOW 93 +#define CSS_PROP_TEXT_TRANSFORM 94 +#define CSS_PROP_TOP 95 +#define CSS_PROP_UNICODE_BIDI 96 +#define CSS_PROP_VERTICAL_ALIGN 97 +#define CSS_PROP_VISIBILITY 98 +#define CSS_PROP_WHITE_SPACE 99 +#define CSS_PROP_WIDOWS 100 +#define CSS_PROP_WIDTH 101 +#define CSS_PROP_WORD_SPACING 102 +#define CSS_PROP_Z_INDEX 103 +#define CSS_PROP_BACKGROUND 104 +#define CSS_PROP_BORDER 105 +#define CSS_PROP_BORDER_COLOR 106 +#define CSS_PROP_BORDER_STYLE 107 +#define CSS_PROP_BORDER_TOP 108 +#define CSS_PROP_BORDER_RIGHT 109 +#define CSS_PROP_BORDER_BOTTOM 110 +#define CSS_PROP_BORDER_LEFT 111 +#define CSS_PROP_BORDER_WIDTH 112 +#define CSS_PROP_BOX_SIZING 113 +#define CSS_PROP_FONT 114 +#define CSS_PROP_LIST_STYLE 115 +#define CSS_PROP_MARGIN 116 +#define CSS_PROP_OUTLINE 117 +#define CSS_PROP_PADDING 118 +#define CSS_PROP_SCROLLBAR_BASE_COLOR 119 +#define CSS_PROP_SCROLLBAR_FACE_COLOR 120 +#define CSS_PROP_SCROLLBAR_SHADOW_COLOR 121 +#define CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR 122 +#define CSS_PROP_SCROLLBAR_3DLIGHT_COLOR 123 +#define CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR 124 +#define CSS_PROP_SCROLLBAR_TRACK_COLOR 125 +#define CSS_PROP_SCROLLBAR_ARROW_COLOR 126 +#define CSS_PROP__KHTML_FLOW_MODE 127 +#define CSS_PROP__KHTML_USER_INPUT 128 + +#define CSS_PROP_MAX CSS_PROP_Z_INDEX +#define CSS_PROP_TOTAL 129 +#endif + diff --git a/khtml/css/cssproperties.in b/khtml/css/cssproperties.in new file mode 100644 index 000000000..0d8980663 --- /dev/null +++ b/khtml/css/cssproperties.in @@ -0,0 +1,147 @@ +# +# all valid CSS2 properties. +# +# aural properties are commented out, as we don't support them anyway. +# +# some properties are used in khtml, but are not part of CSS. They are used to get +# HTML4 compatibility in the rendering engine. +# +# Mircosoft extensions are documented here: +# http://msdn.microsoft.com/workshop/author/css/reference/attributes.asp +# +# CSS_PROP_BACKGROUND_COLOR: +# +background-color +background-image +background-repeat +background-attachment +background-position +# IE Extensions +background-position-x +background-position-y +# CSS3 Extensions +-khtml-background-clip +-khtml-background-origin +-khtml-background-size + +border-collapse +border-spacing +-khtml-border-horizontal-spacing +-khtml-border-vertical-spacing +border-top-color +border-right-color +border-bottom-color +border-left-color +border-top-style +border-right-style +border-bottom-style +border-left-style +border-top-width +border-right-width +border-bottom-width +border-left-width +bottom +caption-side +clear +clip +color +content +counter-increment +counter-reset +cursor +direction +display +empty-cells +float +font-family +font-size +font-style +font-variant +font-weight +height +left +letter-spacing +line-height +list-style-image +list-style-position +list-style-type +margin-top +margin-right +margin-bottom +margin-left +-khtml-margin-start +-khtml-marquee +-khtml-marquee-direction +-khtml-marquee-increment +-khtml-marquee-repetition +-khtml-marquee-speed +-khtml-marquee-style +max-height +max-width +min-height +min-width +orphans +opacity +outline-color +outline-offset +outline-style +outline-width +overflow +overflow-x +overflow-y +padding-top +padding-right +padding-bottom +padding-left +-khtml-padding-start +#page +page-break-after +page-break-before +page-break-inside +position +quotes +right +size +table-layout +text-align +text-decoration +text-indent +text-overflow +text-shadow +text-transform +top +unicode-bidi +vertical-align +visibility +white-space +widows +width +word-spacing +z-index +background +border +border-color +border-style +border-top +border-right +border-bottom +border-left +border-width +box-sizing +font +list-style +margin +outline +padding +# some more IE extensions +scrollbar-base-color +scrollbar-face-color +scrollbar-shadow-color +scrollbar-highlight-color +scrollbar-3dlight-color +scrollbar-darkshadow-color +scrollbar-track-color +scrollbar-arrow-color +# khtml internals +-khtml-flow-mode +-khtml-user-input diff --git a/khtml/css/cssstyleselector.cpp b/khtml/css/cssstyleselector.cpp new file mode 100644 index 000000000..235a2cf20 --- /dev/null +++ b/khtml/css/cssstyleselector.cpp @@ -0,0 +1,4190 @@ +/** + * 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-2006 Allan Sandfeld Jensen (kde@carewolf.com) + * (C) 2004 Germain Garand (germain@ebooksfrance.org) + * (C) 2005, 2006 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., 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 "xml/dom_restyler.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, doc); + + 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, 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, DocumentImpl* doc) +{ + 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, doc); + + 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, DocumentImpl *doc) +{ + 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(doc); + 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(doc); + 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 8 + +void CSSStyleSelector::computeFontSizes(QPaintDeviceMetrics* paintDeviceMetrics, int zoomFactor) +{ + computeFontSizesFor(paintDeviceMetrics, zoomFactor, m_fontSizes, false); + computeFontSizesFor(paintDeviceMetrics, zoomFactor, m_fixedFontSizes, true); +} + +void CSSStyleSelector::computeFontSizesFor(QPaintDeviceMetrics* paintDeviceMetrics, int zoomFactor, QValueVector<int>& fontSizes, bool isFixed) +{ +#ifdef APPLE_CHANGES + // We don't want to scale the settings by the dpi. + const float toPix = 1; +#else + Q_UNUSED( isFixed ); + + // ### get rid of float / double + float toPix = paintDeviceMetrics->logicalDpiY()/72.; + if (toPix < 96./72.) toPix = 96./72.; +#endif // ######### fix isFixed code again. + + fontSizes.resize( MAXFONTSIZES ); + float scale = 1.0; + static const float fontFactors[] = {3./5., 3./4., 8./9., 1., 6./5., 3./2., 2., 3.}; + static const float smallFontFactors[] = {3./4., 5./6., 8./9., 1., 6./5., 3./2., 2., 3.}; + float mediumFontSize, minFontSize, factor; + if (!khtml::printpainter) { + scale *= zoomFactor / 100.0; +#ifdef APPLE_CHANGES + if (isFixed) + mediumFontSize = settings->mediumFixedFontSize() * toPix; + else +#endif + mediumFontSize = settings->mediumFontSize() * toPix; + minFontSize = settings->minFontSize() * toPix; + } + else { + // ## depending on something / configurable ? + mediumFontSize = 12; + minFontSize = 6; + } + const float* factors = scale*mediumFontSize >= 12.5 ? fontFactors : smallFontFactors; + for ( int i = 0; i < MAXFONTSIZES; i++ ) { + factor = scale*factors[i]; + fontSizes[i] = int(KMAX( mediumFontSize*factor +.5f, minFontSize)); + //kdDebug( 6080 ) << "index: " << i << " factor: " << factors[i] << " font pix size: " << int(KMAX( mediumFontSize*factor +.5f, minFontSize)) << endl; + } +} + +#undef MAXFONTSIZES + +static inline void bubbleSort( CSSOrderedProperty **b, CSSOrderedProperty **e ) +{ + while( b < e ) { + bool swapped = false; + CSSOrderedProperty **y = e+1; + CSSOrderedProperty **x = e; + CSSOrderedProperty **swappedPos = 0; + do { + if ( !((**(--x)) < (**(--y))) ) { + swapped = true; + swappedPos = x; + CSSOrderedProperty *tmp = *y; + *y = *x; + *x = tmp; + } + } while( x != b ); + if ( !swapped ) break; + b = swappedPos + 1; + } +} + +RenderStyle *CSSStyleSelector::styleForElement(ElementImpl *e) +{ + if (!e->getDocument()->haveStylesheetsLoaded() || !e->getDocument()->view()) { + if (!styleNotYetAvailable) { + styleNotYetAvailable = new RenderStyle(); + styleNotYetAvailable->setDisplay(NONE); + styleNotYetAvailable->ref(); + } + return styleNotYetAvailable; + } + + // set some variables we will need + pseudoState = PseudoUnknown; + + element = e; + parentNode = e->parentNode(); + parentStyle = ( parentNode && parentNode->renderer()) ? parentNode->renderer()->style() : 0; + view = element->getDocument()->view(); + part = view->part(); + settings = part->settings(); + paintDeviceMetrics = element->getDocument()->paintDeviceMetrics(); + + // reset dynamic DOM dependencies + e->getDocument()->dynamicDomRestyler().resetDependencies(e); + + style = new RenderStyle(); + if( parentStyle ) + style->inheritFrom( parentStyle ); + else + parentStyle = style; + + unsigned int numPropsToApply = 0; + unsigned int numPseudoProps = 0; + + // try to sort out most style rules as early as possible. + Q_UINT16 cssTagId = localNamePart(element->id()); + int smatch = 0; + int schecked = 0; + + for ( unsigned int i = 0; i < selectors_size; i++ ) { + Q_UINT16 tag = localNamePart(selectors[i]->tag); + if ( cssTagId == tag || tag == anyLocalName ) { + ++schecked; + + checkSelector( i, e ); + + if ( selectorCache[i].state == Applies ) { + ++smatch; + +// qDebug("adding property" ); + for ( unsigned int p = 0; p < selectorCache[i].props_size; p += 2 ) + for ( unsigned int j = 0; j < (unsigned int )selectorCache[i].props[p+1]; ++j ) { + if (numPropsToApply >= propsToApplySize ) { + propsToApplySize *= 2; + propsToApply = (CSSOrderedProperty **)realloc( propsToApply, propsToApplySize*sizeof( CSSOrderedProperty * ) ); + } + propsToApply[numPropsToApply++] = properties[selectorCache[i].props[p]+j]; + } + } else if ( selectorCache[i].state == AppliesPseudo ) { + for ( unsigned int p = 0; p < selectorCache[i].props_size; p += 2 ) + for ( unsigned int j = 0; j < (unsigned int) selectorCache[i].props[p+1]; ++j ) { + if (numPseudoProps >= pseudoPropsSize ) { + pseudoPropsSize *= 2; + pseudoProps = (CSSOrderedProperty **)realloc( pseudoProps, pseudoPropsSize*sizeof( CSSOrderedProperty * ) ); + } + pseudoProps[numPseudoProps++] = properties[selectorCache[i].props[p]+j]; + properties[selectorCache[i].props[p]+j]->pseudoId = (RenderStyle::PseudoId) selectors[i]->pseudoId; + } + } + } + else + selectorCache[i].state = Invalid; + + } + + // inline style declarations, after all others. non css hints + // count as author rules, and come before all other style sheets, see hack in append() + numPropsToApply = addInlineDeclarations( e, e->m_styleDecls, numPropsToApply ); + +// qDebug( "styleForElement( %s )", e->tagName().string().latin1() ); +// qDebug( "%d selectors, %d checked, %d match, %d properties ( of %d )", +// selectors_size, schecked, smatch, numPropsToApply, properties_size ); + + bubbleSort( propsToApply, propsToApply+numPropsToApply-1 ); + bubbleSort( pseudoProps, pseudoProps+numPseudoProps-1 ); + + // we can't apply style rules without a view() and a part. This + // tends to happen on delayed destruction of widget Renderobjects + if ( part ) { + fontDirty = false; + + if (numPropsToApply ) { + CSSStyleSelector::style = style; + for (unsigned int i = 0; i < numPropsToApply; ++i) { + if ( fontDirty && propsToApply[i]->priority >= (1 << 30) ) { + // we are past the font properties, time to update to the + // correct font +#ifdef APPLE_CHANGES + checkForGenericFamilyChange(style, parentStyle); +#endif + CSSStyleSelector::style->htmlFont().update( paintDeviceMetrics ); + fontDirty = false; + } + DOM::CSSProperty *prop = propsToApply[i]->prop; +// if (prop->m_id == CSS_PROP__KONQ_USER_INPUT) kdDebug(6080) << "El: "<<e->nodeName().string() << " user-input: "<<((CSSPrimitiveValueImpl *)prop->value())->getIdent() << endl; +// if (prop->m_id == CSS_PROP_TEXT_TRANSFORM) kdDebug(6080) << "El: "<<e->nodeName().string() << endl; + applyRule( prop->m_id, prop->value() ); + } + if ( fontDirty ) { +#ifdef APPLE_CHANGES + checkForGenericFamilyChange(style, parentStyle); +#endif + CSSStyleSelector::style->htmlFont().update( paintDeviceMetrics ); + } + } + + // Clean up our style object's display and text decorations (among other fixups). + adjustRenderStyle(style, e); + + if ( numPseudoProps ) { + fontDirty = false; + //qDebug("%d applying %d pseudo props", e->cssTagId(), pseudoProps->count() ); + for (unsigned int i = 0; i < numPseudoProps; ++i) { + if ( fontDirty && pseudoProps[i]->priority >= (1 << 30) ) { + // we are past the font properties, time to update to the + // correct font + //We have to do this for all pseudo styles + RenderStyle *pseudoStyle = style->pseudoStyle; + while ( pseudoStyle ) { + pseudoStyle->htmlFont().update( paintDeviceMetrics ); + pseudoStyle = pseudoStyle->pseudoStyle; + } + fontDirty = false; + } + + RenderStyle *pseudoStyle; + pseudoStyle = style->getPseudoStyle(pseudoProps[i]->pseudoId); + if (!pseudoStyle) + { + pseudoStyle = style->addPseudoStyle(pseudoProps[i]->pseudoId); + if (pseudoStyle) + pseudoStyle->inheritFrom( style ); + } + + RenderStyle* oldStyle = style; + RenderStyle* oldParentStyle = parentStyle; + parentStyle = style; + style = pseudoStyle; + if ( pseudoStyle ) { + DOM::CSSProperty *prop = pseudoProps[i]->prop; + applyRule( prop->m_id, prop->value() ); + } + style = oldStyle; + parentStyle = oldParentStyle; + } + + if ( fontDirty ) { + RenderStyle *pseudoStyle = style->pseudoStyle; + while ( pseudoStyle ) { + pseudoStyle->htmlFont().update( paintDeviceMetrics ); + pseudoStyle = pseudoStyle->pseudoStyle; + } + } + } + } + + // Now adjust all our pseudo-styles. + RenderStyle *pseudoStyle = style->pseudoStyle; + while (pseudoStyle) { + adjustRenderStyle(pseudoStyle, 0); + pseudoStyle = pseudoStyle->pseudoStyle; + } + + // Now return the style. + return style; +} + +void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, DOM::ElementImpl *e) +{ + // Cache our original display. + style->setOriginalDisplay(style->display()); + + if (style->display() != NONE) { + // If we have a <td> that specifies a float property, in quirks mode we just drop the float + // property. + // Sites also commonly use display:inline/block on <td>s and <table>s. In quirks mode we force + // these tags to retain their display types. + if (!strictParsing && e) { + if (e->id() == ID_TD) { + style->setDisplay(TABLE_CELL); + style->setFloating(FNONE); + } + else if (e->id() == ID_TABLE) + style->setDisplay(style->isDisplayInlineType() ? INLINE_TABLE : TABLE); + } + + // Table headers with a text-align of auto will change the text-align to center. + if (e && e->id() == ID_TH && style->textAlign() == TAAUTO) + style->setTextAlign(CENTER); + + // Mutate the display to BLOCK or TABLE for certain cases, e.g., if someone attempts to + // position or float an inline, compact, or run-in. Cache the original display, since it + // may be needed for positioned elements that have to compute their static normal flow + // positions. We also force inline-level roots to be block-level. + if (style->display() != BLOCK && style->display() != TABLE /*&& style->display() != BOX*/ && + (style->position() == ABSOLUTE || style->position() == FIXED || style->floating() != FNONE || + (e && e->getDocument()->documentElement() == e))) { + if (style->display() == INLINE_TABLE) + style->setDisplay(TABLE); +// else if (style->display() == INLINE_BOX) +// style->setDisplay(BOX); + else if (style->display() == LIST_ITEM) { + // It is a WinIE bug that floated list items lose their bullets, so we'll emulate the quirk, + // but only in quirks mode. + if (!strictParsing && style->floating() != FNONE) + style->setDisplay(BLOCK); + } + else + style->setDisplay(BLOCK); + } + + // After performing the display mutation, check our position. We do not honor position:relative on + // table rows and some other table displays. This is undefined behaviour in CSS2.1 (cf. 9.3.1) + if (style->position() == RELATIVE) { + switch (style->display()) { + case TABLE_ROW_GROUP: + case TABLE_HEADER_GROUP: + case TABLE_FOOTER_GROUP: + case TABLE_ROW: + style->setPosition(STATIC); + default: + break; + } + } + } + + // Frames and framesets never honor position:relative or position:absolute. This is necessary to + // fix a crash where a site tries to position these objects. + if ( e ) { + // ignore display: none for <frame> + if ( e->id() == ID_FRAME ) { + style->setPosition( STATIC ); + style->setDisplay( BLOCK ); + } + else if ( e->id() == ID_FRAMESET ) { + style->setPosition( STATIC ); + } + } + + // Finally update our text decorations in effect, but don't allow text-decoration to percolate through + // tables, inline blocks, inline tables, or run-ins. + if (style->display() == TABLE || style->display() == INLINE_TABLE || style->display() == RUN_IN + || style->display() == INLINE_BLOCK /*|| style->display() == INLINE_BOX*/) + style->setTextDecorationsInEffect(style->textDecoration()); + else + style->addToTextDecorationsInEffect(style->textDecoration()); + + // If either overflow value is not visible, change to auto. + if (style->overflowX() == OMARQUEE && style->overflowY() != OMARQUEE) + style->setOverflowY(OMARQUEE); + else if (style->overflowY() == OMARQUEE && style->overflowX() != OMARQUEE) + style->setOverflowX(OMARQUEE); + else if (style->overflowX() == OVISIBLE && style->overflowY() != OVISIBLE) + style->setOverflowX(OAUTO); + else if (style->overflowY() == OVISIBLE && style->overflowX() != OVISIBLE) + style->setOverflowY(OAUTO); + + // Table rows, sections and the table itself will support overflow:hidden and will ignore scroll/auto. + // FIXME: Eventually table sections will support auto and scroll. + if (style->display() == TABLE || style->display() == INLINE_TABLE || + style->display() == TABLE_ROW_GROUP || style->display() == TABLE_ROW) { + if (style->overflowX() != OVISIBLE && style->overflowX() != OHIDDEN) + style->setOverflowX(OVISIBLE); + if (style->overflowY() != OVISIBLE && style->overflowY() != OHIDDEN) + style->setOverflowY(OVISIBLE); + } + + // Cull out any useless layers and also repeat patterns into additional layers. + style->adjustBackgroundLayers(); + + // Only use slow repaints if we actually have a background image. + // FIXME: We only need to invalidate the fixed regions when scrolling. It's total overkill to + // prevent the entire view from blitting on a scroll. + if (style->hasFixedBackgroundImage() && view) + view->useSlowRepaints(); +} + +unsigned int CSSStyleSelector::addInlineDeclarations(DOM::ElementImpl* e, + DOM::CSSStyleDeclarationImpl *decl, + unsigned int numProps) +{ + CSSStyleDeclarationImpl* addDecls = 0; +#ifdef APPLE_CHANGES + if (e->id() == ID_TD || e->id() == ID_TH) // For now only TableCellElement implements the + addDecls = e->getAdditionalStyleDecls(); // virtual function for shared cell rules. +#else + Q_UNUSED( e ); +#endif + + if (!decl && !addDecls) + return numProps; + + QPtrList<CSSProperty>* values = decl ? decl->values() : 0; + QPtrList<CSSProperty>* addValues = addDecls ? addDecls->values() : 0; + if (!values && !addValues) + return numProps; + + int firstLen = values ? values->count() : 0; + int secondLen = addValues ? addValues->count() : 0; + int totalLen = firstLen + secondLen; + + if (inlineProps.size() < (uint)totalLen) + inlineProps.resize(totalLen + 1); + + if (numProps + totalLen >= propsToApplySize ) { + propsToApplySize += propsToApplySize; + propsToApply = (CSSOrderedProperty **)realloc( propsToApply, propsToApplySize*sizeof( CSSOrderedProperty * ) ); + } + + CSSOrderedProperty *array = (CSSOrderedProperty *)inlineProps.data(); + for(int i = 0; i < totalLen; i++) + { + if (i == firstLen) + values = addValues; + + CSSProperty *prop = values->at(i >= firstLen ? i - firstLen : i); + Source source = Inline; + + if( prop->m_important ) source = InlineImportant; + if( prop->nonCSSHint ) source = NonCSSHint; + + bool first; + // give special priority to font-xxx, color properties + switch(prop->m_id) + { + case CSS_PROP_FONT_STYLE: + case CSS_PROP_FONT_SIZE: + case CSS_PROP_FONT_WEIGHT: + case CSS_PROP_FONT_FAMILY: + case CSS_PROP_FONT_VARIANT: + case CSS_PROP_FONT: + case CSS_PROP_COLOR: + case CSS_PROP_DIRECTION: + case CSS_PROP_DISPLAY: + // these have to be applied first, because other properties use the computed + // values of these properties. + first = true; + break; + default: + first = false; + break; + } + + array->prop = prop; + array->pseudoId = RenderStyle::NOPSEUDO; + array->selector = 0; + array->position = i; + array->priority = (!first << 30) | (source << 24); + propsToApply[numProps++] = array++; + } + return numProps; +} + +// modified version of the one in kurl.cpp +static void cleanpath(QString &path) +{ + int pos; + while ( (pos = path.find( "/../" )) != -1 ) { + int prev = 0; + if ( pos > 0 ) + prev = path.findRev( "/", pos -1 ); + // don't remove the host, i.e. http://foo.org/../foo.html + if (prev < 0 || (prev > 3 && path.findRev("://", prev-1) == prev-2)) + path.remove( pos, 3); + else + // matching directory found ? + path.remove( prev, pos- prev + 3 ); + } + pos = 0; + + // Don't remove "//" from an anchor identifier. -rjw + // Set refPos to -2 to mean "I haven't looked for the anchor yet". + // We don't want to waste a function call on the search for the anchor + // in the vast majority of cases where there is no "//" in the path. + int refPos = -2; + while ( (pos = path.find( "//", pos )) != -1) { + if (refPos == -2) + refPos = path.find("#", 0); + if (refPos > 0 && pos >= refPos) + break; + + if ( pos == 0 || path[pos-1] != ':' ) + path.remove( pos, 1 ); + else + pos += 2; + } + while ( (pos = path.find( "/./" )) != -1) + path.remove( pos, 2 ); + //kdDebug() << "checkPseudoState " << path << endl; +} + +static PseudoState checkPseudoState( const CSSStyleSelector::Encodedurl& encodedurl, DOM::ElementImpl *e ) +{ + if( e->id() != ID_A ) { + return PseudoNone; + } + DOMString attr = e->getAttribute(ATTR_HREF); + if( attr.isNull() ) { + return PseudoNone; + } + QConstString cu(attr.unicode(), attr.length()); + QString u = cu.string(); + if ( !u.contains("://") ) { + if ( u[0] == '/' ) + u = encodedurl.host + u; + else if ( u[0] == '#' ) + u = encodedurl.file + u; + else + u = encodedurl.path + u; + cleanpath( u ); + } + //completeURL( attr.string() ); + bool contains = KHTMLFactory::vLinks()->contains( u ); + if ( !contains && u.contains('/')==2 ) + contains = KHTMLFactory::vLinks()->contains( u+'/' ); + return contains ? PseudoVisited : PseudoLink; +} + +// a helper function for parsing nth-arguments +static bool matchNth(int count, const QString& nth) +{ + if (nth.isEmpty()) return false; + int a = 0; + int b = 0; + if (nth == "odd") { + a = 2; + b = 1; + } + else if (nth == "even") { + a = 2; + b = 0; + } + else { + int n = nth.find('n'); + if (n != -1) { + if (nth[0] == '-') + if (n==1) + a = -1; + else + a = nth.mid(1,n-1).toInt(); + else + if (n==0) + a = 1; + else + a = nth.left(n).toInt(); + + int p = nth.find('+'); + if (p != -1) + b = nth.mid(p+1).toInt(); + else { + p = nth.find('-'); + b = -nth.mid(p+1).toInt(); + } + } + else { + b = nth.toInt(); + } + } + if (a == 0) + return count == b; + else if (a > 0) + if (count < b) + return false; + else + return (count - b) % a == 0; + else if (a < 0) { + if (count > b) + return false; + else + return (b - count) % (-a) == 0; + } + return false; +} + + +// Recursively work the combinator to compute static attribute dependency, similar to +//structure of checkSubSelectors +static void precomputeAttributeDependenciesAux(DOM::DocumentImpl* doc, DOM::CSSSelector* sel, bool isAncestor, bool isSubject) +{ + if(sel->attr) + { + // Sets up global dependencies of attributes + if (isSubject) + doc->dynamicDomRestyler().addDependency(sel->attr, PersonalDependency); + else if (isAncestor) + doc->dynamicDomRestyler().addDependency(sel->attr, AncestorDependency); + else + doc->dynamicDomRestyler().addDependency(sel->attr, PredecessorDependency); + } + if(sel->match == CSSSelector::PseudoClass) + { + switch (sel->pseudoType()) { + case CSSSelector::PseudoNot: + precomputeAttributeDependenciesAux(doc, sel->simpleSelector, isAncestor, true); + break; + default: + break; + } + } + CSSSelector::Relation relation = sel->relation; + sel = sel->tagHistory; + if (!sel) return; + + switch(relation) + { + case CSSSelector::Descendant: + case CSSSelector::Child: + precomputeAttributeDependenciesAux(doc, sel, true, false); + break; + case CSSSelector::IndirectAdjacent: + case CSSSelector::DirectAdjacent: + precomputeAttributeDependenciesAux(doc, sel, false, false); + break; + case CSSSelector::SubSelector: + precomputeAttributeDependenciesAux(doc, sel, isAncestor, isSubject); + break; + } +} + +void CSSStyleSelector::precomputeAttributeDependencies(DOM::DocumentImpl* doc, DOM::CSSSelector* sel) +{ + precomputeAttributeDependenciesAux(doc, sel, false, true); +} + +// Recursive check of selectors and combinators +// It can return 3 different values: +// * SelectorMatches - the selector is match for the node e +// * SelectorFailsLocal - the selector fails for the node e +// * SelectorFails - the selector fails for e and any sibling or ancestor of e +CSSStyleSelector::SelectorMatch CSSStyleSelector::checkSelector(DOM::CSSSelector *sel, DOM::ElementImpl *e, bool isAncestor, bool isSubSelector) +{ + // The simple selector has to match + if(!checkSimpleSelector(sel, e, isAncestor, isSubSelector)) return SelectorFailsLocal; + + // The rest of the selectors has to match + CSSSelector::Relation relation = sel->relation; + + // Prepare next sel + sel = sel->tagHistory; + if (!sel) return SelectorMatches; + + switch(relation) { + case CSSSelector::Descendant: + { + while(true) + { + DOM::NodeImpl* n = e->parentNode(); + if(!n || !n->isElementNode()) return SelectorFails; + e = static_cast<ElementImpl *>(n); + SelectorMatch match = checkSelector(sel, e, true); + if (match != SelectorFailsLocal) + return match; + } + break; + } + case CSSSelector::Child: + { + DOM::NodeImpl* n = e->parentNode(); + if (!strictParsing) + while (n && n->implicitNode()) n = n->parentNode(); + if(!n || !n->isElementNode()) return SelectorFails; + e = static_cast<ElementImpl *>(n); + return checkSelector(sel, e, true); + } + case CSSSelector::IndirectAdjacent: + { + // Sibling selectors always generate structural dependencies + // because newly inserted element might fullfill them. + if (e->parentNode()->isElementNode()) + addDependency(StructuralDependency, static_cast<ElementImpl*>(e->parentNode())); + while(true) + { + DOM::NodeImpl* n = e->previousSibling(); + while( n && !n->isElementNode() ) + n = n->previousSibling(); + if( !n ) return SelectorFailsLocal; + e = static_cast<ElementImpl *>(n); + SelectorMatch match = checkSelector(sel, e, false); + if (match != SelectorFailsLocal) + return match; + }; + break; + } + case CSSSelector::DirectAdjacent: + { + if (e->parentNode()->isElementNode()) + addDependency(StructuralDependency, static_cast<ElementImpl*>(e->parentNode())); + DOM::NodeImpl* n = e->previousSibling(); + while( n && !n->isElementNode() ) + n = n->previousSibling(); + if( !n ) return SelectorFailsLocal; + e = static_cast<ElementImpl *>(n); + return checkSelector(sel, e, false); + } + case CSSSelector::SubSelector: + return checkSelector(sel, e, isAncestor, true); + } + assert(false); // never reached + return SelectorFails; +} + +void CSSStyleSelector::checkSelector(int selIndex, DOM::ElementImpl * e) +{ + assert(e == element); // yes, actually + + dynamicPseudo = RenderStyle::NOPSEUDO; + + selectorCache[ selIndex ].state = Invalid; + CSSSelector *sel = selectors[ selIndex ]; + + // Check the selector + SelectorMatch match = checkSelector(sel, e, true); + if(match != SelectorMatches) return; + + if ( dynamicPseudo != RenderStyle::NOPSEUDO ) { + selectorCache[selIndex].state = AppliesPseudo; + selectors[ selIndex ]->pseudoId = dynamicPseudo; + } else + selectorCache[ selIndex ].state = Applies; + //qDebug( "selector %d applies", selIndex ); + //selectors[ selIndex ]->print(); + return; +} + +void CSSStyleSelector::addDependency(StructuralDependencyType dependencyType, ElementImpl* dependency) +{ + element->getDocument()->dynamicDomRestyler().addDependency(element, dependency, dependencyType); +} + +bool CSSStyleSelector::checkSimpleSelector(DOM::CSSSelector *sel, DOM::ElementImpl *e, bool isAncestor, bool isSubSelector) +{ + if(!e) + return false; + + if (sel->tag != anyQName) { + int eltID = e->id(); + Q_UINT16 localName = localNamePart(eltID); + Q_UINT16 ns = namespacePart(eltID); + Q_UINT16 selLocalName = localNamePart(sel->tag); + Q_UINT16 selNS = namespacePart(sel->tag); + + if (localName <= ID_LAST_TAG && ns == defaultNamespace) { + assert(e->isHTMLElement()); + ns = xhtmlNamespace; + } + + // match on local + if (selLocalName != anyLocalName && localName != selLocalName) return false; + // match on namespace + if (selNS != anyNamespace && ns != selNS) return false; + } + + if(sel->attr) + { + DOMStringImpl* value = e->getAttributeImpl(sel->attr); + if(!value) return false; // attribute is not set + + // attributes are always case-sensitive in XHTML + // attributes are sometimes case-sensitive in HTML + // we only treat id and class selectors as case-sensitive in HTML strict + // for compatibility reasons + bool caseSensitive = e->getDocument()->htmlMode() == DocumentImpl::XHtml; + bool caseSensitive_alt = strictParsing || caseSensitive; + caseSensitive |= (sel->attr > ATTR_LAST_CI_ATTR); + + switch(sel->match) + { + case CSSSelector::Set: + // True if we make it this far + break; + case CSSSelector::Id: + caseSensitive = caseSensitive_alt; + // no break + case CSSSelector::Exact: + return (caseSensitive && !strcmp(sel->value, value)) || + (!caseSensitive && !strcasecmp(sel->value, value)); + break; + case CSSSelector::Class: + caseSensitive = caseSensitive_alt; + // no break + case CSSSelector::List: + { + int sel_len = sel->value.length(); + int val_len = value->length(); + // Be smart compare on length first + if (sel_len > val_len) return false; + // Selector string may not contain spaces + if ((sel->attr != ATTR_CLASS || e->hasClassList()) && sel->value.find(' ') != -1) return false; + if (sel_len == val_len) + return (caseSensitive && !strcmp(sel->value, value)) || + (!caseSensitive && !strcasecmp(sel->value, value)); + // else the value is longer and can be a list + if ( sel->match == CSSSelector::Class && !e->hasClassList() ) return false; + + QChar* sel_uc = sel->value.unicode(); + QChar* val_uc = value->unicode(); + + QConstString sel_str(sel_uc, sel_len); + QConstString val_str(val_uc, val_len); + + int pos = 0; + for ( ;; ) { + pos = val_str.string().find(sel_str.string(), pos, caseSensitive); + if ( pos == -1 ) return false; + if ( pos == 0 || val_uc[pos-1].isSpace() ) { + int endpos = pos + sel_len; + if ( endpos >= val_len || val_uc[endpos].isSpace() ) + break; // We have a match. + } + ++pos; + } + break; + } + case CSSSelector::Contain: + { + //kdDebug( 6080 ) << "checking for contains match" << endl; + QConstString val_str(value->unicode(), value->length()); + QConstString sel_str(sel->value.unicode(), sel->value.length()); + return val_str.string().contains(sel_str.string(), caseSensitive); + } + case CSSSelector::Begin: + { + //kdDebug( 6080 ) << "checking for beginswith match" << endl; + QConstString val_str(value->unicode(), value->length()); + QConstString sel_str(sel->value.unicode(), sel->value.length()); + return val_str.string().startsWith(sel_str.string(), caseSensitive); + } + case CSSSelector::End: + { + //kdDebug( 6080 ) << "checking for endswith match" << endl; + QConstString val_str(value->unicode(), value->length()); + QConstString sel_str(sel->value.unicode(), sel->value.length()); + return val_str.string().endsWith(sel_str.string(), caseSensitive); + } + case CSSSelector::Hyphen: + { + //kdDebug( 6080 ) << "checking for hyphen match" << endl; + QConstString val_str(value->unicode(), value->length()); + QConstString sel_str(sel->value.unicode(), sel->value.length()); + const QString& str = val_str.string(); + const QString& selStr = sel_str.string(); + if(str.length() < selStr.length()) return false; + // Check if str begins with selStr: + if(str.find(selStr, 0, caseSensitive) != 0) return false; + // It does. Check for exact match or following '-': + if(str.length() != selStr.length() + && str[selStr.length()] != '-') return false; + break; + } + case CSSSelector::PseudoClass: + case CSSSelector::PseudoElement: + case CSSSelector::None: + break; + } + } + + if(sel->match == CSSSelector::PseudoClass || sel->match == CSSSelector::PseudoElement) + { + switch (sel->pseudoType()) { + // Pseudo classes: + case CSSSelector::PseudoEmpty: + addDependency(BackwardsStructuralDependency, e); + // If e is not closed yet we don't know the number of children + if (!e->closed()) { + return false; + } + if (!e->firstChild()) + return true; + else { + // check for empty text nodes + NodeImpl *t = e->firstChild(); + + while (t && t->isTextNode() && static_cast<TextImpl*>(t)->length() == 0) t = t->nextSibling(); + + if (t == 0) + return true; + else + return false; + } + break; + case CSSSelector::PseudoFirstChild: { + // first-child matches the first child that is an element! + if (e->parentNode() && e->parentNode()->isElementNode()) { + // Handle dynamic DOM changes + addDependency(StructuralDependency, static_cast<ElementImpl*>(e->parentNode())); + DOM::NodeImpl* n = e->previousSibling(); + while ( n && !n->isElementNode() ) + n = n->previousSibling(); + if ( !n ) + return true; + } + break; + } + case CSSSelector::PseudoLastChild: { + // last-child matches the last child that is an element! + if (e->parentNode() && e->parentNode()->isElementNode()) { + // Handle unfinished parsing and dynamic DOM changes + addDependency(BackwardsStructuralDependency, static_cast<ElementImpl*>(e->parentNode())); + if (!e->parentNode()->closed()) { +// kdDebug(6080) << e->nodeName().string() << "::last-child: Parent unclosed" << endl; + return false; + } + DOM::NodeImpl* n = e->nextSibling(); + while ( n && !n->isElementNode() ) + n = n->nextSibling(); + if ( !n ) + return true; + } + break; + } + case CSSSelector::PseudoOnlyChild: { + // If both first-child and last-child apply, then only-child applies. + if (e->parentNode() && e->parentNode()->isElementNode()) { + addDependency(BackwardsStructuralDependency, static_cast<ElementImpl*>(e->parentNode())); + if (!e->parentNode()->closed()) { + return false; + } + DOM::NodeImpl* n = e->previousSibling(); + while ( n && !n->isElementNode() ) + n = n->previousSibling(); + if ( !n ) { + n = e->nextSibling(); + while ( n && !n->isElementNode() ) + n = n->nextSibling(); + if ( !n ) + return true; + } + } + break; + } + case CSSSelector::PseudoNthChild: { + // nth-child matches every (a*n+b)th element! + if (e->parentNode() && e->parentNode()->isElementNode()) { + addDependency(StructuralDependency, static_cast<ElementImpl*>(e->parentNode())); + int count = 1; + DOM::NodeImpl* n = e->previousSibling(); + while ( n ) { + if (n->isElementNode()) count++; + n = n->previousSibling(); + } +// kdDebug(6080) << "NthChild " << count << "=" << sel->string_arg << endl; + if (matchNth(count,sel->string_arg.string())) + return true; + } + break; + } + case CSSSelector::PseudoNthLastChild: { + if (e->parentNode() && e->parentNode()->isElementNode()) { + addDependency(BackwardsStructuralDependency, static_cast<ElementImpl*>(e->parentNode())); + if (!e->parentNode()->closed()) { + return false; + } + int count = 1; + DOM::NodeImpl* n = e->nextSibling(); + while ( n ) { + if (n->isElementNode()) count++; + n = n->nextSibling(); + } +// kdDebug(6080) << "NthLastChild " << count << "=" << sel->string_arg << endl; + if (matchNth(count,sel->string_arg.string())) + return true; + } + break; + } + case CSSSelector::PseudoFirstOfType: { + // first-of-type matches the first element of its type! + if (e->parentNode() && e->parentNode()->isElementNode()) { + addDependency(StructuralDependency, static_cast<ElementImpl*>(e->parentNode())); + const DOMString& type = e->tagName(); + DOM::NodeImpl* n = e->previousSibling(); + while ( n ) { + if (n->isElementNode()) + if (static_cast<ElementImpl*>(n)->tagName() == type) break; + n = n->previousSibling(); + } + if ( !n ) + return true; + } + break; + } + case CSSSelector::PseudoLastOfType: { + // last-child matches the last child that is an element! + if (e->parentNode() && e->parentNode()->isElementNode()) { + addDependency(BackwardsStructuralDependency, static_cast<ElementImpl*>(e->parentNode())); + if (!e->parentNode()->closed()) { + return false; + } + const DOMString& type = e->tagName(); + DOM::NodeImpl* n = e->nextSibling(); + while ( n ) { + if (n->isElementNode()) + if (static_cast<ElementImpl*>(n)->tagName() == type) break; + n = n->nextSibling(); + } + if ( !n ) + return true; + } + break; + } + case CSSSelector::PseudoOnlyOfType: { + // If both first-of-type and last-of-type apply, then only-of-type applies. + if (e->parentNode() && e->parentNode()->isElementNode()) { + addDependency(BackwardsStructuralDependency, static_cast<ElementImpl*>(e->parentNode())); + if (!e->parentNode()->closed()) { + return false; + } + const DOMString& type = e->tagName(); + DOM::NodeImpl* n = e->previousSibling(); + while ( n && !(n->isElementNode() && static_cast<ElementImpl*>(n)->tagName() == type)) + n = n->previousSibling(); + if ( !n ) { + n = e->nextSibling(); + while ( n && !(n->isElementNode() && static_cast<ElementImpl*>(n)->tagName() == type)) + n = n->nextSibling(); + if ( !n ) + return true; + } + } + break; + } + case CSSSelector::PseudoNthOfType: { + // nth-of-type matches every (a*n+b)th element of this type! + if (e->parentNode() && e->parentNode()->isElementNode()) { + addDependency(StructuralDependency, static_cast<ElementImpl*>(e->parentNode())); + int count = 1; + const DOMString& type = e->tagName(); + DOM::NodeImpl* n = e->previousSibling(); + while ( n ) { + if (n->isElementNode() && static_cast<ElementImpl*>(n)->tagName() == type) count++; + n = n->previousSibling(); + } +// kdDebug(6080) << "NthOfType " << count << "=" << sel->string_arg << endl; + if (matchNth(count,sel->string_arg.string())) + return true; + } + break; + } + case CSSSelector::PseudoNthLastOfType: { + if (e->parentNode() && e->parentNode()->isElementNode()) { + addDependency(BackwardsStructuralDependency, static_cast<ElementImpl*>(e->parentNode())); + if (!e->parentNode()->closed()) { + return false; + } + int count = 1; + const DOMString& type = e->tagName(); + DOM::NodeImpl* n = e->nextSibling(); + while ( n ) { + if (n->isElementNode() && static_cast<ElementImpl*>(n)->tagName() == type) count++; + n = n->nextSibling(); + } +// kdDebug(6080) << "NthLastOfType " << count << "=" << sel->string_arg << endl; + if (matchNth(count,sel->string_arg.string())) + return true; + } + break; + } + case CSSSelector::PseudoTarget: + if (e == e->getDocument()->getCSSTarget()) + return true; + break; + case CSSSelector::PseudoRoot: + if (e == e->getDocument()->documentElement()) + return true; + break; + case CSSSelector::PseudoLink: + if (e == element) { + // cache pseudoState + if ( pseudoState == PseudoUnknown ) + pseudoState = checkPseudoState( encodedurl, e ); + if ( pseudoState == PseudoLink ) + return true; + } else + return checkPseudoState( encodedurl, e ) == PseudoLink; + break; + case CSSSelector::PseudoVisited: + if (e == element) { + // cache pseudoState + if ( pseudoState == PseudoUnknown ) + pseudoState = checkPseudoState( encodedurl, e ); + if ( pseudoState == PseudoVisited ) + return true; + } else + return checkPseudoState( encodedurl, e ) == PseudoVisited; + break; + case CSSSelector::PseudoHover: { + // If we're in quirks mode, then *:hover should only match focusable elements. + if (strictParsing || (sel->tag != anyQName) || isSubSelector || e->isFocusable() ) { + addDependency(HoverDependency, e); + + if (e->hovered()) + return true; + } + break; + } + case CSSSelector::PseudoActive: + // If we're in quirks mode, then *:active should only match focusable elements + if (strictParsing || (sel->tag != anyQName) || isSubSelector || e->isFocusable()) { + addDependency(ActiveDependency, e); + + if (e->active()) + return true; + } + break; + case CSSSelector::PseudoFocus: + if (e != element && e->isFocusable()) { + // *:focus is a default style, no need to track it. + addDependency(OtherStateDependency, e); + } + if (e->focused()) return true; + break; + case CSSSelector::PseudoLang: { + // Set dynamic attribute dependency + if (e == element) { + e->getDocument()->dynamicDomRestyler().addDependency(ATTR_LANG, PersonalDependency); + e->getDocument()->dynamicDomRestyler().addDependency(ATTR_LANG, AncestorDependency); + } + else if (isAncestor) + e->getDocument()->dynamicDomRestyler().addDependency(ATTR_LANG, AncestorDependency); + else + e->getDocument()->dynamicDomRestyler().addDependency(ATTR_LANG, PredecessorDependency); + // ### check xml:lang attribute in XML and XHTML documents + DOMString value = e->getAttribute(ATTR_LANG); + // The LANG attribute is inherited like a property + NodeImpl *n = e->parent();; + while (n && value.isEmpty()) { + if (n->isElementNode()) { + value = static_cast<ElementImpl*>(n)->getAttribute(ATTR_LANG); + } else + if (n->isDocumentNode()) { + value = static_cast<DocumentImpl*>(n)->contentLanguage(); + } + n = n->parent(); + } + if (value.isEmpty()) return false; + + QString langAttr = value.string(); + QString langSel = sel->string_arg.string(); + + if(langAttr.length() < langSel.length()) return false; + + langAttr = langAttr.lower(); + langSel = langSel.lower(); +// kdDebug(6080) << ":lang " << langAttr << "=" << langSel << "?" << endl; + return (langAttr == langSel || langAttr.startsWith(langSel+"-")); + } + case CSSSelector::PseudoNot: { + // check the simple selector + for (CSSSelector* subSel = sel->simpleSelector; subSel; + subSel = subSel->tagHistory) { + // :not cannot nest. I don't really know why this is a restriction in CSS3, + // but it is, so let's honor it. + if (subSel->simpleSelector) + break; + if (!checkSimpleSelector(subSel, e, isAncestor, true)) + return true; + } + break; + } + case CSSSelector::PseudoEnabled: { + if (e->isGenericFormElement()) { + addDependency(OtherStateDependency, e); + HTMLGenericFormElementImpl *form; + form = static_cast<HTMLGenericFormElementImpl*>(e); + return !form->disabled(); + } + break; + } + case CSSSelector::PseudoDisabled: { + if (e->isGenericFormElement()) { + addDependency(OtherStateDependency, e); + HTMLGenericFormElementImpl *form; + form = static_cast<HTMLGenericFormElementImpl*>(e); + return form->disabled(); + } + break; + } + case CSSSelector::PseudoContains: { + if (e->isHTMLElement()) { + addDependency(BackwardsStructuralDependency, e); + if (!e->closed()) { + return false; + } + HTMLElementImpl *elem; + elem = static_cast<HTMLElementImpl*>(e); + DOMString s = elem->innerText(); + QString selStr = sel->string_arg.string(); +// kdDebug(6080) << ":contains(\"" << selStr << "\")" << " on \"" << s << "\"" << endl; + return s.string().contains(selStr); + } + break; + } + case CSSSelector::PseudoChecked: { + if (e->isHTMLElement() && e->id() == ID_INPUT) { + addDependency(OtherStateDependency, e); + return (static_cast<HTMLInputElementImpl*>(e)->checked()); + } + return false; + } + case CSSSelector::PseudoIndeterminate: { +#if 0 + if (e->isHTMLElement() && e->id() == ID_INPUT) { + return (static_cast<HTMLInputElementImpl*>(e)->indeterminate() && + !static_cast<HTMLInputElementImpl*>(e)->checked()); + } + return false; +#endif + } + case CSSSelector::PseudoOther: + break; + + // Pseudo-elements: + case CSSSelector::PseudoFirstLine: + case CSSSelector::PseudoFirstLetter: + case CSSSelector::PseudoSelection: + case CSSSelector::PseudoBefore: + case CSSSelector::PseudoAfter: + case CSSSelector::PseudoMarker: + case CSSSelector::PseudoReplaced: + // Pseudo-elements can only apply to subject + if ( e == element ) { + // Pseudo-elements has to be the last sub-selector on subject + if (sel->tagHistory && sel->relation == CSSSelector::SubSelector) return false; + + assert(dynamicPseudo == RenderStyle::NOPSEUDO); + + switch (sel->pseudoType()) { + case CSSSelector::PseudoFirstLine: + dynamicPseudo = RenderStyle::FIRST_LINE; + break; + case CSSSelector::PseudoFirstLetter: + dynamicPseudo = RenderStyle::FIRST_LETTER; + break; + case CSSSelector::PseudoSelection: + dynamicPseudo = RenderStyle::SELECTION; + break; + case CSSSelector::PseudoBefore: + dynamicPseudo = RenderStyle::BEFORE; + break; + case CSSSelector::PseudoAfter: + dynamicPseudo = RenderStyle::AFTER; + break; + case CSSSelector::PseudoMarker: + dynamicPseudo = RenderStyle::MARKER; + break; + case CSSSelector::PseudoReplaced: + dynamicPseudo = RenderStyle::REPLACED; + break; + default: + assert(false); + } + return true; + } + break; + case CSSSelector::PseudoNotParsed: + assert(false); + break; + } + return false; + } + // ### add the rest of the checks... + return true; +} + +void CSSStyleSelector::clearLists() +{ + delete [] selectors; + if ( selectorCache ) { + for ( unsigned int i = 0; i < selectors_size; i++ ) + delete [] selectorCache[i].props; + + delete [] selectorCache; + } + if ( properties ) { + CSSOrderedProperty **prop = properties; + while ( *prop ) { + delete (*prop); + prop++; + } + delete [] properties; + } + selectors = 0; + properties = 0; + selectorCache = 0; +} + + +void CSSStyleSelector::buildLists() +{ + clearLists(); + // collect all selectors and Properties in lists. Then transfer them to the array for faster lookup. + + QPtrList<CSSSelector> selectorList; + CSSOrderedPropertyList propertyList; + + if(m_medium == "print" && defaultPrintStyle) + defaultPrintStyle->collect( &selectorList, &propertyList, Default, + Default ); + else if(defaultStyle) defaultStyle->collect( &selectorList, &propertyList, + Default, Default ); + + if (!strictParsing && defaultQuirksStyle) + defaultQuirksStyle->collect( &selectorList, &propertyList, Default, Default ); + + if(userStyle) userStyle->collect(&selectorList, &propertyList, User, UserImportant ); + if(authorStyle) authorStyle->collect(&selectorList, &propertyList, Author, AuthorImportant ); + + selectors_size = selectorList.count(); + selectors = new CSSSelector *[selectors_size]; + CSSSelector *s = selectorList.first(); + CSSSelector **sel = selectors; + while ( s ) { + *sel = s; + s = selectorList.next(); + ++sel; + } + + selectorCache = new SelectorCache[selectors_size]; + for ( unsigned int i = 0; i < selectors_size; i++ ) { + selectorCache[i].state = Unknown; + selectorCache[i].props_size = 0; + selectorCache[i].props = 0; + } + + // presort properties. Should make the sort() calls in styleForElement faster. + propertyList.sort(); + properties_size = propertyList.count() + 1; + properties = new CSSOrderedProperty *[ properties_size ]; + CSSOrderedProperty *p = propertyList.first(); + CSSOrderedProperty **prop = properties; + while ( p ) { + *prop = p; + p = propertyList.next(); + ++prop; + } + *prop = 0; + + unsigned int* offsets = new unsigned int[selectors_size]; + if(properties[0]) + offsets[properties[0]->selector] = 0; + for(unsigned int p = 1; p < properties_size; ++p) { + + if(!properties[p] || (properties[p]->selector != properties[p - 1]->selector)) { + unsigned int sel = properties[p - 1]->selector; + int* newprops = new int[selectorCache[sel].props_size+2]; + for ( unsigned int i=0; i < selectorCache[sel].props_size; i++ ) + newprops[i] = selectorCache[sel].props[i]; + + newprops[selectorCache[sel].props_size] = offsets[sel]; + newprops[selectorCache[sel].props_size+1] = p - offsets[sel]; + delete [] selectorCache[sel].props; + selectorCache[sel].props = newprops; + selectorCache[sel].props_size += 2; + + if(properties[p]) { + sel = properties[p]->selector; + offsets[sel] = p; + } + } + } + delete [] offsets; +} + + +// ---------------------------------------------------------------------- + + +CSSOrderedRule::CSSOrderedRule(DOM::CSSStyleRuleImpl *r, DOM::CSSSelector *s, int _index) +{ + rule = r; + if(rule) r->ref(); + index = _index; + selector = s; +} + +CSSOrderedRule::~CSSOrderedRule() +{ + if(rule) rule->deref(); +} + +// ----------------------------------------------------------------- + +CSSStyleSelectorList::CSSStyleSelectorList() + : QPtrList<CSSOrderedRule>() +{ + setAutoDelete(true); +} +CSSStyleSelectorList::~CSSStyleSelectorList() +{ +} + +void CSSStyleSelectorList::append( CSSStyleSheetImpl *sheet, + const DOMString &medium ) +{ + if(!sheet || !sheet->isCSSStyleSheet()) return; + + // No media implies "all", but if a medialist exists it must + // contain our current medium + if( sheet->media() && !sheet->media()->contains( medium ) ) + return; // style sheet not applicable for this medium + + int len = sheet->length(); + + for(int i = 0; i< len; i++) + { + StyleBaseImpl *item = sheet->item(i); + if(item->isStyleRule()) + { + CSSStyleRuleImpl *r = static_cast<CSSStyleRuleImpl *>(item); + QPtrList<CSSSelector> *s = r->selector(); + for(int j = 0; j < (int)s->count(); j++) + { + CSSOrderedRule *rule = new CSSOrderedRule(r, s->at(j), count()); + QPtrList<CSSOrderedRule>::append(rule); + //kdDebug( 6080 ) << "appending StyleRule!" << endl; + } + } + else if(item->isImportRule()) + { + CSSImportRuleImpl *import = static_cast<CSSImportRuleImpl *>(item); + + //kdDebug( 6080 ) << "@import: Media: " + // << import->media()->mediaText().string() << endl; + + if( !import->media() || import->media()->contains( medium ) ) + { + CSSStyleSheetImpl *importedSheet = import->styleSheet(); + append( importedSheet, medium ); + } + } + else if( item->isMediaRule() ) + { + CSSMediaRuleImpl *r = static_cast<CSSMediaRuleImpl *>( item ); + CSSRuleListImpl *rules = r->cssRules(); + + //DOMString mediaText = media->mediaText(); + //kdDebug( 6080 ) << "@media: Media: " + // << r->media()->mediaText().string() << endl; + + if( ( !r->media() || r->media()->contains( medium ) ) && rules) + { + // Traverse child elements of the @import rule. Since + // many elements are not allowed as child we do not use + // a recursive call to append() here + for( unsigned j = 0; j < rules->length(); j++ ) + { + //kdDebug( 6080 ) << "*** Rule #" << j << endl; + + CSSRuleImpl *childItem = rules->item( j ); + if( childItem->isStyleRule() ) + { + // It is a StyleRule, so append it to our list + CSSStyleRuleImpl *styleRule = + static_cast<CSSStyleRuleImpl *>( childItem ); + + QPtrList<CSSSelector> *s = styleRule->selector(); + for( int j = 0; j < ( int ) s->count(); j++ ) + { + CSSOrderedRule *orderedRule = new CSSOrderedRule( + styleRule, s->at( j ), count() ); + QPtrList<CSSOrderedRule>::append( orderedRule ); + } + } + else + { + //kdDebug( 6080 ) << "Ignoring child rule of " + // "ImportRule: rule is not a StyleRule!" << endl; + } + } // for rules + } // if rules + else + { + //kdDebug( 6080 ) << "CSSMediaRule not rendered: " + // << "rule empty or wrong medium!" << endl; + } + } + // ### include other rules + } +} + + +void CSSStyleSelectorList::collect( QPtrList<CSSSelector> *selectorList, CSSOrderedPropertyList *propList, + Source regular, Source important ) +{ + CSSOrderedRule *r = first(); + while( r ) { + CSSSelector *sel = selectorList->first(); + int selectorNum = 0; + while( sel ) { + if ( *sel == *(r->selector) ) + break; + sel = selectorList->next(); + selectorNum++; + } + if ( !sel ) + selectorList->append( r->selector ); +// else +// qDebug("merged one selector"); + propList->append(r->rule->declaration(), selectorNum, r->selector->specificity(), regular, important ); + r = next(); + } +} + +// ------------------------------------------------------------------------- + +int CSSOrderedPropertyList::compareItems(QPtrCollection::Item i1, QPtrCollection::Item i2) +{ + int diff = static_cast<CSSOrderedProperty *>(i1)->priority + - static_cast<CSSOrderedProperty *>(i2)->priority; + return diff ? diff : static_cast<CSSOrderedProperty *>(i1)->position + - static_cast<CSSOrderedProperty *>(i2)->position; +} + +void CSSOrderedPropertyList::append(DOM::CSSStyleDeclarationImpl *decl, uint selector, uint specificity, + Source regular, Source important ) +{ + QPtrList<CSSProperty> *values = decl->values(); + if(!values) return; + int len = values->count(); + for(int i = 0; i < len; i++) + { + CSSProperty *prop = values->at(i); + Source source = regular; + + if( prop->m_important ) source = important; + if( prop->nonCSSHint ) source = NonCSSHint; + + bool first = false; + // give special priority to font-xxx, color properties + switch(prop->m_id) + { + case CSS_PROP_FONT_STYLE: + case CSS_PROP_FONT_SIZE: + case CSS_PROP_FONT_WEIGHT: + case CSS_PROP_FONT_FAMILY: + case CSS_PROP_FONT_VARIANT: + case CSS_PROP_FONT: + case CSS_PROP_COLOR: + case CSS_PROP_DIRECTION: + case CSS_PROP_DISPLAY: + // these have to be applied first, because other properties use the computed + // values of these porperties. + first = true; + break; + default: + break; + } + + QPtrList<CSSOrderedProperty>::append(new CSSOrderedProperty(prop, selector, + first, source, specificity, + count() )); + } +} + +// ------------------------------------------------------------------------------------- +// this is mostly boring stuff on how to apply a certain rule to the renderstyle... + +static Length convertToLength( CSSPrimitiveValueImpl *primitiveValue, RenderStyle *style, QPaintDeviceMetrics *paintDeviceMetrics, bool *ok = 0 ) +{ + Length l; + if ( !primitiveValue ) { + if ( ok ) + *ok = false; + } else { + int type = primitiveValue->primitiveType(); + if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) + l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed); + else if(type == CSSPrimitiveValue::CSS_PERCENTAGE) + l = Length(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE)), Percent); + else if(type == CSSPrimitiveValue::CSS_NUMBER) + l = Length(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER)*100), Percent); + else if (type == CSSPrimitiveValue::CSS_HTML_RELATIVE) + l = Length(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_HTML_RELATIVE)), Relative); + else if ( ok ) + *ok = false; + } + return l; +} + + +// color mapping code +struct colorMap { + int css_value; + QRgb color; +}; + +static const colorMap cmap[] = { + { CSS_VAL_AQUA, 0xFF00FFFF }, + { CSS_VAL_BLACK, 0xFF000000 }, + { CSS_VAL_BLUE, 0xFF0000FF }, + { CSS_VAL_CRIMSON, 0xFFDC143C }, + { CSS_VAL_FUCHSIA, 0xFFFF00FF }, + { CSS_VAL_GRAY, 0xFF808080 }, + { CSS_VAL_GREEN, 0xFF008000 }, + { CSS_VAL_INDIGO, 0xFF4B0082 }, + { CSS_VAL_LIME, 0xFF00FF00 }, + { CSS_VAL_MAROON, 0xFF800000 }, + { CSS_VAL_NAVY, 0xFF000080 }, + { CSS_VAL_OLIVE, 0xFF808000 }, + { CSS_VAL_ORANGE, 0xFFFFA500 }, + { CSS_VAL_PURPLE, 0xFF800080 }, + { CSS_VAL_RED, 0xFFFF0000 }, + { CSS_VAL_SILVER, 0xFFC0C0C0 }, + { CSS_VAL_TEAL, 0xFF008080 }, + { CSS_VAL_WHITE, 0xFFFFFFFF }, + { CSS_VAL_YELLOW, 0xFFFFFF00 }, + { CSS_VAL_INVERT, invertedColor }, + { CSS_VAL_TRANSPARENT, transparentColor }, + { CSS_VAL_GREY, 0xff808080 }, + { 0, 0 } +}; + +struct uiColors { + int css_value; + const char * configGroup; + const char * configEntry; +QPalette::ColorGroup group; +QColorGroup::ColorRole role; +}; + +const char * const wmgroup = "WM"; +const char * const generalgroup = "General"; + +/* Mapping system settings to CSS 2 +* Tried hard to get an appropriate mapping - schlpbch +*/ +static const uiColors uimap[] = { + // Active window border. + { CSS_VAL_ACTIVEBORDER, wmgroup, "background", QPalette::Active, QColorGroup::Light }, + // Active window caption. + { CSS_VAL_ACTIVECAPTION, wmgroup, "background", QPalette::Active, QColorGroup::Text }, + // Text in caption, size box, and scrollbar arrow box. + { CSS_VAL_CAPTIONTEXT, wmgroup, "activeForeground", QPalette::Active, QColorGroup::Text }, + // Face color for three-dimensional display elements. + { CSS_VAL_BUTTONFACE, wmgroup, 0, QPalette::Inactive, QColorGroup::Button }, + // Dark shadow for three-dimensional display elements (for edges facing away from the light source). + { CSS_VAL_BUTTONHIGHLIGHT, wmgroup, 0, QPalette::Inactive, QColorGroup::Light }, + // Shadow color for three-dimensional display elements. + { CSS_VAL_BUTTONSHADOW, wmgroup, 0, QPalette::Inactive, QColorGroup::Shadow }, + // Text on push buttons. + { CSS_VAL_BUTTONTEXT, wmgroup, "buttonForeground", QPalette::Inactive, QColorGroup::ButtonText }, + // Dark shadow for three-dimensional display elements. + { CSS_VAL_THREEDDARKSHADOW, wmgroup, 0, QPalette::Inactive, QColorGroup::Dark }, + // Face color for three-dimensional display elements. + { CSS_VAL_THREEDFACE, wmgroup, 0, QPalette::Inactive, QColorGroup::Button }, + // Highlight color for three-dimensional display elements. + { CSS_VAL_THREEDHIGHLIGHT, wmgroup, 0, QPalette::Inactive, QColorGroup::Light }, + // Light color for three-dimensional display elements (for edges facing the light source). + { CSS_VAL_THREEDLIGHTSHADOW, wmgroup, 0, QPalette::Inactive, QColorGroup::Midlight }, + // Dark shadow for three-dimensional display elements. + { CSS_VAL_THREEDSHADOW, wmgroup, 0, QPalette::Inactive, QColorGroup::Shadow }, + + // Inactive window border. + { CSS_VAL_INACTIVEBORDER, wmgroup, "background", QPalette::Disabled, QColorGroup::Background }, + // Inactive window caption. + { CSS_VAL_INACTIVECAPTION, wmgroup, "inactiveBackground", QPalette::Disabled, QColorGroup::Background }, + // Color of text in an inactive caption. + { CSS_VAL_INACTIVECAPTIONTEXT, wmgroup, "inactiveForeground", QPalette::Disabled, QColorGroup::Text }, + { CSS_VAL_GRAYTEXT, wmgroup, 0, QPalette::Disabled, QColorGroup::Text }, + + // Menu background + { CSS_VAL_MENU, generalgroup, "background", QPalette::Inactive, QColorGroup::Background }, + // Text in menus + { CSS_VAL_MENUTEXT, generalgroup, "foreground", QPalette::Inactive, QColorGroup::Background }, + + // Text of item(s) selected in a control. + { CSS_VAL_HIGHLIGHT, generalgroup, "selectBackground", QPalette::Inactive, QColorGroup::Background }, + + // Text of item(s) selected in a control. + { CSS_VAL_HIGHLIGHTTEXT, generalgroup, "selectForeground", QPalette::Inactive, QColorGroup::Background }, + + // Background color of multiple document interface. + { CSS_VAL_APPWORKSPACE, generalgroup, "background", QPalette::Inactive, QColorGroup::Text }, + + // Scroll bar gray area. + { CSS_VAL_SCROLLBAR, generalgroup, "background", QPalette::Inactive, QColorGroup::Background }, + + // Window background. + { CSS_VAL_WINDOW, generalgroup, "windowBackground", QPalette::Inactive, QColorGroup::Background }, + // Window frame. + { CSS_VAL_WINDOWFRAME, generalgroup, "windowBackground", QPalette::Inactive, QColorGroup::Background }, + // WindowText + { CSS_VAL_WINDOWTEXT, generalgroup, "windowForeground", QPalette::Inactive, QColorGroup::Text }, + { CSS_VAL_TEXT, generalgroup, 0, QPalette::Inactive, QColorGroup::Text }, + { 0, 0, 0, QPalette::NColorGroups, QColorGroup::NColorRoles } +}; + +static QColor colorForCSSValue( int css_value ) +{ + // try the regular ones first + const colorMap *col = cmap; + while ( col->css_value && col->css_value != css_value ) + ++col; + if ( col->css_value ) + return col->color; + + const uiColors *uicol = uimap; + while ( uicol->css_value && uicol->css_value != css_value ) + ++uicol; +#ifndef APPLE_CHANGES + if ( !uicol->css_value ) { + if ( css_value == CSS_VAL_INFOBACKGROUND ) + return QToolTip::palette().inactive().background(); + else if ( css_value == CSS_VAL_INFOTEXT ) + return QToolTip::palette().inactive().foreground(); + else if ( css_value == CSS_VAL_BACKGROUND ) { + KConfig bckgrConfig("kdesktoprc", true, false); // No multi-screen support + bckgrConfig.setGroup("Desktop0"); + // Desktop background. + return bckgrConfig.readColorEntry("Color1", &qApp->palette().disabled().background()); + } + return QColor(); + } +#endif + + const QPalette &pal = qApp->palette(); + QColor c = pal.color( uicol->group, uicol->role ); +#ifndef APPLE_CHANGES + if ( uicol->configEntry ) { + KConfig *globalConfig = KGlobal::config(); + globalConfig->setGroup( uicol->configGroup ); + c = globalConfig->readColorEntry( uicol->configEntry, &c ); + } +#endif + + return c; +} + +static inline int nextFontSize(const QValueVector<int>& a, int v, bool smaller) +{ + // return the nearest bigger/smaller value in scale a, when v is in range. + // otherwise increase/decrease value using a 1.2 fixed ratio + int m, l = 0, r = a.count()-1; + while (l <= r) { + m = (l+r)/2; + if (a[m] == v) + return smaller ? ( m ? a[m-1] : (v*5)/6 ) : + ( m+1<int(a.count()) ? a[m+1] : (v*6)/5 ); + else if (v < a[m]) + r = m-1; + else + l = m+1; + } + if (!l) + return smaller ? (v*5)/6 : kMin((v*6)/5, a[0]); + if (l == int(a.count())) + return smaller ? kMax((v*5)/6, a[r]) : (v*6)/5; + + return smaller ? a[r] : a[l]; +} + +void CSSStyleSelector::applyRule( int id, DOM::CSSValueImpl *value ) +{ +// kdDebug( 6080 ) << "applying property " << getPropertyName(id) << endl; + + CSSPrimitiveValueImpl *primitiveValue = 0; + if(value->isPrimitiveValue()) primitiveValue = static_cast<CSSPrimitiveValueImpl *>(value); + + Length l; + bool apply = false; + + bool isInherit = (parentNode && value->cssValueType() == CSSValue::CSS_INHERIT); + bool isInitial = (value->cssValueType() == CSSValue::CSS_INITIAL) || + (!parentNode && value->cssValueType() == CSSValue::CSS_INHERIT); + + // These properties are used to set the correct margins/padding on RTL lists. + if (id == CSS_PROP__KHTML_MARGIN_START) + id = style->direction() == LTR ? CSS_PROP_MARGIN_LEFT : CSS_PROP_MARGIN_RIGHT; + else if (id == CSS_PROP__KHTML_PADDING_START) + id = style->direction() == LTR ? CSS_PROP_PADDING_LEFT : CSS_PROP_PADDING_RIGHT; + + // What follows is a list that maps the CSS properties into their corresponding front-end + // RenderStyle values. Shorthands (e.g. border, background) occur in this list as well and + // are only hit when mapping "inherit" or "initial" into front-end values. + switch(id) + { +// ident only properties + case CSS_PROP_BACKGROUND_ATTACHMENT: + HANDLE_BACKGROUND_VALUE(backgroundAttachment, BackgroundAttachment, value) + break; + case CSS_PROP__KHTML_BACKGROUND_CLIP: + HANDLE_BACKGROUND_VALUE(backgroundClip, BackgroundClip, value) + break; + case CSS_PROP__KHTML_BACKGROUND_ORIGIN: + HANDLE_BACKGROUND_VALUE(backgroundOrigin, BackgroundOrigin, value) + break; + case CSS_PROP_BACKGROUND_REPEAT: + HANDLE_BACKGROUND_VALUE(backgroundRepeat, BackgroundRepeat, value) + break; + case CSS_PROP__KHTML_BACKGROUND_SIZE: + HANDLE_BACKGROUND_VALUE(backgroundSize, BackgroundSize, value) + break; + case CSS_PROP_BORDER_COLLAPSE: + HANDLE_INHERIT_AND_INITIAL(borderCollapse, BorderCollapse) + if(!primitiveValue) break; + switch(primitiveValue->getIdent()) + { + case CSS_VAL_COLLAPSE: + style->setBorderCollapse(true); + break; + case CSS_VAL_SEPARATE: + style->setBorderCollapse(false); + break; + default: + return; + } + break; + + case CSS_PROP_BORDER_TOP_STYLE: + HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderTopStyle, BorderTopStyle, BorderStyle) + if (!primitiveValue) return; + style->setBorderTopStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL__KHTML_NATIVE)); + break; + case CSS_PROP_BORDER_RIGHT_STYLE: + HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderRightStyle, BorderRightStyle, BorderStyle) + if (!primitiveValue) return; + style->setBorderRightStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL__KHTML_NATIVE)); + break; + case CSS_PROP_BORDER_BOTTOM_STYLE: + HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderBottomStyle, BorderBottomStyle, BorderStyle) + if (!primitiveValue) return; + style->setBorderBottomStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL__KHTML_NATIVE)); + break; + case CSS_PROP_BORDER_LEFT_STYLE: + HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderLeftStyle, BorderLeftStyle, BorderStyle) + if (!primitiveValue) return; + style->setBorderLeftStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL__KHTML_NATIVE)); + break; + case CSS_PROP_OUTLINE_STYLE: + HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(outlineStyle, OutlineStyle, BorderStyle) + if (!primitiveValue) return; + style->setOutlineStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL__KHTML_NATIVE)); + break; + case CSS_PROP_CAPTION_SIDE: + { + HANDLE_INHERIT_AND_INITIAL(captionSide, CaptionSide) + if(!primitiveValue) break; + ECaptionSide c = RenderStyle::initialCaptionSide(); + switch(primitiveValue->getIdent()) + { + case CSS_VAL_LEFT: + c = CAPLEFT; break; + case CSS_VAL_RIGHT: + c = CAPRIGHT; break; + case CSS_VAL_TOP: + c = CAPTOP; break; + case CSS_VAL_BOTTOM: + c = CAPBOTTOM; break; + default: + return; + } + style->setCaptionSide(c); + return; + } + case CSS_PROP_CLEAR: + { + HANDLE_INHERIT_AND_INITIAL(clear, Clear) + if(!primitiveValue) break; + EClear c = CNONE; + switch(primitiveValue->getIdent()) + { + case CSS_VAL_LEFT: + c = CLEFT; break; + case CSS_VAL_RIGHT: + c = CRIGHT; break; + case CSS_VAL_BOTH: + c = CBOTH; break; + case CSS_VAL_NONE: + c = CNONE; break; + default: + return; + } + style->setClear(c); + return; + } + case CSS_PROP_DIRECTION: + { + HANDLE_INHERIT_AND_INITIAL(direction, Direction) + if(!primitiveValue) break; + style->setDirection( (EDirection) (primitiveValue->getIdent() - CSS_VAL_LTR) ); + return; + } + case CSS_PROP_DISPLAY: + { + HANDLE_INHERIT_AND_INITIAL(display, Display) + if(!primitiveValue) break; + int id = primitiveValue->getIdent(); + style->setDisplay( id == CSS_VAL_NONE ? NONE : EDisplay(id - CSS_VAL_INLINE) ); + break; + } + + case CSS_PROP_EMPTY_CELLS: + { + HANDLE_INHERIT(emptyCells, EmptyCells); + if (!primitiveValue) break; + int id = primitiveValue->getIdent(); + if (id == CSS_VAL_SHOW) + style->setEmptyCells(SHOW); + else if (id == CSS_VAL_HIDE) + style->setEmptyCells(HIDE); + break; + } + case CSS_PROP_FLOAT: + { + HANDLE_INHERIT_AND_INITIAL(floating, Floating) + if(!primitiveValue) return; + EFloat f; + switch(primitiveValue->getIdent()) + { + case CSS_VAL__KHTML_LEFT: + f = FLEFT_ALIGN; break; + case CSS_VAL_LEFT: + f = FLEFT; break; + case CSS_VAL__KHTML_RIGHT: + f = FRIGHT_ALIGN; break; + case CSS_VAL_RIGHT: + f = FRIGHT; break; + case CSS_VAL_NONE: + case CSS_VAL_CENTER: //Non standart CSS-Value + f = FNONE; break; + default: + return; + } + if (f!=FNONE && style->display()==LIST_ITEM) + style->setDisplay(BLOCK); + + style->setFloating(f); + break; + } + + case CSS_PROP_FONT_STYLE: + { + FontDef fontDef = style->htmlFont().fontDef; + if (isInherit) + fontDef.italic = parentStyle->htmlFont().fontDef.italic; + else if (isInitial) + fontDef.italic = false; + else { + if(!primitiveValue) return; + switch(primitiveValue->getIdent()) { + case CSS_VAL_OBLIQUE: + // ### oblique is the same as italic for the moment... + case CSS_VAL_ITALIC: + fontDef.italic = true; + break; + case CSS_VAL_NORMAL: + fontDef.italic = false; + break; + default: + return; + } + } + fontDirty |= style->setFontDef( fontDef ); + break; + } + + + case CSS_PROP_FONT_VARIANT: + { + FontDef fontDef = style->htmlFont().fontDef; + if (isInherit) + fontDef.smallCaps = parentStyle->htmlFont().fontDef.smallCaps; + else if (isInitial) + fontDef.smallCaps = false; + else { + if(!primitiveValue) return; + int id = primitiveValue->getIdent(); + if ( id == CSS_VAL_NORMAL ) + fontDef.smallCaps = false; + else if ( id == CSS_VAL_SMALL_CAPS ) + fontDef.smallCaps = true; + else + return; + } + fontDirty |= style->setFontDef( fontDef ); + break; + } + + case CSS_PROP_FONT_WEIGHT: + { + FontDef fontDef = style->htmlFont().fontDef; + if (isInherit) + fontDef.weight = parentStyle->htmlFont().fontDef.weight; + else if (isInitial) + fontDef.weight = QFont::Normal; + else { + if(!primitiveValue) return; + if(primitiveValue->getIdent()) + { + switch(primitiveValue->getIdent()) { + // ### we just support normal and bold fonts at the moment... + // setWeight can actually accept values between 0 and 99... + case CSS_VAL_BOLD: + case CSS_VAL_BOLDER: + case CSS_VAL_600: + case CSS_VAL_700: + case CSS_VAL_800: + case CSS_VAL_900: + fontDef.weight = QFont::Bold; + break; + case CSS_VAL_NORMAL: + case CSS_VAL_LIGHTER: + case CSS_VAL_100: + case CSS_VAL_200: + case CSS_VAL_300: + case CSS_VAL_400: + case CSS_VAL_500: + fontDef.weight = QFont::Normal; + break; + default: + return; + } + } + else + { + // ### fix parsing of 100-900 values in parser, apply them here + } + } + fontDirty |= style->setFontDef( fontDef ); + break; + } + + case CSS_PROP_LIST_STYLE_POSITION: + { + HANDLE_INHERIT_AND_INITIAL(listStylePosition, ListStylePosition) + if (!primitiveValue) return; + if (primitiveValue->getIdent()) + style->setListStylePosition( (EListStylePosition) (primitiveValue->getIdent() - CSS_VAL_OUTSIDE) ); + return; + } + + case CSS_PROP_LIST_STYLE_TYPE: + { + HANDLE_INHERIT_AND_INITIAL(listStyleType, ListStyleType) + if (!primitiveValue) return; + if (primitiveValue->getIdent()) + { + EListStyleType t; + int id = primitiveValue->getIdent(); + if ( id == CSS_VAL_NONE) { // important!! + t = LNONE; + } else { + t = EListStyleType(id - CSS_VAL_DISC); + } + style->setListStyleType(t); + } + return; + } + + case CSS_PROP_OVERFLOW: + { + if (isInherit) { + style->setOverflowX(parentStyle->overflowX()); + style->setOverflowY(parentStyle->overflowY()); + return; + } + + if (isInitial) { + style->setOverflowX(RenderStyle::initialOverflowX()); + style->setOverflowY(RenderStyle::initialOverflowY()); + return; + } + + if (!primitiveValue) return; + EOverflow o; + switch(primitiveValue->getIdent()) + { + case CSS_VAL_VISIBLE: + o = OVISIBLE; break; + case CSS_VAL_HIDDEN: + o = OHIDDEN; break; + case CSS_VAL_SCROLL: + o = OSCROLL; break; + case CSS_VAL_AUTO: + o = OAUTO; break; + case CSS_VAL_MARQUEE: + o = OMARQUEE; break; + default: + return; + } + style->setOverflowX(o); + style->setOverflowY(o); + return; + } + case CSS_PROP_OVERFLOW_X: + { + HANDLE_INHERIT_AND_INITIAL(overflowX, OverflowX) + if (!primitiveValue) return; + EOverflow o; + switch(primitiveValue->getIdent()) + { + case CSS_VAL_VISIBLE: + o = OVISIBLE; break; + case CSS_VAL_HIDDEN: + o = OHIDDEN; break; + case CSS_VAL_SCROLL: + o = OSCROLL; break; + case CSS_VAL_AUTO: + o = OAUTO; break; + default: + return; + } + style->setOverflowX(o); + return; + } + case CSS_PROP_OVERFLOW_Y: + { + HANDLE_INHERIT_AND_INITIAL(overflowY, OverflowY) + if (!primitiveValue) return; + EOverflow o; + switch(primitiveValue->getIdent()) + { + case CSS_VAL_VISIBLE: + o = OVISIBLE; break; + case CSS_VAL_HIDDEN: + o = OHIDDEN; break; + case CSS_VAL_SCROLL: + o = OSCROLL; break; + case CSS_VAL_AUTO: + o = OAUTO; break; + default: + return; + } + style->setOverflowY(o); + return; + } + case CSS_PROP_PAGE_BREAK_BEFORE: + { + HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(pageBreakBefore, PageBreakBefore, PageBreak) + if (!primitiveValue) return; + switch (primitiveValue->getIdent()) { + case CSS_VAL_AUTO: + style->setPageBreakBefore(PBAUTO); + break; + case CSS_VAL_LEFT: + case CSS_VAL_RIGHT: + // CSS2.1: "Conforming user agents may map left/right to always." + case CSS_VAL_ALWAYS: + style->setPageBreakBefore(PBALWAYS); + break; + case CSS_VAL_AVOID: + style->setPageBreakBefore(PBAVOID); + break; + } + break; + } + + case CSS_PROP_PAGE_BREAK_AFTER: + { + HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(pageBreakAfter, PageBreakAfter, PageBreak) + if (!primitiveValue) return; + switch (primitiveValue->getIdent()) { + case CSS_VAL_AUTO: + style->setPageBreakAfter(PBAUTO); + break; + case CSS_VAL_LEFT: + case CSS_VAL_RIGHT: + // CSS2.1: "Conforming user agents may map left/right to always." + case CSS_VAL_ALWAYS: + style->setPageBreakAfter(PBALWAYS); + break; + case CSS_VAL_AVOID: + style->setPageBreakAfter(PBAVOID); + break; + } + break; + } + + case CSS_PROP_PAGE_BREAK_INSIDE: { + HANDLE_INHERIT_AND_INITIAL(pageBreakInside, PageBreakInside) + if (!primitiveValue) return; + if (primitiveValue->getIdent() == CSS_VAL_AUTO) + style->setPageBreakInside(true); + else if (primitiveValue->getIdent() == CSS_VAL_AVOID) + style->setPageBreakInside(false); + return; + } +// case CSS_PROP_PAUSE_AFTER: +// case CSS_PROP_PAUSE_BEFORE: + break; + + case CSS_PROP_POSITION: + { + HANDLE_INHERIT_AND_INITIAL(position, Position) + if (!primitiveValue) return; + EPosition p; + switch(primitiveValue->getIdent()) + { + case CSS_VAL_STATIC: + p = STATIC; break; + case CSS_VAL_RELATIVE: + p = RELATIVE; break; + case CSS_VAL_ABSOLUTE: + p = ABSOLUTE; break; + case CSS_VAL_FIXED: + { + view->useSlowRepaints(); + p = FIXED; + break; + } + default: + return; + } + style->setPosition(p); + return; + } + + case CSS_PROP_TABLE_LAYOUT: { + HANDLE_INHERIT_AND_INITIAL(tableLayout, TableLayout) + + if ( !primitiveValue ) + return; + + ETableLayout l = RenderStyle::initialTableLayout(); + switch( primitiveValue->getIdent() ) { + case CSS_VAL_FIXED: + l = TFIXED; + // fall through + case CSS_VAL_AUTO: + style->setTableLayout( l ); + default: + break; + } + break; + } + + case CSS_PROP_UNICODE_BIDI: { + HANDLE_INHERIT_AND_INITIAL(unicodeBidi, UnicodeBidi) + if(!primitiveValue) break; + switch (primitiveValue->getIdent()) { + case CSS_VAL_NORMAL: + style->setUnicodeBidi(UBNormal); + break; + case CSS_VAL_EMBED: + style->setUnicodeBidi(Embed); + break; + case CSS_VAL_BIDI_OVERRIDE: + style->setUnicodeBidi(Override); + break; + default: + return; + } + break; + } + case CSS_PROP_TEXT_TRANSFORM: { + HANDLE_INHERIT_AND_INITIAL(textTransform, TextTransform) + + if(!primitiveValue) break; + if(!primitiveValue->getIdent()) return; + + ETextTransform tt; + switch(primitiveValue->getIdent()) { + case CSS_VAL_CAPITALIZE: tt = CAPITALIZE; break; + case CSS_VAL_UPPERCASE: tt = UPPERCASE; break; + case CSS_VAL_LOWERCASE: tt = LOWERCASE; break; + case CSS_VAL_NONE: + default: tt = TTNONE; break; + } + style->setTextTransform(tt); + break; + } + + case CSS_PROP_VISIBILITY: + { + HANDLE_INHERIT_AND_INITIAL(visibility, Visibility) + + if(!primitiveValue) break; + switch( primitiveValue->getIdent() ) { + case CSS_VAL_HIDDEN: + style->setVisibility( HIDDEN ); + break; + case CSS_VAL_VISIBLE: + style->setVisibility( VISIBLE ); + break; + case CSS_VAL_COLLAPSE: + style->setVisibility( COLLAPSE ); + default: + break; + } + break; + } + case CSS_PROP_WHITE_SPACE: + HANDLE_INHERIT_AND_INITIAL(whiteSpace, WhiteSpace) + + if(!primitiveValue) break; + if(!primitiveValue->getIdent()) return; + + EWhiteSpace s; + switch(primitiveValue->getIdent()) { + case CSS_VAL__KHTML_NOWRAP: + s = KHTML_NOWRAP; + break; + case CSS_VAL_NOWRAP: + s = NOWRAP; + break; + case CSS_VAL_PRE: + s = PRE; + break; + case CSS_VAL_PRE_WRAP: + s = PRE_WRAP; + break; + case CSS_VAL_PRE_LINE: + s = PRE_LINE; + break; + case CSS_VAL_NORMAL: + default: + s = NORMAL; + break; + } + style->setWhiteSpace(s); + break; + + case CSS_PROP_BACKGROUND_POSITION: + HANDLE_BACKGROUND_INHERIT_AND_INITIAL(backgroundXPosition, BackgroundXPosition); + HANDLE_BACKGROUND_INHERIT_AND_INITIAL(backgroundYPosition, BackgroundYPosition); + break; + case CSS_PROP_BACKGROUND_POSITION_X: { + HANDLE_BACKGROUND_VALUE(backgroundXPosition, BackgroundXPosition, value) + break; + } + case CSS_PROP_BACKGROUND_POSITION_Y: { + HANDLE_BACKGROUND_VALUE(backgroundYPosition, BackgroundYPosition, value) + break; + } + case CSS_PROP_BORDER_SPACING: { + if(value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return; + style->setBorderHorizontalSpacing(parentStyle->borderHorizontalSpacing()); + style->setBorderVerticalSpacing(parentStyle->borderVerticalSpacing()); + break; + } + case CSS_PROP__KHTML_BORDER_HORIZONTAL_SPACING: { + HANDLE_INHERIT_AND_INITIAL(borderHorizontalSpacing, BorderHorizontalSpacing) + if (!primitiveValue) break; + short spacing = primitiveValue->computeLength(style, paintDeviceMetrics); + style->setBorderHorizontalSpacing(spacing); + break; + } + case CSS_PROP__KHTML_BORDER_VERTICAL_SPACING: { + HANDLE_INHERIT_AND_INITIAL(borderVerticalSpacing, BorderVerticalSpacing) + if (!primitiveValue) break; + short spacing = primitiveValue->computeLength(style, paintDeviceMetrics); + style->setBorderVerticalSpacing(spacing); + break; + } + + case CSS_PROP_CURSOR: + HANDLE_INHERIT_AND_INITIAL(cursor, Cursor) + if(primitiveValue) + style->setCursor( (ECursor) (primitiveValue->getIdent() - CSS_VAL_AUTO) ); + break; +// colors || inherit + case CSS_PROP_BACKGROUND_COLOR: + case CSS_PROP_BORDER_TOP_COLOR: + case CSS_PROP_BORDER_RIGHT_COLOR: + case CSS_PROP_BORDER_BOTTOM_COLOR: + case CSS_PROP_BORDER_LEFT_COLOR: + case CSS_PROP_COLOR: + case CSS_PROP_OUTLINE_COLOR: + // this property is an extension used to get HTML4 <font> right. + case CSS_PROP_SCROLLBAR_BASE_COLOR: + case CSS_PROP_SCROLLBAR_FACE_COLOR: + case CSS_PROP_SCROLLBAR_SHADOW_COLOR: + case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR: + case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR: + case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR: + case CSS_PROP_SCROLLBAR_TRACK_COLOR: + case CSS_PROP_SCROLLBAR_ARROW_COLOR: + { + QColor col; + if (isInherit) { + HANDLE_INHERIT_COND(CSS_PROP_BACKGROUND_COLOR, backgroundColor, BackgroundColor) + HANDLE_INHERIT_COND(CSS_PROP_BORDER_TOP_COLOR, borderTopColor, BorderTopColor) + HANDLE_INHERIT_COND(CSS_PROP_BORDER_BOTTOM_COLOR, borderBottomColor, BorderBottomColor) + HANDLE_INHERIT_COND(CSS_PROP_BORDER_RIGHT_COLOR, borderRightColor, BorderRightColor) + HANDLE_INHERIT_COND(CSS_PROP_BORDER_LEFT_COLOR, borderLeftColor, BorderLeftColor) + HANDLE_INHERIT_COND(CSS_PROP_COLOR, color, Color) + HANDLE_INHERIT_COND(CSS_PROP_OUTLINE_COLOR, outlineColor, OutlineColor) + return; + } else if (isInitial) { + // The border/outline colors will just map to the invalid color |col| above. This will have the + // effect of forcing the use of the currentColor when it comes time to draw the borders (and of + // not painting the background since the color won't be valid). + if (id == CSS_PROP_COLOR) + col = RenderStyle::initialColor(); + } else { + if(!primitiveValue ) + return; + int ident = primitiveValue->getIdent(); + if ( ident ) { + if ( ident == CSS_VAL__KHTML_TEXT ) + col = element->getDocument()->textColor(); + // ### should be eliminated + else if ( ident == CSS_VAL_TRANSPARENT + && id != CSS_PROP_BORDER_TOP_COLOR + && id != CSS_PROP_BORDER_RIGHT_COLOR + && id != CSS_PROP_BORDER_BOTTOM_COLOR + && id != CSS_PROP_BORDER_LEFT_COLOR ) + col = QColor(); + else + col = colorForCSSValue( ident ); + } else if ( primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_RGBCOLOR ) { +#ifndef APPLE_CHANGES + if(qAlpha(primitiveValue->getRGBColorValue())) +#endif + col.setRgb(primitiveValue->getRGBColorValue()); + } else { + return; + } + } + //kdDebug( 6080 ) << "applying color " << col.isValid() << endl; + switch(id) + { + case CSS_PROP_BACKGROUND_COLOR: + style->setBackgroundColor(col); break; + case CSS_PROP_BORDER_TOP_COLOR: + style->setBorderTopColor(col); break; + case CSS_PROP_BORDER_RIGHT_COLOR: + style->setBorderRightColor(col); break; + case CSS_PROP_BORDER_BOTTOM_COLOR: + style->setBorderBottomColor(col); break; + case CSS_PROP_BORDER_LEFT_COLOR: + style->setBorderLeftColor(col); break; + case CSS_PROP_COLOR: + style->setColor(col); break; + case CSS_PROP_OUTLINE_COLOR: + style->setOutlineColor(col); break; +#ifndef APPLE_CHANGES + case CSS_PROP_SCROLLBAR_FACE_COLOR: + style->setPaletteColor(QPalette::Active, QColorGroup::Button, col); + style->setPaletteColor(QPalette::Inactive, QColorGroup::Button, col); + break; + case CSS_PROP_SCROLLBAR_SHADOW_COLOR: + style->setPaletteColor(QPalette::Active, QColorGroup::Shadow, col); + style->setPaletteColor(QPalette::Inactive, QColorGroup::Shadow, col); + break; + case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR: + style->setPaletteColor(QPalette::Active, QColorGroup::Light, col); + style->setPaletteColor(QPalette::Inactive, QColorGroup::Light, col); + break; + case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR: + break; + case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR: + style->setPaletteColor(QPalette::Active, QColorGroup::Dark, col); + style->setPaletteColor(QPalette::Inactive, QColorGroup::Dark, col); + break; + case CSS_PROP_SCROLLBAR_TRACK_COLOR: + style->setPaletteColor(QPalette::Active, QColorGroup::Mid, col); + style->setPaletteColor(QPalette::Inactive, QColorGroup::Mid, col); + style->setPaletteColor(QPalette::Active, QColorGroup::Background, col); + style->setPaletteColor(QPalette::Inactive, QColorGroup::Background, col); + // fall through + case CSS_PROP_SCROLLBAR_BASE_COLOR: + style->setPaletteColor(QPalette::Active, QColorGroup::Base, col); + style->setPaletteColor(QPalette::Inactive, QColorGroup::Base, col); + break; + case CSS_PROP_SCROLLBAR_ARROW_COLOR: + style->setPaletteColor(QPalette::Active, QColorGroup::ButtonText, col); + style->setPaletteColor(QPalette::Inactive, QColorGroup::ButtonText, col); + break; +#endif + default: + return; + } + return; + } + break; +// uri || inherit + case CSS_PROP_BACKGROUND_IMAGE: + HANDLE_BACKGROUND_VALUE(backgroundImage, BackgroundImage, value) + break; + case CSS_PROP_LIST_STYLE_IMAGE: + { + HANDLE_INHERIT_AND_INITIAL(listStyleImage, ListStyleImage) + if (!primitiveValue) return; + style->setListStyleImage(static_cast<CSSImageValueImpl *>(primitiveValue)->image()); + //kdDebug( 6080 ) << "setting image in list to " << image->image() << endl; + break; + } + +// length + case CSS_PROP_BORDER_TOP_WIDTH: + case CSS_PROP_BORDER_RIGHT_WIDTH: + case CSS_PROP_BORDER_BOTTOM_WIDTH: + case CSS_PROP_BORDER_LEFT_WIDTH: + case CSS_PROP_OUTLINE_WIDTH: + { + if (isInherit) { + HANDLE_INHERIT_COND(CSS_PROP_BORDER_TOP_WIDTH, borderTopWidth, BorderTopWidth) + HANDLE_INHERIT_COND(CSS_PROP_BORDER_RIGHT_WIDTH, borderRightWidth, BorderRightWidth) + HANDLE_INHERIT_COND(CSS_PROP_BORDER_BOTTOM_WIDTH, borderBottomWidth, BorderBottomWidth) + HANDLE_INHERIT_COND(CSS_PROP_BORDER_LEFT_WIDTH, borderLeftWidth, BorderLeftWidth) + HANDLE_INHERIT_COND(CSS_PROP_OUTLINE_WIDTH, outlineWidth, OutlineWidth) + return; + } + else if (isInitial) { + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_TOP_WIDTH, BorderTopWidth, BorderWidth) + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_RIGHT_WIDTH, BorderRightWidth, BorderWidth) + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_BOTTOM_WIDTH, BorderBottomWidth, BorderWidth) + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_LEFT_WIDTH, BorderLeftWidth, BorderWidth) + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_OUTLINE_WIDTH, OutlineWidth, BorderWidth) + return; + } + + if(!primitiveValue) break; + short width = 3; + switch(primitiveValue->getIdent()) + { + case CSS_VAL_THIN: + width = 1; + break; + case CSS_VAL_MEDIUM: + width = 3; + break; + case CSS_VAL_THICK: + width = 5; + break; + case CSS_VAL_INVALID: + { + double widthd = primitiveValue->computeLengthFloat(style, paintDeviceMetrics); + width = (int)widthd; + // somewhat resemble Mozilla's granularity + // this makes border-width: 0.5pt borders visible + if (width == 0 && widthd >= 0.025) width++; + break; + } + default: + return; + } + + if(width < 0) return; + switch(id) + { + case CSS_PROP_BORDER_TOP_WIDTH: + style->setBorderTopWidth(width); + break; + case CSS_PROP_BORDER_RIGHT_WIDTH: + style->setBorderRightWidth(width); + break; + case CSS_PROP_BORDER_BOTTOM_WIDTH: + style->setBorderBottomWidth(width); + break; + case CSS_PROP_BORDER_LEFT_WIDTH: + style->setBorderLeftWidth(width); + break; + case CSS_PROP_OUTLINE_WIDTH: + style->setOutlineWidth(width); + break; + default: + return; + } + return; + } + + case CSS_PROP_LETTER_SPACING: + case CSS_PROP_WORD_SPACING: + { + if (isInherit) { + HANDLE_INHERIT_COND(CSS_PROP_LETTER_SPACING, letterSpacing, LetterSpacing) + HANDLE_INHERIT_COND(CSS_PROP_WORD_SPACING, wordSpacing, WordSpacing) + return; + } else if (isInitial) { + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_LETTER_SPACING, LetterSpacing, LetterWordSpacing) + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_WORD_SPACING, WordSpacing, LetterWordSpacing) + return; + } + if(!primitiveValue) return; + + int width = 0; + if (primitiveValue->getIdent() != CSS_VAL_NORMAL) + width = primitiveValue->computeLength(style, paintDeviceMetrics); + + switch(id) + { + case CSS_PROP_LETTER_SPACING: + style->setLetterSpacing(width); + break; + case CSS_PROP_WORD_SPACING: + style->setWordSpacing(width); + break; + // ### needs the definitions in renderstyle + default: break; + } + return; + } + + // length, percent + case CSS_PROP_MAX_WIDTH: + // +none +inherit + if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE) { + apply = true; + l = Length(UNDEFINED, Fixed); + } + case CSS_PROP_TOP: + case CSS_PROP_LEFT: + case CSS_PROP_RIGHT: + case CSS_PROP_BOTTOM: + case CSS_PROP_WIDTH: + case CSS_PROP_MIN_WIDTH: + case CSS_PROP_MARGIN_TOP: + case CSS_PROP_MARGIN_RIGHT: + case CSS_PROP_MARGIN_BOTTOM: + case CSS_PROP_MARGIN_LEFT: + // +inherit +auto + if(id != CSS_PROP_MAX_WIDTH && primitiveValue && + primitiveValue->getIdent() == CSS_VAL_AUTO) + { + //kdDebug( 6080 ) << "found value=auto" << endl; + apply = true; + } + case CSS_PROP_PADDING_TOP: + case CSS_PROP_PADDING_RIGHT: + case CSS_PROP_PADDING_BOTTOM: + case CSS_PROP_PADDING_LEFT: + case CSS_PROP_TEXT_INDENT: + // +inherit + { + if (isInherit) { + HANDLE_INHERIT_COND(CSS_PROP_MAX_WIDTH, maxWidth, MaxWidth) + HANDLE_INHERIT_COND(CSS_PROP_BOTTOM, bottom, Bottom) + HANDLE_INHERIT_COND(CSS_PROP_TOP, top, Top) + HANDLE_INHERIT_COND(CSS_PROP_LEFT, left, Left) + HANDLE_INHERIT_COND(CSS_PROP_RIGHT, right, Right) + HANDLE_INHERIT_COND(CSS_PROP_WIDTH, width, Width) + HANDLE_INHERIT_COND(CSS_PROP_MIN_WIDTH, minWidth, MinWidth) + HANDLE_INHERIT_COND(CSS_PROP_PADDING_TOP, paddingTop, PaddingTop) + HANDLE_INHERIT_COND(CSS_PROP_PADDING_RIGHT, paddingRight, PaddingRight) + HANDLE_INHERIT_COND(CSS_PROP_PADDING_BOTTOM, paddingBottom, PaddingBottom) + HANDLE_INHERIT_COND(CSS_PROP_PADDING_LEFT, paddingLeft, PaddingLeft) + HANDLE_INHERIT_COND(CSS_PROP_MARGIN_TOP, marginTop, MarginTop) + HANDLE_INHERIT_COND(CSS_PROP_MARGIN_RIGHT, marginRight, MarginRight) + HANDLE_INHERIT_COND(CSS_PROP_MARGIN_BOTTOM, marginBottom, MarginBottom) + HANDLE_INHERIT_COND(CSS_PROP_MARGIN_LEFT, marginLeft, MarginLeft) + HANDLE_INHERIT_COND(CSS_PROP_TEXT_INDENT, textIndent, TextIndent) + return; + } else if (isInitial) { + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MAX_WIDTH, MaxWidth, MaxSize) + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BOTTOM, Bottom, Offset) + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_TOP, Top, Offset) + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_LEFT, Left, Offset) + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_RIGHT, Right, Offset) + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_WIDTH, Width, Size) + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MIN_WIDTH, MinWidth, MinSize) + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_TOP, PaddingTop, Padding) + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_RIGHT, PaddingRight, Padding) + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_BOTTOM, PaddingBottom, Padding) + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_LEFT, PaddingLeft, Padding) + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_TOP, MarginTop, Margin) + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_RIGHT, MarginRight, Margin) + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_BOTTOM, MarginBottom, Margin) + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_LEFT, MarginLeft, Margin) + HANDLE_INITIAL_COND(CSS_PROP_TEXT_INDENT, TextIndent) + return; + } + + if (primitiveValue && !apply) { + int type = primitiveValue->primitiveType(); + if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) + // Handle our quirky margin units if we have them. + l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed, + primitiveValue->isQuirkValue()); + else if(type == CSSPrimitiveValue::CSS_PERCENTAGE) + l = Length((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent); + else if (type == CSSPrimitiveValue::CSS_HTML_RELATIVE) + l = Length(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_HTML_RELATIVE)), Relative); + else + return; + apply = true; + } + if(!apply) return; + switch(id) + { + case CSS_PROP_MAX_WIDTH: + style->setMaxWidth(l); break; + case CSS_PROP_BOTTOM: + style->setBottom(l); break; + case CSS_PROP_TOP: + style->setTop(l); break; + case CSS_PROP_LEFT: + style->setLeft(l); break; + case CSS_PROP_RIGHT: + style->setRight(l); break; + case CSS_PROP_WIDTH: + style->setWidth(l); break; + case CSS_PROP_MIN_WIDTH: + style->setMinWidth(l); break; + case CSS_PROP_PADDING_TOP: + style->setPaddingTop(l); break; + case CSS_PROP_PADDING_RIGHT: + style->setPaddingRight(l); break; + case CSS_PROP_PADDING_BOTTOM: + style->setPaddingBottom(l); break; + case CSS_PROP_PADDING_LEFT: + style->setPaddingLeft(l); break; + case CSS_PROP_MARGIN_TOP: + style->setMarginTop(l); break; + case CSS_PROP_MARGIN_RIGHT: + style->setMarginRight(l); break; + case CSS_PROP_MARGIN_BOTTOM: + style->setMarginBottom(l); break; + case CSS_PROP_MARGIN_LEFT: + style->setMarginLeft(l); break; + case CSS_PROP_TEXT_INDENT: + style->setTextIndent(l); break; + default: break; + } + return; + } + + case CSS_PROP_MAX_HEIGHT: + if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE) { + apply = true; + l = Length(UNDEFINED, Fixed); + } + case CSS_PROP_HEIGHT: + case CSS_PROP_MIN_HEIGHT: + if(id != CSS_PROP_MAX_HEIGHT && primitiveValue && + primitiveValue->getIdent() == CSS_VAL_AUTO) + apply = true; + if (isInherit) { + HANDLE_INHERIT_COND(CSS_PROP_MAX_HEIGHT, maxHeight, MaxHeight) + HANDLE_INHERIT_COND(CSS_PROP_HEIGHT, height, Height) + HANDLE_INHERIT_COND(CSS_PROP_MIN_HEIGHT, minHeight, MinHeight) + return; + } + else if (isInitial) { + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MAX_HEIGHT, MaxHeight, MaxSize) + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_HEIGHT, Height, Size) + HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MIN_HEIGHT, MinHeight, MinSize) + return; + } + + if (primitiveValue && !apply) + { + int type = primitiveValue->primitiveType(); + if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) + l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed); + else if(type == CSSPrimitiveValue::CSS_PERCENTAGE) + l = Length((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent); + else + return; + apply = true; + } + if(!apply) return; + switch(id) + { + case CSS_PROP_MAX_HEIGHT: + style->setMaxHeight(l); break; + case CSS_PROP_HEIGHT: + style->setHeight(l); break; + case CSS_PROP_MIN_HEIGHT: + style->setMinHeight(l); break; + default: + return; + } + return; + + break; + + case CSS_PROP_VERTICAL_ALIGN: + HANDLE_INHERIT_AND_INITIAL(verticalAlign, VerticalAlign) + if (!primitiveValue) return; + if (primitiveValue->getIdent()) { + khtml::EVerticalAlign align; + + switch(primitiveValue->getIdent()) + { + case CSS_VAL_TOP: + align = TOP; break; + case CSS_VAL_BOTTOM: + align = BOTTOM; break; + case CSS_VAL_MIDDLE: + align = MIDDLE; break; + case CSS_VAL_BASELINE: + align = BASELINE; break; + case CSS_VAL_TEXT_BOTTOM: + align = TEXT_BOTTOM; break; + case CSS_VAL_TEXT_TOP: + align = TEXT_TOP; break; + case CSS_VAL_SUB: + align = SUB; break; + case CSS_VAL_SUPER: + align = SUPER; break; + case CSS_VAL__KHTML_BASELINE_MIDDLE: + align = BASELINE_MIDDLE; break; + default: + return; + } + style->setVerticalAlign(align); + return; + } else { + int type = primitiveValue->primitiveType(); + Length l; + if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) + l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed ); + else if(type == CSSPrimitiveValue::CSS_PERCENTAGE) + l = Length( int( primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE) ), Percent ); + + style->setVerticalAlign( LENGTH ); + style->setVerticalAlignLength( l ); + } + break; + + case CSS_PROP_FONT_SIZE: + { + FontDef fontDef = style->htmlFont().fontDef; + int oldSize; + int size = 0; + + float toPix = paintDeviceMetrics->logicalDpiY()/72.; + if (toPix < 96./72.) toPix = 96./72.; + + int minFontSize = int(settings->minFontSize() * toPix); + + if(parentNode) { + oldSize = parentStyle->font().pixelSize(); + } else + oldSize = m_fontSizes[3]; + + if (isInherit ) + size = oldSize; + else if (isInitial) + size = m_fontSizes[3]; + else if(primitiveValue->getIdent()) { + // keywords are being used. Pick the correct default + // based off the font family. +#ifdef APPLE_CHANGES + const QValueVector<int>& fontSizes = (fontDef.genericFamily == FontDef::eMonospace) ? + m_fixedFontSizes : m_fontSizes; +#else + const QValueVector<int>& fontSizes = m_fontSizes; +#endif + switch(primitiveValue->getIdent()) + { + case CSS_VAL_XX_SMALL: size = int( fontSizes[0] ); break; + case CSS_VAL_X_SMALL: size = int( fontSizes[1] ); break; + case CSS_VAL_SMALL: size = int( fontSizes[2] ); break; + case CSS_VAL_MEDIUM: size = int( fontSizes[3] ); break; + case CSS_VAL_LARGE: size = int( fontSizes[4] ); break; + case CSS_VAL_X_LARGE: size = int( fontSizes[5] ); break; + case CSS_VAL_XX_LARGE: size = int( fontSizes[6] ); break; + case CSS_VAL__KHTML_XXX_LARGE: size = int( fontSizes[7] ); break; + case CSS_VAL_LARGER: + size = nextFontSize(fontSizes, oldSize, false); + break; + case CSS_VAL_SMALLER: + size = nextFontSize(fontSizes, oldSize, true); + break; + default: + return; + } + + } else { + int type = primitiveValue->primitiveType(); + if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) { + if ( !khtml::printpainter && type != CSSPrimitiveValue::CSS_EMS && type != CSSPrimitiveValue::CSS_EXS && + view && view->part()) + size = int( primitiveValue->computeLengthFloat(parentStyle, paintDeviceMetrics) * + view->part()->zoomFactor() ) / 100; + else + size = int( primitiveValue->computeLengthFloat(parentStyle, paintDeviceMetrics) ); + } + else if(type == CSSPrimitiveValue::CSS_PERCENTAGE) + size = int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE) + * parentStyle->font().pixelSize()) / 100; + else + return; + } + + if (size < 0) return; + + // we never want to get smaller than the minimum font size to keep fonts readable + // do not however maximize zero as that is commonly used for fancy layouting purposes + if (size && size < minFontSize) size = minFontSize; + + //kdDebug( 6080 ) << "computed raw font size: " << size << endl; + + fontDef.size = size; + fontDirty |= style->setFontDef( fontDef ); + return; + } + + case CSS_PROP_Z_INDEX: + { + HANDLE_INHERIT(zIndex, ZIndex) + else if (isInitial) { + style->setHasAutoZIndex(); + return; + } + + if (!primitiveValue) + return; + + if (primitiveValue->getIdent() == CSS_VAL_AUTO) { + style->setHasAutoZIndex(); + return; + } + + if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER) + return; // Error case. + + style->setZIndex((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER)); + return; + } + + case CSS_PROP_WIDOWS: + { + HANDLE_INHERIT_AND_INITIAL(widows, Widows) + if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER) + return; + style->setWidows((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER)); + break; + } + + case CSS_PROP_ORPHANS: + { + HANDLE_INHERIT_AND_INITIAL(orphans, Orphans) + if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER) + return; + style->setOrphans((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER)); + break; + } + +// length, percent, number + case CSS_PROP_LINE_HEIGHT: + { + HANDLE_INHERIT_AND_INITIAL(lineHeight, LineHeight) + if(!primitiveValue) return; + Length lineHeight; + int type = primitiveValue->primitiveType(); + if (primitiveValue->getIdent() == CSS_VAL_NORMAL) + lineHeight = Length( -100, Percent ); + else if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) { + // Scale for the font zoom factor only for types other than "em" and "ex", since those are + // already based on the font size. + if ( !khtml::printpainter && type != CSSPrimitiveValue::CSS_EMS && type != CSSPrimitiveValue::CSS_EXS && + view && view->part()) + lineHeight = Length(primitiveValue->computeLength(style, paintDeviceMetrics) * + view->part()->zoomFactor()/100, Fixed ); + else + lineHeight = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed ); + } else if (type == CSSPrimitiveValue::CSS_PERCENTAGE) + lineHeight = Length( ( style->font().pixelSize() * int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE)) ) / 100, Fixed ); + else if (type == CSSPrimitiveValue::CSS_NUMBER) + lineHeight = Length(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER)*100), Percent); + else + return; + style->setLineHeight(lineHeight); + return; + } + +// string + case CSS_PROP_TEXT_ALIGN: + { + HANDLE_INHERIT_AND_INITIAL(textAlign, TextAlign) + if (!primitiveValue) return; + if (primitiveValue->getIdent()) + style->setTextAlign( (ETextAlign) (primitiveValue->getIdent() - CSS_VAL__KHTML_AUTO) ); + return; + } + +// rect + case CSS_PROP_CLIP: + { + Length top = Length(); + Length right = Length(); + Length bottom = Length(); + Length left = Length(); + + bool hasClip = false; + + if (isInherit && parentStyle->hasClip()) { + hasClip = true; + top = parentStyle->clipTop(); + right = parentStyle->clipRight(); + bottom = parentStyle->clipBottom(); + left = parentStyle->clipLeft(); + } else if (primitiveValue && primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_RECT) { + RectImpl *rect = primitiveValue->getRectValue(); + if (rect) { + hasClip = true; + top = convertToLength( rect->top(), style, paintDeviceMetrics ); + right = convertToLength( rect->right(), style, paintDeviceMetrics ); + bottom = convertToLength( rect->bottom(), style, paintDeviceMetrics ); + left = convertToLength( rect->left(), style, paintDeviceMetrics ); + } + } + + style->setClip(top, right, bottom, left); + style->setHasClip(hasClip); + + // rect, ident + break; + } + +// lists + case CSS_PROP_CONTENT: + // list of string, uri, counter, attr, i + { + // FIXME: In CSS3, it will be possible to inherit content. In CSS2 it is not. This + // note is a reminder that eventually "inherit" needs to be supported. + + // not allowed on non-generated pseudo-elements: + if ( style->styleType()==RenderStyle::FIRST_LETTER || + style->styleType()==RenderStyle::FIRST_LINE || + style->styleType()==RenderStyle::SELECTION ) + break; + + if (isInitial) { + style->setContentNormal(); + return; + } + + if (primitiveValue && primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_IDENT) { + // normal | none + if (primitiveValue->getIdent() == CSS_VAL_NORMAL) + style->setContentNormal(); + else + if (primitiveValue->getIdent() == CSS_VAL_NONE) + style->setContentNone(); + else + assert(false); + return; + } + + if(!value->isValueList()) return; + CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value); + int len = list->length(); + + style->setContentNormal(); // clear the content + + for(int i = 0; i < len; i++) { + CSSValueImpl *item = list->item(i); + if(!item->isPrimitiveValue()) continue; + CSSPrimitiveValueImpl *val = static_cast<CSSPrimitiveValueImpl *>(item); + if(val->primitiveType()==CSSPrimitiveValue::CSS_STRING) + { + style->addContent(val->getStringValue()); + } + else if (val->primitiveType()==CSSPrimitiveValue::CSS_ATTR) + { + // TODO: setup dynamic attribute dependencies + int attrID = element->getDocument()->getId(NodeImpl::AttributeId, val->getStringValue(), false, true); + if (attrID) + style->addContent(element->getAttribute(attrID).implementation()); + else + kdDebug(6080) << "Attribute \"" << val->getStringValue() << "\" not found" << endl; + } + else if (val->primitiveType()==CSSPrimitiveValue::CSS_URI) + { + CSSImageValueImpl *image = static_cast<CSSImageValueImpl *>(val); + style->addContent(image->image()); + } + else if (val->primitiveType()==CSSPrimitiveValue::CSS_COUNTER) + { + style->addContent(val->getCounterValue()); + } + else if (val->primitiveType()==CSSPrimitiveValue::CSS_IDENT) + { + EQuoteContent quote; + switch (val->getIdent()) { + case CSS_VAL_OPEN_QUOTE: + quote = OPEN_QUOTE; + break; + case CSS_VAL_NO_OPEN_QUOTE: + quote = NO_OPEN_QUOTE; + break; + case CSS_VAL_CLOSE_QUOTE: + quote = CLOSE_QUOTE; + break; + case CSS_VAL_NO_CLOSE_QUOTE: + quote = NO_CLOSE_QUOTE; + break; + default: + assert(false); + } + style->addContent(quote); + } else + kdDebug(6080) << "Unrecognized CSS content" << endl; + + } + break; + } + + case CSS_PROP_COUNTER_INCREMENT: { + if(!value->isValueList()) return; + + CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value); + style->setCounterIncrement(list); + break; + } + case CSS_PROP_COUNTER_RESET: { + if(!value->isValueList()) return; + + CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value); + style->setCounterReset(list); + break; + } + case CSS_PROP_FONT_FAMILY: + // list of strings and ids + { + if (isInherit) { + FontDef parentFontDef = parentStyle->htmlFont().fontDef; + FontDef fontDef = style->htmlFont().fontDef; + fontDef.family = parentFontDef.family; + if (style->setFontDef(fontDef)) + fontDirty = true; + return; + } + else if (isInitial) { + FontDef fontDef = style->htmlFont().fontDef; + FontDef initialDef = FontDef(); +#ifdef APPLE_CHANGES + fontDef.family = initialDef.firstFamily(); +#else + fontDef.family = QString::null; +#endif + if (style->setFontDef(fontDef)) + fontDirty = true; + return; + } + if(!value->isValueList()) return; + FontDef fontDef = style->htmlFont().fontDef; + CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value); + int len = list->length(); + for(int i = 0; i < len; i++) { + CSSValueImpl *item = list->item(i); + if(!item->isPrimitiveValue()) continue; + CSSPrimitiveValueImpl *val = static_cast<CSSPrimitiveValueImpl *>(item); + QString face; + if( val->primitiveType() == CSSPrimitiveValue::CSS_STRING ) + face = static_cast<FontFamilyValueImpl *>(val)->fontName(); + else if ( val->primitiveType() == CSSPrimitiveValue::CSS_IDENT ) { + switch( val->getIdent() ) { + case CSS_VAL_SERIF: + face = settings->serifFontName(); + break; + case CSS_VAL_SANS_SERIF: + face = settings->sansSerifFontName(); + break; + case CSS_VAL_CURSIVE: + face = settings->cursiveFontName(); + break; + case CSS_VAL_FANTASY: + face = settings->fantasyFontName(); + break; + case CSS_VAL_MONOSPACE: + face = settings->fixedFontName(); + break; + default: + return; + } + } else { + return; + } + if ( !face.isEmpty() ) { + fontDef.family = face; + fontDirty |= style->setFontDef( fontDef ); + return; + } + } + break; + } + case CSS_PROP_QUOTES: + HANDLE_INHERIT_AND_INITIAL(quotes, Quotes) + if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE) { + // set a set of empty quotes + QuotesValueImpl* quotes = new QuotesValueImpl(); + style->setQuotes(quotes); + } else { + QuotesValueImpl* quotes = static_cast<QuotesValueImpl *>(value); + style->setQuotes(quotes); + } + break; + case CSS_PROP_SIZE: + // ### look up + break; + case CSS_PROP_TEXT_DECORATION: { + // list of ident + HANDLE_INHERIT_AND_INITIAL(textDecoration, TextDecoration) + int t = RenderStyle::initialTextDecoration(); + if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE) { + // do nothing + } else { + if(!value->isValueList()) return; + CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value); + int len = list->length(); + for(int i = 0; i < len; i++) + { + CSSValueImpl *item = list->item(i); + if(!item->isPrimitiveValue()) continue; + primitiveValue = static_cast<CSSPrimitiveValueImpl *>(item); + switch(primitiveValue->getIdent()) + { + case CSS_VAL_NONE: + t = TDNONE; break; + case CSS_VAL_UNDERLINE: + t |= UNDERLINE; break; + case CSS_VAL_OVERLINE: + t |= OVERLINE; break; + case CSS_VAL_LINE_THROUGH: + t |= LINE_THROUGH; break; + case CSS_VAL_BLINK: + t |= BLINK; break; + default: + return; + } + } + } + style->setTextDecoration(t); + break; + } + case CSS_PROP__KHTML_FLOW_MODE: + HANDLE_INHERIT_AND_INITIAL(flowAroundFloats, FlowAroundFloats) + if (!primitiveValue) return; + if (primitiveValue->getIdent()) { + style->setFlowAroundFloats( primitiveValue->getIdent() == CSS_VAL__KHTML_AROUND_FLOATS ); + return; + } + break; + case CSS_PROP__KHTML_USER_INPUT: { + if(value->cssValueType() == CSSValue::CSS_INHERIT) + { + if(!parentNode) return; + style->setUserInput(parentStyle->userInput()); +// kdDebug() << "UI erm" << endl; + return; + } + if(!primitiveValue) return; + int id = primitiveValue->getIdent(); + if (id == CSS_VAL_NONE) + style->setUserInput(UI_NONE); + else + style->setUserInput(EUserInput(id - CSS_VAL_ENABLED)); +// kdDebug(6080) << "userInput: " << style->userEdit() << endl; + return; + } + +// shorthand properties + case CSS_PROP_BACKGROUND: + if (isInitial) { + style->clearBackgroundLayers(); + return; + } + else if (isInherit) { + if (parentStyle) + style->inheritBackgroundLayers(*parentStyle->backgroundLayers()); + else + style->clearBackgroundLayers(); + return; + } + break; + case CSS_PROP_BORDER: + case CSS_PROP_BORDER_STYLE: + case CSS_PROP_BORDER_WIDTH: + case CSS_PROP_BORDER_COLOR: + if(id == CSS_PROP_BORDER || id == CSS_PROP_BORDER_COLOR) + { + if (isInherit) { + style->setBorderTopColor(parentStyle->borderTopColor()); + style->setBorderBottomColor(parentStyle->borderBottomColor()); + style->setBorderLeftColor(parentStyle->borderLeftColor()); + style->setBorderRightColor(parentStyle->borderRightColor()); + } + else if (isInitial) { + style->setBorderTopColor(QColor()); // Reset to invalid color so currentColor is used instead. + style->setBorderBottomColor(QColor()); + style->setBorderLeftColor(QColor()); + style->setBorderRightColor(QColor()); + } + } + if (id == CSS_PROP_BORDER || id == CSS_PROP_BORDER_STYLE) + { + if (isInherit) { + style->setBorderTopStyle(parentStyle->borderTopStyle()); + style->setBorderBottomStyle(parentStyle->borderBottomStyle()); + style->setBorderLeftStyle(parentStyle->borderLeftStyle()); + style->setBorderRightStyle(parentStyle->borderRightStyle()); + } + else if (isInitial) { + style->setBorderTopStyle(RenderStyle::initialBorderStyle()); + style->setBorderBottomStyle(RenderStyle::initialBorderStyle()); + style->setBorderLeftStyle(RenderStyle::initialBorderStyle()); + style->setBorderRightStyle(RenderStyle::initialBorderStyle()); + } + } + if (id == CSS_PROP_BORDER || id == CSS_PROP_BORDER_WIDTH) + { + if (isInherit) { + style->setBorderTopWidth(parentStyle->borderTopWidth()); + style->setBorderBottomWidth(parentStyle->borderBottomWidth()); + style->setBorderLeftWidth(parentStyle->borderLeftWidth()); + style->setBorderRightWidth(parentStyle->borderRightWidth()); + } + else if (isInitial) { + style->setBorderTopWidth(RenderStyle::initialBorderWidth()); + style->setBorderBottomWidth(RenderStyle::initialBorderWidth()); + style->setBorderLeftWidth(RenderStyle::initialBorderWidth()); + style->setBorderRightWidth(RenderStyle::initialBorderWidth()); + } + } + return; + case CSS_PROP_BORDER_TOP: + if ( isInherit ) { + style->setBorderTopColor(parentStyle->borderTopColor()); + style->setBorderTopStyle(parentStyle->borderTopStyle()); + style->setBorderTopWidth(parentStyle->borderTopWidth()); + } else if (isInitial) + style->resetBorderTop(); + return; + case CSS_PROP_BORDER_RIGHT: + if (isInherit) { + style->setBorderRightColor(parentStyle->borderRightColor()); + style->setBorderRightStyle(parentStyle->borderRightStyle()); + style->setBorderRightWidth(parentStyle->borderRightWidth()); + } + else if (isInitial) + style->resetBorderRight(); + return; + case CSS_PROP_BORDER_BOTTOM: + if (isInherit) { + style->setBorderBottomColor(parentStyle->borderBottomColor()); + style->setBorderBottomStyle(parentStyle->borderBottomStyle()); + style->setBorderBottomWidth(parentStyle->borderBottomWidth()); + } + else if (isInitial) + style->resetBorderBottom(); + return; + case CSS_PROP_BORDER_LEFT: + if (isInherit) { + style->setBorderLeftColor(parentStyle->borderLeftColor()); + style->setBorderLeftStyle(parentStyle->borderLeftStyle()); + style->setBorderLeftWidth(parentStyle->borderLeftWidth()); + } + else if (isInitial) + style->resetBorderLeft(); + return; + case CSS_PROP_MARGIN: + if (isInherit) { + style->setMarginTop(parentStyle->marginTop()); + style->setMarginBottom(parentStyle->marginBottom()); + style->setMarginLeft(parentStyle->marginLeft()); + style->setMarginRight(parentStyle->marginRight()); + } + else if (isInitial) + style->resetMargin(); + return; + case CSS_PROP_PADDING: + if (isInherit) { + style->setPaddingTop(parentStyle->paddingTop()); + style->setPaddingBottom(parentStyle->paddingBottom()); + style->setPaddingLeft(parentStyle->paddingLeft()); + style->setPaddingRight(parentStyle->paddingRight()); + } + else if (isInitial) + style->resetPadding(); + return; + case CSS_PROP_FONT: + if ( isInherit ) { + FontDef fontDef = parentStyle->htmlFont().fontDef; + style->setLineHeight( parentStyle->lineHeight() ); + fontDirty |= style->setFontDef( fontDef ); + } else if (isInitial) { + FontDef fontDef; + style->setLineHeight(RenderStyle::initialLineHeight()); + if (style->setFontDef( fontDef )) + fontDirty = true; + } else if ( value->isFontValue() ) { + FontValueImpl *font = static_cast<FontValueImpl *>(value); + if ( !font->style || !font->variant || !font->weight || + !font->size || !font->lineHeight || !font->family ) + return; + applyRule( CSS_PROP_FONT_STYLE, font->style ); + applyRule( CSS_PROP_FONT_VARIANT, font->variant ); + applyRule( CSS_PROP_FONT_WEIGHT, font->weight ); + applyRule( CSS_PROP_FONT_SIZE, font->size ); + + // Line-height can depend on font().pixelSize(), so we have to update the font + // before we evaluate line-height, e.g., font: 1em/1em. FIXME: Still not + // good enough: style="font:1em/1em; font-size:36px" should have a line-height of 36px. + if (fontDirty) + CSSStyleSelector::style->htmlFont().update( paintDeviceMetrics ); + + applyRule( CSS_PROP_LINE_HEIGHT, font->lineHeight ); + applyRule( CSS_PROP_FONT_FAMILY, font->family ); + } + return; + + case CSS_PROP_LIST_STYLE: + if (isInherit) { + style->setListStyleType(parentStyle->listStyleType()); + style->setListStyleImage(parentStyle->listStyleImage()); + style->setListStylePosition(parentStyle->listStylePosition()); + } + else if (isInitial) { + style->setListStyleType(RenderStyle::initialListStyleType()); + style->setListStyleImage(RenderStyle::initialListStyleImage()); + style->setListStylePosition(RenderStyle::initialListStylePosition()); + } + break; + case CSS_PROP_OUTLINE: + if (isInherit) { + style->setOutlineWidth(parentStyle->outlineWidth()); + style->setOutlineColor(parentStyle->outlineColor()); + style->setOutlineStyle(parentStyle->outlineStyle()); + } + else if (isInitial) + style->resetOutline(); + break; + /* CSS3 properties */ + case CSS_PROP_BOX_SIZING: + HANDLE_INHERIT(boxSizing, BoxSizing) + if (!primitiveValue) return; + if (primitiveValue->getIdent() == CSS_VAL_CONTENT_BOX) + style->setBoxSizing(CONTENT_BOX); + else + if (primitiveValue->getIdent() == CSS_VAL_BORDER_BOX) + style->setBoxSizing(BORDER_BOX); + break; + case CSS_PROP_OUTLINE_OFFSET: { + HANDLE_INHERIT_AND_INITIAL(outlineOffset, OutlineOffset) + + int offset = primitiveValue->computeLength(style, paintDeviceMetrics); + if (offset < 0) return; + + style->setOutlineOffset(offset); + break; + } + case CSS_PROP_TEXT_SHADOW: { + if (isInherit) { + style->setTextShadow(parentStyle->textShadow() ? new ShadowData(*parentStyle->textShadow()) : 0); + return; + } + else if (isInitial) { + style->setTextShadow(0); + return; + } + + if (primitiveValue) { // none + style->setTextShadow(0); + return; + } + + if (!value->isValueList()) return; + CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value); + int len = list->length(); + for (int i = 0; i < len; i++) { + ShadowValueImpl *item = static_cast<ShadowValueImpl*>(list->item(i)); + + int x = item->x->computeLength(style, paintDeviceMetrics); + int y = item->y->computeLength(style, paintDeviceMetrics); + int blur = item->blur ? item->blur->computeLength(style, paintDeviceMetrics) : 0; + QColor col = khtml::transparentColor; + if (item->color) { + int ident = item->color->getIdent(); + if (ident) + col = colorForCSSValue( ident ); + else if (item->color->primitiveType() == CSSPrimitiveValue::CSS_RGBCOLOR) + col.setRgb(item->color->getRGBColorValue()); + } + ShadowData* shadowData = new ShadowData(x, y, blur, col); + style->setTextShadow(shadowData, i != 0); + } + + break; + } + case CSS_PROP_OPACITY: + HANDLE_INHERIT_AND_INITIAL(opacity, Opacity) + if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER) + return; // Error case. + + // Clamp opacity to the range 0-1 + style->setOpacity(kMin(1.0f, kMax(0.0f, (float)primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER)))); + break; + case CSS_PROP__KHTML_MARQUEE: + if (value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return; + style->setMarqueeDirection(parentStyle->marqueeDirection()); + style->setMarqueeIncrement(parentStyle->marqueeIncrement()); + style->setMarqueeSpeed(parentStyle->marqueeSpeed()); + style->setMarqueeLoopCount(parentStyle->marqueeLoopCount()); + style->setMarqueeBehavior(parentStyle->marqueeBehavior()); + break; + case CSS_PROP__KHTML_MARQUEE_REPETITION: { + HANDLE_INHERIT_AND_INITIAL(marqueeLoopCount, MarqueeLoopCount) + if (!primitiveValue) return; + if (primitiveValue->getIdent() == CSS_VAL_INFINITE) + style->setMarqueeLoopCount(-1); // -1 means repeat forever. + else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) + style->setMarqueeLoopCount((int)(primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER))); + break; + } + case CSS_PROP__KHTML_MARQUEE_SPEED: { + HANDLE_INHERIT_AND_INITIAL(marqueeSpeed, MarqueeSpeed) + if (!primitiveValue) return; + if (primitiveValue->getIdent()) { + switch (primitiveValue->getIdent()) + { + case CSS_VAL_SLOW: + style->setMarqueeSpeed(500); // 500 msec. + break; + case CSS_VAL_NORMAL: + style->setMarqueeSpeed(85); // 85msec. The WinIE default. + break; + case CSS_VAL_FAST: + style->setMarqueeSpeed(10); // 10msec. Super fast. + break; + } + } + else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_S) + style->setMarqueeSpeed(int(1000*primitiveValue->floatValue(CSSPrimitiveValue::CSS_S))); + else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_MS) + style->setMarqueeSpeed(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_MS))); + else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) // For scrollamount support. + style->setMarqueeSpeed(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER))); + break; + } + case CSS_PROP__KHTML_MARQUEE_INCREMENT: { + HANDLE_INHERIT_AND_INITIAL(marqueeIncrement, MarqueeIncrement) + if (!primitiveValue) return; + if (primitiveValue->getIdent()) { + switch (primitiveValue->getIdent()) + { + case CSS_VAL_SMALL: + style->setMarqueeIncrement(Length(1, Fixed)); // 1px. + break; + case CSS_VAL_NORMAL: + style->setMarqueeIncrement(Length(6, Fixed)); // 6px. The WinIE default. + break; + case CSS_VAL_LARGE: + style->setMarqueeIncrement(Length(36, Fixed)); // 36px. + break; + } + } + else { + bool ok = true; + Length l = convertToLength(primitiveValue, style, paintDeviceMetrics, &ok); + if (ok) + style->setMarqueeIncrement(l); + } + break; + } + case CSS_PROP__KHTML_MARQUEE_STYLE: { + HANDLE_INHERIT_AND_INITIAL(marqueeBehavior, MarqueeBehavior) + if (!primitiveValue || !primitiveValue->getIdent()) return; + switch (primitiveValue->getIdent()) + { + case CSS_VAL_NONE: + style->setMarqueeBehavior(MNONE); + break; + case CSS_VAL_SCROLL: + style->setMarqueeBehavior(MSCROLL); + break; + case CSS_VAL_SLIDE: + style->setMarqueeBehavior(MSLIDE); + break; + case CSS_VAL_ALTERNATE: + style->setMarqueeBehavior(MALTERNATE); + break; + case CSS_VAL_UNFURL: + style->setMarqueeBehavior(MUNFURL); + break; + } + break; + } + case CSS_PROP__KHTML_MARQUEE_DIRECTION: { + HANDLE_INHERIT_AND_INITIAL(marqueeDirection, MarqueeDirection) + if (!primitiveValue || !primitiveValue->getIdent()) return; + switch (primitiveValue->getIdent()) + { + case CSS_VAL_FORWARDS: + style->setMarqueeDirection(MFORWARD); + break; + case CSS_VAL_BACKWARDS: + style->setMarqueeDirection(MBACKWARD); + break; + case CSS_VAL_AUTO: + style->setMarqueeDirection(MAUTO); + break; + case CSS_VAL_AHEAD: + case CSS_VAL_UP: // We don't support vertical languages, so AHEAD just maps to UP. + style->setMarqueeDirection(MUP); + break; + case CSS_VAL_REVERSE: + case CSS_VAL_DOWN: // REVERSE just maps to DOWN, since we don't do vertical text. + style->setMarqueeDirection(MDOWN); + break; + case CSS_VAL_LEFT: + style->setMarqueeDirection(MLEFT); + break; + case CSS_VAL_RIGHT: + style->setMarqueeDirection(MRIGHT); + break; + } + break; + case CSS_PROP_TEXT_OVERFLOW: { + // This property is supported by WinIE, and so we leave off the "-khtml-" in order to + // work with WinIE-specific pages that use the property. + HANDLE_INHERIT_AND_INITIAL(textOverflow, TextOverflow) + if (!primitiveValue || !primitiveValue->getIdent()) + return; + style->setTextOverflow(primitiveValue->getIdent() == CSS_VAL_ELLIPSIS); + break; + } + } + default: + return; + } +} + +void CSSStyleSelector::mapBackgroundAttachment(BackgroundLayer* layer, DOM::CSSValueImpl* value) +{ + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + layer->setBackgroundAttachment(RenderStyle::initialBackgroundAttachment()); + return; + } + + if (!value->isPrimitiveValue()) return; + CSSPrimitiveValueImpl* primitiveValue = static_cast<CSSPrimitiveValueImpl*>(value); + switch (primitiveValue->getIdent()) { + case CSS_VAL_FIXED: + layer->setBackgroundAttachment(false); + break; + case CSS_VAL_SCROLL: + layer->setBackgroundAttachment(true); + break; + default: + return; + } +} + +void CSSStyleSelector::mapBackgroundClip(BackgroundLayer* layer, CSSValueImpl* value) +{ + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + layer->setBackgroundClip(RenderStyle::initialBackgroundClip()); + return; + } + + if (!value->isPrimitiveValue()) return; + CSSPrimitiveValueImpl* primitiveValue = static_cast<CSSPrimitiveValueImpl*>(value); + switch (primitiveValue->getIdent()) { + case CSS_VAL_BORDER: + layer->setBackgroundClip(BGBORDER); + break; + case CSS_VAL_PADDING: + layer->setBackgroundClip(BGPADDING); + break; + default: // CSS_VAL_CONTENT + layer->setBackgroundClip(BGCONTENT); + break; + } +} + +void CSSStyleSelector::mapBackgroundOrigin(BackgroundLayer* layer, CSSValueImpl* value) +{ + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + layer->setBackgroundOrigin(RenderStyle::initialBackgroundOrigin()); + return; + } + + if (!value->isPrimitiveValue()) return; + CSSPrimitiveValueImpl* primitiveValue = static_cast<CSSPrimitiveValueImpl*>(value); + switch (primitiveValue->getIdent()) { + case CSS_VAL_BORDER: + layer->setBackgroundOrigin(BGBORDER); + break; + case CSS_VAL_PADDING: + layer->setBackgroundOrigin(BGPADDING); + break; + default: // CSS_VAL_CONTENT + layer->setBackgroundOrigin(BGCONTENT); + break; + } +} + +void CSSStyleSelector::mapBackgroundImage(BackgroundLayer* layer, DOM::CSSValueImpl* value) +{ + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + layer->setBackgroundImage(RenderStyle::initialBackgroundImage()); + return; + } + + if (!value->isPrimitiveValue()) return; + CSSPrimitiveValueImpl* primitiveValue = static_cast<CSSPrimitiveValueImpl*>(value); + layer->setBackgroundImage(static_cast<CSSImageValueImpl *>(primitiveValue)->image()); +} + +void CSSStyleSelector::mapBackgroundRepeat(BackgroundLayer* layer, DOM::CSSValueImpl* value) +{ + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + layer->setBackgroundRepeat(RenderStyle::initialBackgroundRepeat()); + return; + } + + if (!value->isPrimitiveValue()) return; + CSSPrimitiveValueImpl* primitiveValue = static_cast<CSSPrimitiveValueImpl*>(value); + switch(primitiveValue->getIdent()) { + case CSS_VAL_REPEAT: + layer->setBackgroundRepeat(REPEAT); + break; + case CSS_VAL_REPEAT_X: + layer->setBackgroundRepeat(REPEAT_X); + break; + case CSS_VAL_REPEAT_Y: + layer->setBackgroundRepeat(REPEAT_Y); + break; + case CSS_VAL_NO_REPEAT: + layer->setBackgroundRepeat(NO_REPEAT); + break; + default: + return; + } +} + + +void CSSStyleSelector::mapBackgroundSize(BackgroundLayer* layer, CSSValueImpl* value) +{ + LengthSize b = RenderStyle::initialBackgroundSize(); + + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + layer->setBackgroundSize(b); + return; + } + + if (!value->isPrimitiveValue()) + return; + + CSSPrimitiveValueImpl* primitiveValue = static_cast<CSSPrimitiveValueImpl*>(value); + PairImpl* pair = primitiveValue->getPairValue(); + if (!pair) + return; + + CSSPrimitiveValueImpl* first = static_cast<CSSPrimitiveValueImpl*>(pair->first()); + CSSPrimitiveValueImpl* second = static_cast<CSSPrimitiveValueImpl*>(pair->second()); + + if (!first || !second) + return; + + Length firstLength, secondLength; + int firstType = first->primitiveType(); + int secondType = second->primitiveType(); + + if (firstType == CSSPrimitiveValue::CSS_UNKNOWN) + firstLength = Length(Variable); + else if (firstType > CSSPrimitiveValue::CSS_PERCENTAGE && firstType < CSSPrimitiveValue::CSS_DEG) + firstLength = Length(first->computeLength(style, paintDeviceMetrics), Fixed); + else if (firstType == CSSPrimitiveValue::CSS_PERCENTAGE) + firstLength = Length((int)first->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent); + else + return; + + if (secondType == CSSPrimitiveValue::CSS_UNKNOWN) + secondLength = Length(Variable); + else if (secondType > CSSPrimitiveValue::CSS_PERCENTAGE && secondType < CSSPrimitiveValue::CSS_DEG) + secondLength = Length(second->computeLength(style, paintDeviceMetrics), Fixed); + else if (secondType == CSSPrimitiveValue::CSS_PERCENTAGE) + secondLength = Length((int)second->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent); + else + return; + + b.width = firstLength; + b.height = secondLength; + layer->setBackgroundSize(b); +} + +void CSSStyleSelector::mapBackgroundXPosition(BackgroundLayer* layer, DOM::CSSValueImpl* value) +{ + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + layer->setBackgroundXPosition(RenderStyle::initialBackgroundXPosition()); + return; + } + + if (!value->isPrimitiveValue()) return; + CSSPrimitiveValueImpl* primitiveValue = static_cast<CSSPrimitiveValueImpl*>(value); + Length l; + int type = primitiveValue->primitiveType(); + if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) + l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed); + else if(type == CSSPrimitiveValue::CSS_PERCENTAGE) + l = Length((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent); + else + return; + layer->setBackgroundXPosition(l); +} + +void CSSStyleSelector::mapBackgroundYPosition(BackgroundLayer* layer, DOM::CSSValueImpl* value) +{ + if (value->cssValueType() == CSSValue::CSS_INITIAL) { + layer->setBackgroundYPosition(RenderStyle::initialBackgroundYPosition()); + return; + } + + if (!value->isPrimitiveValue()) return; + CSSPrimitiveValueImpl* primitiveValue = static_cast<CSSPrimitiveValueImpl*>(value); + Length l; + int type = primitiveValue->primitiveType(); + if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) + l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed); + else if(type == CSSPrimitiveValue::CSS_PERCENTAGE) + l = Length((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent); + else + return; + layer->setBackgroundYPosition(l); +} + +#ifdef APPLE_CHANGES +void CSSStyleSelector::checkForGenericFamilyChange(RenderStyle* aStyle, RenderStyle* aParentStyle) +{ + const FontDef& childFont = aStyle->htmlFont().fontDef; + + if (childFont.sizeSpecified || !aParentStyle) + return; + + const FontDef& parentFont = aParentStyle->htmlFont().fontDef; + + if (childFont.genericFamily == parentFont.genericFamily) + return; + + // For now, lump all families but monospace together. + if (childFont.genericFamily != FontDef::eMonospace && + parentFont.genericFamily != FontDef::eMonospace) + return; + + // We know the parent is monospace or the child is monospace, and that font + // size was unspecified. We want to alter our font size to use the correct + // "medium" font for our family. + float size = 0; + int minFontSize = settings->minFontSize(); + size = (childFont.genericFamily == FontDef::eMonospace) ? m_fixedFontSizes[3] : m_fontSizes[3]; + int isize = (int)size; + if (isize < minFontSize) + isize = minFontSize; + + FontDef newFontDef(childFont); + newFontDef.size = isize; + aStyle->setFontDef(newFontDef); +} +#endif + +} // namespace khtml diff --git a/khtml/css/cssstyleselector.h b/khtml/css/cssstyleselector.h new file mode 100644 index 000000000..235eb72a6 --- /dev/null +++ b/khtml/css/cssstyleselector.h @@ -0,0 +1,333 @@ +/* + * This file is part of the CSS implementation for KDE. + * + * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) + * Copyright (C) 2003, 2005, 2006 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ +#ifndef _CSS_cssstyleselector_h_ +#define _CSS_cssstyleselector_h_ + +#include <qptrlist.h> +#include <qvaluevector.h> + +#include "rendering/render_style.h" +#include "dom/dom_string.h" +#include "xml/dom_restyler.h" + +class KHTMLSettings; +class KHTMLView; +class KHTMLPart; +class KHTMLFactory; +class KURL; + +namespace DOM { + class DocumentImpl; + class NodeImpl; + class ElementImpl; + class StyleSheetImpl; + class CSSStyleRuleImpl; + class CSSStyleSheetImpl; + class CSSSelector; + class CSSStyleDeclarationImpl; + class CSSProperty; + class StyleSheetListImpl; + class CSSValueImpl; +} + +namespace khtml +{ + class CSSStyleSelectorList; + class CSSOrderedRule; + class CSSOrderedProperty; + class CSSOrderedPropertyList; + class RenderStyle; + + /* + * to remember the source where a rule came from. Differentiates between + * important and not important rules. This is ordered in the order they have to be applied + * to the RenderStyle. + */ + enum Source { + Default = 0, + NonCSSHint = 1, + User = 2, + Author = 3, + Inline = 4, + AuthorImportant = 5, + InlineImportant = 6, + UserImportant =7 + }; + + /** + * this class selects a RenderStyle for a given Element based on the + * collection of stylesheets it contains. This is just a virtual base class + * for specific implementations of the Selector. At the moment only CSSStyleSelector + * exists, but someone may wish to implement XSL... + */ + class StyleSelector + { + public: + StyleSelector() {} + + /* as nobody has implemented a second style selector up to now comment out + the virtual methods until then, so the class has no vptr. + */ +// virtual ~StyleSelector() {} +// virtual RenderStyle *styleForElement(DOM::ElementImpl *e) = 0; + + enum State { + None = 0x00, + Hover = 0x01, + Focus = 0x02, + Active = 0x04 + }; + }; + + + /** + * the StyleSelector implementation for CSS. + */ + class CSSStyleSelector : public StyleSelector + { + public: + /** + * creates a new StyleSelector for a Document. + * goes through all StyleSheets defined in the document and + * creates a list of rules it needs to apply to objects + * + * Also takes into account special cases for HTML documents, + * including the defaultStyle (which is html only) + */ + CSSStyleSelector( DOM::DocumentImpl* doc, QString userStyleSheet, DOM::StyleSheetListImpl *styleSheets, const KURL &url, + bool _strictParsing ); + /** + * same as above but for a single stylesheet. + */ + CSSStyleSelector( DOM::CSSStyleSheetImpl *sheet ); + + ~CSSStyleSelector(); + + void addSheet( DOM::CSSStyleSheetImpl *sheet ); + KDE_EXPORT static void clear(); + static void reparseConfiguration(); + + static void loadDefaultStyle(const KHTMLSettings *s, DOM::DocumentImpl *doc); + + RenderStyle *styleForElement(DOM::ElementImpl *e); + + QValueVector<int> fontSizes() const { return m_fontSizes; } + QValueVector<int> fixedFontSizes() const { return m_fixedFontSizes; } + + bool strictParsing; + struct Encodedurl { + QString host; //also contains protocol + QString path; + QString file; + } encodedurl; + + void computeFontSizes(QPaintDeviceMetrics* paintDeviceMetrics, int zoomFactor); + void computeFontSizesFor(QPaintDeviceMetrics* paintDeviceMetrics, int zoomFactor, QValueVector<int>& fontSizes, bool isFixed); + + static void precomputeAttributeDependencies(DOM::DocumentImpl* doc, DOM::CSSSelector* sel); + protected: + /* checks if the complete selector (which can be build up from a few CSSSelector's + with given relationships matches the given Element */ + void checkSelector(int selector, DOM::ElementImpl *e); + /* checks if the selector matches the given Element */ + bool checkSimpleSelector(DOM::CSSSelector *selector, DOM::ElementImpl *e, bool isAncestor, bool isSubSelector = false); + + enum SelectorMatch {SelectorMatches = 0, SelectorFailsLocal, SelectorFails}; + SelectorMatch checkSelector(DOM::CSSSelector *sel, DOM::ElementImpl *e, bool isAncestor, bool isSubSelector = false); + + void addDependency(StructuralDependencyType dependencyType, DOM::ElementImpl* dependency); +#ifdef APPLE_CHANGES + /* This function fixes up the default font size if it detects that the + current generic font family has changed. -dwh */ + void checkForGenericFamilyChange(RenderStyle* aStyle, RenderStyle* aParentStyle); +#endif + + /* builds up the selectors and properties lists from the CSSStyleSelectorList's */ + void buildLists(); + void clearLists(); + + void adjustRenderStyle(RenderStyle* style, DOM::ElementImpl *e); + + unsigned int addInlineDeclarations(DOM::ElementImpl* e, DOM::CSSStyleDeclarationImpl *decl, + unsigned int numProps); + + static DOM::CSSStyleSheetImpl *s_defaultSheet; + static DOM::CSSStyleSheetImpl *s_quirksSheet; + static CSSStyleSelectorList *s_defaultStyle; + static CSSStyleSelectorList *s_defaultQuirksStyle; + static CSSStyleSelectorList *s_defaultPrintStyle; + static RenderStyle* styleNotYetAvailable; + + CSSStyleSelectorList *defaultStyle; + CSSStyleSelectorList *defaultQuirksStyle; + CSSStyleSelectorList *defaultPrintStyle; + + CSSStyleSelectorList *authorStyle; + CSSStyleSelectorList *userStyle; + DOM::CSSStyleSheetImpl *userSheet; + +public: + + private: + void init(const KHTMLSettings* settings, DOM::DocumentImpl* doc); + + void mapBackgroundAttachment(BackgroundLayer* layer, DOM::CSSValueImpl* value); + void mapBackgroundClip(BackgroundLayer* layer, DOM::CSSValueImpl* value); + void mapBackgroundOrigin(BackgroundLayer* layer, DOM::CSSValueImpl* value); + void mapBackgroundImage(BackgroundLayer* layer, DOM::CSSValueImpl* value); + void mapBackgroundRepeat(BackgroundLayer* layer, DOM::CSSValueImpl* value); + void mapBackgroundSize(BackgroundLayer* layer, DOM::CSSValueImpl* value); + void mapBackgroundXPosition(BackgroundLayer* layer, DOM::CSSValueImpl* value); + void mapBackgroundYPosition(BackgroundLayer* layer, DOM::CSSValueImpl* value); + + public: // we need to make the enum public for SelectorCache + enum SelectorState { + Unknown = 0, + Applies, + AppliesPseudo, + Invalid + }; + + enum SelectorMedia { + MediaAural = 1, + MediaBraille, + MediaEmboss, + MediaHandheld, + MediaPrint, + MediaProjection, + MediaScreen, + MediaTTY, + MediaTV + }; + protected: + + struct SelectorCache { + SelectorState state; + unsigned int props_size; + int *props; + }; + + unsigned int selectors_size; + DOM::CSSSelector **selectors; + SelectorCache *selectorCache; + unsigned int properties_size; + CSSOrderedProperty **properties; + QMemArray<CSSOrderedProperty> inlineProps; + QString m_medium; + CSSOrderedProperty **propsToApply; + CSSOrderedProperty **pseudoProps; + unsigned int propsToApplySize; + unsigned int pseudoPropsSize; + + + RenderStyle::PseudoId dynamicPseudo; + + RenderStyle *style; + RenderStyle *parentStyle; + DOM::ElementImpl *element; + DOM::NodeImpl *parentNode; + KHTMLView *view; + KHTMLPart *part; + const KHTMLSettings *settings; + QPaintDeviceMetrics *paintDeviceMetrics; + QValueVector<int> m_fontSizes; + QValueVector<int> m_fixedFontSizes; + + bool fontDirty; + + void applyRule(int id, DOM::CSSValueImpl *value); + }; + + /* + * List of properties that get applied to the Element. We need to collect them first + * and then apply them one by one, because we have to change the apply order. + * Some properties depend on other one already being applied (for example all properties specifying + * some length need to have already the correct font size. Same applies to color + * + * While sorting them, we have to take care not to mix up the original order. + */ + class CSSOrderedProperty + { + public: + CSSOrderedProperty(DOM::CSSProperty *_prop, uint _selector, + bool first, Source source, unsigned int specificity, + unsigned int _position ) + : prop ( _prop ), pseudoId( RenderStyle::NOPSEUDO ), selector( _selector ), + position( _position ) + { + priority = (!first << 30) | (source << 24) | specificity; + } + + bool operator < ( const CSSOrderedProperty &other ) const { + if (priority < other.priority) return true; + if (priority > other.priority) return false; + if (position < other.position) return true; + return false; + } + + DOM::CSSProperty *prop; + RenderStyle::PseudoId pseudoId; + unsigned int selector; + unsigned int position; + + Q_UINT32 priority; + }; + + /* + * This is the list we will collect all properties we need to apply in. + * It will get sorted once before applying. + */ + class CSSOrderedPropertyList : public QPtrList<CSSOrderedProperty> + { + public: + virtual int compareItems(QPtrCollection::Item i1, QPtrCollection::Item i2); + void append(DOM::CSSStyleDeclarationImpl *decl, uint selector, uint specificity, + Source regular, Source important ); + }; + + class CSSOrderedRule + { + public: + CSSOrderedRule(DOM::CSSStyleRuleImpl *r, DOM::CSSSelector *s, int _index); + ~CSSOrderedRule(); + + DOM::CSSSelector *selector; + DOM::CSSStyleRuleImpl *rule; + int index; + }; + + class CSSStyleSelectorList : public QPtrList<CSSOrderedRule> + { + public: + CSSStyleSelectorList(); + virtual ~CSSStyleSelectorList(); + + void append( DOM::CSSStyleSheetImpl *sheet, + const DOM::DOMString &medium = "screen" ); + + void collect( QPtrList<DOM::CSSSelector> *selectorList, CSSOrderedPropertyList *propList, + Source regular, Source important ); + }; + +} +#endif diff --git a/khtml/css/cssvalues.c b/khtml/css/cssvalues.c new file mode 100644 index 000000000..ad4dbb9db --- /dev/null +++ b/khtml/css/cssvalues.c @@ -0,0 +1,1359 @@ +/* ANSI-C code produced by gperf version 3.0.1 */ +/* Command-line: gperf -L ANSI-C -E -c -C -n -o -t -k '*' -NfindValue -Hhash_val -Wwordlist_value -D cssvalues.gperf */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>." +#endif + +#line 1 "cssvalues.gperf" + +/* This file is automatically generated from cssvalues.in by makevalues, do not edit */ +/* Copyright 1999 W. Bastian */ +#include "cssvalues.h" +#line 6 "cssvalues.gperf" +struct css_value { + const char *name; + int id; +}; + +static const css_value* findValue (register const char *str, register unsigned int len); +/* maximum key range = 3056, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +hash_val (register const char *str, register unsigned int len) +{ + static const unsigned short asso_values[] = + { + 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, + 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, + 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, + 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, + 3056, 3056, 3056, 3056, 3056, 420, 225, 3056, 0, 0, + 105, 100, 40, 35, 20, 15, 10, 5, 3056, 3056, + 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, + 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, + 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, + 3056, 3056, 3056, 3056, 3056, 3056, 3056, 175, 60, 0, + 20, 45, 235, 380, 270, 5, 113, 65, 0, 35, + 0, 5, 265, 465, 100, 20, 5, 195, 223, 13, + 3, 68, 10, 3056, 3056, 3056, 3056, 3056, 3056, 3056, + 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, + 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, + 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, + 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, + 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, + 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, + 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, + 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, + 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, + 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, + 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, + 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, 3056, + 3056, 3056, 3056, 3056, 3056, 3056, 3056 + }; + register int hval = 0; + + switch (len) + { + default: + hval += asso_values[(unsigned char)str[27]]; + /*FALLTHROUGH*/ + case 27: + hval += asso_values[(unsigned char)str[26]]; + /*FALLTHROUGH*/ + case 26: + hval += asso_values[(unsigned char)str[25]]; + /*FALLTHROUGH*/ + case 25: + hval += asso_values[(unsigned char)str[24]]; + /*FALLTHROUGH*/ + case 24: + hval += asso_values[(unsigned char)str[23]]; + /*FALLTHROUGH*/ + case 23: + hval += asso_values[(unsigned char)str[22]]; + /*FALLTHROUGH*/ + case 22: + hval += asso_values[(unsigned char)str[21]]; + /*FALLTHROUGH*/ + case 21: + hval += asso_values[(unsigned char)str[20]]; + /*FALLTHROUGH*/ + case 20: + hval += asso_values[(unsigned char)str[19]]; + /*FALLTHROUGH*/ + case 19: + hval += asso_values[(unsigned char)str[18]]; + /*FALLTHROUGH*/ + case 18: + hval += asso_values[(unsigned char)str[17]]; + /*FALLTHROUGH*/ + case 17: + hval += asso_values[(unsigned char)str[16]]; + /*FALLTHROUGH*/ + case 16: + hval += asso_values[(unsigned char)str[15]]; + /*FALLTHROUGH*/ + case 15: + hval += asso_values[(unsigned char)str[14]]; + /*FALLTHROUGH*/ + case 14: + hval += asso_values[(unsigned char)str[13]]; + /*FALLTHROUGH*/ + case 13: + hval += asso_values[(unsigned char)str[12]]; + /*FALLTHROUGH*/ + case 12: + hval += asso_values[(unsigned char)str[11]]; + /*FALLTHROUGH*/ + case 11: + hval += asso_values[(unsigned char)str[10]]; + /*FALLTHROUGH*/ + case 10: + hval += asso_values[(unsigned char)str[9]]; + /*FALLTHROUGH*/ + case 9: + hval += asso_values[(unsigned char)str[8]]; + /*FALLTHROUGH*/ + case 8: + hval += asso_values[(unsigned char)str[7]]; + /*FALLTHROUGH*/ + case 7: + hval += asso_values[(unsigned char)str[6]]; + /*FALLTHROUGH*/ + case 6: + hval += asso_values[(unsigned char)str[5]]; + /*FALLTHROUGH*/ + case 5: + hval += asso_values[(unsigned char)str[4]]; + /*FALLTHROUGH*/ + case 4: + hval += asso_values[(unsigned char)str[3]]; + /*FALLTHROUGH*/ + case 3: + hval += asso_values[(unsigned char)str[2]+1]; + /*FALLTHROUGH*/ + case 2: + hval += asso_values[(unsigned char)str[1]]; + /*FALLTHROUGH*/ + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval; +} + +#ifdef __GNUC__ +__inline +#endif +const struct css_value * +findValue (register const char *str, register unsigned int len) +{ + enum + { + TOTAL_KEYWORDS = 274, + MIN_WORD_LENGTH = 2, + MAX_WORD_LENGTH = 28, + MIN_HASH_VALUE = 0, + MAX_HASH_VALUE = 3055 + }; + + static const struct css_value wordlist_value[] = + { +#line 40 "cssvalues.gperf" + {"100", CSS_VAL_100}, +#line 48 "cssvalues.gperf" + {"900", CSS_VAL_900}, +#line 47 "cssvalues.gperf" + {"800", CSS_VAL_800}, +#line 46 "cssvalues.gperf" + {"700", CSS_VAL_700}, +#line 45 "cssvalues.gperf" + {"600", CSS_VAL_600}, +#line 216 "cssvalues.gperf" + {"ltr", CSS_VAL_LTR}, +#line 276 "cssvalues.gperf" + {"down", CSS_VAL_DOWN}, +#line 146 "cssvalues.gperf" + {"disc", CSS_VAL_DISC}, +#line 44 "cssvalues.gperf" + {"500", CSS_VAL_500}, +#line 43 "cssvalues.gperf" + {"400", CSS_VAL_400}, +#line 258 "cssvalues.gperf" + {"scroll", CSS_VAL_SCROLL}, +#line 83 "cssvalues.gperf" + {"lime", CSS_VAL_LIME}, +#line 17 "cssvalues.gperf" + {"none", CSS_VAL_NONE}, +#line 19 "cssvalues.gperf" + {"inset", CSS_VAL_INSET}, +#line 118 "cssvalues.gperf" + {"window", CSS_VAL_WINDOW}, +#line 286 "cssvalues.gperf" + {"content", CSS_VAL_CONTENT}, +#line 147 "cssvalues.gperf" + {"circle", CSS_VAL_CIRCLE}, +#line 33 "cssvalues.gperf" + {"italic", CSS_VAL_ITALIC}, +#line 145 "cssvalues.gperf" + {"inside", CSS_VAL_INSIDE}, +#line 25 "cssvalues.gperf" + {"solid", CSS_VAL_SOLID}, +#line 183 "cssvalues.gperf" + {"inline", CSS_VAL_INLINE}, +#line 261 "cssvalues.gperf" + {"static", CSS_VAL_STATIC}, +#line 204 "cssvalues.gperf" + {"move", CSS_VAL_MOVE}, +#line 42 "cssvalues.gperf" + {"300", CSS_VAL_300}, +#line 249 "cssvalues.gperf" + {"level", CSS_VAL_LEVEL}, +#line 41 "cssvalues.gperf" + {"200", CSS_VAL_200}, +#line 254 "cssvalues.gperf" + {"mix", CSS_VAL_MIX}, +#line 91 "cssvalues.gperf" + {"teal", CSS_VAL_TEAL}, +#line 51 "cssvalues.gperf" + {"small", CSS_VAL_SMALL}, +#line 120 "cssvalues.gperf" + {"windowtext", CSS_VAL_WINDOWTEXT}, +#line 37 "cssvalues.gperf" + {"bold", CSS_VAL_BOLD}, +#line 213 "cssvalues.gperf" + {"text", CSS_VAL_TEXT}, +#line 149 "cssvalues.gperf" + {"box", CSS_VAL_BOX}, +#line 217 "cssvalues.gperf" + {"rtl", CSS_VAL_RTL}, +#line 242 "cssvalues.gperf" + {"embed", CSS_VAL_EMBED}, +#line 128 "cssvalues.gperf" + {"middle", CSS_VAL_MIDDLE}, +#line 252 "cssvalues.gperf" + {"lower", CSS_VAL_LOWER}, +#line 236 "cssvalues.gperf" + {"below", CSS_VAL_BELOW}, +#line 63 "cssvalues.gperf" + {"condensed", CSS_VAL_CONDENSED}, +#line 14 "cssvalues.gperf" + {"inherit", CSS_VAL_INHERIT}, +#line 93 "cssvalues.gperf" + {"yellow", CSS_VAL_YELLOW}, +#line 247 "cssvalues.gperf" + {"invert", CSS_VAL_INVERT}, +#line 76 "cssvalues.gperf" + {"black", CSS_VAL_BLACK}, +#line 89 "cssvalues.gperf" + {"red", CSS_VAL_RED}, +#line 280 "cssvalues.gperf" + {"slide", CSS_VAL_SLIDE}, +#line 139 "cssvalues.gperf" + {"center", CSS_VAL_CENTER}, +#line 59 "cssvalues.gperf" + {"wider", CSS_VAL_WIDER}, +#line 129 "cssvalues.gperf" + {"sub", CSS_VAL_SUB}, +#line 189 "cssvalues.gperf" + {"table", CSS_VAL_TABLE}, +#line 269 "cssvalues.gperf" + {"enabled", CSS_VAL_ENABLED}, +#line 36 "cssvalues.gperf" + {"normal", CSS_VAL_NORMAL}, +#line 238 "cssvalues.gperf" + {"blink", CSS_VAL_BLINK}, +#line 84 "cssvalues.gperf" + {"maroon", CSS_VAL_MAROON}, +#line 251 "cssvalues.gperf" + {"loud", CSS_VAL_LOUD}, +#line 285 "cssvalues.gperf" + {"border", CSS_VAL_BORDER}, +#line 85 "cssvalues.gperf" + {"navy", CSS_VAL_NAVY}, +#line 57 "cssvalues.gperf" + {"smaller", CSS_VAL_SMALLER}, +#line 38 "cssvalues.gperf" + {"bolder", CSS_VAL_BOLDER}, +#line 28 "cssvalues.gperf" + {"icon", CSS_VAL_ICON}, +#line 78 "cssvalues.gperf" + {"crimson", CSS_VAL_CRIMSON}, +#line 29 "cssvalues.gperf" + {"menu", CSS_VAL_MENU}, +#line 23 "cssvalues.gperf" + {"dotted", CSS_VAL_DOTTED}, +#line 277 "cssvalues.gperf" + {"slow", CSS_VAL_SLOW}, +#line 151 "cssvalues.gperf" + {"decimal", CSS_VAL_DECIMAL}, +#line 15 "cssvalues.gperf" + {"initial", CSS_VAL_INITIAL}, +#line 134 "cssvalues.gperf" + {"bottom", CSS_VAL_BOTTOM}, +#line 214 "cssvalues.gperf" + {"wait", CSS_VAL_WAIT}, +#line 69 "cssvalues.gperf" + {"serif", CSS_VAL_SERIF}, +#line 77 "cssvalues.gperf" + {"blue", CSS_VAL_BLUE}, +#line 270 "cssvalues.gperf" + {"disabled", CSS_VAL_DISABLED}, +#line 127 "cssvalues.gperf" + {"baseline", CSS_VAL_BASELINE}, +#line 111 "cssvalues.gperf" + {"menutext", CSS_VAL_MENUTEXT}, +#line 221 "cssvalues.gperf" + {"visible", CSS_VAL_VISIBLE}, +#line 26 "cssvalues.gperf" + {"double", CSS_VAL_DOUBLE}, +#line 52 "cssvalues.gperf" + {"medium", CSS_VAL_MEDIUM}, +#line 245 "cssvalues.gperf" + {"hide", CSS_VAL_HIDE}, +#line 274 "cssvalues.gperf" + {"reverse", CSS_VAL_REVERSE}, +#line 243 "cssvalues.gperf" + {"fixed", CSS_VAL_FIXED}, +#line 283 "cssvalues.gperf" + {"clip", CSS_VAL_CLIP}, +#line 112 "cssvalues.gperf" + {"scrollbar", CSS_VAL_SCROLLBAR}, +#line 18 "cssvalues.gperf" + {"hidden", CSS_VAL_HIDDEN}, +#line 86 "cssvalues.gperf" + {"olive", CSS_VAL_OLIVE}, +#line 263 "cssvalues.gperf" + {"thin", CSS_VAL_THIN}, +#line 184 "cssvalues.gperf" + {"block", CSS_VAL_BLOCK}, +#line 220 "cssvalues.gperf" + {"lowercase", CSS_VAL_LOWERCASE}, +#line 284 "cssvalues.gperf" + {"ellipsis", CSS_VAL_ELLIPSIS}, +#line 241 "cssvalues.gperf" + {"cross", CSS_VAL_CROSS}, +#line 278 "cssvalues.gperf" + {"fast", CSS_VAL_FAST}, +#line 90 "cssvalues.gperf" + {"silver", CSS_VAL_SILVER}, +#line 137 "cssvalues.gperf" + {"left", CSS_VAL_LEFT}, +#line 264 "cssvalues.gperf" + {"underline", CSS_VAL_UNDERLINE}, +#line 82 "cssvalues.gperf" + {"indigo", CSS_VAL_INDIGO}, +#line 234 "cssvalues.gperf" + {"always", CSS_VAL_ALWAYS}, +#line 279 "cssvalues.gperf" + {"infinite", CSS_VAL_INFINITE}, +#line 92 "cssvalues.gperf" + {"white", CSS_VAL_WHITE}, +#line 110 "cssvalues.gperf" + {"infotext", CSS_VAL_INFOTEXT}, +#line 187 "cssvalues.gperf" + {"compact", CSS_VAL_COMPACT}, +#line 262 "cssvalues.gperf" + {"thick", CSS_VAL_THICK}, +#line 60 "cssvalues.gperf" + {"narrower", CSS_VAL_NARROWER}, +#line 275 "cssvalues.gperf" + {"up", CSS_VAL_UP}, +#line 49 "cssvalues.gperf" + {"xx-small", CSS_VAL_XX_SMALL}, +#line 207 "cssvalues.gperf" + {"nw-resize", CSS_VAL_NW_RESIZE}, +#line 22 "cssvalues.gperf" + {"outset", CSS_VAL_OUTSET}, +#line 244 "cssvalues.gperf" + {"hand", CSS_VAL_HAND}, +#line 161 "cssvalues.gperf" + {"hebrew", CSS_VAL_HEBREW}, +#line 133 "cssvalues.gperf" + {"top", CSS_VAL_TOP}, +#line 210 "cssvalues.gperf" + {"sw-resize", CSS_VAL_SW_RESIZE}, +#line 144 "cssvalues.gperf" + {"outside", CSS_VAL_OUTSIDE}, +#line 233 "cssvalues.gperf" + {"absolute", CSS_VAL_ABSOLUTE}, +#line 206 "cssvalues.gperf" + {"ne-resize", CSS_VAL_NE_RESIZE}, +#line 162 "cssvalues.gperf" + {"armenian", CSS_VAL_ARMENIAN}, +#line 71 "cssvalues.gperf" + {"cursive", CSS_VAL_CURSIVE}, +#line 209 "cssvalues.gperf" + {"se-resize", CSS_VAL_SE_RESIZE}, +#line 101 "cssvalues.gperf" + {"buttontext", CSS_VAL_BUTTONTEXT}, +#line 185 "cssvalues.gperf" + {"list-item", CSS_VAL_LIST_ITEM}, +#line 239 "cssvalues.gperf" + {"both", CSS_VAL_BOTH}, +#line 202 "cssvalues.gperf" + {"pointer", CSS_VAL_POINTER}, +#line 24 "cssvalues.gperf" + {"dashed", CSS_VAL_DASHED}, +#line 222 "cssvalues.gperf" + {"collapse", CSS_VAL_COLLAPSE}, +#line 227 "cssvalues.gperf" + {"nowrap", CSS_VAL_NOWRAP}, +#line 268 "cssvalues.gperf" + {"content-box", CSS_VAL_CONTENT_BOX}, +#line 73 "cssvalues.gperf" + {"monospace", CSS_VAL_MONOSPACE}, +#line 208 "cssvalues.gperf" + {"n-resize", CSS_VAL_N_RESIZE}, +#line 260 "cssvalues.gperf" + {"show", CSS_VAL_SHOW}, +#line 199 "cssvalues.gperf" + {"auto", CSS_VAL_AUTO}, +#line 21 "cssvalues.gperf" + {"ridge", CSS_VAL_RIDGE}, +#line 212 "cssvalues.gperf" + {"w-resize", CSS_VAL_W_RESIZE}, +#line 256 "cssvalues.gperf" + {"portrait", CSS_VAL_PORTRAIT}, +#line 211 "cssvalues.gperf" + {"s-resize", CSS_VAL_S_RESIZE}, +#line 271 "cssvalues.gperf" + {"forwards", CSS_VAL_FORWARDS}, +#line 87 "cssvalues.gperf" + {"orange", CSS_VAL_ORANGE}, +#line 228 "cssvalues.gperf" + {"pre", CSS_VAL_PRE}, +#line 80 "cssvalues.gperf" + {"gray", CSS_VAL_GRAY}, +#line 205 "cssvalues.gperf" + {"e-resize", CSS_VAL_E_RESIZE}, +#line 255 "cssvalues.gperf" + {"overline", CSS_VAL_OVERLINE}, +#line 215 "cssvalues.gperf" + {"help", CSS_VAL_HELP}, +#line 53 "cssvalues.gperf" + {"large", CSS_VAL_LARGE}, +#line 140 "cssvalues.gperf" + {"justify", CSS_VAL_JUSTIFY}, +#line 240 "cssvalues.gperf" + {"crop", CSS_VAL_CROP}, +#line 257 "cssvalues.gperf" + {"relative", CSS_VAL_RELATIVE}, +#line 50 "cssvalues.gperf" + {"x-small", CSS_VAL_X_SMALL}, +#line 188 "cssvalues.gperf" + {"inline-block", CSS_VAL_INLINE_BLOCK}, +#line 64 "cssvalues.gperf" + {"semi-condensed", CSS_VAL_SEMI_CONDENSED}, +#line 272 "cssvalues.gperf" + {"backwards", CSS_VAL_BACKWARDS}, +#line 138 "cssvalues.gperf" + {"right", CSS_VAL_RIGHT}, +#line 119 "cssvalues.gperf" + {"windowframe", CSS_VAL_WINDOWFRAME}, +#line 27 "cssvalues.gperf" + {"caption", CSS_VAL_CAPTION}, +#line 132 "cssvalues.gperf" + {"text-bottom", CSS_VAL_TEXT_BOTTOM}, +#line 103 "cssvalues.gperf" + {"graytext", CSS_VAL_GRAYTEXT}, +#line 106 "cssvalues.gperf" + {"inactiveborder", CSS_VAL_INACTIVEBORDER}, +#line 72 "cssvalues.gperf" + {"fantasy", CSS_VAL_FANTASY}, +#line 235 "cssvalues.gperf" + {"avoid", CSS_VAL_AVOID}, +#line 197 "cssvalues.gperf" + {"table-cell", CSS_VAL_TABLE_CELL}, +#line 39 "cssvalues.gperf" + {"lighter", CSS_VAL_LIGHTER}, +#line 248 "cssvalues.gperf" + {"landscape", CSS_VAL_LANDSCAPE}, +#line 102 "cssvalues.gperf" + {"captiontext", CSS_VAL_CAPTIONTEXT}, +#line 58 "cssvalues.gperf" + {"larger", CSS_VAL_LARGER}, +#line 186 "cssvalues.gperf" + {"run-in", CSS_VAL_RUN_IN}, +#line 267 "cssvalues.gperf" + {"border-box", CSS_VAL_BORDER_BOX}, +#line 281 "cssvalues.gperf" + {"alternate", CSS_VAL_ALTERNATE}, +#line 174 "cssvalues.gperf" + {"lower-latin", CSS_VAL_LOWER_LATIN}, +#line 81 "cssvalues.gperf" + {"green", CSS_VAL_GREEN}, +#line 194 "cssvalues.gperf" + {"table-row", CSS_VAL_TABLE_ROW}, +#line 232 "cssvalues.gperf" + {"above", CSS_VAL_ABOVE}, +#line 66 "cssvalues.gperf" + {"expanded", CSS_VAL_EXPANDED}, +#line 74 "cssvalues.gperf" + {"transparent", CSS_VAL_TRANSPARENT}, +#line 121 "cssvalues.gperf" + {"grey", CSS_VAL_GREY}, +#line 88 "cssvalues.gperf" + {"purple", CSS_VAL_PURPLE}, +#line 190 "cssvalues.gperf" + {"inline-table", CSS_VAL_INLINE_TABLE}, +#line 107 "cssvalues.gperf" + {"inactivecaption", CSS_VAL_INACTIVECAPTION}, +#line 34 "cssvalues.gperf" + {"oblique", CSS_VAL_OBLIQUE}, +#line 131 "cssvalues.gperf" + {"text-top", CSS_VAL_TEXT_TOP}, +#line 201 "cssvalues.gperf" + {"default", CSS_VAL_DEFAULT}, +#line 130 "cssvalues.gperf" + {"super", CSS_VAL_SUPER}, +#line 123 "cssvalues.gperf" + {"repeat", CSS_VAL_REPEAT}, +#line 108 "cssvalues.gperf" + {"inactivecaptiontext", CSS_VAL_INACTIVECAPTIONTEXT}, +#line 114 "cssvalues.gperf" + {"threedface", CSS_VAL_THREEDFACE}, +#line 126 "cssvalues.gperf" + {"no-repeat", CSS_VAL_NO_REPEAT}, +#line 282 "cssvalues.gperf" + {"unfurl", CSS_VAL_UNFURL}, +#line 273 "cssvalues.gperf" + {"ahead", CSS_VAL_AHEAD}, +#line 196 "cssvalues.gperf" + {"table-column", CSS_VAL_TABLE_COLUMN}, +#line 218 "cssvalues.gperf" + {"capitalize", CSS_VAL_CAPITALIZE}, +#line 159 "cssvalues.gperf" + {"lower-roman", CSS_VAL_LOWER_ROMAN}, +#line 287 "cssvalues.gperf" + {"padding", CSS_VAL_PADDING}, +#line 117 "cssvalues.gperf" + {"threedshadow", CSS_VAL_THREEDSHADOW}, +#line 98 "cssvalues.gperf" + {"buttonface", CSS_VAL_BUTTONFACE}, +#line 79 "cssvalues.gperf" + {"fuchsia", CSS_VAL_FUCHSIA}, +#line 55 "cssvalues.gperf" + {"xx-large", CSS_VAL_XX_LARGE}, +#line 200 "cssvalues.gperf" + {"crosshair", CSS_VAL_CROSSHAIR}, +#line 246 "cssvalues.gperf" + {"higher", CSS_VAL_HIGHER}, +#line 100 "cssvalues.gperf" + {"buttonshadow", CSS_VAL_BUTTONSHADOW}, +#line 94 "cssvalues.gperf" + {"activeborder", CSS_VAL_ACTIVEBORDER}, +#line 253 "cssvalues.gperf" + {"marquee", CSS_VAL_MARQUEE}, +#line 31 "cssvalues.gperf" + {"small-caption", CSS_VAL_SMALL_CAPTION}, +#line 35 "cssvalues.gperf" + {"small-caps", CSS_VAL_SMALL_CAPS}, +#line 122 "cssvalues.gperf" + {"-khtml-text", CSS_VAL__KHTML_TEXT}, +#line 20 "cssvalues.gperf" + {"groove", CSS_VAL_GROOVE}, +#line 97 "cssvalues.gperf" + {"background", CSS_VAL_BACKGROUND}, +#line 178 "cssvalues.gperf" + {"katakana", CSS_VAL_KATAKANA}, +#line 148 "cssvalues.gperf" + {"square", CSS_VAL_SQUARE}, +#line 259 "cssvalues.gperf" + {"separate", CSS_VAL_SEPARATE}, +#line 75 "cssvalues.gperf" + {"aqua", CSS_VAL_AQUA}, +#line 70 "cssvalues.gperf" + {"sans-serif", CSS_VAL_SANS_SERIF}, +#line 32 "cssvalues.gperf" + {"status-bar", CSS_VAL_STATUS_BAR}, +#line 65 "cssvalues.gperf" + {"semi-expanded", CSS_VAL_SEMI_EXPANDED}, +#line 230 "cssvalues.gperf" + {"pre-line", CSS_VAL_PRE_LINE}, +#line 237 "cssvalues.gperf" + {"bidi-override", CSS_VAL_BIDI_OVERRIDE}, +#line 62 "cssvalues.gperf" + {"extra-condensed", CSS_VAL_EXTRA_CONDENSED}, +#line 95 "cssvalues.gperf" + {"activecaption", CSS_VAL_ACTIVECAPTION}, +#line 198 "cssvalues.gperf" + {"table-caption", CSS_VAL_TABLE_CAPTION}, +#line 154 "cssvalues.gperf" + {"-khtml-lao", CSS_VAL__KHTML_LAO}, +#line 143 "cssvalues.gperf" + {"-khtml-center", CSS_VAL__KHTML_CENTER}, +#line 54 "cssvalues.gperf" + {"x-large", CSS_VAL_X_LARGE}, +#line 30 "cssvalues.gperf" + {"message-box", CSS_VAL_MESSAGE_BOX}, +#line 203 "cssvalues.gperf" + {"progress", CSS_VAL_PROGRESS}, +#line 177 "cssvalues.gperf" + {"hiragana", CSS_VAL_HIRAGANA}, +#line 171 "cssvalues.gperf" + {"lower-greek", CSS_VAL_LOWER_GREEK}, +#line 150 "cssvalues.gperf" + {"-khtml-diamond", CSS_VAL__KHTML_DIAMOND}, +#line 141 "cssvalues.gperf" + {"-khtml-left", CSS_VAL__KHTML_LEFT}, +#line 61 "cssvalues.gperf" + {"ultra-condensed", CSS_VAL_ULTRA_CONDENSED}, +#line 158 "cssvalues.gperf" + {"-khtml-tibetan", CSS_VAL__KHTML_TIBETAN}, +#line 124 "cssvalues.gperf" + {"repeat-x", CSS_VAL_REPEAT_X}, +#line 265 "cssvalues.gperf" + {"-khtml-normal", CSS_VAL__KHTML_NORMAL}, +#line 113 "cssvalues.gperf" + {"threeddarkshadow", CSS_VAL_THREEDDARKSHADOW}, +#line 219 "cssvalues.gperf" + {"uppercase", CSS_VAL_UPPERCASE}, +#line 125 "cssvalues.gperf" + {"repeat-y", CSS_VAL_REPEAT_Y}, +#line 136 "cssvalues.gperf" + {"-khtml-auto", CSS_VAL__KHTML_AUTO}, +#line 163 "cssvalues.gperf" + {"georgian", CSS_VAL_GEORGIAN}, +#line 109 "cssvalues.gperf" + {"infobackground", CSS_VAL_INFOBACKGROUND}, +#line 16 "cssvalues.gperf" + {"-khtml-native", CSS_VAL__KHTML_NATIVE}, +#line 157 "cssvalues.gperf" + {"-khtml-thai", CSS_VAL__KHTML_THAI}, +#line 224 "cssvalues.gperf" + {"no-close-quote", CSS_VAL_NO_CLOSE_QUOTE}, +#line 173 "cssvalues.gperf" + {"lower-alpha", CSS_VAL_LOWER_ALPHA}, +#line 156 "cssvalues.gperf" + {"-khtml-urdu", CSS_VAL__KHTML_URDU}, +#line 223 "cssvalues.gperf" + {"close-quote", CSS_VAL_CLOSE_QUOTE}, +#line 104 "cssvalues.gperf" + {"highlight", CSS_VAL_HIGHLIGHT}, +#line 231 "cssvalues.gperf" + {"-khtml-nowrap", CSS_VAL__KHTML_NOWRAP}, +#line 67 "cssvalues.gperf" + {"extra-expanded", CSS_VAL_EXTRA_EXPANDED}, +#line 105 "cssvalues.gperf" + {"highlighttext", CSS_VAL_HIGHLIGHTTEXT}, +#line 155 "cssvalues.gperf" + {"-khtml-persian", CSS_VAL__KHTML_PERSIAN}, +#line 116 "cssvalues.gperf" + {"threedlightshadow", CSS_VAL_THREEDLIGHTSHADOW}, +#line 229 "cssvalues.gperf" + {"pre-wrap", CSS_VAL_PRE_WRAP}, +#line 96 "cssvalues.gperf" + {"appworkspace", CSS_VAL_APPWORKSPACE}, +#line 226 "cssvalues.gperf" + {"open-quote", CSS_VAL_OPEN_QUOTE}, +#line 68 "cssvalues.gperf" + {"ultra-expanded", CSS_VAL_ULTRA_EXPANDED}, +#line 176 "cssvalues.gperf" + {"upper-latin", CSS_VAL_UPPER_LATIN}, +#line 225 "cssvalues.gperf" + {"no-open-quote", CSS_VAL_NO_OPEN_QUOTE}, +#line 250 "cssvalues.gperf" + {"line-through", CSS_VAL_LINE_THROUGH}, +#line 142 "cssvalues.gperf" + {"-khtml-right", CSS_VAL__KHTML_RIGHT}, +#line 164 "cssvalues.gperf" + {"cjk-ideographic", CSS_VAL_CJK_IDEOGRAPHIC}, +#line 160 "cssvalues.gperf" + {"upper-roman", CSS_VAL_UPPER_ROMAN}, +#line 135 "cssvalues.gperf" + {"-khtml-baseline-middle", CSS_VAL__KHTML_BASELINE_MIDDLE}, +#line 153 "cssvalues.gperf" + {"-khtml-arabic-indic", CSS_VAL__KHTML_ARABIC_INDIC}, +#line 152 "cssvalues.gperf" + {"decimal-leading-zero", CSS_VAL_DECIMAL_LEADING_ZERO}, +#line 115 "cssvalues.gperf" + {"threedhighlight", CSS_VAL_THREEDHIGHLIGHT}, +#line 180 "cssvalues.gperf" + {"katakana-iroha", CSS_VAL_KATAKANA_IROHA}, +#line 99 "cssvalues.gperf" + {"buttonhighlight", CSS_VAL_BUTTONHIGHLIGHT}, +#line 56 "cssvalues.gperf" + {"-khtml-xxx-large", CSS_VAL__KHTML_XXX_LARGE}, +#line 191 "cssvalues.gperf" + {"table-row-group", CSS_VAL_TABLE_ROW_GROUP}, +#line 182 "cssvalues.gperf" + {"-khtml-close-quote", CSS_VAL__KHTML_CLOSE_QUOTE}, +#line 179 "cssvalues.gperf" + {"hiragana-iroha", CSS_VAL_HIRAGANA_IROHA}, +#line 195 "cssvalues.gperf" + {"table-column-group", CSS_VAL_TABLE_COLUMN_GROUP}, +#line 266 "cssvalues.gperf" + {"-khtml-around-floats", CSS_VAL__KHTML_AROUND_FLOATS}, +#line 175 "cssvalues.gperf" + {"upper-alpha", CSS_VAL_UPPER_ALPHA}, +#line 181 "cssvalues.gperf" + {"-khtml-open-quote", CSS_VAL__KHTML_OPEN_QUOTE}, +#line 193 "cssvalues.gperf" + {"table-footer-group", CSS_VAL_TABLE_FOOTER_GROUP}, +#line 192 "cssvalues.gperf" + {"table-header-group", CSS_VAL_TABLE_HEADER_GROUP}, +#line 165 "cssvalues.gperf" + {"-khtml-japanese-formal", CSS_VAL__KHTML_JAPANESE_FORMAL}, +#line 166 "cssvalues.gperf" + {"-khtml-japanese-informal", CSS_VAL__KHTML_JAPANESE_INFORMAL}, +#line 172 "cssvalues.gperf" + {"-khtml-upper-greek", CSS_VAL__KHTML_UPPER_GREEK}, +#line 169 "cssvalues.gperf" + {"-khtml-trad-chinese-formal", CSS_VAL__KHTML_TRAD_CHINESE_FORMAL}, +#line 170 "cssvalues.gperf" + {"-khtml-trad-chinese-informal", CSS_VAL__KHTML_TRAD_CHINESE_INFORMAL}, +#line 167 "cssvalues.gperf" + {"-khtml-simp-chinese-formal", CSS_VAL__KHTML_SIMP_CHINESE_FORMAL}, +#line 168 "cssvalues.gperf" + {"-khtml-simp-chinese-informal", CSS_VAL__KHTML_SIMP_CHINESE_INFORMAL} + }; + + static const short lookup[] = + { + 0, -1, -1, -1, -1, 1, -1, -1, -1, -1, + 2, -1, -1, -1, -1, 3, -1, -1, -1, -1, + 4, -1, -1, -1, -1, 5, -1, -1, 6, -1, + 7, -1, -1, -1, -1, 8, -1, -1, -1, -1, + 9, -1, -1, -1, -1, 10, -1, -1, -1, -1, + 11, -1, -1, -1, -1, 12, -1, -1, -1, -1, + 13, 14, -1, -1, -1, 15, -1, -1, -1, -1, + 16, -1, -1, -1, -1, 17, -1, -1, -1, -1, + 18, -1, -1, -1, -1, 19, -1, -1, -1, -1, + 20, -1, -1, -1, -1, 21, -1, -1, 22, -1, + 23, -1, -1, 24, -1, 25, -1, -1, 26, -1, + 27, -1, -1, -1, -1, 28, -1, -1, -1, 29, + 30, -1, -1, 31, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 32, -1, -1, -1, -1, -1, -1, + 33, -1, -1, -1, -1, 34, -1, -1, -1, -1, + 35, -1, -1, 36, -1, -1, -1, -1, 37, -1, + 38, -1, -1, -1, -1, 39, 40, -1, 41, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 42, -1, -1, -1, -1, + 43, -1, -1, -1, -1, -1, -1, -1, 44, -1, + 45, -1, -1, -1, -1, -1, -1, -1, 46, -1, + -1, -1, -1, -1, -1, 47, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 48, -1, -1, -1, -1, + 49, -1, -1, -1, -1, 50, -1, -1, 51, -1, + 52, -1, -1, -1, -1, -1, -1, -1, 53, -1, + 54, -1, -1, -1, -1, -1, 55, -1, -1, -1, + 56, -1, -1, -1, -1, 57, -1, -1, -1, -1, + 58, -1, -1, 59, -1, -1, -1, -1, -1, -1, + 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 61, -1, -1, -1, -1, -1, -1, -1, 62, -1, + 63, -1, -1, 64, -1, 65, 66, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 67, -1, -1, 68, -1, + 69, -1, -1, -1, -1, 70, -1, -1, 71, -1, + -1, -1, -1, 72, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 73, -1, -1, -1, -1, -1, -1, + 74, -1, -1, -1, -1, 75, -1, -1, 76, -1, + -1, -1, -1, 77, -1, -1, -1, -1, 78, -1, + 79, -1, -1, -1, -1, 80, 81, -1, 82, -1, + 83, -1, -1, 84, -1, 85, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 86, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 87, -1, -1, -1, -1, -1, -1, -1, 88, -1, + 89, -1, -1, -1, -1, 90, -1, -1, -1, -1, + 91, 92, -1, -1, -1, 93, 94, -1, 95, -1, + 96, -1, -1, 97, -1, -1, -1, -1, 98, -1, + 99, 100, -1, 101, -1, 102, -1, -1, -1, -1, + 103, -1, -1, 104, -1, 105, -1, -1, -1, -1, + -1, -1, -1, 106, -1, 107, -1, -1, -1, -1, + 108, -1, -1, -1, -1, 109, -1, -1, -1, -1, + 110, -1, -1, -1, -1, -1, -1, -1, 111, -1, + -1, -1, -1, -1, -1, 112, -1, -1, 113, -1, + -1, -1, -1, -1, -1, 114, -1, -1, -1, -1, + 115, -1, -1, 116, -1, 117, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 118, -1, -1, 119, -1, + -1, -1, -1, 120, -1, 121, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 122, -1, -1, 123, -1, + 124, -1, -1, -1, -1, 125, -1, -1, 126, -1, + 127, -1, -1, -1, -1, 128, -1, -1, 129, -1, + 130, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 131, -1, -1, -1, -1, -1, -1, -1, 132, -1, + 133, -1, -1, 134, -1, 135, -1, -1, -1, -1, + 136, -1, -1, -1, -1, -1, 137, -1, -1, -1, + 138, -1, -1, 139, -1, -1, -1, -1, 140, -1, + 141, -1, -1, -1, -1, 142, -1, -1, 143, -1, + 144, 145, -1, -1, -1, 146, -1, -1, 147, -1, + -1, -1, -1, -1, -1, -1, 148, -1, -1, -1, + -1, -1, -1, 149, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 150, -1, -1, -1, -1, 151, -1, + 152, -1, -1, -1, -1, 153, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 154, -1, -1, -1, -1, + -1, -1, -1, 155, -1, -1, -1, -1, -1, -1, + 156, -1, -1, -1, -1, 157, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 158, -1, + 159, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 160, -1, + 161, -1, -1, 162, -1, -1, -1, -1, 163, -1, + -1, -1, -1, 164, -1, 165, -1, -1, -1, -1, + -1, -1, -1, 166, -1, -1, -1, -1, -1, -1, + 167, -1, -1, -1, -1, 168, -1, -1, 169, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 170, -1, -1, -1, -1, -1, -1, -1, 171, -1, + 172, -1, -1, -1, -1, 173, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 174, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 175, -1, -1, -1, + 176, -1, -1, -1, -1, 177, -1, -1, -1, -1, + 178, -1, -1, -1, -1, 179, -1, -1, -1, -1, + 180, -1, -1, -1, -1, 181, -1, -1, 182, -1, + 183, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 184, -1, + -1, -1, -1, -1, -1, 185, -1, -1, -1, -1, + 186, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 187, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 188, -1, -1, -1, -1, + 189, -1, -1, 190, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 191, -1, -1, -1, -1, -1, -1, + 192, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 193, -1, -1, -1, -1, 194, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 195, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 196, -1, + 197, -1, -1, -1, -1, 198, -1, -1, 199, -1, + 200, -1, -1, -1, -1, -1, -1, -1, 201, -1, + -1, -1, -1, -1, -1, 202, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 203, -1, -1, 204, -1, -1, -1, -1, -1, -1, + 205, -1, -1, -1, -1, -1, -1, -1, 206, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 207, -1, -1, -1, -1, 208, -1, + 209, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 210, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 211, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 212, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 213, -1, 214, -1, -1, -1, -1, + 215, -1, -1, -1, -1, -1, -1, -1, 216, -1, + 217, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 218, -1, -1, -1, -1, + 219, -1, -1, -1, -1, 220, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 221, -1, + -1, -1, -1, -1, -1, 222, -1, -1, 223, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 224, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 225, -1, -1, -1, -1, -1, -1, + 226, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 227, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 228, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 229, -1, 230, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 231, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 232, -1, + 233, -1, -1, -1, -1, 234, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 235, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 236, -1, + -1, 237, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 238, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 239, -1, -1, -1, -1, -1, -1, -1, 240, -1, + -1, -1, -1, 241, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 242, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 243, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 244, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 245, -1, -1, -1, -1, + 246, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 247, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 248, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 249, -1, 250, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 251, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 252, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 253, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 254, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 255, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 256, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 257, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 258, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 259, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 260, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 261, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 262, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 263, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 264, -1, -1, -1, -1, 265, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 266, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 267, -1, + -1, -1, -1, 268, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 269, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 270, -1, -1, -1, -1, + 271, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 272, -1, -1, -1, -1, 273 + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash_val (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register int index = lookup[key]; + + if (index >= 0) + { + register const char *s = wordlist_value[index].name; + + if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') + return &wordlist_value[index]; + } + } + } + return 0; +} +#line 288 "cssvalues.gperf" + +static const char * const valueList[] = { +"", +"inherit", +"initial", +"-khtml-native", +"none", +"hidden", +"inset", +"groove", +"ridge", +"outset", +"dotted", +"dashed", +"solid", +"double", +"caption", +"icon", +"menu", +"message-box", +"small-caption", +"status-bar", +"italic", +"oblique", +"small-caps", +"normal", +"bold", +"bolder", +"lighter", +"100", +"200", +"300", +"400", +"500", +"600", +"700", +"800", +"900", +"xx-small", +"x-small", +"small", +"medium", +"large", +"x-large", +"xx-large", +"-khtml-xxx-large", +"smaller", +"larger", +"wider", +"narrower", +"ultra-condensed", +"extra-condensed", +"condensed", +"semi-condensed", +"semi-expanded", +"expanded", +"extra-expanded", +"ultra-expanded", +"serif", +"sans-serif", +"cursive", +"fantasy", +"monospace", +"transparent", +"aqua", +"black", +"blue", +"crimson", +"fuchsia", +"gray", +"green", +"indigo", +"lime", +"maroon", +"navy", +"olive", +"orange", +"purple", +"red", +"silver", +"teal", +"white", +"yellow", +"activeborder", +"activecaption", +"appworkspace", +"background", +"buttonface", +"buttonhighlight", +"buttonshadow", +"buttontext", +"captiontext", +"graytext", +"highlight", +"highlighttext", +"inactiveborder", +"inactivecaption", +"inactivecaptiontext", +"infobackground", +"infotext", +"menutext", +"scrollbar", +"threeddarkshadow", +"threedface", +"threedhighlight", +"threedlightshadow", +"threedshadow", +"window", +"windowframe", +"windowtext", +"grey", +"-khtml-text", +"repeat", +"repeat-x", +"repeat-y", +"no-repeat", +"baseline", +"middle", +"sub", +"super", +"text-top", +"text-bottom", +"top", +"bottom", +"-khtml-baseline-middle", +"-khtml-auto", +"left", +"right", +"center", +"justify", +"-khtml-left", +"-khtml-right", +"-khtml-center", +"outside", +"inside", +"disc", +"circle", +"square", +"box", +"-khtml-diamond", +"decimal", +"decimal-leading-zero", +"-khtml-arabic-indic", +"-khtml-lao", +"-khtml-persian", +"-khtml-urdu", +"-khtml-thai", +"-khtml-tibetan", +"lower-roman", +"upper-roman", +"hebrew", +"armenian", +"georgian", +"cjk-ideographic", +"-khtml-japanese-formal", +"-khtml-japanese-informal", +"-khtml-simp-chinese-formal", +"-khtml-simp-chinese-informal", +"-khtml-trad-chinese-formal", +"-khtml-trad-chinese-informal", +"lower-greek", +"-khtml-upper-greek", +"lower-alpha", +"lower-latin", +"upper-alpha", +"upper-latin", +"hiragana", +"katakana", +"hiragana-iroha", +"katakana-iroha", +"-khtml-open-quote", +"-khtml-close-quote", +"inline", +"block", +"list-item", +"run-in", +"compact", +"inline-block", +"table", +"inline-table", +"table-row-group", +"table-header-group", +"table-footer-group", +"table-row", +"table-column-group", +"table-column", +"table-cell", +"table-caption", +"auto", +"crosshair", +"default", +"pointer", +"progress", +"move", +"e-resize", +"ne-resize", +"nw-resize", +"n-resize", +"se-resize", +"sw-resize", +"s-resize", +"w-resize", +"text", +"wait", +"help", +"ltr", +"rtl", +"capitalize", +"uppercase", +"lowercase", +"visible", +"collapse", +"close-quote", +"no-close-quote", +"no-open-quote", +"open-quote", +"nowrap", +"pre", +"pre-wrap", +"pre-line", +"-khtml-nowrap", +"above", +"absolute", +"always", +"avoid", +"below", +"bidi-override", +"blink", +"both", +"crop", +"cross", +"embed", +"fixed", +"hand", +"hide", +"higher", +"invert", +"landscape", +"level", +"line-through", +"loud", +"lower", +"marquee", +"mix", +"overline", +"portrait", +"relative", +"scroll", +"separate", +"show", +"static", +"thick", +"thin", +"underline", +"-khtml-normal", +"-khtml-around-floats", +"border-box", +"content-box", +"enabled", +"disabled", +"forwards", +"backwards", +"ahead", +"reverse", +"up", +"down", +"slow", +"fast", +"infinite", +"slide", +"alternate", +"unfurl", +"clip", +"ellipsis", +"border", +"content", +"padding", + 0 +}; +DOMString getValueName(unsigned short id) +{ + if(id >= CSS_VAL_TOTAL || id == 0) + return DOMString(); + else + return DOMString(valueList[id]); +} + diff --git a/khtml/css/cssvalues.h b/khtml/css/cssvalues.h new file mode 100644 index 000000000..0e0442c79 --- /dev/null +++ b/khtml/css/cssvalues.h @@ -0,0 +1,289 @@ +/* This file is automatically generated from cssvalues.in by +#makevalues, do not edit */ +/* Copyright 1998 W. Bastian */ + +#ifndef CSSVALUES_H +#define CSSVALUES_H + +DOM::DOMString getValueName(unsigned short id) KDE_NO_EXPORT; + +#define CSS_VAL_INVALID 0 +#define CSS_VAL_MIN 1 +#define CSS_VAL_INHERIT 1 +#define CSS_VAL_INITIAL 2 +#define CSS_VAL__KHTML_NATIVE 3 +#define CSS_VAL_NONE 4 +#define CSS_VAL_HIDDEN 5 +#define CSS_VAL_INSET 6 +#define CSS_VAL_GROOVE 7 +#define CSS_VAL_RIDGE 8 +#define CSS_VAL_OUTSET 9 +#define CSS_VAL_DOTTED 10 +#define CSS_VAL_DASHED 11 +#define CSS_VAL_SOLID 12 +#define CSS_VAL_DOUBLE 13 +#define CSS_VAL_CAPTION 14 +#define CSS_VAL_ICON 15 +#define CSS_VAL_MENU 16 +#define CSS_VAL_MESSAGE_BOX 17 +#define CSS_VAL_SMALL_CAPTION 18 +#define CSS_VAL_STATUS_BAR 19 +#define CSS_VAL_ITALIC 20 +#define CSS_VAL_OBLIQUE 21 +#define CSS_VAL_SMALL_CAPS 22 +#define CSS_VAL_NORMAL 23 +#define CSS_VAL_BOLD 24 +#define CSS_VAL_BOLDER 25 +#define CSS_VAL_LIGHTER 26 +#define CSS_VAL_100 27 +#define CSS_VAL_200 28 +#define CSS_VAL_300 29 +#define CSS_VAL_400 30 +#define CSS_VAL_500 31 +#define CSS_VAL_600 32 +#define CSS_VAL_700 33 +#define CSS_VAL_800 34 +#define CSS_VAL_900 35 +#define CSS_VAL_XX_SMALL 36 +#define CSS_VAL_X_SMALL 37 +#define CSS_VAL_SMALL 38 +#define CSS_VAL_MEDIUM 39 +#define CSS_VAL_LARGE 40 +#define CSS_VAL_X_LARGE 41 +#define CSS_VAL_XX_LARGE 42 +#define CSS_VAL__KHTML_XXX_LARGE 43 +#define CSS_VAL_SMALLER 44 +#define CSS_VAL_LARGER 45 +#define CSS_VAL_WIDER 46 +#define CSS_VAL_NARROWER 47 +#define CSS_VAL_ULTRA_CONDENSED 48 +#define CSS_VAL_EXTRA_CONDENSED 49 +#define CSS_VAL_CONDENSED 50 +#define CSS_VAL_SEMI_CONDENSED 51 +#define CSS_VAL_SEMI_EXPANDED 52 +#define CSS_VAL_EXPANDED 53 +#define CSS_VAL_EXTRA_EXPANDED 54 +#define CSS_VAL_ULTRA_EXPANDED 55 +#define CSS_VAL_SERIF 56 +#define CSS_VAL_SANS_SERIF 57 +#define CSS_VAL_CURSIVE 58 +#define CSS_VAL_FANTASY 59 +#define CSS_VAL_MONOSPACE 60 +#define CSS_VAL_TRANSPARENT 61 +#define CSS_VAL_AQUA 62 +#define CSS_VAL_BLACK 63 +#define CSS_VAL_BLUE 64 +#define CSS_VAL_CRIMSON 65 +#define CSS_VAL_FUCHSIA 66 +#define CSS_VAL_GRAY 67 +#define CSS_VAL_GREEN 68 +#define CSS_VAL_INDIGO 69 +#define CSS_VAL_LIME 70 +#define CSS_VAL_MAROON 71 +#define CSS_VAL_NAVY 72 +#define CSS_VAL_OLIVE 73 +#define CSS_VAL_ORANGE 74 +#define CSS_VAL_PURPLE 75 +#define CSS_VAL_RED 76 +#define CSS_VAL_SILVER 77 +#define CSS_VAL_TEAL 78 +#define CSS_VAL_WHITE 79 +#define CSS_VAL_YELLOW 80 +#define CSS_VAL_ACTIVEBORDER 81 +#define CSS_VAL_ACTIVECAPTION 82 +#define CSS_VAL_APPWORKSPACE 83 +#define CSS_VAL_BACKGROUND 84 +#define CSS_VAL_BUTTONFACE 85 +#define CSS_VAL_BUTTONHIGHLIGHT 86 +#define CSS_VAL_BUTTONSHADOW 87 +#define CSS_VAL_BUTTONTEXT 88 +#define CSS_VAL_CAPTIONTEXT 89 +#define CSS_VAL_GRAYTEXT 90 +#define CSS_VAL_HIGHLIGHT 91 +#define CSS_VAL_HIGHLIGHTTEXT 92 +#define CSS_VAL_INACTIVEBORDER 93 +#define CSS_VAL_INACTIVECAPTION 94 +#define CSS_VAL_INACTIVECAPTIONTEXT 95 +#define CSS_VAL_INFOBACKGROUND 96 +#define CSS_VAL_INFOTEXT 97 +#define CSS_VAL_MENUTEXT 98 +#define CSS_VAL_SCROLLBAR 99 +#define CSS_VAL_THREEDDARKSHADOW 100 +#define CSS_VAL_THREEDFACE 101 +#define CSS_VAL_THREEDHIGHLIGHT 102 +#define CSS_VAL_THREEDLIGHTSHADOW 103 +#define CSS_VAL_THREEDSHADOW 104 +#define CSS_VAL_WINDOW 105 +#define CSS_VAL_WINDOWFRAME 106 +#define CSS_VAL_WINDOWTEXT 107 +#define CSS_VAL_GREY 108 +#define CSS_VAL__KHTML_TEXT 109 +#define CSS_VAL_REPEAT 110 +#define CSS_VAL_REPEAT_X 111 +#define CSS_VAL_REPEAT_Y 112 +#define CSS_VAL_NO_REPEAT 113 +#define CSS_VAL_BASELINE 114 +#define CSS_VAL_MIDDLE 115 +#define CSS_VAL_SUB 116 +#define CSS_VAL_SUPER 117 +#define CSS_VAL_TEXT_TOP 118 +#define CSS_VAL_TEXT_BOTTOM 119 +#define CSS_VAL_TOP 120 +#define CSS_VAL_BOTTOM 121 +#define CSS_VAL__KHTML_BASELINE_MIDDLE 122 +#define CSS_VAL__KHTML_AUTO 123 +#define CSS_VAL_LEFT 124 +#define CSS_VAL_RIGHT 125 +#define CSS_VAL_CENTER 126 +#define CSS_VAL_JUSTIFY 127 +#define CSS_VAL__KHTML_LEFT 128 +#define CSS_VAL__KHTML_RIGHT 129 +#define CSS_VAL__KHTML_CENTER 130 +#define CSS_VAL_OUTSIDE 131 +#define CSS_VAL_INSIDE 132 +#define CSS_VAL_DISC 133 +#define CSS_VAL_CIRCLE 134 +#define CSS_VAL_SQUARE 135 +#define CSS_VAL_BOX 136 +#define CSS_VAL__KHTML_DIAMOND 137 +#define CSS_VAL_DECIMAL 138 +#define CSS_VAL_DECIMAL_LEADING_ZERO 139 +#define CSS_VAL__KHTML_ARABIC_INDIC 140 +#define CSS_VAL__KHTML_LAO 141 +#define CSS_VAL__KHTML_PERSIAN 142 +#define CSS_VAL__KHTML_URDU 143 +#define CSS_VAL__KHTML_THAI 144 +#define CSS_VAL__KHTML_TIBETAN 145 +#define CSS_VAL_LOWER_ROMAN 146 +#define CSS_VAL_UPPER_ROMAN 147 +#define CSS_VAL_HEBREW 148 +#define CSS_VAL_ARMENIAN 149 +#define CSS_VAL_GEORGIAN 150 +#define CSS_VAL_CJK_IDEOGRAPHIC 151 +#define CSS_VAL__KHTML_JAPANESE_FORMAL 152 +#define CSS_VAL__KHTML_JAPANESE_INFORMAL 153 +#define CSS_VAL__KHTML_SIMP_CHINESE_FORMAL 154 +#define CSS_VAL__KHTML_SIMP_CHINESE_INFORMAL 155 +#define CSS_VAL__KHTML_TRAD_CHINESE_FORMAL 156 +#define CSS_VAL__KHTML_TRAD_CHINESE_INFORMAL 157 +#define CSS_VAL_LOWER_GREEK 158 +#define CSS_VAL__KHTML_UPPER_GREEK 159 +#define CSS_VAL_LOWER_ALPHA 160 +#define CSS_VAL_LOWER_LATIN 161 +#define CSS_VAL_UPPER_ALPHA 162 +#define CSS_VAL_UPPER_LATIN 163 +#define CSS_VAL_HIRAGANA 164 +#define CSS_VAL_KATAKANA 165 +#define CSS_VAL_HIRAGANA_IROHA 166 +#define CSS_VAL_KATAKANA_IROHA 167 +#define CSS_VAL__KHTML_OPEN_QUOTE 168 +#define CSS_VAL__KHTML_CLOSE_QUOTE 169 +#define CSS_VAL_INLINE 170 +#define CSS_VAL_BLOCK 171 +#define CSS_VAL_LIST_ITEM 172 +#define CSS_VAL_RUN_IN 173 +#define CSS_VAL_COMPACT 174 +#define CSS_VAL_INLINE_BLOCK 175 +#define CSS_VAL_TABLE 176 +#define CSS_VAL_INLINE_TABLE 177 +#define CSS_VAL_TABLE_ROW_GROUP 178 +#define CSS_VAL_TABLE_HEADER_GROUP 179 +#define CSS_VAL_TABLE_FOOTER_GROUP 180 +#define CSS_VAL_TABLE_ROW 181 +#define CSS_VAL_TABLE_COLUMN_GROUP 182 +#define CSS_VAL_TABLE_COLUMN 183 +#define CSS_VAL_TABLE_CELL 184 +#define CSS_VAL_TABLE_CAPTION 185 +#define CSS_VAL_AUTO 186 +#define CSS_VAL_CROSSHAIR 187 +#define CSS_VAL_DEFAULT 188 +#define CSS_VAL_POINTER 189 +#define CSS_VAL_PROGRESS 190 +#define CSS_VAL_MOVE 191 +#define CSS_VAL_E_RESIZE 192 +#define CSS_VAL_NE_RESIZE 193 +#define CSS_VAL_NW_RESIZE 194 +#define CSS_VAL_N_RESIZE 195 +#define CSS_VAL_SE_RESIZE 196 +#define CSS_VAL_SW_RESIZE 197 +#define CSS_VAL_S_RESIZE 198 +#define CSS_VAL_W_RESIZE 199 +#define CSS_VAL_TEXT 200 +#define CSS_VAL_WAIT 201 +#define CSS_VAL_HELP 202 +#define CSS_VAL_LTR 203 +#define CSS_VAL_RTL 204 +#define CSS_VAL_CAPITALIZE 205 +#define CSS_VAL_UPPERCASE 206 +#define CSS_VAL_LOWERCASE 207 +#define CSS_VAL_VISIBLE 208 +#define CSS_VAL_COLLAPSE 209 +#define CSS_VAL_CLOSE_QUOTE 210 +#define CSS_VAL_NO_CLOSE_QUOTE 211 +#define CSS_VAL_NO_OPEN_QUOTE 212 +#define CSS_VAL_OPEN_QUOTE 213 +#define CSS_VAL_NOWRAP 214 +#define CSS_VAL_PRE 215 +#define CSS_VAL_PRE_WRAP 216 +#define CSS_VAL_PRE_LINE 217 +#define CSS_VAL__KHTML_NOWRAP 218 +#define CSS_VAL_ABOVE 219 +#define CSS_VAL_ABSOLUTE 220 +#define CSS_VAL_ALWAYS 221 +#define CSS_VAL_AVOID 222 +#define CSS_VAL_BELOW 223 +#define CSS_VAL_BIDI_OVERRIDE 224 +#define CSS_VAL_BLINK 225 +#define CSS_VAL_BOTH 226 +#define CSS_VAL_CROP 227 +#define CSS_VAL_CROSS 228 +#define CSS_VAL_EMBED 229 +#define CSS_VAL_FIXED 230 +#define CSS_VAL_HAND 231 +#define CSS_VAL_HIDE 232 +#define CSS_VAL_HIGHER 233 +#define CSS_VAL_INVERT 234 +#define CSS_VAL_LANDSCAPE 235 +#define CSS_VAL_LEVEL 236 +#define CSS_VAL_LINE_THROUGH 237 +#define CSS_VAL_LOUD 238 +#define CSS_VAL_LOWER 239 +#define CSS_VAL_MARQUEE 240 +#define CSS_VAL_MIX 241 +#define CSS_VAL_OVERLINE 242 +#define CSS_VAL_PORTRAIT 243 +#define CSS_VAL_RELATIVE 244 +#define CSS_VAL_SCROLL 245 +#define CSS_VAL_SEPARATE 246 +#define CSS_VAL_SHOW 247 +#define CSS_VAL_STATIC 248 +#define CSS_VAL_THICK 249 +#define CSS_VAL_THIN 250 +#define CSS_VAL_UNDERLINE 251 +#define CSS_VAL__KHTML_NORMAL 252 +#define CSS_VAL__KHTML_AROUND_FLOATS 253 +#define CSS_VAL_BORDER_BOX 254 +#define CSS_VAL_CONTENT_BOX 255 +#define CSS_VAL_ENABLED 256 +#define CSS_VAL_DISABLED 257 +#define CSS_VAL_FORWARDS 258 +#define CSS_VAL_BACKWARDS 259 +#define CSS_VAL_AHEAD 260 +#define CSS_VAL_REVERSE 261 +#define CSS_VAL_UP 262 +#define CSS_VAL_DOWN 263 +#define CSS_VAL_SLOW 264 +#define CSS_VAL_FAST 265 +#define CSS_VAL_INFINITE 266 +#define CSS_VAL_SLIDE 267 +#define CSS_VAL_ALTERNATE 268 +#define CSS_VAL_UNFURL 269 +#define CSS_VAL_CLIP 270 +#define CSS_VAL_ELLIPSIS 271 +#define CSS_VAL_BORDER 272 +#define CSS_VAL_CONTENT 273 +#define CSS_VAL_PADDING 274 + +#define CSS_VAL_TOTAL 275 +#endif + diff --git a/khtml/css/cssvalues.in b/khtml/css/cssvalues.in new file mode 100644 index 000000000..86db77670 --- /dev/null +++ b/khtml/css/cssvalues.in @@ -0,0 +1,473 @@ +# These are all values accepted for CSS2. +# +# WARNING: +# -------- +# +# The Values are sorted according to the properties they belong to, +# and have to be in the same order as the enums in render_style.h. +# +# If not, the optimizations in the cssparser and style selector will fail, +# and produce incorrect results. +# +inherit +initial +# +# CSS_PROP_OUTLINE_STYLE +# CSS_PROP_BORDER_TOP_STYLE +# CSS_PROP_BORDER_BOTTOM_STYLE +# CSS_PROP_BORDER_LEFT_STYLE +-khtml-native +none +hidden +inset +groove +ridge +outset +dotted +dashed +solid +double +# +# CSS_PROP_FONT: +# +caption +icon +menu +message-box +small-caption +status-bar +# +# CSS_PROP_FONT_STYLE: +# +#normal +italic +oblique +# +# CSS_PROP_FONT_VARIANT: +# +#normal +small-caps +# +# CSS_PROP_FONT_WEIGHT: +# +normal +bold +bolder +lighter +100 +200 +300 +400 +500 +600 +700 +800 +900 +# +# CSS_PROP_FONT_SIZE: +# +xx-small +x-small +small +medium +large +x-large +xx-large +-khtml-xxx-large +smaller +larger +# +# CSS_PROP_FONT_STRETCH: +# +#normal +wider +narrower +ultra-condensed +extra-condensed +condensed +semi-condensed +semi-expanded +expanded +extra-expanded +ultra-expanded +# +# CSS_PROP_GENERIC_FONT_FAMILY: +# +serif +sans-serif +cursive +fantasy +monospace +# +# +# CSS_PROP_BACKGROUND_COLOR: +# +transparent +# +# +# CSS_PROP_*_COLOR +# +aqua +black +blue +crimson +fuchsia +gray +green +indigo +lime +maroon +navy +olive +orange +purple +red +silver +teal +white +yellow +activeborder +activecaption +appworkspace +background +buttonface +buttonhighlight +buttonshadow +buttontext +captiontext +graytext +highlight +highlighttext +inactiveborder +inactivecaption +inactivecaptiontext +infobackground +infotext +menutext +scrollbar +threeddarkshadow +threedface +threedhighlight +threedlightshadow +threedshadow +window +windowframe +windowtext +# +# colors in non strict mode +grey +-khtml-text +# +# CSS_PROP_BACKGROUND_REPEAT: +# +repeat +repeat-x +repeat-y +no-repeat +# +# CSS_PROP_VERTICAL_ALIGN: +# +baseline +middle +sub +super +text-top +text-bottom +top +bottom +# HTML alignment MIDDLE has no corresponding CSS alignment +-khtml-baseline-middle +# +# CSS_PROP_TEXT_ALIGN: +# +-khtml-auto +left +right +center +justify +-khtml-left +-khtml-right +-khtml-center +# +# CSS_PROP_LIST_STYLE_POSITION: +# +outside +inside +# +# CSS_PROP_LIST_STYLE_TYPE: +# +disc +circle +square +box +-khtml-diamond +decimal +decimal-leading-zero +-khtml-arabic-indic +-khtml-lao +-khtml-persian +-khtml-urdu +-khtml-thai +-khtml-tibetan +lower-roman +upper-roman +hebrew +armenian +georgian +cjk-ideographic +-khtml-japanese-formal +-khtml-japanese-informal +-khtml-simp-chinese-formal +-khtml-simp-chinese-informal +-khtml-trad-chinese-formal +-khtml-trad-chinese-informal +lower-greek +-khtml-upper-greek +lower-alpha +lower-latin +upper-alpha +upper-latin +hiragana +katakana +hiragana-iroha +katakana-iroha +-khtml-open-quote +-khtml-close-quote +#none +# +# CSS_PROP_DISPLAY: +# +inline +block +list-item +run-in +compact +inline-block +table +inline-table +table-row-group +table-header-group +table-footer-group +table-row +table-column-group +table-column +table-cell +table-caption +#none +# +# CSS_PROP_CURSOR: +# +auto +crosshair +default +pointer +progress +move +e-resize +ne-resize +nw-resize +n-resize +se-resize +sw-resize +s-resize +w-resize +text +wait +help +# +# CSS_PROP_DIRECTION: +# +ltr +rtl +# +# CSS_PROP_TEXT_TRANSFORM: +# +capitalize +uppercase +lowercase +#none +# +# CSS_PROP_VISIBILITY: +# +visible +#hidden +collapse +# +# CSS_PROP_CONTENT: +# +close-quote +no-close-quote +no-open-quote +open-quote +# +# CSS_PROP_WHITE_SPACE: +# +#normal +nowrap +pre +pre-wrap +pre-line +-khtml-nowrap +# +# Unordered rest +# +above +absolute +always +avoid +below +bidi-override +blink +both +crop +cross +embed +fixed +hand +hide +higher +invert +landscape +level +line-through +loud +lower +marquee +mix +overline +portrait +relative +scroll +separate +show +static +thick +thin +underline +# +# CSS_PROP__KHTML_FLOW_MODE +-khtml-normal +-khtml-around-floats + +# CSS3 Values +# CSS_PROP__KHTML_BOX_SIZING +border-box +content-box + +# CSS_PROP__KHTML_USER_INPUT +enabled +disabled +#none + +# CSS_PROP_MARQUEE_DIRECTION +forwards +backwards +ahead +reverse +# left +# right +up +down +# auto + +# CSS_PROP_MARQUEE_SPEED +slow +# normal +fast + +# CSS_PROP_MARQUEE_REPETITION +infinite + +# CSS_PROP_MARQUEE_STYLE +# none +slide +# scroll +alternate +unfurl + +# +# CSS_PROP_TEXT_OVERFLOW +# +clip +ellipsis + +# +# CSS_PROP_BACKGROUND_CLIP/ORIGIN +# +border +content +padding + +# +# Not supported: +# +# CSS_PROP_BORDER_IMAGE +# +# stretch +# repeat +# round +# +# CSS_PROP_AZIMUTH: +# +#A left-side +#A far-left +#A #left +#A center-left +#A #center +#A center-right +#A right +#A far-right +#A right-side +#A behind +#A leftwards +#A rightwards +# +# CSS_PROP_SPEECH_RATE: +# +#A x-slow +#A slow +#A #medium +#A x-fast +#A fast +#A faster +#A slower +# +# CSS_PROP_VOLUME: +# +#A silent +#A x-soft +#A soft +#A #medium +#A high +#A x-high +#A x-loud +# +# CSS_PROP_PITCH: +# +#A x-low +#A low +#A #medium +#A #high +#A #x-high +# +# CSS_PROP_SPEAK: +# +#A #normal +#A #none +#A spell-out +# +# CSS_PROP_SPEAK_HEADER: +# +#A #once +#A always +# +# CSS_PROP_SPEAK_NUMERAL: +# +#A digits +#A continuous +# +# CSS_PROP_SPEAK_PUNCTUATION: +# +#A code +#A #none + diff --git a/khtml/css/html4.css b/khtml/css/html4.css new file mode 100644 index 000000000..c3fd1a347 --- /dev/null +++ b/khtml/css/html4.css @@ -0,0 +1,549 @@ +/* + * The default style sheet used by khtml to render HTML pages + * (C) 2000-2003 Lars Knoll (knoll@kde.org) + * + * Konqueror/khtml relies on the existence of this style sheet for + * rendering. Do not remove or modify this file unless you know + * what you are doing. + */ + +@namespace "http://www.w3.org/1999/xhtml"; + +html { + display: block; + color: -khtml-text; +} + +/* + * head and it's children all have display=none + */ + +head { + display: none; +} + +meta { + display: none; +} + +title { + display: none; +} + +link { + display: none; +} + +style { + display: none; +} + +script { + display: none; +} + +/* + * generic block level elements + */ + +@media print { + body { + display: block; + margin: 0px; + } +} + +@media screen { + body { + display: block; + margin: 10px; + } +} + +p { + display: block; + margin: 1.0__qem 0px; +} + +div { + display: block; +} + +/* to force a block level context for some cases (broken HTML) */ + +layer { + display: block; +} + +address { + display: block; +} + +blockquote { + display: block; + margin: 1__qem 40px 1em 40px; +} + +q { + display: inline; +} + +q:before { + content: open-quote; +} + +q:after { + content: close-quote; +} + +center { + display: block; + /* special centering to be able to emulate the html4/netscape behavior */ + text-align: -khtml-center; +} + +hr { + display: block; + margin: 12px auto; + border-style: inset; + border-width: 1px; + -khtml-flow-mode: -khtml-around-floats +} + +map { + display: inline; +} + +/* + * heading elements + * margin values rely on font-sizes ratio defined in css-2.1 15.7 + * (cf. cssstyleselector for absolute font-sizes computation) + * we have an 1.1/font-ratio margin + */ + +h1 { + display: block; + font-size: xx-large; + margin: .55__qem 0 .55em 0; + font-weight: bolder; +} + +h2 { + display: block; + font-size: x-large; + margin: .73__qem 0 .73em 0; + font-weight: bolder; +} + +h3 { + display: block; + font-size: large; + margin: 0.92__qem 0 0.92em 0; + font-weight: bolder; +} + +h4 { + display: block; + font-size: medium; + margin: 1.1__qem 0 1.1em 0; + font-weight: bolder; +} + +h5 { + display: block; + font-size: small; + margin: 1.24__qem 0 1.24em 0; + font-weight: bolder; +} + +h6 { + display: block; + font-size: xx-small; + margin: 1.83__qem 0 1.83em 0; + font-weight: bolder; +} + +/* + * tables + */ + +table { + display: table; + border-collapse: separate; + border-spacing: 2px; + -khtml-flow-mode: -khtml-around-floats; + box-sizing: border-box; +} + +table[align="center"] { + margin-left: auto; + margin-right: auto; +} + +table[align="left"] { + float: -khtml-left; +} + +table[align="right"] { + float: -khtml-right; +} + +thead { + display: table-header-group; + border-color: inherit; + vertical-align: middle; +} + +tbody { + display: table-row-group; + border-color: inherit; + vertical-align: middle; +} + +tfoot { + display: table-footer-group; + border-color: inherit; + vertical-align: middle; +} + +col { + display: table-column; +} + +colgroup { + display: table-column-group; +} + +tr { + display: table-row; + vertical-align: inherit; + border-color: inherit; +} + + +td, th { + display: table-cell; + vertical-align: inherit; +} + +th { + font-weight: bolder; +} + +caption { + display: table-caption; + text-align: -khtml-center; +} + +/* + * lists + */ + +ul, menu, dir { + display: block; + list-style-type: disc; + margin: 1__qem 0 1em 0; + -khtml-padding-start: 40px +} + +ol { + display: block; + list-style-type: decimal; + margin: 1__qem 0 1em 0; + -khtml-padding-start: 40px +} + +li { + display: list-item; + -khtml-flow-mode: -khtml-around-floats; +} + + +ul ul, ol ul { + list-style-type: circle; +} + +ol ol ul, ol ul ul, ul ol ul, ul ul ul { + list-style-type: square; +} + + +dd { + display: block; +} + +dl > dd { + -khtml-margin-start: 40px; +} + +dl { + display: block; + margin: 1__qem 0 1em 0; +} + +dt { + display: block; +} + +dl[compact] > dt { + display: compact; +} + +ol ul, +ul ol, +ul ul, +ol ol { + margin-top: auto; + margin-bottom: auto; +} + +li > p { + margin-top: auto; +/* margin-bottom: auto;*/ +} + +li > div { + margin-top: auto; +/* margin-bottom: auto;*/ +} + +/* + * form elements + */ + +form { + display: block; + margin: 0__qem 0 1em 0; +} + +legend { + display: block; + padding-left: 2px; + padding-right: 2px; + border: none; + margin: 0; +} + +fieldset { + display: block; + padding: 0.75em 0.625em; + margin: 1.0em 0; + border: 2px groove threedface; + -khtml-flow-mode: -khtml-around-floats +} + +button { + display: inline-block; + border: 2px outset buttonface; + background-color: buttonface; + color: buttontext; + padding: 2px 2px 2px 2px; + cursor: default; +} + +button:active { + border-style: inset; +} + +input, textarea { + text-align: -khtml-auto; +} + +input, textarea, select, button { + font-weight: normal; + margin: 0__qem; +} + +input { color: windowtext; + font-family: sans-serif; + font-size: small; + border: 2px -khtml-native; +} + +input[type="hidden"] { + display: none; +} + +input[type="radio"], input[type="checkbox"] { + margin: 0 0.5ex; + color: buttontext; +} + +input[type="text"], input[type="password"] { + cursor: text; +} + +input[type="submit"], input[type="reset"], input[type="button"] { + color: buttontext; +} + +isindex { color: windowtext; font-size: small; } + + +option, +optgroup, +area, +param { + display: none; +} + +select { + font-family: sans-serif; + font-size: small; + color: windowtext; +} + +textarea { + color: windowtext; + font-family: monospace; + border: 2px -khtml-native; +} + +/* + * inline elements + */ + +u, +ins { + text-decoration: underline; +} + +strong, +b { + font-weight: bolder; +} + +i, +cite, +em, +var, +address { + font-style: italic; +} + +tt, +code, +kbd, +samp { + font-family: monospace; +} + +pre, +xmp, +plaintext { + display: block; + font-family: monospace; + white-space: pre; + margin: 1__qem 0; +} + +big { + font-size: larger; +} + +small { + font-size: smaller; +} + +s, +strike, +del { + text-decoration: line-through; +} + +sub { + vertical-align: sub; + font-size: smaller; +} +sup { + vertical-align: super; + font-size: smaller; +} + +abbr, acronym { + font-variant: small-caps; + letter-spacing: 0.1em +} + +pre[wrap] { + white-space: pre-wrap +} + +*|:focus { outline: 1px dotted invert } +a:link:active { color: red; outline: 1px dotted invert; } +a:visited:active { color: red; outline: 1px dotted invert; } + +/* with the current design it is too expensive to set this default via css +:before,:after { white-space: pre-line } +*/ + +/* ### use this to replace renderbr + br:before { content: "\n" } +*/ + + +/* bidirectionality settings (do not change) */ + +bdo[dir="ltr"] { + direction: ltr; + unicode-bidi: bidi-override; +} + +bdo[dir="rtl"] { + direction: rtl; + unicode-bidi: bidi-override; +} + +/* ### this selector seems to be still broken ... + *[dir="ltr"] { direction: ltr; unicode-bidi: embed } + *[dir="rtl"] { direction: rtl; unicode-bidi: embed } +*/ + +/* elements that are block-level in html4 */ +/* ### don't support unicode-bidi at the moment + address, blockquote, body, dd, div, dl, dt, fieldset, + form, frame, frameset, h1, h2, h3, h4, h5, h6, iframe, + noscript, noframes, object, ol, p, ul, applet, center, + dir, hr, menu, pre, li, table, tr, thead, tbody, tfoot, + col, colgroup, td, th, caption + { unicode-bidi: embed } +*/ + +/* end bidi settings */ + +/* + * other elements + */ + +noframes { + display: none; +} + +frameset { + display: block; +} + +frame { + display: block; +} + +nobr { + white-space: nowrap; +} + +wbr { + white-space: normal; +} + +marquee { + display: inline-block; + overflow: marquee; +} + +/* noscript is handled internally, as it depends on the html settings */ + +@media print { + h1, h2, h3, + h4, h5, h6 { page-break-after: avoid } + ul, ol, dl { page-break-before: avoid } +} diff --git a/khtml/css/makeprop b/khtml/css/makeprop new file mode 100644 index 000000000..a1a30ac97 --- /dev/null +++ b/khtml/css/makeprop @@ -0,0 +1,57 @@ +# This file is part of the KDE libraries +# +# Copyright (C) 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., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. +# +#---------------------------------------------------------------------------- +# +# KDE HTML Widget -- Script to generate cssproperties.c and cssproperties.h +# +grep "^[^\#]" cssproperties.in > cssproperties.strip + +echo -e '%{\n/* This file is automatically generated from cssproperties.in by makeprop, do not edit */\n/* Copyright 1999 W. Bastian */\n#include "cssproperties.h"\n%}\nstruct props {\n const char *name;\n int id;\n};\n\nstatic const struct props * findProp (register const char *str, register unsigned int len);\n\n%%' > cssproperties.gperf +cat cssproperties.strip | awk '{ do { prop = $0; gsub("-", "_"); print prop ", CSS_PROP_" toupper($0) } while (getline) }' >> cssproperties.gperf +echo '%%' >> cssproperties.gperf +echo -e '/* This file is automatically generated from cssproperties.in by makeprop, do not edit */\n/* Copyright 1998 W. Bastian */\n\n#ifndef CSSPROPERTIES_H\n#define CSSPROPERTIES_H\n\nDOM::DOMString getPropertyName(unsigned short id) KDE_NO_EXPORT;\n' > cssproperties.h +cat cssproperties.strip | awk '{ \ +i=1; \ +print "#define CSS_PROP_INVALID 0"; \ +print "#define CSS_PROP_MIN 1"; \ +do { gsub("-", "_"); print "#define CSS_PROP_" toupper($0) " " i; i = i + 1 } while (getline); \ +print ""; \ +print "#define CSS_PROP_MAX CSS_PROP_Z_INDEX"; \ +print "#define CSS_PROP_TOTAL " i \ +}' >> cssproperties.h +gperf -a -L 'ANSI-C' -E -C -c -o -t -k '*' -NfindProp -Hhash_prop -Wwordlist_prop -D -s 2 cssproperties.gperf > cssproperties.c || exit 1 +echo -e '#endif\n' >> cssproperties.h + +cat cssproperties.strip | awk '{ \ +i=1; \ +print "static const char * const propertyList[] = {"; \ +print "\"\","; \ +do { print "\"" $0 "\", "; i = i + 1 } while (getline); \ +print " 0"; \ +print "};"; \ +print "DOMString getPropertyName(unsigned short id)"; \ +print "{"; \ +print " if(id >= CSS_PROP_TOTAL || id == 0)"; \ +print " return DOMString();";\ +print " else";\ +print " return DOMString(propertyList[id]);"; \ +print "}"; \ +print ""; \ +}' >> cssproperties.c diff --git a/khtml/css/makevalues b/khtml/css/makevalues new file mode 100755 index 000000000..0f81f1612 --- /dev/null +++ b/khtml/css/makevalues @@ -0,0 +1,63 @@ +#!/bin/sh +# This file is part of the KDE libraries +# +# Copyright (C) 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., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. +# +#---------------------------------------------------------------------------- +# +# KDE HTML Widget -- Script to generate cssvalues.c and cssvalues.h +# +grep "^[^\#]" cssvalues.in > cssvalues.strip + +echo -e '%{\n/* This file is automatically generated from cssvalues.in by makevalues, do not edit */\n/* Copyright 1999 W. Bastian */\n#include "cssvalues.h"\n%}\nstruct css_value {\n const char *name;\n int id;\n};\n\nstatic const css_value* findValue (register const char *str, register unsigned int len);\n\n%%' > cssvalues.gperf +cat cssvalues.strip | awk '{ do { prop = $0; gsub("-", "_"); print prop ", CSS_VAL_" toupper($0) } while (getline) }' >> cssvalues.gperf +echo '%%' >> cssvalues.gperf +echo -e '/* This file is automatically generated from cssvalues.in by +#makevalues, do not edit */\n/* Copyright 1998 W. Bastian */\n\n#ifndef CSSVALUES_H\n#define CSSVALUES_H\n\nDOM::DOMString getValueName(unsigned short id) KDE_NO_EXPORT;\n' > cssvalues.h +cat cssvalues.strip | awk '{ \ +i=1; \ +print "#define CSS_VAL_INVALID 0"; \ +print "#define CSS_VAL_MIN 1"; \ +do { gsub("-", "_"); print "#define CSS_VAL_" toupper($0) " " i; i = i + 1 } while (getline); \ +print ""; \ +print "#define CSS_VAL_TOTAL " i \ +}' >> cssvalues.h +gperf -L 'ANSI-C' -E -c -C -n -o -t -k '*' -NfindValue -Hhash_val -Wwordlist_value -D cssvalues.gperf > cssvalues.c || exit 1 +echo -e '#endif\n' >> cssvalues.h + +cat cssvalues.strip | awk '{ \ +i=1; \ +print "static const char * const valueList[] = {"; \ +print "\"\","; \ +do { print "\"" $0 "\", "; i = i + 1 } while (getline); \ +print " 0"; \ +print "};"; \ +print "DOMString getValueName(unsigned short id)"; \ +print "{"; \ +print " if(id >= CSS_VAL_TOTAL || id == 0)"; \ +print " return DOMString();";\ +print " else";\ +print " return DOMString(valueList[id]);"; \ +print "}"; \ +print ""; \ +}' >> cssvalues.c + + + + + diff --git a/khtml/css/parser.cpp b/khtml/css/parser.cpp new file mode 100644 index 000000000..8f339055a --- /dev/null +++ b/khtml/css/parser.cpp @@ -0,0 +1,2874 @@ +/* A Bison parser, made by GNU Bison 1.875d. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Written by Richard Stallman by simplifying the original so called + ``semantic'' parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 1 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + +/* If NAME_PREFIX is specified substitute the variables and functions + names. */ +#define yyparse cssyyparse +#define yylex cssyylex +#define yyerror cssyyerror +#define yylval cssyylval +#define yychar cssyychar +#define yydebug cssyydebug +#define yynerrs cssyynerrs + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + UNIMPORTANT_TOK = 258, + S = 259, + SGML_CD = 260, + INCLUDES = 261, + DASHMATCH = 262, + BEGINSWITH = 263, + ENDSWITH = 264, + CONTAINS = 265, + STRING = 266, + IDENT = 267, + NTH = 268, + HASH = 269, + IMPORT_SYM = 270, + PAGE_SYM = 271, + MEDIA_SYM = 272, + FONT_FACE_SYM = 273, + CHARSET_SYM = 274, + NAMESPACE_SYM = 275, + KHTML_RULE_SYM = 276, + KHTML_DECLS_SYM = 277, + KHTML_VALUE_SYM = 278, + IMPORTANT_SYM = 279, + QEMS = 280, + EMS = 281, + EXS = 282, + PXS = 283, + CMS = 284, + MMS = 285, + INS = 286, + PTS = 287, + PCS = 288, + DEGS = 289, + RADS = 290, + GRADS = 291, + MSECS = 292, + SECS = 293, + HERZ = 294, + KHERZ = 295, + DIMEN = 296, + PERCENTAGE = 297, + FLOAT = 298, + INTEGER = 299, + URI = 300, + FUNCTION = 301, + NOTFUNCTION = 302, + UNICODERANGE = 303 + }; +#endif +#define UNIMPORTANT_TOK 258 +#define S 259 +#define SGML_CD 260 +#define INCLUDES 261 +#define DASHMATCH 262 +#define BEGINSWITH 263 +#define ENDSWITH 264 +#define CONTAINS 265 +#define STRING 266 +#define IDENT 267 +#define NTH 268 +#define HASH 269 +#define IMPORT_SYM 270 +#define PAGE_SYM 271 +#define MEDIA_SYM 272 +#define FONT_FACE_SYM 273 +#define CHARSET_SYM 274 +#define NAMESPACE_SYM 275 +#define KHTML_RULE_SYM 276 +#define KHTML_DECLS_SYM 277 +#define KHTML_VALUE_SYM 278 +#define IMPORTANT_SYM 279 +#define QEMS 280 +#define EMS 281 +#define EXS 282 +#define PXS 283 +#define CMS 284 +#define MMS 285 +#define INS 286 +#define PTS 287 +#define PCS 288 +#define DEGS 289 +#define RADS 290 +#define GRADS 291 +#define MSECS 292 +#define SECS 293 +#define HERZ 294 +#define KHERZ 295 +#define DIMEN 296 +#define PERCENTAGE 297 +#define FLOAT 298 +#define INTEGER 299 +#define URI 300 +#define FUNCTION 301 +#define NOTFUNCTION 302 +#define UNICODERANGE 303 + + + + +/* Copy the first part of user declarations. */ + + + +/* + * This file is part of the KDE libraries + * Copyright (C) 2002-2003 Lars Knoll (knoll@kde.org) + * Copyright (c) 2003 Apple Computer + * Copyright (C) 2003 Dirk Mueller (mueller@kde.org) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <string.h> +#include <stdlib.h> + +#include <dom/dom_string.h> +#include <xml/dom_docimpl.h> +#include <css/cssstyleselector.h> +#include <css/css_ruleimpl.h> +#include <css/css_stylesheetimpl.h> +#include <css/css_valueimpl.h> +#include <misc/htmlhashes.h> +#include "cssparser.h" + +#include <assert.h> +#include <kdebug.h> +//#define CSS_DEBUG + +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 + +// turn off inlining to void warning with newer gcc +#undef __inline +#define __inline +#include "cssproperties.c" +#include "cssvalues.c" +#undef __inline + +int DOM::getPropertyID(const char *tagStr, int len) +{ + const struct props *propsPtr = findProp(tagStr, len); + if (!propsPtr) + return 0; + + return propsPtr->id; +} + +static inline int getValueID(const char *tagStr, int len) +{ + const struct css_value *val = findValue(tagStr, len); + if (!val) + return 0; + + return val->id; +} + + +#define YYDEBUG 0 +#undef YYMAXDEPTH +#define YYPARSE_PARAM parser + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) + +typedef union YYSTYPE { + CSSRuleImpl *rule; + CSSSelector *selector; + QPtrList<CSSSelector> *selectorList; + bool ok; + MediaListImpl *mediaList; + CSSMediaRuleImpl *mediaRule; + CSSRuleListImpl *ruleList; + ParseString string; + float val; + int prop_id; + unsigned int attribute; + unsigned int element; + unsigned int ns; + CSSSelector::Relation relation; + CSSSelector::Match match; + bool b; + char tok; + Value value; + ValueList *valueList; +} YYSTYPE; +/* Line 191 of yacc.c. */ + +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + +/* Copy the second part of user declarations. */ + + + +static inline int cssyyerror(const char *x ) +{ +#ifdef CSS_DEBUG + qDebug( "%s", x ); +#else + Q_UNUSED( x ); +#endif + return 1; +} + +static int cssyylex( YYSTYPE *yylval ) { + return CSSParser::current()->lex( yylval ); +} + +#define null 1 + + + +/* Line 214 of yacc.c. */ + + +#if ! defined (yyoverflow) || YYERROR_VERBOSE + +# ifndef YYFREE +# define YYFREE free +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# endif + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# define YYSTACK_ALLOC alloca +# endif +# else +# if defined (alloca) || defined (_ALLOCA_H) +# define YYSTACK_ALLOC alloca +# else +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# else +# if defined (__STDC__) || defined (__cplusplus) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# endif +#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ + + +#if (! defined (yyoverflow) \ + && (! defined (__cplusplus) \ + || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + short int yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined (__GNUC__) && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined (__STDC__) || defined (__cplusplus) + typedef signed char yysigned_char; +#else + typedef short int yysigned_char; +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 16 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 479 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 67 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 54 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 162 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 305 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 303 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const unsigned char yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 64, 18, 58, 57, 61, 16, 65, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 15, 56, + 2, 63, 60, 2, 66, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 17, 2, 62, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 54, 19, 55, 59, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const unsigned short int yyprhs[] = +{ + 0, 0, 3, 9, 12, 15, 18, 25, 28, 34, + 35, 38, 39, 42, 45, 46, 52, 56, 60, 61, + 65, 72, 76, 80, 81, 85, 92, 96, 100, 101, + 104, 105, 109, 111, 113, 115, 117, 119, 121, 124, + 126, 128, 129, 131, 133, 138, 141, 149, 150, 154, + 157, 161, 165, 169, 173, 176, 179, 182, 183, 185, + 187, 190, 192, 197, 200, 202, 206, 209, 211, 214, + 217, 220, 224, 227, 231, 236, 240, 242, 244, 246, + 249, 252, 254, 256, 258, 260, 263, 266, 271, 280, + 286, 296, 298, 300, 302, 304, 306, 308, 310, 312, + 315, 319, 324, 329, 334, 339, 345, 350, 355, 360, + 366, 372, 376, 380, 385, 390, 396, 399, 402, 405, + 406, 408, 412, 415, 418, 419, 421, 424, 427, 430, + 433, 436, 439, 441, 443, 446, 449, 452, 455, 458, + 461, 464, 467, 470, 473, 476, 479, 482, 485, 488, + 491, 494, 497, 500, 506, 510, 513, 517, 521, 524, + 530, 534, 536 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yysigned_char yyrhs[] = +{ + 68, 0, -1, 74, 73, 75, 77, 80, -1, 69, + 72, -1, 70, 72, -1, 71, 72, -1, 26, 54, + 72, 92, 72, 55, -1, 27, 106, -1, 28, 54, + 72, 111, 55, -1, -1, 72, 4, -1, -1, 73, + 5, -1, 73, 4, -1, -1, 24, 72, 11, 72, + 56, -1, 24, 1, 119, -1, 24, 1, 56, -1, + -1, 75, 76, 73, -1, 20, 72, 82, 72, 83, + 56, -1, 20, 1, 119, -1, 20, 1, 56, -1, + -1, 77, 78, 73, -1, 25, 72, 79, 82, 72, + 56, -1, 25, 1, 119, -1, 25, 1, 56, -1, + -1, 12, 4, -1, -1, 80, 81, 73, -1, 92, + -1, 85, -1, 88, -1, 89, -1, 118, -1, 117, + -1, 76, 1, -1, 11, -1, 50, -1, -1, 84, + -1, 87, -1, 84, 57, 72, 87, -1, 84, 1, + -1, 22, 72, 84, 54, 72, 86, 55, -1, -1, + 86, 92, 72, -1, 12, 72, -1, 21, 1, 119, + -1, 21, 1, 56, -1, 23, 1, 119, -1, 23, + 1, 56, -1, 58, 72, -1, 59, 72, -1, 60, + 72, -1, -1, 61, -1, 58, -1, 93, 106, -1, + 94, -1, 93, 57, 72, 94, -1, 93, 1, -1, + 96, -1, 94, 90, 96, -1, 94, 1, -1, 19, + -1, 18, 19, -1, 12, 19, -1, 97, 72, -1, + 97, 98, 72, -1, 98, 72, -1, 95, 97, 72, + -1, 95, 97, 98, 72, -1, 95, 98, 72, -1, + 12, -1, 18, -1, 99, -1, 98, 99, -1, 98, + 1, -1, 14, -1, 100, -1, 102, -1, 105, -1, + 16, 12, -1, 12, 72, -1, 17, 72, 101, 62, + -1, 17, 72, 101, 103, 72, 104, 72, 62, -1, + 17, 72, 95, 101, 62, -1, 17, 72, 95, 101, + 103, 72, 104, 72, 62, -1, 63, -1, 6, -1, + 7, -1, 8, -1, 9, -1, 10, -1, 12, -1, + 11, -1, 15, 12, -1, 15, 15, 12, -1, 15, + 51, 13, 64, -1, 15, 51, 49, 64, -1, 15, + 51, 12, 64, -1, 15, 51, 11, 64, -1, 15, + 52, 72, 96, 64, -1, 54, 72, 108, 55, -1, + 54, 72, 1, 55, -1, 54, 72, 107, 55, -1, + 54, 72, 107, 108, 55, -1, 54, 72, 107, 1, + 55, -1, 108, 56, 72, -1, 1, 56, 72, -1, + 107, 108, 56, 72, -1, 107, 1, 56, 72, -1, + 109, 15, 72, 111, 110, -1, 1, 119, -1, 12, + 72, -1, 29, 72, -1, -1, 113, -1, 111, 112, + 113, -1, 65, 72, -1, 57, 72, -1, -1, 114, + -1, 91, 114, -1, 46, 72, -1, 11, 72, -1, + 12, 72, -1, 50, 72, -1, 53, 72, -1, 116, + -1, 115, -1, 49, 72, -1, 48, 72, -1, 47, + 72, -1, 33, 72, -1, 34, 72, -1, 35, 72, + -1, 36, 72, -1, 37, 72, -1, 38, 72, -1, + 39, 72, -1, 40, 72, -1, 41, 72, -1, 42, + 72, -1, 43, 72, -1, 44, 72, -1, 45, 72, + -1, 31, 72, -1, 30, 72, -1, 32, 72, -1, + 51, 72, 111, 64, 72, -1, 51, 72, 1, -1, + 14, 72, -1, 66, 1, 119, -1, 66, 1, 56, + -1, 1, 119, -1, 54, 1, 120, 1, 55, -1, + 54, 1, 55, -1, 119, -1, 120, 1, 119, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const unsigned short int yyrline[] = +{ + 0, 257, 257, 258, 259, 260, 264, 271, 277, 302, + 303, 306, 308, 309, 312, 314, 319, 320, 323, 325, + 336, 346, 349, 355, 356, 360, 368, 369, 373, 374, + 377, 379, 390, 391, 392, 393, 394, 395, 396, 400, + 401, 405, 408, 413, 417, 422, 429, 443, 444, 454, + 476, 479, 485, 488, 494, 495, 496, 497, 501, 502, + 506, 526, 540, 555, 562, 565, 579, 586, 587, 588, + 592, 596, 601, 606, 613, 622, 634, 650, 656, 660, + 670, 677, 683, 684, 685, 689, 698, 722, 727, 733, + 741, 753, 756, 759, 762, 765, 768, 774, 775, 779, + 785, 791, 798, 805, 812, 819, 828, 831, 834, 837, + 842, 848, 852, 855, 860, 866, 888, 894, 901, 902, + 906, 910, 926, 929, 932, 938, 939, 941, 942, 943, + 949, 950, 951, 953, 959, 960, 961, 962, 963, 964, + 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, + 975, 976, 977, 982, 990, 1006, 1013, 1019, 1028, 1054, + 1055, 1059, 1060 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE +/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "UNIMPORTANT_TOK", "S", "SGML_CD", + "INCLUDES", "DASHMATCH", "BEGINSWITH", "ENDSWITH", "CONTAINS", "STRING", + "IDENT", "NTH", "HASH", "':'", "'.'", "'['", "'*'", "'|'", "IMPORT_SYM", + "PAGE_SYM", "MEDIA_SYM", "FONT_FACE_SYM", "CHARSET_SYM", "NAMESPACE_SYM", + "KHTML_RULE_SYM", "KHTML_DECLS_SYM", "KHTML_VALUE_SYM", "IMPORTANT_SYM", + "QEMS", "EMS", "EXS", "PXS", "CMS", "MMS", "INS", "PTS", "PCS", "DEGS", + "RADS", "GRADS", "MSECS", "SECS", "HERZ", "KHERZ", "DIMEN", "PERCENTAGE", + "FLOAT", "INTEGER", "URI", "FUNCTION", "NOTFUNCTION", "UNICODERANGE", + "'{'", "'}'", "';'", "','", "'+'", "'~'", "'>'", "'-'", "']'", "'='", + "')'", "'/'", "'@'", "$accept", "stylesheet", "khtml_rule", + "khtml_decls", "khtml_value", "maybe_space", "maybe_sgml", + "maybe_charset", "import_list", "import", "namespace_list", "namespace", + "maybe_ns_prefix", "rule_list", "rule", "string_or_uri", + "maybe_media_list", "media_list", "media", "ruleset_list", "medium", + "page", "font_face", "combinator", "unary_operator", "ruleset", + "selector_list", "selector", "namespace_selector", "simple_selector", + "element_name", "specifier_list", "specifier", "class", "attrib_id", + "attrib", "match", "ident_or_string", "pseudo", "declaration_block", + "declaration_list", "declaration", "property", "prio", "expr", + "operator", "term", "unary_term", "function", "hexcolor", "invalid_at", + "invalid_rule", "invalid_block", "invalid_block_list", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const unsigned short int yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 58, 46, 91, 42, 124, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, + 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 123, 125, 59, 44, 43, 126, + 62, 45, 93, 61, 41, 47, 64 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const unsigned char yyr1[] = +{ + 0, 67, 68, 68, 68, 68, 69, 70, 71, 72, + 72, 73, 73, 73, 74, 74, 74, 74, 75, 75, + 76, 76, 76, 77, 77, 78, 78, 78, 79, 79, + 80, 80, 81, 81, 81, 81, 81, 81, 81, 82, + 82, 83, 83, 84, 84, 84, 85, 86, 86, 87, + 88, 88, 89, 89, 90, 90, 90, 90, 91, 91, + 92, 93, 93, 93, 94, 94, 94, 95, 95, 95, + 96, 96, 96, 96, 96, 96, 97, 97, 98, 98, + 98, 99, 99, 99, 99, 100, 101, 102, 102, 102, + 102, 103, 103, 103, 103, 103, 103, 104, 104, 105, + 105, 105, 105, 105, 105, 105, 106, 106, 106, 106, + 106, 107, 107, 107, 107, 108, 108, 109, 110, 110, + 111, 111, 112, 112, 112, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 115, 115, 116, 117, 117, 118, 119, + 119, 120, 120 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const unsigned char yyr2[] = +{ + 0, 2, 5, 2, 2, 2, 6, 2, 5, 0, + 2, 0, 2, 2, 0, 5, 3, 3, 0, 3, + 6, 3, 3, 0, 3, 6, 3, 3, 0, 2, + 0, 3, 1, 1, 1, 1, 1, 1, 2, 1, + 1, 0, 1, 1, 4, 2, 7, 0, 3, 2, + 3, 3, 3, 3, 2, 2, 2, 0, 1, 1, + 2, 1, 4, 2, 1, 3, 2, 1, 2, 2, + 2, 3, 2, 3, 4, 3, 1, 1, 1, 2, + 2, 1, 1, 1, 1, 2, 2, 4, 8, 5, + 9, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 3, 4, 4, 4, 4, 5, 4, 4, 4, 5, + 5, 3, 3, 4, 4, 5, 2, 2, 2, 0, + 1, 3, 2, 2, 0, 1, 2, 2, 2, 2, + 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 5, 3, 2, 3, 3, 2, 5, + 3, 1, 3 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const unsigned char yydefact[] = +{ + 14, 0, 0, 0, 0, 0, 9, 9, 9, 11, + 0, 0, 9, 9, 7, 9, 1, 3, 4, 5, + 18, 0, 17, 16, 10, 9, 0, 0, 0, 13, + 12, 23, 0, 0, 76, 81, 0, 0, 9, 77, + 67, 9, 0, 0, 0, 64, 9, 0, 78, 82, + 83, 84, 0, 9, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 59, 58, 0, 124, 120, 125, 133, + 132, 0, 11, 30, 160, 161, 0, 15, 69, 99, + 0, 0, 9, 85, 0, 68, 0, 63, 9, 60, + 66, 9, 9, 9, 0, 76, 77, 9, 0, 70, + 0, 80, 72, 79, 107, 9, 116, 117, 0, 108, + 0, 106, 9, 9, 128, 129, 155, 151, 150, 152, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 127, 136, 135, 134, 130, 0, 131, + 126, 8, 9, 9, 0, 0, 0, 19, 0, 11, + 0, 0, 100, 0, 0, 0, 0, 0, 9, 0, + 0, 0, 6, 0, 54, 55, 56, 65, 73, 0, + 75, 71, 112, 110, 9, 109, 9, 111, 0, 154, + 124, 123, 122, 121, 22, 21, 39, 40, 9, 0, + 28, 24, 0, 0, 9, 0, 0, 0, 11, 33, + 34, 35, 32, 37, 36, 159, 162, 104, 103, 101, + 102, 0, 86, 9, 0, 92, 93, 94, 95, 96, + 87, 91, 9, 0, 74, 114, 113, 124, 9, 41, + 27, 26, 0, 0, 158, 0, 0, 0, 0, 38, + 31, 105, 89, 9, 0, 9, 115, 153, 9, 0, + 0, 43, 29, 9, 51, 50, 0, 53, 52, 157, + 156, 0, 98, 97, 9, 118, 49, 20, 45, 9, + 0, 9, 9, 0, 0, 25, 47, 0, 88, 44, + 0, 90, 46, 9, 48 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const short int yydefgoto[] = +{ + -1, 5, 6, 7, 8, 232, 20, 9, 31, 92, + 93, 169, 253, 170, 218, 208, 269, 270, 219, 300, + 271, 220, 221, 114, 85, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 181, 50, 242, 284, 51, 14, + 54, 55, 56, 266, 86, 164, 87, 88, 89, 90, + 223, 224, 126, 96 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -167 +static const short int yypact[] = +{ + 252, 19, -46, -32, -20, 44, -167, -167, -167, -167, + 147, 183, -167, -167, -167, -167, -167, 96, 96, 96, + 34, 114, -167, -167, -167, -167, 333, 156, 355, -167, + -167, 85, 98, -2, 99, -167, 158, 109, -167, 152, + -167, -167, 52, 241, 222, -167, 229, 162, -167, -167, + -167, -167, 215, -167, 101, 168, 118, -167, -167, -167, + -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, + -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, + -167, -167, -167, -167, -167, 430, 127, -167, -167, -167, + -167, 119, -167, 160, -167, -167, 189, -167, -167, -167, + 202, 116, -167, -167, 14, -167, 104, -167, -167, -167, + -167, -167, -167, -167, 346, -167, -167, 229, 162, 96, + 162, -167, 96, -167, -167, -167, -167, 96, 238, -167, + 210, -167, -167, -167, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 273, 96, + -167, -167, -167, -167, 398, 150, 5, 34, 185, -167, + 125, 157, -167, 154, 169, 217, 218, 333, 99, 152, + 237, 41, -167, 333, 96, 96, 96, -167, 96, 162, + 96, 96, 96, -167, -167, -167, -167, 96, 355, -167, + -36, 96, 96, -167, -167, -167, -167, -167, -167, 161, + 110, 34, 232, 288, -167, 295, 296, 326, -167, -167, + -167, -167, -167, -167, -167, -167, -167, -167, -167, -167, + -167, 264, 96, -167, 87, -167, -167, -167, -167, -167, + -167, -167, -167, 324, 96, 96, 96, 143, -167, 171, + -167, -167, 325, 88, -167, 198, 171, 207, 219, -167, + 34, -167, -167, -167, 31, -167, -167, 96, -167, 274, + 35, -167, -167, -167, -167, -167, 97, -167, -167, -167, + -167, 31, -167, -167, -167, 96, 96, -167, -167, -167, + 79, -167, -167, 23, 171, -167, 96, 27, -167, -167, + 213, -167, -167, -167, 96 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const short int yypgoto[] = +{ + -167, -167, -167, -167, -167, -1, -82, -167, -167, 163, + -167, -167, -167, -167, -167, 82, -167, 76, -167, -167, + 50, -167, -167, -167, -167, -166, -167, 170, 242, -95, + 310, -29, -34, -167, 175, -167, 122, 89, -167, 315, + -167, 314, -167, -167, -157, -167, 208, 286, -167, -167, + -167, -167, -7, -167 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -120 +static const short int yytable[] = +{ + 11, 200, 24, 23, 222, 17, 18, 19, 12, 24, + 167, 26, 27, 123, 28, 118, 206, 120, 24, 187, + 10, 162, 13, -9, 33, 95, 178, 24, 248, 163, + -9, 24, 179, 40, 15, 24, 288, 104, 29, 30, + 106, 247, 282, 283, 16, 119, 122, 235, 236, 237, + 238, 239, 127, 107, 97, 207, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 231, 24, 123, 298, 123, 211, 189, 301, + 166, -42, 289, 235, 236, 237, 238, 239, 288, 206, + 24, 177, 128, 240, 241, 91, 13, 183, 24, 108, + 184, 185, 186, 53, 24, 32, 188, 190, 98, 191, + 165, 103, 252, -9, 192, -2, 212, 173, 174, 175, + -9, 197, 198, 133, 303, 295, 260, 34, 207, 35, + 36, 37, 38, 39, 40, 91, 213, 214, 215, 262, + 241, 291, 21, 94, 289, 123, 129, 52, 205, 182, + 24, 201, 202, 121, 226, 176, -9, 210, 53, -9, + 99, 105, 265, 100, -9, 24, 35, 36, 37, 38, + -9, -9, 161, 268, 162, 168, 209, 24, 244, -9, + 171, 216, 163, 245, 25, 246, -9, -9, -119, -119, + 162, 21, 251, 22, 21, 254, 204, 249, 163, 101, + 102, 21, 225, 256, 172, 21, -9, 250, 227, -9, + -9, -9, -9, 131, 132, 34, -9, 35, 36, 37, + 38, 39, 40, 228, 115, -9, 35, 36, 37, 38, + 116, 264, 110, 35, 36, 37, 38, 267, 275, 233, + 278, 280, 21, -57, 274, -57, -57, -57, -57, -57, + -57, 21, 281, 277, 285, 195, 196, 286, 302, 21, + 124, 125, 290, 21, 199, 279, 1, 24, 2, 3, + 4, 229, 230, 293, 57, 58, 21, 59, 294, 255, + 296, 297, 21, 193, 194, -61, 257, 258, -61, 111, + 112, 113, 304, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 110, 82, 259, 261, 272, + 287, 83, 276, 217, 84, 273, -57, 24, -57, -57, + -57, -57, -57, -57, 299, 34, 180, 35, 36, 37, + 38, 39, 40, 243, 117, 234, 263, 109, 34, 24, + 35, 36, 37, 38, 39, 40, 57, 58, 130, 59, + 292, 160, 203, 0, 0, 0, 0, 0, -62, 0, + 0, -62, 111, 112, 113, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 0, 82, 57, + 58, 0, 59, 83, 0, 0, 84, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 0, 82, 0, 0, 0, 0, 83, 0, 0, 84, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 0, 77, 78, 79 +}; + +static const short int yycheck[] = +{ + 1, 158, 4, 10, 170, 6, 7, 8, 54, 4, + 92, 12, 13, 47, 15, 44, 11, 46, 4, 114, + 1, 57, 54, 4, 25, 32, 12, 4, 64, 65, + 11, 4, 18, 19, 54, 4, 1, 38, 4, 5, + 41, 198, 11, 12, 0, 46, 47, 6, 7, 8, + 9, 10, 53, 1, 56, 50, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 177, 4, 118, 62, 120, 169, 117, 62, + 91, 56, 57, 6, 7, 8, 9, 10, 1, 11, + 4, 102, 1, 62, 63, 20, 54, 108, 4, 57, + 111, 112, 113, 12, 4, 1, 117, 118, 19, 120, + 1, 12, 12, 4, 125, 0, 1, 11, 12, 13, + 11, 132, 133, 15, 300, 56, 218, 12, 50, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 62, + 63, 54, 54, 55, 57, 189, 55, 1, 165, 55, + 4, 162, 163, 1, 171, 49, 4, 168, 12, 50, + 12, 19, 29, 15, 12, 4, 14, 15, 16, 17, + 18, 19, 55, 12, 57, 25, 1, 4, 189, 4, + 1, 66, 65, 194, 11, 196, 11, 12, 55, 56, + 57, 54, 209, 56, 54, 212, 56, 208, 65, 51, + 52, 54, 55, 214, 12, 54, 54, 56, 64, 57, + 58, 59, 60, 55, 56, 12, 64, 14, 15, 16, + 17, 18, 19, 64, 12, 50, 14, 15, 16, 17, + 18, 242, 1, 14, 15, 16, 17, 248, 255, 12, + 257, 258, 54, 12, 56, 14, 15, 16, 17, 18, + 19, 54, 263, 56, 265, 55, 56, 268, 55, 54, + 55, 56, 273, 54, 1, 56, 24, 4, 26, 27, + 28, 64, 64, 284, 11, 12, 54, 14, 289, 1, + 291, 292, 54, 55, 56, 54, 1, 1, 57, 58, + 59, 60, 303, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 1, 53, 1, 64, 4, + 56, 58, 256, 170, 61, 253, 12, 4, 14, 15, + 16, 17, 18, 19, 294, 12, 104, 14, 15, 16, + 17, 18, 19, 183, 44, 180, 234, 42, 12, 4, + 14, 15, 16, 17, 18, 19, 11, 12, 54, 14, + 281, 85, 164, -1, -1, -1, -1, -1, 54, -1, + -1, 57, 58, 59, 60, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, -1, 53, 11, + 12, -1, 14, 58, -1, -1, 61, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + -1, 53, -1, -1, -1, -1, 58, -1, -1, 61, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, -1, 47, 48, 49 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const unsigned char yystos[] = +{ + 0, 24, 26, 27, 28, 68, 69, 70, 71, 74, + 1, 72, 54, 54, 106, 54, 0, 72, 72, 72, + 73, 54, 56, 119, 4, 11, 72, 72, 72, 4, + 5, 75, 1, 72, 12, 14, 15, 16, 17, 18, + 19, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 102, 105, 1, 12, 107, 108, 109, 11, 12, 14, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 53, 58, 61, 91, 111, 113, 114, 115, + 116, 20, 76, 77, 55, 119, 120, 56, 19, 12, + 15, 51, 52, 12, 72, 19, 72, 1, 57, 106, + 1, 58, 59, 60, 90, 12, 18, 97, 98, 72, + 98, 1, 72, 99, 55, 56, 119, 72, 1, 55, + 108, 55, 56, 15, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 114, 55, 57, 65, 112, 1, 72, 73, 25, 78, + 80, 1, 12, 11, 12, 13, 49, 72, 12, 18, + 95, 101, 55, 72, 72, 72, 72, 96, 72, 98, + 72, 72, 72, 55, 56, 55, 56, 72, 72, 1, + 111, 72, 72, 113, 56, 119, 11, 50, 82, 1, + 72, 73, 1, 21, 22, 23, 66, 76, 81, 85, + 88, 89, 92, 117, 118, 55, 119, 64, 64, 64, + 64, 96, 72, 12, 101, 6, 7, 8, 9, 10, + 62, 63, 103, 94, 72, 72, 72, 111, 64, 72, + 56, 119, 12, 79, 119, 1, 72, 1, 1, 1, + 73, 64, 62, 103, 72, 29, 110, 72, 12, 83, + 84, 87, 4, 82, 56, 119, 84, 56, 119, 56, + 119, 72, 11, 12, 104, 72, 72, 56, 1, 57, + 72, 54, 104, 72, 72, 56, 72, 72, 62, 87, + 86, 62, 55, 92, 72 +}; + +#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) +# define YYSIZE_T __SIZE_TYPE__ +#endif +#if ! defined (YYSIZE_T) && defined (size_t) +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) +# if defined (__STDC__) || defined (__cplusplus) +# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +#endif +#if ! defined (YYSIZE_T) +# define YYSIZE_T unsigned int +#endif + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror ("syntax error: cannot back up");\ + YYERROR; \ + } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Compute the default location (before the actions + are run). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + ((Current).first_line = (Rhs)[1].first_line, \ + (Current).first_column = (Rhs)[1].first_column, \ + (Current).last_line = (Rhs)[N].last_line, \ + (Current).last_column = (Rhs)[N].last_column) +#endif + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (&yylval, YYLEX_PARAM) +#else +# define YYLEX yylex (&yylval) +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +# define YYDSYMPRINT(Args) \ +do { \ + if (yydebug) \ + yysymprint Args; \ +} while (0) + +# define YYDSYMPRINTF(Title, Token, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yysymprint (stderr, \ + Token, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_stack_print (short int *bottom, short int *top) +#else +static void +yy_stack_print (bottom, top) + short int *bottom; + short int *top; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (/* Nothing. */; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_reduce_print (int yyrule) +#else +static void +yy_reduce_print (yyrule) + int yyrule; +#endif +{ + int yyi; + unsigned int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", + yyrule - 1, yylno); + /* Print the symbols being reduced, and their result. */ + for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) + YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); + YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YYDSYMPRINT(Args) +# define YYDSYMPRINTF(Title, Token, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0 +# undef YYMAXDEPTH +#endif + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined (__GLIBC__) && defined (_STRING_H) +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +# if defined (__STDC__) || defined (__cplusplus) +yystrlen (const char *yystr) +# else +yystrlen (yystr) + const char *yystr; +# endif +{ + register const char *yys = yystr; + + while (*yys++ != '\0') + continue; + + return yys - yystr - 1; +} +# endif +# endif + +# ifndef yystpcpy +# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +# if defined (__STDC__) || defined (__cplusplus) +yystpcpy (char *yydest, const char *yysrc) +# else +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +# endif +{ + register char *yyd = yydest; + register const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +#endif /* !YYERROR_VERBOSE */ + + + +#if YYDEBUG +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) +#else +static void +yysymprint (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + if (yytype < YYNTOKENS) + { + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); +# ifdef YYPRINT + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + } + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + switch (yytype) + { + default: + break; + } + YYFPRINTF (yyoutput, ")"); +} + +#endif /* ! YYDEBUG */ +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yydestruct (int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yytype, yyvaluep) + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + switch (yytype) + { + case 83: /* maybe_media_list */ + + { delete yyvaluep->mediaList; yyvaluep->mediaList = 0; }; + + break; + case 84: /* media_list */ + + { delete yyvaluep->mediaList; yyvaluep->mediaList = 0; }; + + break; + case 86: /* ruleset_list */ + + { delete yyvaluep->ruleList; yyvaluep->ruleList = 0; }; + + break; + case 93: /* selector_list */ + + { delete yyvaluep->selectorList; yyvaluep->selectorList = 0; }; + + break; + case 94: /* selector */ + + { delete yyvaluep->selector; yyvaluep->selector = 0; }; + + break; + case 96: /* simple_selector */ + + { delete yyvaluep->selector; yyvaluep->selector = 0; }; + + break; + case 98: /* specifier_list */ + + { delete yyvaluep->selector; yyvaluep->selector = 0; }; + + break; + case 99: /* specifier */ + + { delete yyvaluep->selector; yyvaluep->selector = 0; }; + + break; + case 100: /* class */ + + { delete yyvaluep->selector; yyvaluep->selector = 0; }; + + break; + case 102: /* attrib */ + + { delete yyvaluep->selector; yyvaluep->selector = 0; }; + + break; + case 105: /* pseudo */ + + { delete yyvaluep->selector; yyvaluep->selector = 0; }; + + break; + case 111: /* expr */ + + { delete yyvaluep->valueList; yyvaluep->valueList = 0; }; + + break; + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM); +# else +int yyparse (); +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM) +# else +int yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + /* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + register int yystate; + register int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + short int yyssa[YYINITDEPTH]; + short int *yyss = yyssa; + register short int *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + register YYSTYPE *yyvsp; + + + +#define YYPOPSTACK (yyvsp--, yyssp--) + + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + /* When reducing, the number of symbols on the RHS of the reduced + rule. */ + int yylen; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; + + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. + */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + short int *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyoverflowlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyoverflowlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + short int *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; + + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + yystate = yyn; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 6: + + { + CSSParser *p = static_cast<CSSParser *>(parser); + p->rule = yyvsp[-2].rule; + ;} + break; + + case 7: + + { + /* can be empty */ + ;} + break; + + case 8: + + { + CSSParser *p = static_cast<CSSParser *>(parser); + if ( yyvsp[-1].valueList ) { + p->valueList = yyvsp[-1].valueList; +#ifdef CSS_DEBUG + kdDebug( 6080 ) << " got property for " << p->id << + (p->important?" important":"")<< endl; + bool ok = +#endif + p->parseValue( p->id, p->important ); +#ifdef CSS_DEBUG + if ( !ok ) + kdDebug( 6080 ) << " couldn't parse value!" << endl; +#endif + } +#ifdef CSS_DEBUG + else + kdDebug( 6080 ) << " no value found!" << endl; +#endif + delete p->valueList; + p->valueList = 0; + ;} + break; + + case 15: + + { +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "charset rule: " << qString(yyvsp[-2].string) << endl; +#endif + ;} + break; + + case 19: + + { + CSSParser *p = static_cast<CSSParser *>(parser); + if ( yyvsp[-1].rule && p->styleElement && p->styleElement->isCSSStyleSheet() ) { + p->styleElement->append( yyvsp[-1].rule ); + } else { + delete yyvsp[-1].rule; + } + ;} + break; + + case 20: + + { +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "@import: " << qString(yyvsp[-3].string) << endl; +#endif + CSSParser *p = static_cast<CSSParser *>(parser); + if ( yyvsp[-1].mediaList && p->styleElement && p->styleElement->isCSSStyleSheet() ) + yyval.rule = new CSSImportRuleImpl( p->styleElement, domString(yyvsp[-3].string), yyvsp[-1].mediaList ); + else + yyval.rule = 0; + ;} + break; + + case 21: + + { + yyval.rule = 0; + ;} + break; + + case 22: + + { + yyval.rule = 0; + ;} + break; + + case 25: + + { +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "@namespace: " << qString(yyvsp[-2].string) << endl; +#endif + CSSParser *p = static_cast<CSSParser *>(parser); + if (p->styleElement && p->styleElement->isCSSStyleSheet()) + static_cast<CSSStyleSheetImpl*>(p->styleElement)->addNamespace(p, domString(yyvsp[-3].string), domString(yyvsp[-2].string)); + ;} + break; + + case 28: + + { yyval.string.string = 0; ;} + break; + + case 29: + + { yyval.string = yyvsp[-1].string; ;} + break; + + case 31: + + { + CSSParser *p = static_cast<CSSParser *>(parser); + if ( yyvsp[-1].rule && p->styleElement && p->styleElement->isCSSStyleSheet() ) { + p->styleElement->append( yyvsp[-1].rule ); + } else { + delete yyvsp[-1].rule; + } + ;} + break; + + case 38: + + { delete yyvsp[-1].rule; yyval.rule = 0; ;} + break; + + case 41: + + { + yyval.mediaList = new MediaListImpl(); + ;} + break; + + case 43: + + { + yyval.mediaList = new MediaListImpl(); + yyval.mediaList->appendMedium( domString(yyvsp[0].string).lower() ); + ;} + break; + + case 44: + + { + yyval.mediaList = yyvsp[-3].mediaList; + if (yyval.mediaList) + yyval.mediaList->appendMedium( domString(yyvsp[0].string).lower() ); + ;} + break; + + case 45: + + { + delete yyvsp[-1].mediaList; + yyval.mediaList = 0; + ;} + break; + + case 46: + + { + CSSParser *p = static_cast<CSSParser *>(parser); + if ( yyvsp[-4].mediaList && yyvsp[-1].ruleList && + p->styleElement && p->styleElement->isCSSStyleSheet() ) { + yyval.rule = new CSSMediaRuleImpl( static_cast<CSSStyleSheetImpl*>(p->styleElement), yyvsp[-4].mediaList, yyvsp[-1].ruleList ); + } else { + yyval.rule = 0; + delete yyvsp[-4].mediaList; + delete yyvsp[-1].ruleList; + } + ;} + break; + + case 47: + + { yyval.ruleList = 0; ;} + break; + + case 48: + + { + yyval.ruleList = yyvsp[-2].ruleList; + if ( yyvsp[-1].rule ) { + if ( !yyval.ruleList ) yyval.ruleList = new CSSRuleListImpl(); + yyval.ruleList->append( yyvsp[-1].rule ); + } + ;} + break; + + case 49: + + { + yyval.string = yyvsp[-1].string; + ;} + break; + + case 50: + + { + yyval.rule = 0; + ;} + break; + + case 51: + + { + yyval.rule = 0; + ;} + break; + + case 52: + + { + yyval.rule = 0; + ;} + break; + + case 53: + + { + yyval.rule = 0; + ;} + break; + + case 54: + + { yyval.relation = CSSSelector::DirectAdjacent; ;} + break; + + case 55: + + { yyval.relation = CSSSelector::IndirectAdjacent; ;} + break; + + case 56: + + { yyval.relation = CSSSelector::Child; ;} + break; + + case 57: + + { yyval.relation = CSSSelector::Descendant; ;} + break; + + case 58: + + { yyval.val = -1; ;} + break; + + case 59: + + { yyval.val = 1; ;} + break; + + case 60: + + { +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "got ruleset" << endl << " selector:" << endl; +#endif + CSSParser *p = static_cast<CSSParser *>(parser); + if ( yyvsp[-1].selectorList && yyvsp[0].ok && p->numParsedProperties ) { + CSSStyleRuleImpl *rule = new CSSStyleRuleImpl( p->styleElement ); + CSSStyleDeclarationImpl *decl = p->createStyleDeclaration( rule ); + rule->setSelector( yyvsp[-1].selectorList ); + rule->setDeclaration(decl); + yyval.rule = rule; + } else { + yyval.rule = 0; + delete yyvsp[-1].selectorList; + p->clearProperties(); + } + ;} + break; + + case 61: + + { + if ( yyvsp[0].selector ) { + yyval.selectorList = new QPtrList<CSSSelector>; + yyval.selectorList->setAutoDelete( true ); +#ifdef CSS_DEBUG + kdDebug( 6080 ) << " got simple selector:" << endl; + yyvsp[0].selector->print(); +#endif + yyval.selectorList->append( yyvsp[0].selector ); + khtml::CSSStyleSelector::precomputeAttributeDependencies(static_cast<CSSParser *>(parser)->document(), yyvsp[0].selector); + } else { + yyval.selectorList = 0; + } + ;} + break; + + case 62: + + { + if ( yyvsp[-3].selectorList && yyvsp[0].selector ) { + yyval.selectorList = yyvsp[-3].selectorList; + yyval.selectorList->append( yyvsp[0].selector ); + khtml::CSSStyleSelector::precomputeAttributeDependencies(static_cast<CSSParser *>(parser)->document(), yyvsp[0].selector); +#ifdef CSS_DEBUG + kdDebug( 6080 ) << " got simple selector:" << endl; + yyvsp[0].selector->print(); +#endif + } else { + delete yyvsp[-3].selectorList; + delete yyvsp[0].selector; + yyval.selectorList = 0; + } + ;} + break; + + case 63: + + { + delete yyvsp[-1].selectorList; + yyval.selectorList = 0; + ;} + break; + + case 64: + + { + yyval.selector = yyvsp[0].selector; + ;} + break; + + case 65: + + { + if ( !yyvsp[-2].selector || !yyvsp[0].selector ) { + delete yyvsp[-2].selector; + delete yyvsp[0].selector; + yyval.selector = 0; + } else { + yyval.selector = yyvsp[0].selector; + CSSSelector *end = yyvsp[0].selector; + while( end->tagHistory ) + end = end->tagHistory; + end->relation = yyvsp[-1].relation; + end->tagHistory = yyvsp[-2].selector; + } + ;} + break; + + case 66: + + { + delete yyvsp[-1].selector; + yyval.selector = 0; + ;} + break; + + case 67: + + { yyval.string.string = 0; yyval.string.length = 0; ;} + break; + + case 68: + + { static unsigned short star = '*'; yyval.string.string = ☆ yyval.string.length = 1; ;} + break; + + case 69: + + { yyval.string = yyvsp[-1].string; ;} + break; + + case 70: + + { + yyval.selector = new CSSSelector(); + yyval.selector->tag = yyvsp[-1].element; + ;} + break; + + case 71: + + { + yyval.selector = yyvsp[-1].selector; + if ( yyval.selector ) + yyval.selector->tag = yyvsp[-2].element; + ;} + break; + + case 72: + + { + yyval.selector = yyvsp[-1].selector; + if ( yyval.selector ) + yyval.selector->tag = makeId(static_cast<CSSParser*>(parser)->defaultNamespace(), anyLocalName); + ;} + break; + + case 73: + + { + yyval.selector = new CSSSelector(); + yyval.selector->tag = yyvsp[-1].element; + CSSParser *p = static_cast<CSSParser *>(parser); + if (p->styleElement && p->styleElement->isCSSStyleSheet()) + static_cast<CSSStyleSheetImpl*>(p->styleElement)->determineNamespace(yyval.selector->tag, domString(yyvsp[-2].string)); + ;} + break; + + case 74: + + { + yyval.selector = yyvsp[-1].selector; + if (yyval.selector) { + yyval.selector->tag = yyvsp[-2].element; + CSSParser *p = static_cast<CSSParser *>(parser); + if (p->styleElement && p->styleElement->isCSSStyleSheet()) + static_cast<CSSStyleSheetImpl*>(p->styleElement)->determineNamespace(yyval.selector->tag, domString(yyvsp[-3].string)); + } + ;} + break; + + case 75: + + { + yyval.selector = yyvsp[-1].selector; + if (yyval.selector) { + yyval.selector->tag = makeId(anyNamespace, anyLocalName); + CSSParser *p = static_cast<CSSParser *>(parser); + if (p->styleElement && p->styleElement->isCSSStyleSheet()) + static_cast<CSSStyleSheetImpl*>(p->styleElement)->determineNamespace(yyval.selector->tag, domString(yyvsp[-2].string)); + } + ;} + break; + + case 76: + + { + CSSParser *p = static_cast<CSSParser *>(parser); + DOM::DocumentImpl *doc = p->document(); + QString tag = qString(yyvsp[0].string); + if ( doc ) { + if (doc->isHTMLDocument()) + tag = tag.lower(); + const DOMString dtag(tag); + yyval.element = makeId(p->defaultNamespace(), doc->getId(NodeImpl::ElementId, dtag.implementation(), false, true)); + } else { + yyval.element = makeId(p->defaultNamespace(), khtml::getTagID(tag.lower().ascii(), tag.length())); + // this case should never happen - only when loading + // the default stylesheet - which must not contain unknown tags +// assert($$ != 0); + } + ;} + break; + + case 77: + + { + yyval.element = makeId(static_cast<CSSParser*>(parser)->defaultNamespace(), anyLocalName); + ;} + break; + + case 78: + + { + yyval.selector = yyvsp[0].selector; + yyval.selector->nonCSSHint = static_cast<CSSParser *>(parser)->nonCSSHint; + ;} + break; + + case 79: + + { + yyval.selector = yyvsp[-1].selector; + if ( yyval.selector ) { + CSSSelector *end = yyvsp[-1].selector; + while( end->tagHistory ) + end = end->tagHistory; + end->relation = CSSSelector::SubSelector; + end->tagHistory = yyvsp[0].selector; + } + ;} + break; + + case 80: + + { + delete yyvsp[-1].selector; + yyval.selector = 0; + ;} + break; + + case 81: + + { + yyval.selector = new CSSSelector(); + yyval.selector->match = CSSSelector::Id; + yyval.selector->attr = ATTR_ID; + yyval.selector->value = domString(yyvsp[0].string); + ;} + break; + + case 85: + + { + yyval.selector = new CSSSelector(); + yyval.selector->match = CSSSelector::Class; + yyval.selector->attr = ATTR_CLASS; + yyval.selector->value = domString(yyvsp[0].string); + ;} + break; + + case 86: + + { + CSSParser *p = static_cast<CSSParser *>(parser); + DOM::DocumentImpl *doc = p->document(); + + QString attr = qString(yyvsp[-1].string); + if ( doc ) { + if (doc->isHTMLDocument()) + attr = attr.lower(); + const DOMString dattr(attr); +#ifdef APPLE_CHANGES + yyval.attribute = doc->attrId(0, dattr.implementation(), false); +#else + yyval.attribute = doc->getId(NodeImpl::AttributeId, dattr.implementation(), false, true); +#endif + } else { + yyval.attribute = khtml::getAttrID(attr.lower().ascii(), attr.length()); + // this case should never happen - only when loading + // the default stylesheet - which must not contain unknown attributes + assert(yyval.attribute != 0); + } + ;} + break; + + case 87: + + { + yyval.selector = new CSSSelector(); + yyval.selector->attr = yyvsp[-1].attribute; + yyval.selector->match = CSSSelector::Set; + ;} + break; + + case 88: + + { + yyval.selector = new CSSSelector(); + yyval.selector->attr = yyvsp[-5].attribute; + yyval.selector->match = yyvsp[-4].match; + yyval.selector->value = domString(yyvsp[-2].string); + ;} + break; + + case 89: + + { + yyval.selector = new CSSSelector(); + yyval.selector->attr = yyvsp[-1].attribute; + yyval.selector->match = CSSSelector::Set; + CSSParser *p = static_cast<CSSParser *>(parser); + if (p->styleElement && p->styleElement->isCSSStyleSheet()) + static_cast<CSSStyleSheetImpl*>(p->styleElement)->determineNamespace(yyval.selector->attr, domString(yyvsp[-2].string)); + ;} + break; + + case 90: + + { + yyval.selector = new CSSSelector(); + yyval.selector->attr = yyvsp[-5].attribute; + yyval.selector->match = (CSSSelector::Match)yyvsp[-4].match; + yyval.selector->value = domString(yyvsp[-2].string); + CSSParser *p = static_cast<CSSParser *>(parser); + if (p->styleElement && p->styleElement->isCSSStyleSheet()) + static_cast<CSSStyleSheetImpl*>(p->styleElement)->determineNamespace(yyval.selector->attr, domString(yyvsp[-6].string)); + ;} + break; + + case 91: + + { + yyval.match = CSSSelector::Exact; + ;} + break; + + case 92: + + { + yyval.match = CSSSelector::List; + ;} + break; + + case 93: + + { + yyval.match = CSSSelector::Hyphen; + ;} + break; + + case 94: + + { + yyval.match = CSSSelector::Begin; + ;} + break; + + case 95: + + { + yyval.match = CSSSelector::End; + ;} + break; + + case 96: + + { + yyval.match = CSSSelector::Contain; + ;} + break; + + case 99: + + { + yyval.selector = new CSSSelector(); + yyval.selector->match = CSSSelector::PseudoClass; + yyval.selector->value = domString(yyvsp[0].string); + ;} + break; + + case 100: + + { + yyval.selector = new CSSSelector(); + yyval.selector->match = CSSSelector::PseudoElement; + yyval.selector->value = domString(yyvsp[0].string); + ;} + break; + + case 101: + + { + yyval.selector = new CSSSelector(); + yyval.selector->match = CSSSelector::PseudoClass; + yyval.selector->string_arg = domString(yyvsp[-1].string); + yyval.selector->value = domString(yyvsp[-2].string); + ;} + break; + + case 102: + + { + yyval.selector = new CSSSelector(); + yyval.selector->match = CSSSelector::PseudoClass; + yyval.selector->string_arg = QString::number(yyvsp[-1].val); + yyval.selector->value = domString(yyvsp[-2].string); + ;} + break; + + case 103: + + { + yyval.selector = new CSSSelector(); + yyval.selector->match = CSSSelector::PseudoClass; + yyval.selector->string_arg = domString(yyvsp[-1].string); + yyval.selector->value = domString(yyvsp[-2].string); + ;} + break; + + case 104: + + { + yyval.selector = new CSSSelector(); + yyval.selector->match = CSSSelector::PseudoClass; + yyval.selector->string_arg = domString(yyvsp[-1].string); + yyval.selector->value = domString(yyvsp[-2].string); + ;} + break; + + case 105: + + { + yyval.selector = new CSSSelector(); + yyval.selector->match = CSSSelector::PseudoClass; + yyval.selector->simpleSelector = yyvsp[-1].selector; + yyval.selector->value = domString(yyvsp[-3].string); + ;} + break; + + case 106: + + { + yyval.ok = yyvsp[-1].ok; + ;} + break; + + case 107: + + { + yyval.ok = false; + ;} + break; + + case 108: + + { + yyval.ok = yyvsp[-1].ok; + ;} + break; + + case 109: + + { + yyval.ok = yyvsp[-2].ok; + if ( yyvsp[-1].ok ) + yyval.ok = yyvsp[-1].ok; + ;} + break; + + case 110: + + { + yyval.ok = yyvsp[-2].ok; + ;} + break; + + case 111: + + { + yyval.ok = yyvsp[-2].ok; + ;} + break; + + case 112: + + { + yyval.ok = false; + ;} + break; + + case 113: + + { + yyval.ok = yyvsp[-3].ok; + if ( yyvsp[-2].ok ) + yyval.ok = yyvsp[-2].ok; + ;} + break; + + case 114: + + { + yyval.ok = yyvsp[-3].ok; + ;} + break; + + case 115: + + { + yyval.ok = false; + CSSParser *p = static_cast<CSSParser *>(parser); + if ( yyvsp[-4].prop_id && yyvsp[-1].valueList ) { + p->valueList = yyvsp[-1].valueList; +#ifdef CSS_DEBUG + kdDebug( 6080 ) << " got property: " << yyvsp[-4].prop_id << + (yyvsp[0].b?" important":"")<< endl; +#endif + bool ok = p->parseValue( yyvsp[-4].prop_id, yyvsp[0].b ); + if ( ok ) + yyval.ok = ok; +#ifdef CSS_DEBUG + else + kdDebug( 6080 ) << " couldn't parse value!" << endl; +#endif + } else { + delete yyvsp[-1].valueList; + } + delete p->valueList; + p->valueList = 0; + ;} + break; + + case 116: + + { + yyval.ok = false; + ;} + break; + + case 117: + + { + QString str = qString(yyvsp[-1].string); + yyval.prop_id = getPropertyID( str.lower().latin1(), str.length() ); + ;} + break; + + case 118: + + { yyval.b = true; ;} + break; + + case 119: + + { yyval.b = false; ;} + break; + + case 120: + + { + yyval.valueList = new ValueList; + yyval.valueList->addValue( yyvsp[0].value ); + ;} + break; + + case 121: + + { + yyval.valueList = yyvsp[-2].valueList; + if ( yyval.valueList ) { + if ( yyvsp[-1].tok ) { + Value v; + v.id = 0; + v.unit = Value::Operator; + v.iValue = yyvsp[-1].tok; + yyval.valueList->addValue( v ); + } + yyval.valueList->addValue( yyvsp[0].value ); + } + ;} + break; + + case 122: + + { + yyval.tok = '/'; + ;} + break; + + case 123: + + { + yyval.tok = ','; + ;} + break; + + case 124: + + { + yyval.tok = 0; + ;} + break; + + case 125: + + { yyval.value = yyvsp[0].value; ;} + break; + + case 126: + + { yyval.value = yyvsp[0].value; yyval.value.fValue *= yyvsp[-1].val; ;} + break; + + case 127: + + { yyval.value.id = 0; yyval.value.string = yyvsp[-1].string; yyval.value.unit = CSSPrimitiveValue::CSS_DIMENSION; ;} + break; + + case 128: + + { yyval.value.id = 0; yyval.value.string = yyvsp[-1].string; yyval.value.unit = CSSPrimitiveValue::CSS_STRING; ;} + break; + + case 129: + + { + QString str = qString( yyvsp[-1].string ); + yyval.value.id = getValueID( str.lower().latin1(), str.length() ); + yyval.value.unit = CSSPrimitiveValue::CSS_IDENT; + yyval.value.string = yyvsp[-1].string; + ;} + break; + + case 130: + + { yyval.value.id = 0; yyval.value.string = yyvsp[-1].string; yyval.value.unit = CSSPrimitiveValue::CSS_URI; ;} + break; + + case 131: + + { yyval.value.id = 0; yyval.value.iValue = 0; yyval.value.unit = CSSPrimitiveValue::CSS_UNKNOWN;/* ### */ ;} + break; + + case 132: + + { yyval.value.id = 0; yyval.value.string = yyvsp[0].string; yyval.value.unit = CSSPrimitiveValue::CSS_RGBCOLOR; ;} + break; + + case 133: + + { + yyval.value = yyvsp[0].value; + ;} + break; + + case 134: + + { yyval.value.id = 0; yyval.value.isInt = true; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_NUMBER; ;} + break; + + case 135: + + { yyval.value.id = 0; yyval.value.isInt = false; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_NUMBER; ;} + break; + + case 136: + + { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_PERCENTAGE; ;} + break; + + case 137: + + { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_PX; ;} + break; + + case 138: + + { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_CM; ;} + break; + + case 139: + + { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_MM; ;} + break; + + case 140: + + { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_IN; ;} + break; + + case 141: + + { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_PT; ;} + break; + + case 142: + + { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_PC; ;} + break; + + case 143: + + { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_DEG; ;} + break; + + case 144: + + { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_RAD; ;} + break; + + case 145: + + { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_GRAD; ;} + break; + + case 146: + + { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_MS; ;} + break; + + case 147: + + { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_S; ;} + break; + + case 148: + + { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_HZ; ;} + break; + + case 149: + + { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_KHZ; ;} + break; + + case 150: + + { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_EMS; ;} + break; + + case 151: + + { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = Value::Q_EMS; ;} + break; + + case 152: + + { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_EXS; ;} + break; + + case 153: + + { + Function *f = new Function; + f->name = yyvsp[-4].string; + f->args = yyvsp[-2].valueList; + yyval.value.id = 0; + yyval.value.unit = Value::Function; + yyval.value.function = f; + ;} + break; + + case 154: + + { + Function *f = new Function; + f->name = yyvsp[-2].string; + f->args = 0; + yyval.value.id = 0; + yyval.value.unit = Value::Function; + yyval.value.function = f; + ;} + break; + + case 155: + + { yyval.string = yyvsp[-1].string; ;} + break; + + case 156: + + { + yyval.rule = 0; +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "skipped invalid @-rule" << endl; +#endif + ;} + break; + + case 157: + + { + yyval.rule = 0; +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "skipped invalid @-rule" << endl; +#endif + ;} + break; + + case 158: + + { + yyval.rule = 0; +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "skipped invalid rule" << endl; +#endif + ;} + break; + + + } + +/* Line 1010 of yacc.c. */ + + + yyvsp -= yylen; + yyssp -= yylen; + + + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (YYPACT_NINF < yyn && yyn < YYLAST) + { + YYSIZE_T yysize = 0; + int yytype = YYTRANSLATE (yychar); + const char* yyprefix; + char *yymsg; + int yyx; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 0; + + yyprefix = ", expecting "; + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]); + yycount += 1; + if (yycount == 5) + { + yysize = 0; + break; + } + } + yysize += (sizeof ("syntax error, unexpected ") + + yystrlen (yytname[yytype])); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) + { + char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); + yyp = yystpcpy (yyp, yytname[yytype]); + + if (yycount < 5) + { + yyprefix = ", expecting "; + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + yyp = yystpcpy (yyp, yyprefix); + yyp = yystpcpy (yyp, yytname[yyx]); + yyprefix = " or "; + } + } + yyerror (yymsg); + YYSTACK_FREE (yymsg); + } + else + yyerror ("syntax error; also virtual memory exhausted"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror ("syntax error"); + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* If at end of input, pop the error token, + then the rest of the stack, then return failure. */ + if (yychar == YYEOF) + for (;;) + { + YYPOPSTACK; + if (yyssp == yyss) + YYABORT; + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[*yyssp], yyvsp); + } + } + else + { + YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); + yydestruct (yytoken, &yylval); + yychar = YYEMPTY; + + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + +#ifdef __GNUC__ + /* Pacify GCC when the user code never invokes YYERROR and the label + yyerrorlab therefore never appears in user code. */ + if (0) + goto yyerrorlab; +#endif + + yyvsp -= yylen; + yyssp -= yylen; + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[yystate], yyvsp); + YYPOPSTACK; + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + if (yyn == YYFINAL) + YYACCEPT; + + YYDPRINTF ((stderr, "Shifting error token, ")); + + *++yyvsp = yylval; + + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*----------------------------------------------. +| yyoverflowlab -- parser overflow comes here. | +`----------------------------------------------*/ +yyoverflowlab: + yyerror ("parser stack overflow"); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + return yyresult; +} + + + + + + diff --git a/khtml/css/parser.h b/khtml/css/parser.h new file mode 100644 index 000000000..239de28fc --- /dev/null +++ b/khtml/css/parser.h @@ -0,0 +1,163 @@ +/* A Bison parser, made by GNU Bison 1.875d. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + UNIMPORTANT_TOK = 258, + S = 259, + SGML_CD = 260, + INCLUDES = 261, + DASHMATCH = 262, + BEGINSWITH = 263, + ENDSWITH = 264, + CONTAINS = 265, + STRING = 266, + IDENT = 267, + NTH = 268, + HASH = 269, + IMPORT_SYM = 270, + PAGE_SYM = 271, + MEDIA_SYM = 272, + FONT_FACE_SYM = 273, + CHARSET_SYM = 274, + NAMESPACE_SYM = 275, + KHTML_RULE_SYM = 276, + KHTML_DECLS_SYM = 277, + KHTML_VALUE_SYM = 278, + IMPORTANT_SYM = 279, + QEMS = 280, + EMS = 281, + EXS = 282, + PXS = 283, + CMS = 284, + MMS = 285, + INS = 286, + PTS = 287, + PCS = 288, + DEGS = 289, + RADS = 290, + GRADS = 291, + MSECS = 292, + SECS = 293, + HERZ = 294, + KHERZ = 295, + DIMEN = 296, + PERCENTAGE = 297, + FLOAT = 298, + INTEGER = 299, + URI = 300, + FUNCTION = 301, + NOTFUNCTION = 302, + UNICODERANGE = 303 + }; +#endif +#define UNIMPORTANT_TOK 258 +#define S 259 +#define SGML_CD 260 +#define INCLUDES 261 +#define DASHMATCH 262 +#define BEGINSWITH 263 +#define ENDSWITH 264 +#define CONTAINS 265 +#define STRING 266 +#define IDENT 267 +#define NTH 268 +#define HASH 269 +#define IMPORT_SYM 270 +#define PAGE_SYM 271 +#define MEDIA_SYM 272 +#define FONT_FACE_SYM 273 +#define CHARSET_SYM 274 +#define NAMESPACE_SYM 275 +#define KHTML_RULE_SYM 276 +#define KHTML_DECLS_SYM 277 +#define KHTML_VALUE_SYM 278 +#define IMPORTANT_SYM 279 +#define QEMS 280 +#define EMS 281 +#define EXS 282 +#define PXS 283 +#define CMS 284 +#define MMS 285 +#define INS 286 +#define PTS 287 +#define PCS 288 +#define DEGS 289 +#define RADS 290 +#define GRADS 291 +#define MSECS 292 +#define SECS 293 +#define HERZ 294 +#define KHERZ 295 +#define DIMEN 296 +#define PERCENTAGE 297 +#define FLOAT 298 +#define INTEGER 299 +#define URI 300 +#define FUNCTION 301 +#define NOTFUNCTION 302 +#define UNICODERANGE 303 + + + + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) + +typedef union YYSTYPE { + CSSRuleImpl *rule; + CSSSelector *selector; + QPtrList<CSSSelector> *selectorList; + bool ok; + MediaListImpl *mediaList; + CSSMediaRuleImpl *mediaRule; + CSSRuleListImpl *ruleList; + ParseString string; + float val; + int prop_id; + unsigned int attribute; + unsigned int element; + unsigned int ns; + CSSSelector::Relation relation; + CSSSelector::Match match; + bool b; + char tok; + Value value; + ValueList *valueList; +} YYSTYPE; +/* Line 1285 of yacc.c. */ + +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + + + diff --git a/khtml/css/parser.y b/khtml/css/parser.y new file mode 100644 index 000000000..50e558db9 --- /dev/null +++ b/khtml/css/parser.y @@ -0,0 +1,1064 @@ +%{ + +/* + * This file is part of the KDE libraries + * Copyright (C) 2002-2003 Lars Knoll (knoll@kde.org) + * Copyright (c) 2003 Apple Computer + * Copyright (C) 2003 Dirk Mueller (mueller@kde.org) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <string.h> +#include <stdlib.h> + +#include <dom/dom_string.h> +#include <xml/dom_docimpl.h> +#include <css/cssstyleselector.h> +#include <css/css_ruleimpl.h> +#include <css/css_stylesheetimpl.h> +#include <css/css_valueimpl.h> +#include <misc/htmlhashes.h> +#include "cssparser.h" + +#include <assert.h> +#include <kdebug.h> +//#define CSS_DEBUG + +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 + +// turn off inlining to void warning with newer gcc +#undef __inline +#define __inline +#include "cssproperties.c" +#include "cssvalues.c" +#undef __inline + +int DOM::getPropertyID(const char *tagStr, int len) +{ + const struct props *propsPtr = findProp(tagStr, len); + if (!propsPtr) + return 0; + + return propsPtr->id; +} + +static inline int getValueID(const char *tagStr, int len) +{ + const struct css_value *val = findValue(tagStr, len); + if (!val) + return 0; + + return val->id; +} + + +#define YYDEBUG 0 +#undef YYMAXDEPTH +#define YYPARSE_PARAM parser +%} + +%pure_parser + +%union { + CSSRuleImpl *rule; + CSSSelector *selector; + QPtrList<CSSSelector> *selectorList; + bool ok; + MediaListImpl *mediaList; + CSSMediaRuleImpl *mediaRule; + CSSRuleListImpl *ruleList; + ParseString string; + float val; + int prop_id; + unsigned int attribute; + unsigned int element; + unsigned int ns; + CSSSelector::Relation relation; + CSSSelector::Match match; + bool b; + char tok; + Value value; + ValueList *valueList; +} + +%{ + +static inline int cssyyerror(const char *x ) +{ +#ifdef CSS_DEBUG + qDebug( "%s", x ); +#else + Q_UNUSED( x ); +#endif + return 1; +} + +static int cssyylex( YYSTYPE *yylval ) { + return CSSParser::current()->lex( yylval ); +} + +#define null 1 + +%} + +%destructor { delete $$; $$ = 0; } expr; +%destructor { delete $$; $$ = 0; } maybe_media_list media_list; +%destructor { delete $$; $$ = 0; } selector_list; +%destructor { delete $$; $$ = 0; } ruleset_list; +%destructor { delete $$; $$ = 0; } specifier specifier_list simple_selector selector class attrib pseudo; + +%no-lines +%verbose + +%left UNIMPORTANT_TOK + +%token S SGML_CD + +%token INCLUDES +%token DASHMATCH +%token BEGINSWITH +%token ENDSWITH +%token CONTAINS + +%token <string> STRING + +%right <string> IDENT + +%token <string> NTH + +%nonassoc <string> HASH +%nonassoc ':' +%nonassoc '.' +%nonassoc '[' +%nonassoc '*' +%nonassoc error +%left '|' + +%left IMPORT_SYM +%token PAGE_SYM +%token MEDIA_SYM +%token FONT_FACE_SYM +%token CHARSET_SYM +%token NAMESPACE_SYM +%token KHTML_RULE_SYM +%token KHTML_DECLS_SYM +%token KHTML_VALUE_SYM + +%token IMPORTANT_SYM + +%token <val> QEMS +%token <val> EMS +%token <val> EXS +%token <val> PXS +%token <val> CMS +%token <val> MMS +%token <val> INS +%token <val> PTS +%token <val> PCS +%token <val> DEGS +%token <val> RADS +%token <val> GRADS +%token <val> MSECS +%token <val> SECS +%token <val> HERZ +%token <val> KHERZ +%token <string> DIMEN +%token <val> PERCENTAGE +%token <val> FLOAT +%token <val> INTEGER + +%token <string> URI +%token <string> FUNCTION +%token <string> NOTFUNCTION + +%token <string> UNICODERANGE + +%type <relation> combinator + +%type <rule> ruleset +%type <rule> media +%type <rule> import +%type <rule> page +%type <rule> font_face +%type <rule> invalid_rule +%type <rule> invalid_at +%type <rule> rule + +%type <string> namespace_selector + +%type <string> string_or_uri +%type <string> ident_or_string +%type <string> medium +%type <string> hexcolor +%type <string> maybe_ns_prefix + +%type <mediaList> media_list +%type <mediaList> maybe_media_list + +%type <ruleList> ruleset_list + +%type <prop_id> property + +%type <selector> specifier +%type <selector> specifier_list +%type <selector> simple_selector +%type <selector> selector +%type <selectorList> selector_list +%type <selector> class +%type <selector> attrib +%type <selector> pseudo + +%type <ok> declaration_block +%type <ok> declaration_list +%type <ok> declaration + +%type <b> prio + +%type <match> match +%type <val> unary_operator +%type <tok> operator + +%type <valueList> expr +%type <value> term +%type <value> unary_term +%type <value> function + +%type <element> element_name + +%type <attribute> attrib_id + +%% + +stylesheet: + maybe_charset maybe_sgml import_list namespace_list rule_list + | khtml_rule maybe_space + | khtml_decls maybe_space + | khtml_value maybe_space + ; + +khtml_rule: + KHTML_RULE_SYM '{' maybe_space ruleset maybe_space '}' { + CSSParser *p = static_cast<CSSParser *>(parser); + p->rule = $4; + } +; + +khtml_decls: + KHTML_DECLS_SYM declaration_block { + /* can be empty */ + } +; + +khtml_value: + KHTML_VALUE_SYM '{' maybe_space expr '}' { + CSSParser *p = static_cast<CSSParser *>(parser); + if ( $4 ) { + p->valueList = $4; +#ifdef CSS_DEBUG + kdDebug( 6080 ) << " got property for " << p->id << + (p->important?" important":"")<< endl; + bool ok = +#endif + p->parseValue( p->id, p->important ); +#ifdef CSS_DEBUG + if ( !ok ) + kdDebug( 6080 ) << " couldn't parse value!" << endl; +#endif + } +#ifdef CSS_DEBUG + else + kdDebug( 6080 ) << " no value found!" << endl; +#endif + delete p->valueList; + p->valueList = 0; + } +; + +maybe_space: + /* empty */ %prec UNIMPORTANT_TOK + | maybe_space S + ; + +maybe_sgml: + /* empty */ + | maybe_sgml SGML_CD + | maybe_sgml S + ; + +maybe_charset: + /* empty */ + | CHARSET_SYM maybe_space STRING maybe_space ';' { +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "charset rule: " << qString($3) << endl; +#endif + } + | CHARSET_SYM error invalid_block + | CHARSET_SYM error ';' + ; + +import_list: + /* empty */ + | import_list import maybe_sgml { + CSSParser *p = static_cast<CSSParser *>(parser); + if ( $2 && p->styleElement && p->styleElement->isCSSStyleSheet() ) { + p->styleElement->append( $2 ); + } else { + delete $2; + } + } + ; + +import: + IMPORT_SYM maybe_space string_or_uri maybe_space maybe_media_list ';' { +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "@import: " << qString($3) << endl; +#endif + CSSParser *p = static_cast<CSSParser *>(parser); + if ( $5 && p->styleElement && p->styleElement->isCSSStyleSheet() ) + $$ = new CSSImportRuleImpl( p->styleElement, domString($3), $5 ); + else + $$ = 0; + } + | IMPORT_SYM error invalid_block { + $$ = 0; + } + | IMPORT_SYM error ';' { + $$ = 0; + } + ; + +namespace_list: + /* empty */ %prec UNIMPORTANT_TOK + | namespace_list namespace maybe_sgml +; + +namespace: +NAMESPACE_SYM maybe_space maybe_ns_prefix string_or_uri maybe_space ';' { +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "@namespace: " << qString($4) << endl; +#endif + CSSParser *p = static_cast<CSSParser *>(parser); + if (p->styleElement && p->styleElement->isCSSStyleSheet()) + static_cast<CSSStyleSheetImpl*>(p->styleElement)->addNamespace(p, domString($3), domString($4)); + } +| NAMESPACE_SYM error invalid_block +| NAMESPACE_SYM error ';' + ; + +maybe_ns_prefix: +/* empty */ { $$.string = 0; } +| IDENT S { $$ = $1; } + ; + +rule_list: + /* empty */ + | rule_list rule maybe_sgml { + CSSParser *p = static_cast<CSSParser *>(parser); + if ( $2 && p->styleElement && p->styleElement->isCSSStyleSheet() ) { + p->styleElement->append( $2 ); + } else { + delete $2; + } + } + ; + +rule: + ruleset + | media + | page + | font_face + | invalid_rule + | invalid_at + | import error { delete $1; $$ = 0; } + ; + +string_or_uri: + STRING + | URI + ; + +maybe_media_list: + /* empty */ { + $$ = new MediaListImpl(); + } + | media_list +; + + +media_list: + medium { + $$ = new MediaListImpl(); + $$->appendMedium( domString($1).lower() ); + } + | media_list ',' maybe_space medium { + $$ = $1; + if ($$) + $$->appendMedium( domString($4).lower() ); + } + | media_list error { + delete $1; + $$ = 0; + } + ; + +media: + MEDIA_SYM maybe_space media_list '{' maybe_space ruleset_list '}' { + CSSParser *p = static_cast<CSSParser *>(parser); + if ( $3 && $6 && + p->styleElement && p->styleElement->isCSSStyleSheet() ) { + $$ = new CSSMediaRuleImpl( static_cast<CSSStyleSheetImpl*>(p->styleElement), $3, $6 ); + } else { + $$ = 0; + delete $3; + delete $6; + } + } + ; + +ruleset_list: + /* empty */ { $$ = 0; } + | ruleset_list ruleset maybe_space { + $$ = $1; + if ( $2 ) { + if ( !$$ ) $$ = new CSSRuleListImpl(); + $$->append( $2 ); + } + } + ; + +medium: + IDENT maybe_space { + $$ = $1; + } + ; + +/* +page: + PAGE_SYM maybe_space IDENT? pseudo_page? maybe_space + '{' maybe_space declaration [ ';' maybe_space declaration ]* '}' maybe_space + ; + +pseudo_page + : ':' IDENT + ; + +font_face + : FONT_FACE_SYM maybe_space + '{' maybe_space declaration [ ';' maybe_space declaration ]* '}' maybe_space + ; +*/ + +page: + PAGE_SYM error invalid_block { + $$ = 0; + } + | PAGE_SYM error ';' { + $$ = 0; + } + ; + +font_face: + FONT_FACE_SYM error invalid_block { + $$ = 0; + } + | FONT_FACE_SYM error ';' { + $$ = 0; + } +; + +combinator: + '+' maybe_space { $$ = CSSSelector::DirectAdjacent; } + | '~' maybe_space { $$ = CSSSelector::IndirectAdjacent; } + | '>' maybe_space { $$ = CSSSelector::Child; } + | /* empty */ { $$ = CSSSelector::Descendant; } + ; + +unary_operator: + '-' { $$ = -1; } + | '+' { $$ = 1; } + ; + +ruleset: + selector_list declaration_block { +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "got ruleset" << endl << " selector:" << endl; +#endif + CSSParser *p = static_cast<CSSParser *>(parser); + if ( $1 && $2 && p->numParsedProperties ) { + CSSStyleRuleImpl *rule = new CSSStyleRuleImpl( p->styleElement ); + CSSStyleDeclarationImpl *decl = p->createStyleDeclaration( rule ); + rule->setSelector( $1 ); + rule->setDeclaration(decl); + $$ = rule; + } else { + $$ = 0; + delete $1; + p->clearProperties(); + } + } + ; + +selector_list: + selector %prec UNIMPORTANT_TOK { + if ( $1 ) { + $$ = new QPtrList<CSSSelector>; + $$->setAutoDelete( true ); +#ifdef CSS_DEBUG + kdDebug( 6080 ) << " got simple selector:" << endl; + $1->print(); +#endif + $$->append( $1 ); + khtml::CSSStyleSelector::precomputeAttributeDependencies(static_cast<CSSParser *>(parser)->document(), $1); + } else { + $$ = 0; + } + } + | selector_list ',' maybe_space selector %prec UNIMPORTANT_TOK { + if ( $1 && $4 ) { + $$ = $1; + $$->append( $4 ); + khtml::CSSStyleSelector::precomputeAttributeDependencies(static_cast<CSSParser *>(parser)->document(), $4); +#ifdef CSS_DEBUG + kdDebug( 6080 ) << " got simple selector:" << endl; + $4->print(); +#endif + } else { + delete $1; + delete $4; + $$ = 0; + } + } + | selector_list error { + delete $1; + $$ = 0; + } + ; + +selector: + simple_selector { + $$ = $1; + } + | selector combinator simple_selector { + if ( !$1 || !$3 ) { + delete $1; + delete $3; + $$ = 0; + } else { + $$ = $3; + CSSSelector *end = $3; + while( end->tagHistory ) + end = end->tagHistory; + end->relation = $2; + end->tagHistory = $1; + } + } + | selector error { + delete $1; + $$ = 0; + } + ; + +namespace_selector: + /* empty */ '|' { $$.string = 0; $$.length = 0; } + | '*' '|' { static unsigned short star = '*'; $$.string = ☆ $$.length = 1; } + | IDENT '|' { $$ = $1; } +; + +simple_selector: + element_name maybe_space { + $$ = new CSSSelector(); + $$->tag = $1; + } + | element_name specifier_list maybe_space { + $$ = $2; + if ( $$ ) + $$->tag = $1; + } + | specifier_list maybe_space { + $$ = $1; + if ( $$ ) + $$->tag = makeId(static_cast<CSSParser*>(parser)->defaultNamespace(), anyLocalName); + } + | namespace_selector element_name maybe_space { + $$ = new CSSSelector(); + $$->tag = $2; + CSSParser *p = static_cast<CSSParser *>(parser); + if (p->styleElement && p->styleElement->isCSSStyleSheet()) + static_cast<CSSStyleSheetImpl*>(p->styleElement)->determineNamespace($$->tag, domString($1)); + } + | namespace_selector element_name specifier_list maybe_space { + $$ = $3; + if ($$) { + $$->tag = $2; + CSSParser *p = static_cast<CSSParser *>(parser); + if (p->styleElement && p->styleElement->isCSSStyleSheet()) + static_cast<CSSStyleSheetImpl*>(p->styleElement)->determineNamespace($$->tag, domString($1)); + } + } + | namespace_selector specifier_list maybe_space { + $$ = $2; + if ($$) { + $$->tag = makeId(anyNamespace, anyLocalName); + CSSParser *p = static_cast<CSSParser *>(parser); + if (p->styleElement && p->styleElement->isCSSStyleSheet()) + static_cast<CSSStyleSheetImpl*>(p->styleElement)->determineNamespace($$->tag, domString($1)); + } + } + ; + +element_name: + IDENT { + CSSParser *p = static_cast<CSSParser *>(parser); + DOM::DocumentImpl *doc = p->document(); + QString tag = qString($1); + if ( doc ) { + if (doc->isHTMLDocument()) + tag = tag.lower(); + const DOMString dtag(tag); + $$ = makeId(p->defaultNamespace(), doc->getId(NodeImpl::ElementId, dtag.implementation(), false, true)); + } else { + $$ = makeId(p->defaultNamespace(), khtml::getTagID(tag.lower().ascii(), tag.length())); + // this case should never happen - only when loading + // the default stylesheet - which must not contain unknown tags +// assert($$ != 0); + } + } + | '*' { + $$ = makeId(static_cast<CSSParser*>(parser)->defaultNamespace(), anyLocalName); + } + ; + +specifier_list: + specifier { + $$ = $1; + $$->nonCSSHint = static_cast<CSSParser *>(parser)->nonCSSHint; + } + | specifier_list specifier { + $$ = $1; + if ( $$ ) { + CSSSelector *end = $1; + while( end->tagHistory ) + end = end->tagHistory; + end->relation = CSSSelector::SubSelector; + end->tagHistory = $2; + } + } + | specifier_list error { + delete $1; + $$ = 0; + } +; + +specifier: + HASH { + $$ = new CSSSelector(); + $$->match = CSSSelector::Id; + $$->attr = ATTR_ID; + $$->value = domString($1); + } + | class + | attrib + | pseudo + ; + +class: + '.' IDENT { + $$ = new CSSSelector(); + $$->match = CSSSelector::Class; + $$->attr = ATTR_CLASS; + $$->value = domString($2); + } + ; + +attrib_id: + IDENT maybe_space { + CSSParser *p = static_cast<CSSParser *>(parser); + DOM::DocumentImpl *doc = p->document(); + + QString attr = qString($1); + if ( doc ) { + if (doc->isHTMLDocument()) + attr = attr.lower(); + const DOMString dattr(attr); +#ifdef APPLE_CHANGES + $$ = doc->attrId(0, dattr.implementation(), false); +#else + $$ = doc->getId(NodeImpl::AttributeId, dattr.implementation(), false, true); +#endif + } else { + $$ = khtml::getAttrID(attr.lower().ascii(), attr.length()); + // this case should never happen - only when loading + // the default stylesheet - which must not contain unknown attributes + assert($$ != 0); + } + } + ; + +attrib: + '[' maybe_space attrib_id ']' { + $$ = new CSSSelector(); + $$->attr = $3; + $$->match = CSSSelector::Set; + } + | '[' maybe_space attrib_id match maybe_space ident_or_string maybe_space ']' { + $$ = new CSSSelector(); + $$->attr = $3; + $$->match = $4; + $$->value = domString($6); + } + | '[' maybe_space namespace_selector attrib_id ']' { + $$ = new CSSSelector(); + $$->attr = $4; + $$->match = CSSSelector::Set; + CSSParser *p = static_cast<CSSParser *>(parser); + if (p->styleElement && p->styleElement->isCSSStyleSheet()) + static_cast<CSSStyleSheetImpl*>(p->styleElement)->determineNamespace($$->attr, domString($3)); + } + | '[' maybe_space namespace_selector attrib_id match maybe_space ident_or_string maybe_space ']' { + $$ = new CSSSelector(); + $$->attr = $4; + $$->match = (CSSSelector::Match)$5; + $$->value = domString($7); + CSSParser *p = static_cast<CSSParser *>(parser); + if (p->styleElement && p->styleElement->isCSSStyleSheet()) + static_cast<CSSStyleSheetImpl*>(p->styleElement)->determineNamespace($$->attr, domString($3)); + } + ; + +match: + '=' { + $$ = CSSSelector::Exact; + } + | INCLUDES { + $$ = CSSSelector::List; + } + | DASHMATCH { + $$ = CSSSelector::Hyphen; + } + | BEGINSWITH { + $$ = CSSSelector::Begin; + } + | ENDSWITH { + $$ = CSSSelector::End; + } + | CONTAINS { + $$ = CSSSelector::Contain; + } + ; + +ident_or_string: + IDENT + | STRING + ; + +pseudo: + ':' IDENT { + $$ = new CSSSelector(); + $$->match = CSSSelector::PseudoClass; + $$->value = domString($2); + } + | + ':' ':' IDENT { + $$ = new CSSSelector(); + $$->match = CSSSelector::PseudoElement; + $$->value = domString($3); + } + // used by :nth-* + | ':' FUNCTION NTH ')' { + $$ = new CSSSelector(); + $$->match = CSSSelector::PseudoClass; + $$->string_arg = domString($3); + $$->value = domString($2); + } + // used by :nth-* + | ':' FUNCTION INTEGER ')' { + $$ = new CSSSelector(); + $$->match = CSSSelector::PseudoClass; + $$->string_arg = QString::number($3); + $$->value = domString($2); + } + // used by :nth-* and :lang + | ':' FUNCTION IDENT ')' { + $$ = new CSSSelector(); + $$->match = CSSSelector::PseudoClass; + $$->string_arg = domString($3); + $$->value = domString($2); + } + // used by :contains + | ':' FUNCTION STRING ')' { + $$ = new CSSSelector(); + $$->match = CSSSelector::PseudoClass; + $$->string_arg = domString($3); + $$->value = domString($2); + } + // used only by :not + | ':' NOTFUNCTION maybe_space simple_selector ')' { + $$ = new CSSSelector(); + $$->match = CSSSelector::PseudoClass; + $$->simpleSelector = $4; + $$->value = domString($2); + } + ; + +declaration_block: + '{' maybe_space declaration '}' { + $$ = $3; + } + | '{' maybe_space error '}' { + $$ = false; + } + | '{' maybe_space declaration_list '}' { + $$ = $3; + } + | '{' maybe_space declaration_list declaration '}' { + $$ = $3; + if ( $4 ) + $$ = $4; + } + | '{' maybe_space declaration_list error '}' { + $$ = $3; + } + ; + +declaration_list: + declaration ';' maybe_space { + $$ = $1; + } + | + error ';' maybe_space { + $$ = false; + } + | declaration_list declaration ';' maybe_space { + $$ = $1; + if ( $2 ) + $$ = $2; + } + | declaration_list error ';' maybe_space { + $$ = $1; + } + ; + +declaration: + property ':' maybe_space expr prio { + $$ = false; + CSSParser *p = static_cast<CSSParser *>(parser); + if ( $1 && $4 ) { + p->valueList = $4; +#ifdef CSS_DEBUG + kdDebug( 6080 ) << " got property: " << $1 << + ($5?" important":"")<< endl; +#endif + bool ok = p->parseValue( $1, $5 ); + if ( ok ) + $$ = ok; +#ifdef CSS_DEBUG + else + kdDebug( 6080 ) << " couldn't parse value!" << endl; +#endif + } else { + delete $4; + } + delete p->valueList; + p->valueList = 0; + } + | error invalid_block { + $$ = false; + } + ; + +property: + IDENT maybe_space { + QString str = qString($1); + $$ = getPropertyID( str.lower().latin1(), str.length() ); + } + ; + +prio: + IMPORTANT_SYM maybe_space { $$ = true; } + | /* empty */ { $$ = false; } + ; + +expr: + term { + $$ = new ValueList; + $$->addValue( $1 ); + } + | expr operator term { + $$ = $1; + if ( $$ ) { + if ( $2 ) { + Value v; + v.id = 0; + v.unit = Value::Operator; + v.iValue = $2; + $$->addValue( v ); + } + $$->addValue( $3 ); + } + } + ; + +operator: + '/' maybe_space { + $$ = '/'; + } + | ',' maybe_space { + $$ = ','; + } + | /* empty */ { + $$ = 0; + } + ; + +term: + unary_term { $$ = $1; } + | unary_operator unary_term { $$ = $2; $$.fValue *= $1; } + /* DIMEN is an unary_term, but since we store the string we must not modify fValue */ + | DIMEN maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; } + | STRING maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_STRING; } + | IDENT maybe_space { + QString str = qString( $1 ); + $$.id = getValueID( str.lower().latin1(), str.length() ); + $$.unit = CSSPrimitiveValue::CSS_IDENT; + $$.string = $1; + } + | URI maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_URI; } + | UNICODERANGE maybe_space { $$.id = 0; $$.iValue = 0; $$.unit = CSSPrimitiveValue::CSS_UNKNOWN;/* ### */ } + | hexcolor { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_RGBCOLOR; } +/* ### according to the specs a function can have a unary_operator in front. I know no case where this makes sense */ + | function { + $$ = $1; + } + ; + +unary_term: + INTEGER maybe_space { $$.id = 0; $$.isInt = true; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; } + | FLOAT maybe_space { $$.id = 0; $$.isInt = false; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; } + | PERCENTAGE maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PERCENTAGE; } + | PXS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PX; } + | CMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_CM; } + | MMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_MM; } + | INS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_IN; } + | PTS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PT; } + | PCS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PC; } + | DEGS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_DEG; } + | RADS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_RAD; } + | GRADS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_GRAD; } + | MSECS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_MS; } + | SECS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_S; } + | HERZ maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_HZ; } + | KHERZ maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_KHZ; } + | EMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_EMS; } + | QEMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = Value::Q_EMS; } + | EXS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_EXS; } + ; + + +function: + FUNCTION maybe_space expr ')' maybe_space { + Function *f = new Function; + f->name = $1; + f->args = $3; + $$.id = 0; + $$.unit = Value::Function; + $$.function = f; + } + | FUNCTION maybe_space error { + Function *f = new Function; + f->name = $1; + f->args = 0; + $$.id = 0; + $$.unit = Value::Function; + $$.function = f; + } + + ; +/* + * There is a constraint on the color that it must + * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F]) + * after the "#"; e.g., "#000" is OK, but "#abcd" is not. + */ +hexcolor: + HASH maybe_space { $$ = $1; } + ; + + +/* error handling rules */ + +invalid_at: + '@' error invalid_block { + $$ = 0; +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "skipped invalid @-rule" << endl; +#endif + } + | '@' error ';' { + $$ = 0; +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "skipped invalid @-rule" << endl; +#endif + } + ; + +invalid_rule: + error invalid_block { + $$ = 0; +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "skipped invalid rule" << endl; +#endif + } +/* + Seems like the two rules below are trying too much and violating + http://www.hixie.ch/tests/evil/mixed/csserrorhandling.html + + | error ';' { + $$ = 0; +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "skipped invalid rule" << endl; +#endif + } + | error '}' { + $$ = 0; +#ifdef CSS_DEBUG + kdDebug( 6080 ) << "skipped invalid rule" << endl; +#endif + } +*/ + ; + +invalid_block: + '{' error invalid_block_list error '}' + | '{' error '}' + ; + +invalid_block_list: + invalid_block + | invalid_block_list error invalid_block +; + +%% + diff --git a/khtml/css/quirks.css b/khtml/css/quirks.css new file mode 100644 index 000000000..6a02ee0bd --- /dev/null +++ b/khtml/css/quirks.css @@ -0,0 +1,41 @@ +/* + * This style sheet is used by khtml to render HTML pages in quirks mode + * (C) 2000-2003 Lars Knoll (knoll@kde.org) + * + * Konqueror/khtml relies on the existence of this style sheet for + * rendering. Do not remove or modify this file unless you know + * what you are doing. + */ + +/* Give floated images margins of 3px */ +img[align="left"] { + margin-right: 3px; +} + +img[align="right"] { + margin-left: 3px; +} + +/* Tables reset both line-height and white-space in quirks mode. + Compatible with WinIE. For some reason they don't reset font-family */ +table { + white-space: normal; + line-height: normal; + color: -khtml-text; + font-size: medium; + empty-cells: hide; + text-align: -khtml-auto; + font-weight: initial; +} + +LAYER { + position: absolute; +} + +DIV > LAYER { + position: static; +} + +ILAYER > LAYER { + position: relative; +}
\ No newline at end of file diff --git a/khtml/css/tokenizer.cpp b/khtml/css/tokenizer.cpp new file mode 100644 index 000000000..493a98032 --- /dev/null +++ b/khtml/css/tokenizer.cpp @@ -0,0 +1,930 @@ +/* + * This file is part of the DOM implementation for KDE. + * + * Copyright (C) 2003 Lars Knoll (knoll@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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/* This file is mostly data generated by flex. Unfortunately flex + can't handle 16bit strings directly, so we just copy the part of + the code we need and modify it to our needs. + + Most of the defines below are to make sure we can easily use the + flex generated code, using as little editing as possible. + + The flex syntax to generate the lexer are more or less directly + copied from the CSS2.1 specs, with some fixes for comments and + the important symbol. + + To regenerate, run flex on tokenizer.flex. After this, copy the + data tables and the YY_DECL method over to this file. Remove the + init code from YY_DECL and change the YY_END_OF_BUFFER to only call + yyterminate(). + +*/ + +// --------- begin generated code ------------------- +#define YY_NUM_RULES 51 +#define YY_END_OF_BUFFER 52 +static yyconst short int yy_accept[331] = + { 0, + 0, 0, 52, 50, 2, 2, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 42, 50, 50, 50, 50, + 11, 11, 11, 50, 50, 2, 0, 0, 0, 10, + 0, 13, 0, 8, 0, 0, 9, 0, 0, 0, + 11, 11, 43, 0, 41, 0, 0, 42, 0, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 12, + 40, 40, 37, 0, 0, 0, 0, 0, 0, 0, + 0, 11, 11, 7, 47, 11, 0, 0, 11, 11, + 0, 11, 6, 5, 0, 0, 0, 10, 0, 0, + 13, 13, 0, 0, 10, 0, 0, 4, 12, 0, + + 0, 40, 40, 40, 0, 40, 28, 40, 24, 26, + 40, 38, 30, 40, 29, 36, 40, 32, 31, 27, + 40, 0, 0, 0, 0, 0, 0, 0, 0, 11, + 11, 11, 12, 11, 11, 48, 48, 11, 0, 0, + 0, 13, 0, 0, 0, 1, 40, 40, 40, 40, + 33, 40, 39, 12, 34, 3, 0, 0, 0, 0, + 0, 0, 0, 11, 11, 44, 0, 48, 48, 48, + 47, 0, 0, 13, 0, 0, 0, 40, 40, 40, + 35, 0, 0, 0, 0, 0, 0, 15, 11, 11, + 49, 48, 48, 48, 48, 0, 0, 0, 0, 46, + + 0, 0, 0, 13, 0, 40, 40, 25, 0, 0, + 0, 0, 16, 0, 11, 11, 49, 48, 48, 48, + 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 46, 0, 0, 0, 0, 13, 0, 40, 40, + 0, 0, 0, 14, 0, 11, 11, 49, 48, 48, + 48, 48, 48, 48, 0, 45, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, + 0, 40, 40, 0, 18, 0, 0, 11, 49, 48, + 48, 48, 48, 48, 48, 48, 0, 45, 0, 0, + 0, 45, 0, 0, 0, 0, 40, 0, 0, 0, + + 0, 0, 49, 0, 0, 0, 23, 0, 0, 0, + 17, 19, 49, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 20, 0, 0, 0, 21, 22, 0 + } ; + +static yyconst int yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 4, 5, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 12, 18, 19, 20, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 12, 12, 22, + 23, 24, 25, 26, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 39, 52, 39, 53, + 12, 27, 12, 28, 29, 12, 30, 31, 32, 33, + + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 39, 52, + 39, 53, 12, 54, 12, 55, 1, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56 + } ; + +static yyconst int yy_meta[57] = + { 0, + 1, 2, 3, 3, 3, 4, 4, 4, 4, 4, + 4, 4, 4, 5, 4, 4, 4, 6, 4, 4, + 6, 4, 4, 4, 7, 4, 8, 4, 8, 9, + 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 4, 4, 8 + } ; + +static yyconst short int yy_base[359] = + { 0, + 0, 0, 807, 1638, 55, 60, 65, 64, 779, 781, + 60, 780, 56, 781, 785, 93, 793, 63, 126, 773, + 61, 75, 136, 772, 771, 162, 167, 751, 70, 1638, + 204, 764, 154, 1638, 63, 238, 1638, 760, 64, 160, + 82, 183, 133, 767, 1638, 755, 760, 0, 183, 53, + 753, 52, 83, 169, 135, 121, 57, 192, 205, 206, + 225, 86, 745, 752, 729, 731, 723, 716, 723, 726, + 725, 231, 276, 1638, 1638, 234, 254, 733, 235, 249, + 291, 277, 1638, 1638, 701, 195, 172, 219, 325, 359, + 717, 393, 217, 237, 286, 427, 461, 1638, 160, 727, + + 135, 715, 495, 714, 344, 256, 700, 265, 699, 698, + 88, 697, 696, 175, 695, 694, 233, 693, 679, 678, + 267, 684, 664, 670, 656, 640, 651, 622, 627, 446, + 305, 529, 639, 320, 321, 318, 634, 323, 614, 287, + 521, 536, 326, 544, 641, 1638, 551, 621, 585, 311, + 619, 339, 618, 360, 617, 1638, 594, 582, 556, 559, + 564, 567, 566, 577, 592, 1638, 600, 324, 574, 572, + 634, 549, 620, 635, 641, 579, 324, 656, 662, 278, + 567, 551, 544, 562, 526, 528, 501, 1638, 677, 683, + 698, 382, 523, 522, 521, 732, 758, 288, 341, 1638, + + 784, 496, 718, 744, 791, 799, 806, 517, 502, 489, + 486, 471, 1638, 474, 814, 821, 829, 383, 493, 485, + 484, 481, 400, 343, 407, 863, 356, 897, 931, 957, + 983, 1009, 1035, 1069, 475, 848, 882, 917, 943, 969, + 486, 453, 460, 1638, 445, 995, 1076, 1084, 416, 448, + 447, 444, 443, 426, 440, 1638, 444, 408, 509, 1118, + 1152, 601, 358, 1131, 1186, 1220, 1205, 407, 1227, 1235, + 1242, 481, 1250, 456, 1638, 417, 406, 535, 1257, 403, + 1638, 1638, 1638, 1638, 1638, 1638, 1049, 409, 410, 1265, + 1299, 426, 443, 1285, 1300, 370, 676, 354, 334, 352, + + 339, 283, 1306, 1321, 1327, 1342, 1638, 261, 226, 225, + 1638, 1638, 1638, 1348, 1363, 1369, 214, 192, 129, 1384, + 1390, 1405, 73, 1638, 52, 1411, 1426, 1638, 1638, 1638, + 1460, 1464, 1472, 1476, 1482, 1487, 1495, 1501, 1509, 1518, + 1520, 1526, 1530, 1536, 1545, 1551, 1555, 1564, 1568, 1576, + 1580, 1588, 1596, 1604, 1608, 1616, 1624, 1628 + } ; + +static yyconst short int yy_def[359] = + { 0, + 330, 1, 330, 330, 330, 330, 330, 331, 332, 330, + 333, 330, 334, 330, 330, 330, 330, 330, 335, 330, + 336, 336, 336, 330, 330, 330, 330, 330, 331, 330, + 337, 332, 338, 330, 333, 339, 330, 330, 330, 335, + 336, 336, 16, 340, 330, 341, 330, 16, 342, 343, + 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, + 343, 343, 343, 330, 330, 330, 330, 330, 330, 330, + 330, 336, 336, 330, 330, 336, 344, 330, 336, 336, + 330, 336, 330, 330, 330, 331, 331, 331, 331, 337, + 332, 332, 333, 333, 333, 333, 339, 330, 330, 340, + + 345, 343, 343, 343, 346, 343, 343, 343, 343, 343, + 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, + 343, 330, 330, 330, 330, 330, 330, 330, 330, 73, + 336, 73, 330, 336, 336, 347, 330, 336, 330, 331, + 89, 92, 333, 96, 348, 330, 103, 343, 103, 343, + 343, 343, 343, 343, 343, 330, 330, 330, 330, 330, + 330, 330, 330, 73, 132, 330, 330, 349, 330, 330, + 350, 330, 89, 92, 96, 348, 345, 103, 149, 343, + 343, 330, 330, 330, 330, 330, 330, 330, 73, 132, + 330, 351, 330, 330, 330, 350, 350, 352, 353, 330, + + 354, 330, 89, 92, 96, 103, 149, 343, 330, 330, + 330, 330, 330, 330, 73, 132, 330, 355, 330, 330, + 330, 330, 330, 352, 330, 356, 353, 357, 350, 350, + 350, 350, 350, 354, 330, 89, 92, 96, 103, 149, + 330, 330, 330, 330, 330, 73, 132, 330, 358, 330, + 330, 330, 330, 330, 330, 330, 352, 352, 352, 352, + 356, 353, 353, 353, 353, 357, 233, 330, 89, 92, + 96, 343, 149, 330, 330, 330, 330, 246, 330, 330, + 330, 330, 330, 330, 330, 330, 352, 352, 352, 260, + 353, 353, 353, 265, 233, 330, 343, 330, 330, 330, + + 330, 330, 330, 260, 265, 233, 330, 330, 330, 330, + 330, 330, 330, 260, 265, 233, 330, 330, 330, 260, + 265, 233, 330, 330, 330, 260, 265, 330, 330, 0, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330 + } ; + +static yyconst short int yy_nxt[1695] = + { 0, + 4, 5, 6, 5, 5, 5, 7, 8, 9, 10, + 4, 4, 11, 4, 4, 12, 4, 13, 14, 15, + 16, 17, 4, 4, 4, 18, 19, 20, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 22, 21, 21, 21, 21, 21, 21, 23, + 21, 21, 21, 24, 25, 21, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, + 27, 30, 30, 38, 75, 30, 39, 30, 105, 105, + 65, 106, 40, 105, 39, 329, 36, 77, 75, 36, + 31, 78, 79, 107, 66, 75, 31, 67, 42, 113, + + 68, 77, 28, 45, 69, 70, 99, 71, 77, 105, + 46, 47, 105, 48, 105, 121, 108, 152, 80, 49, + 328, 50, 51, 51, 52, 53, 54, 51, 55, 56, + 57, 51, 58, 51, 59, 60, 51, 61, 51, 62, + 63, 51, 51, 51, 51, 51, 73, 105, 51, 75, + 101, 330, 81, 43, 146, 73, 73, 73, 73, 73, + 73, 105, 77, 26, 26, 26, 26, 26, 27, 27, + 27, 27, 27, 112, 92, 51, 78, 78, 325, 30, + 73, 111, 82, 92, 92, 92, 92, 92, 92, 73, + 73, 73, 73, 73, 73, 105, 75, 29, 31, 78, + + 79, 105, 30, 103, 28, 29, 29, 29, 86, 77, + 109, 88, 103, 103, 103, 103, 103, 103, 105, 35, + 110, 31, 78, 117, 89, 324, 30, 153, 114, 30, + 90, 105, 105, 89, 89, 89, 89, 89, 89, 35, + 35, 35, 93, 36, 75, 31, 115, 75, 75, 30, + 95, 105, 116, 154, 323, 134, 118, 77, 96, 105, + 77, 77, 75, 36, 97, 319, 318, 96, 96, 96, + 96, 96, 96, 119, 132, 77, 120, 72, 72, 72, + 72, 72, 105, 132, 132, 132, 132, 132, 132, 75, + 75, 105, 317, 105, 30, 225, 130, 135, 30, 155, + + 151, 150, 77, 77, 105, 130, 130, 130, 130, 130, + 130, 136, 36, 31, 226, 137, 312, 138, 75, 208, + 136, 136, 136, 136, 136, 136, 87, 140, 140, 140, + 87, 77, 30, 75, 166, 167, 171, 105, 30, 177, + 134, 167, 169, 146, 180, 141, 77, 77, 193, 77, + 225, 31, 36, 225, 141, 141, 141, 141, 141, 141, + 29, 29, 29, 86, 149, 105, 88, 228, 225, 226, + 225, 181, 311, 149, 149, 149, 149, 149, 149, 89, + 154, 310, 228, 309, 228, 90, 105, 308, 89, 89, + 89, 89, 89, 89, 91, 91, 91, 91, 91, 167, + + 167, 223, 223, 223, 223, 223, 219, 250, 255, 255, + 255, 255, 255, 142, 200, 225, 225, 225, 307, 33, + 167, 256, 142, 142, 142, 142, 142, 142, 94, 143, + 143, 143, 94, 167, 226, 226, 226, 302, 225, 30, + 281, 255, 255, 255, 255, 255, 224, 144, 301, 296, + 286, 225, 228, 36, 256, 225, 144, 144, 144, 144, + 144, 144, 35, 35, 35, 93, 164, 285, 284, 228, + 226, 283, 282, 95, 277, 164, 164, 164, 164, 164, + 164, 96, 102, 102, 102, 102, 102, 97, 298, 276, + 96, 96, 96, 96, 96, 96, 102, 102, 102, 102, + + 102, 275, 299, 274, 268, 254, 300, 105, 253, 252, + 287, 255, 255, 255, 287, 147, 225, 251, 245, 244, + 243, 105, 242, 288, 147, 147, 147, 147, 147, 147, + 131, 131, 131, 131, 131, 226, 131, 131, 131, 131, + 131, 173, 241, 105, 235, 222, 221, 220, 214, 165, + 173, 173, 173, 173, 173, 173, 174, 213, 165, 165, + 165, 165, 165, 165, 175, 174, 174, 174, 174, 174, + 174, 178, 212, 175, 175, 175, 175, 175, 175, 211, + 178, 178, 178, 178, 178, 178, 148, 148, 148, 148, + 148, 210, 209, 105, 177, 202, 195, 189, 194, 188, + + 187, 186, 185, 227, 184, 179, 189, 189, 189, 189, + 189, 189, 190, 225, 179, 179, 179, 179, 179, 179, + 191, 190, 190, 190, 190, 190, 190, 228, 183, 191, + 191, 191, 191, 191, 191, 196, 196, 196, 196, 196, + 203, 198, 182, 105, 105, 105, 199, 105, 200, 203, + 203, 203, 203, 203, 203, 204, 177, 172, 170, 133, + 201, 205, 163, 162, 204, 204, 204, 204, 204, 204, + 205, 205, 205, 205, 205, 205, 206, 148, 148, 148, + 148, 148, 207, 161, 160, 206, 206, 206, 206, 206, + 206, 207, 207, 207, 207, 207, 207, 215, 159, 158, + + 157, 156, 105, 216, 105, 105, 215, 215, 215, 215, + 215, 215, 216, 216, 216, 216, 216, 216, 217, 105, + 105, 105, 105, 105, 105, 105, 105, 217, 217, 217, + 217, 217, 217, 196, 196, 196, 196, 196, 236, 198, + 105, 105, 101, 33, 199, 139, 200, 236, 236, 236, + 236, 236, 236, 133, 129, 128, 127, 126, 201, 223, + 223, 223, 223, 223, 237, 330, 125, 124, 123, 122, + 330, 105, 200, 237, 237, 237, 237, 237, 237, 105, + 43, 49, 101, 98, 201, 223, 223, 223, 223, 229, + 33, 231, 85, 84, 83, 74, 231, 231, 232, 64, + + 44, 43, 37, 34, 233, 33, 330, 330, 330, 330, + 234, 238, 330, 233, 233, 233, 233, 233, 233, 239, + 238, 238, 238, 238, 238, 238, 240, 330, 239, 239, + 239, 239, 239, 239, 246, 240, 240, 240, 240, 240, + 240, 247, 330, 246, 246, 246, 246, 246, 246, 248, + 247, 247, 247, 247, 247, 247, 330, 330, 248, 248, + 248, 248, 248, 248, 224, 224, 224, 257, 269, 330, + 259, 330, 330, 330, 330, 330, 330, 269, 269, 269, + 269, 269, 269, 260, 330, 330, 330, 330, 330, 261, + 330, 330, 260, 260, 260, 260, 260, 260, 227, 227, + + 227, 262, 270, 330, 330, 330, 330, 330, 330, 264, + 330, 270, 270, 270, 270, 270, 270, 265, 330, 330, + 330, 330, 330, 266, 330, 330, 265, 265, 265, 265, + 265, 265, 223, 223, 223, 223, 223, 271, 330, 330, + 330, 330, 330, 330, 330, 200, 271, 271, 271, 271, + 271, 271, 330, 330, 330, 330, 330, 201, 223, 223, + 223, 223, 223, 272, 330, 330, 330, 330, 330, 330, + 330, 200, 272, 272, 272, 272, 272, 272, 330, 330, + 330, 330, 330, 201, 223, 223, 223, 223, 223, 273, + 330, 330, 330, 330, 330, 330, 330, 200, 273, 273, + + 273, 273, 273, 273, 330, 330, 330, 330, 330, 201, + 223, 223, 223, 223, 223, 76, 330, 330, 330, 330, + 330, 330, 330, 200, 76, 76, 76, 76, 76, 76, + 330, 330, 330, 330, 330, 201, 229, 229, 229, 229, + 229, 330, 330, 330, 330, 330, 330, 330, 330, 200, + 287, 255, 255, 255, 287, 267, 225, 330, 330, 330, + 330, 201, 330, 288, 267, 267, 267, 267, 267, 267, + 223, 223, 223, 223, 229, 226, 231, 330, 330, 330, + 330, 231, 231, 232, 330, 330, 330, 330, 330, 233, + 330, 330, 330, 330, 330, 234, 278, 330, 233, 233, + + 233, 233, 233, 233, 279, 278, 278, 278, 278, 278, + 278, 330, 330, 279, 279, 279, 279, 279, 279, 258, + 289, 289, 289, 258, 330, 225, 330, 330, 330, 330, + 330, 330, 291, 255, 255, 255, 291, 330, 290, 330, + 330, 330, 330, 225, 226, 292, 330, 290, 290, 290, + 290, 290, 290, 224, 224, 224, 257, 228, 330, 259, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 260, 330, 330, 330, 330, 330, 261, 330, + 330, 260, 260, 260, 260, 260, 260, 263, 293, 293, + 293, 263, 330, 330, 330, 330, 330, 330, 225, 330, + + 330, 330, 330, 330, 330, 330, 294, 330, 330, 330, + 330, 330, 228, 330, 330, 294, 294, 294, 294, 294, + 294, 227, 227, 227, 262, 295, 330, 330, 330, 330, + 330, 330, 264, 330, 295, 295, 295, 295, 295, 295, + 265, 330, 330, 330, 330, 330, 266, 29, 330, 265, + 265, 265, 265, 265, 265, 32, 29, 29, 29, 29, + 29, 29, 35, 330, 32, 32, 32, 32, 32, 32, + 297, 35, 35, 35, 35, 35, 35, 303, 330, 297, + 297, 297, 297, 297, 297, 304, 303, 303, 303, 303, + 303, 303, 330, 330, 304, 304, 304, 304, 304, 304, + + 291, 255, 255, 255, 291, 305, 330, 330, 330, 330, + 330, 225, 330, 292, 305, 305, 305, 305, 305, 305, + 306, 330, 330, 330, 330, 228, 313, 330, 330, 306, + 306, 306, 306, 306, 306, 313, 313, 313, 313, 313, + 313, 314, 330, 330, 330, 330, 330, 315, 330, 330, + 314, 314, 314, 314, 314, 314, 315, 315, 315, 315, + 315, 315, 316, 330, 330, 330, 330, 330, 320, 330, + 330, 316, 316, 316, 316, 316, 316, 320, 320, 320, + 320, 320, 320, 321, 330, 330, 330, 330, 330, 322, + 330, 330, 321, 321, 321, 321, 321, 321, 322, 322, + + 322, 322, 322, 322, 326, 330, 330, 330, 330, 330, + 327, 330, 330, 326, 326, 326, 326, 326, 326, 327, + 327, 327, 327, 327, 327, 197, 330, 330, 330, 330, + 330, 224, 330, 330, 197, 197, 197, 197, 197, 197, + 224, 224, 224, 224, 224, 224, 227, 330, 330, 330, + 330, 330, 330, 330, 330, 227, 227, 227, 227, 227, + 227, 29, 330, 29, 29, 29, 29, 29, 29, 32, + 330, 32, 32, 35, 330, 35, 35, 35, 35, 35, + 35, 41, 330, 41, 41, 72, 72, 72, 72, 72, + 72, 76, 76, 330, 76, 76, 87, 87, 87, 87, + + 87, 87, 87, 87, 91, 91, 91, 91, 91, 91, + 94, 94, 94, 94, 94, 94, 94, 94, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 51, 51, 102, + 102, 102, 102, 102, 102, 104, 330, 104, 104, 131, + 131, 131, 131, 131, 131, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 148, 148, 148, 148, 148, 148, + 168, 168, 330, 168, 176, 176, 176, 176, 176, 176, + 176, 176, 176, 192, 192, 330, 192, 197, 197, 197, + 330, 197, 197, 197, 197, 218, 218, 330, 218, 224, + 330, 224, 224, 224, 224, 224, 224, 227, 330, 227, + + 227, 227, 227, 227, 227, 230, 230, 230, 230, 230, + 230, 230, 230, 249, 249, 330, 249, 258, 258, 258, + 258, 258, 258, 258, 258, 263, 263, 263, 263, 263, + 263, 263, 263, 280, 280, 330, 280, 3, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330 + + } ; + +static yyconst short int yy_chk[1695] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 5, 5, 5, 5, + 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, + 7, 8, 11, 13, 21, 35, 13, 29, 52, 50, + 18, 50, 13, 57, 39, 325, 11, 21, 22, 35, + 8, 22, 22, 52, 18, 41, 29, 18, 13, 57, + + 18, 22, 7, 16, 18, 18, 39, 18, 41, 53, + 16, 16, 62, 16, 111, 62, 53, 111, 22, 16, + 323, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 19, 56, 16, 23, + 101, 43, 23, 43, 101, 19, 19, 19, 19, 19, + 19, 55, 23, 26, 26, 26, 26, 26, 27, 27, + 27, 27, 27, 56, 33, 43, 99, 99, 319, 87, + 40, 55, 23, 33, 33, 33, 33, 33, 33, 40, + 40, 40, 40, 40, 40, 54, 42, 86, 87, 42, + + 42, 114, 86, 49, 27, 31, 31, 31, 31, 42, + 54, 31, 49, 49, 49, 49, 49, 49, 58, 93, + 54, 86, 60, 60, 31, 318, 88, 114, 58, 93, + 31, 59, 60, 31, 31, 31, 31, 31, 31, 36, + 36, 36, 36, 93, 72, 88, 59, 76, 79, 94, + 36, 61, 59, 117, 317, 79, 61, 72, 36, 117, + 76, 79, 80, 94, 36, 310, 309, 36, 36, 36, + 36, 36, 36, 61, 77, 80, 61, 73, 73, 73, + 73, 73, 106, 77, 77, 77, 77, 77, 77, 73, + 82, 108, 308, 121, 140, 198, 73, 80, 95, 121, + + 108, 106, 73, 82, 180, 73, 73, 73, 73, 73, + 73, 81, 95, 140, 198, 81, 302, 82, 131, 180, + 81, 81, 81, 81, 81, 81, 89, 89, 89, 89, + 89, 131, 89, 134, 135, 136, 138, 150, 143, 177, + 134, 168, 136, 177, 150, 89, 134, 135, 168, 138, + 224, 89, 143, 199, 89, 89, 89, 89, 89, 89, + 90, 90, 90, 90, 105, 152, 90, 199, 227, 224, + 263, 152, 301, 105, 105, 105, 105, 105, 105, 90, + 154, 300, 227, 299, 263, 90, 154, 298, 90, 90, + 90, 90, 90, 90, 92, 92, 92, 92, 92, 192, + + 218, 223, 223, 223, 223, 223, 192, 218, 225, 225, + 225, 225, 225, 92, 223, 258, 288, 289, 296, 92, + 280, 225, 92, 92, 92, 92, 92, 92, 96, 96, + 96, 96, 96, 249, 258, 288, 289, 277, 292, 96, + 249, 255, 255, 255, 255, 255, 257, 96, 276, 268, + 254, 257, 292, 96, 255, 293, 96, 96, 96, 96, + 96, 96, 97, 97, 97, 97, 130, 253, 252, 293, + 257, 251, 250, 97, 245, 130, 130, 130, 130, 130, + 130, 97, 272, 272, 272, 272, 272, 97, 274, 243, + 97, 97, 97, 97, 97, 97, 103, 103, 103, 103, + + 103, 242, 274, 241, 235, 222, 274, 272, 221, 220, + 259, 259, 259, 259, 259, 103, 259, 219, 214, 212, + 211, 103, 210, 259, 103, 103, 103, 103, 103, 103, + 132, 132, 132, 132, 132, 259, 278, 278, 278, 278, + 278, 141, 209, 208, 202, 195, 194, 193, 187, 132, + 141, 141, 141, 141, 141, 141, 142, 186, 132, 132, + 132, 132, 132, 132, 144, 142, 142, 142, 142, 142, + 142, 147, 185, 144, 144, 144, 144, 144, 144, 184, + 147, 147, 147, 147, 147, 147, 149, 149, 149, 149, + 149, 183, 182, 181, 176, 172, 170, 164, 169, 163, + + 162, 161, 160, 262, 159, 149, 164, 164, 164, 164, + 164, 164, 165, 262, 149, 149, 149, 149, 149, 149, + 167, 165, 165, 165, 165, 165, 165, 262, 158, 167, + 167, 167, 167, 167, 167, 171, 171, 171, 171, 171, + 173, 171, 157, 155, 153, 151, 171, 148, 171, 173, + 173, 173, 173, 173, 173, 174, 145, 139, 137, 133, + 171, 175, 129, 128, 174, 174, 174, 174, 174, 174, + 175, 175, 175, 175, 175, 175, 178, 297, 297, 297, + 297, 297, 179, 127, 126, 178, 178, 178, 178, 178, + 178, 179, 179, 179, 179, 179, 179, 189, 125, 124, + + 123, 122, 297, 190, 120, 119, 189, 189, 189, 189, + 189, 189, 190, 190, 190, 190, 190, 190, 191, 118, + 116, 115, 113, 112, 110, 109, 107, 191, 191, 191, + 191, 191, 191, 196, 196, 196, 196, 196, 203, 196, + 104, 102, 100, 91, 196, 85, 196, 203, 203, 203, + 203, 203, 203, 78, 71, 70, 69, 68, 196, 197, + 197, 197, 197, 197, 204, 197, 67, 66, 65, 64, + 197, 63, 197, 204, 204, 204, 204, 204, 204, 51, + 47, 46, 44, 38, 197, 201, 201, 201, 201, 201, + 32, 201, 28, 25, 24, 20, 201, 201, 201, 17, + + 15, 14, 12, 10, 201, 9, 3, 0, 0, 0, + 201, 205, 0, 201, 201, 201, 201, 201, 201, 206, + 205, 205, 205, 205, 205, 205, 207, 0, 206, 206, + 206, 206, 206, 206, 215, 207, 207, 207, 207, 207, + 207, 216, 0, 215, 215, 215, 215, 215, 215, 217, + 216, 216, 216, 216, 216, 216, 0, 0, 217, 217, + 217, 217, 217, 217, 226, 226, 226, 226, 236, 0, + 226, 0, 0, 0, 0, 0, 0, 236, 236, 236, + 236, 236, 236, 226, 0, 0, 0, 0, 0, 226, + 0, 0, 226, 226, 226, 226, 226, 226, 228, 228, + + 228, 228, 237, 0, 0, 0, 0, 0, 0, 228, + 0, 237, 237, 237, 237, 237, 237, 228, 0, 0, + 0, 0, 0, 228, 0, 0, 228, 228, 228, 228, + 228, 228, 229, 229, 229, 229, 229, 238, 229, 0, + 0, 0, 0, 229, 0, 229, 238, 238, 238, 238, + 238, 238, 0, 0, 0, 0, 0, 229, 230, 230, + 230, 230, 230, 239, 230, 0, 0, 0, 0, 230, + 0, 230, 239, 239, 239, 239, 239, 239, 0, 0, + 0, 0, 0, 230, 231, 231, 231, 231, 231, 240, + 231, 0, 0, 0, 0, 231, 0, 231, 240, 240, + + 240, 240, 240, 240, 0, 0, 0, 0, 0, 231, + 232, 232, 232, 232, 232, 246, 232, 0, 0, 0, + 0, 232, 0, 232, 246, 246, 246, 246, 246, 246, + 0, 0, 0, 0, 0, 232, 233, 233, 233, 233, + 233, 0, 233, 0, 0, 0, 0, 233, 0, 233, + 287, 287, 287, 287, 287, 233, 287, 0, 0, 0, + 0, 233, 0, 287, 233, 233, 233, 233, 233, 233, + 234, 234, 234, 234, 234, 287, 234, 0, 0, 0, + 0, 234, 234, 234, 0, 0, 0, 0, 0, 234, + 0, 0, 0, 0, 0, 234, 247, 0, 234, 234, + + 234, 234, 234, 234, 248, 247, 247, 247, 247, 247, + 247, 0, 0, 248, 248, 248, 248, 248, 248, 260, + 260, 260, 260, 260, 0, 260, 0, 0, 0, 0, + 0, 0, 264, 264, 264, 264, 264, 0, 260, 0, + 0, 0, 0, 264, 260, 264, 0, 260, 260, 260, + 260, 260, 260, 261, 261, 261, 261, 264, 0, 261, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 261, 0, 0, 0, 0, 0, 261, 0, + 0, 261, 261, 261, 261, 261, 261, 265, 265, 265, + 265, 265, 0, 0, 0, 0, 0, 0, 265, 0, + + 0, 0, 0, 0, 0, 0, 265, 0, 0, 0, + 0, 0, 265, 0, 0, 265, 265, 265, 265, 265, + 265, 266, 266, 266, 266, 267, 0, 0, 0, 0, + 0, 0, 266, 0, 267, 267, 267, 267, 267, 267, + 266, 0, 0, 0, 0, 0, 266, 269, 0, 266, + 266, 266, 266, 266, 266, 270, 269, 269, 269, 269, + 269, 269, 271, 0, 270, 270, 270, 270, 270, 270, + 273, 271, 271, 271, 271, 271, 271, 279, 0, 273, + 273, 273, 273, 273, 273, 290, 279, 279, 279, 279, + 279, 279, 0, 0, 290, 290, 290, 290, 290, 290, + + 291, 291, 291, 291, 291, 294, 0, 0, 0, 0, + 0, 291, 0, 291, 294, 294, 294, 294, 294, 294, + 295, 0, 0, 0, 0, 291, 303, 0, 0, 295, + 295, 295, 295, 295, 295, 303, 303, 303, 303, 303, + 303, 304, 0, 0, 0, 0, 0, 305, 0, 0, + 304, 304, 304, 304, 304, 304, 305, 305, 305, 305, + 305, 305, 306, 0, 0, 0, 0, 0, 314, 0, + 0, 306, 306, 306, 306, 306, 306, 314, 314, 314, + 314, 314, 314, 315, 0, 0, 0, 0, 0, 316, + 0, 0, 315, 315, 315, 315, 315, 315, 316, 316, + + 316, 316, 316, 316, 320, 0, 0, 0, 0, 0, + 321, 0, 0, 320, 320, 320, 320, 320, 320, 321, + 321, 321, 321, 321, 321, 322, 0, 0, 0, 0, + 0, 326, 0, 0, 322, 322, 322, 322, 322, 322, + 326, 326, 326, 326, 326, 326, 327, 0, 0, 0, + 0, 0, 0, 0, 0, 327, 327, 327, 327, 327, + 327, 331, 0, 331, 331, 331, 331, 331, 331, 332, + 0, 332, 332, 333, 0, 333, 333, 333, 333, 333, + 333, 334, 0, 334, 334, 335, 335, 335, 335, 335, + 335, 336, 336, 0, 336, 336, 337, 337, 337, 337, + + 337, 337, 337, 337, 338, 338, 338, 338, 338, 338, + 339, 339, 339, 339, 339, 339, 339, 339, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 341, 341, 342, + 342, 342, 342, 342, 342, 343, 0, 343, 343, 344, + 344, 344, 344, 344, 344, 345, 345, 345, 345, 345, + 345, 345, 345, 345, 346, 346, 346, 346, 346, 346, + 347, 347, 0, 347, 348, 348, 348, 348, 348, 348, + 348, 348, 348, 349, 349, 0, 349, 350, 350, 350, + 0, 350, 350, 350, 350, 351, 351, 0, 351, 352, + 0, 352, 352, 352, 352, 352, 352, 353, 0, 353, + + 353, 353, 353, 353, 353, 354, 354, 354, 354, 354, + 354, 354, 354, 355, 355, 0, 355, 356, 356, 356, + 356, 356, 356, 356, 356, 357, 357, 357, 357, 357, + 357, 357, 357, 358, 358, 0, 358, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330 + + } ; + +YY_DECL + { + register yy_state_type yy_current_state; + register unsigned short *yy_cp, *yy_bp; + register int yy_act; + +#line 25 "tokenizer.flex" + + +#line 1009 "tok" + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yy_start; +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 331 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 1638 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + + +do_action: /* This label is used only to access EOF actions. */ + + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yy_hold_char; + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 27 "tokenizer.flex" +/* ignore comments */ + YY_BREAK +case 2: +YY_RULE_SETUP +#line 29 "tokenizer.flex" +{yyTok = S; return yyTok;} + YY_BREAK +case 3: +YY_RULE_SETUP +#line 31 "tokenizer.flex" +{yyTok = SGML_CD; return yyTok;} + YY_BREAK +case 4: +YY_RULE_SETUP +#line 32 "tokenizer.flex" +{yyTok = SGML_CD; return yyTok;} + YY_BREAK +case 5: +YY_RULE_SETUP +#line 33 "tokenizer.flex" +{yyTok = INCLUDES; return yyTok;} + YY_BREAK +case 6: +YY_RULE_SETUP +#line 34 "tokenizer.flex" +{yyTok = DASHMATCH; return yyTok;} + YY_BREAK +case 7: +YY_RULE_SETUP +#line 35 "tokenizer.flex" +{yyTok = BEGINSWITH; return yyTok;} + YY_BREAK +case 8: +YY_RULE_SETUP +#line 36 "tokenizer.flex" +{yyTok = ENDSWITH; return yyTok;} + YY_BREAK +case 9: +YY_RULE_SETUP +#line 37 "tokenizer.flex" +{yyTok = CONTAINS; return yyTok;} + YY_BREAK +case 10: +YY_RULE_SETUP +#line 39 "tokenizer.flex" +{yyTok = STRING; return yyTok;} + YY_BREAK +case 11: +YY_RULE_SETUP +#line 41 "tokenizer.flex" +{yyTok = IDENT; return yyTok;} + YY_BREAK +case 12: +YY_RULE_SETUP +#line 43 "tokenizer.flex" +{yyTok = NTH; return yyTok;} + YY_BREAK +case 13: +YY_RULE_SETUP +#line 45 "tokenizer.flex" +{yyTok = HASH; return yyTok;} + YY_BREAK +case 14: +YY_RULE_SETUP +#line 47 "tokenizer.flex" +{yyTok = IMPORT_SYM; return yyTok;} + YY_BREAK +case 15: +YY_RULE_SETUP +#line 48 "tokenizer.flex" +{yyTok = PAGE_SYM; return yyTok;} + YY_BREAK +case 16: +YY_RULE_SETUP +#line 49 "tokenizer.flex" +{yyTok = MEDIA_SYM; return yyTok;} + YY_BREAK +case 17: +YY_RULE_SETUP +#line 50 "tokenizer.flex" +{yyTok = FONT_FACE_SYM; return yyTok;} + YY_BREAK +case 18: +YY_RULE_SETUP +#line 51 "tokenizer.flex" +{yyTok = CHARSET_SYM; return yyTok;} + YY_BREAK +case 19: +YY_RULE_SETUP +#line 52 "tokenizer.flex" +{yyTok = NAMESPACE_SYM; return yyTok; } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 53 "tokenizer.flex" +{yyTok = KHTML_RULE_SYM; return yyTok; } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 54 "tokenizer.flex" +{yyTok = KHTML_DECLS_SYM; return yyTok; } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 55 "tokenizer.flex" +{yyTok = KHTML_VALUE_SYM; return yyTok; } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 57 "tokenizer.flex" +{yyTok = IMPORTANT_SYM; return yyTok;} + YY_BREAK +case 24: +YY_RULE_SETUP +#line 59 "tokenizer.flex" +{yyTok = EMS; return yyTok;} + YY_BREAK +case 25: +YY_RULE_SETUP +#line 60 "tokenizer.flex" +{yyTok = QEMS; return yyTok;} /* quirky ems */ + YY_BREAK +case 26: +YY_RULE_SETUP +#line 61 "tokenizer.flex" +{yyTok = EXS; return yyTok;} + YY_BREAK +case 27: +YY_RULE_SETUP +#line 62 "tokenizer.flex" +{yyTok = PXS; return yyTok;} + YY_BREAK +case 28: +YY_RULE_SETUP +#line 63 "tokenizer.flex" +{yyTok = CMS; return yyTok;} + YY_BREAK +case 29: +YY_RULE_SETUP +#line 64 "tokenizer.flex" +{yyTok = MMS; return yyTok;} + YY_BREAK +case 30: +YY_RULE_SETUP +#line 65 "tokenizer.flex" +{yyTok = INS; return yyTok;} + YY_BREAK +case 31: +YY_RULE_SETUP +#line 66 "tokenizer.flex" +{yyTok = PTS; return yyTok;} + YY_BREAK +case 32: +YY_RULE_SETUP +#line 67 "tokenizer.flex" +{yyTok = PCS; return yyTok;} + YY_BREAK +case 33: +YY_RULE_SETUP +#line 68 "tokenizer.flex" +{yyTok = DEGS; return yyTok;} + YY_BREAK +case 34: +YY_RULE_SETUP +#line 69 "tokenizer.flex" +{yyTok = RADS; return yyTok;} + YY_BREAK +case 35: +YY_RULE_SETUP +#line 70 "tokenizer.flex" +{yyTok = GRADS; return yyTok;} + YY_BREAK +case 36: +YY_RULE_SETUP +#line 71 "tokenizer.flex" +{yyTok = MSECS; return yyTok;} + YY_BREAK +case 37: +YY_RULE_SETUP +#line 72 "tokenizer.flex" +{yyTok = SECS; return yyTok;} + YY_BREAK +case 38: +YY_RULE_SETUP +#line 73 "tokenizer.flex" +{yyTok = HERZ; return yyTok;} + YY_BREAK +case 39: +YY_RULE_SETUP +#line 74 "tokenizer.flex" +{yyTok = KHERZ; return yyTok;} + YY_BREAK +case 40: +YY_RULE_SETUP +#line 75 "tokenizer.flex" +{yyTok = DIMEN; return yyTok;} + YY_BREAK +case 41: +YY_RULE_SETUP +#line 76 "tokenizer.flex" +{yyTok = PERCENTAGE; return yyTok;} + YY_BREAK +case 42: +YY_RULE_SETUP +#line 77 "tokenizer.flex" +{yyTok = INTEGER; return yyTok;} + YY_BREAK +case 43: +YY_RULE_SETUP +#line 78 "tokenizer.flex" +{yyTok = FLOAT; return yyTok;} + YY_BREAK +case 44: +YY_RULE_SETUP +#line 81 "tokenizer.flex" +{yyTok = NOTFUNCTION; return yyTok;} + YY_BREAK +case 45: +YY_RULE_SETUP +#line 82 "tokenizer.flex" +{yyTok = URI; return yyTok;} + YY_BREAK +case 46: +YY_RULE_SETUP +#line 83 "tokenizer.flex" +{yyTok = URI; return yyTok;} + YY_BREAK +case 47: +YY_RULE_SETUP +#line 84 "tokenizer.flex" +{yyTok = FUNCTION; return yyTok;} + YY_BREAK +case 48: +YY_RULE_SETUP +#line 86 "tokenizer.flex" +{yyTok = UNICODERANGE; return yyTok;} + YY_BREAK +case 49: +YY_RULE_SETUP +#line 87 "tokenizer.flex" +{yyTok = UNICODERANGE; return yyTok;} + YY_BREAK +case 50: +YY_RULE_SETUP +#line 89 "tokenizer.flex" +{yyTok = *yytext; return yyTok;} + YY_BREAK +case 51: +YY_RULE_SETUP +#line 91 "tokenizer.flex" +ECHO; + YY_BREAK +#line 1347 "tok" +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + yy_c_buf_p = yytext; + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of yylex */ diff --git a/khtml/css/tokenizer.flex b/khtml/css/tokenizer.flex new file mode 100644 index 000000000..3c24d8e07 --- /dev/null +++ b/khtml/css/tokenizer.flex @@ -0,0 +1,92 @@ +%option case-insensitive +%option noyywrap +%option 8bit + +h [0-9a-fA-F] +nonascii [\200-\377] +unicode \\{h}{1,6}[ \t\r\n\f]? +escape {unicode}|\\[ -~\200-\377] +nmstart [_a-zA-Z]|{nonascii}|{escape} +nmchar [_a-zA-Z0-9-]|{nonascii}|{escape} +string1 \"([\t !#$%&(-~]|\\{nl}|\'|{nonascii}|{escape})*\" +string2 \'([\t !#$%&(-~]|\\{nl}|\"|{nonascii}|{escape})*\' + +ident -?{nmstart}{nmchar}* +name {nmchar}+ +num [0-9]+|[0-9]*"."[0-9]+ +intnum [0-9]+ +string {string1}|{string2} +url ([!#$%&*-~]|{nonascii}|{escape})* +w [ \t\r\n\f]* +nl \n|\r\n|\r|\f +range \?{1,6}|{h}(\?{0,5}|{h}(\?{0,4}|{h}(\?{0,3}|{h}(\?{0,2}|{h}(\??|{h}))))) +nth (-?[0-9]*n[\+-][0-9]+)|(-?[0-9]*n) + +%% + +\/\*[^*]*\*+([^/*][^*]*\*+)*\/ /* ignore comments */ + +[ \t\r\n\f]+ {yyTok = S; return yyTok;} + +"<!--" {yyTok = SGML_CD; return yyTok;} +"-->" {yyTok = SGML_CD; return yyTok;} +"~=" {yyTok = INCLUDES; return yyTok;} +"|=" {yyTok = DASHMATCH; return yyTok;} +"^=" {yyTok = BEGINSWITH; return yyTok;} +"$=" {yyTok = ENDSWITH; return yyTok;} +"*=" {yyTok = CONTAINS; return yyTok;} + +{string} {yyTok = STRING; return yyTok;} + +{ident} {yyTok = IDENT; return yyTok;} + +{nth} {yyTok = NTH; return yyTok;} + +"#"{name} {yyTok = HASH; return yyTok;} + +"@import" {yyTok = IMPORT_SYM; return yyTok;} +"@page" {yyTok = PAGE_SYM; return yyTok;} +"@media" {yyTok = MEDIA_SYM; return yyTok;} +"@font-face" {yyTok = FONT_FACE_SYM; return yyTok;} +"@charset" {yyTok = CHARSET_SYM; return yyTok;} +"@namespace" {yyTok = NAMESPACE_SYM; return yyTok; } +"@-khtml-rule" {yyTok = KHTML_RULE_SYM; return yyTok; } +"@-khtml-decls" {yyTok = KHTML_DECLS_SYM; return yyTok; } +"@-khtml-value" {yyTok = KHTML_VALUE_SYM; return yyTok; } + +"!"{w}"important" {yyTok = IMPORTANT_SYM; return yyTok;} + +{num}em {yyTok = EMS; return yyTok;} +{num}__qem {yyTok = QEMS; return yyTok;} /* quirky ems */ +{num}ex {yyTok = EXS; return yyTok;} +{num}px {yyTok = PXS; return yyTok;} +{num}cm {yyTok = CMS; return yyTok;} +{num}mm {yyTok = MMS; return yyTok;} +{num}in {yyTok = INS; return yyTok;} +{num}pt {yyTok = PTS; return yyTok;} +{num}pc {yyTok = PCS; return yyTok;} +{num}deg {yyTok = DEGS; return yyTok;} +{num}rad {yyTok = RADS; return yyTok;} +{num}grad {yyTok = GRADS; return yyTok;} +{num}ms {yyTok = MSECS; return yyTok;} +{num}s {yyTok = SECS; return yyTok;} +{num}Hz {yyTok = HERZ; return yyTok;} +{num}kHz {yyTok = KHERZ; return yyTok;} +{num}{ident} {yyTok = DIMEN; return yyTok;} +{num}% {yyTok = PERCENTAGE; return yyTok;} +{intnum} {yyTok = INTEGER; return yyTok;} +{num} {yyTok = FLOAT; return yyTok;} + + +"not(" {yyTok = NOTFUNCTION; return yyTok;} +"url("{w}{string}{w}")" {yyTok = URI; return yyTok;} +"url("{w}{url}{w}")" {yyTok = URI; return yyTok;} +{ident}"(" {yyTok = FUNCTION; return yyTok;} + +U\+{range} {yyTok = UNICODERANGE; return yyTok;} +U\+{h}{1,6}-{h}{1,6} {yyTok = UNICODERANGE; return yyTok;} + +. {yyTok = *yytext; return yyTok;} + +%% + |