summaryrefslogtreecommitdiffstats
path: root/khtml/css/cssparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'khtml/css/cssparser.cpp')
-rw-r--r--khtml/css/cssparser.cpp2614
1 files changed, 0 insertions, 2614 deletions
diff --git a/khtml/css/cssparser.cpp b/khtml/css/cssparser.cpp
deleted file mode 100644
index b4480ab7d..000000000
--- a/khtml/css/cssparser.cpp
+++ /dev/null
@@ -1,2614 +0,0 @@
-/*
- * 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) );
- // tqDebug("parse string = '%s'", TQConstString( (const TQChar *)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] = '}';
- // tqDebug("parse string = '%s'", TQConstString( (const TQChar *)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 )
-{
- TQPtrList<CSSProperty> *propList = new TQPtrList<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;
- TQString 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
- // tqDebug("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);
- }
- case CSS_PROP_WORD_WRAP:
- {
- // normal | break-word
- if ( id == CSS_VAL_NORMAL || id == CSS_VAL_BREAK_WORD )
- valid_primitive = true;
- break;
- }
- 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();
- //tqDebug("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;
- TQString fname = qString( val->function->name ).lower();
- if (!args) return false;
- if (fname == "attr(") {
- if ( args->size() != 1)
- return false;
- Value *a = args->current();
- if (a->unit != CSSPrimitiveValue::CSS_IDENT) {
- isValid=false;
- break;
- }
- if (qString(a->string)[0] == '-') {
- isValid=false;
- break;
- }
- 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;
- if (qString(i->string)[0] == '-') 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;
- TQString fname = qString( value->function->name ).lower();
- //tqDebug( "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 ) : TQString::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();
- TQString currFace;
-
- while ( value ) {
-// kdDebug( 6080 ) << "got value " << value->id << " / "
-// << (value->unit == CSSPrimitiveValue::CSS_STRING ||
-// value->unit == CSSPrimitiveValue::CSS_IDENT ? qString( value->string ) : TQString::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 = TQString::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 = TQString::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 = TQString::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 = TQString::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 TQString &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
- TQColor 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. ) {
- TQString 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 = tqRgb(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 = tqRgba(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::tqRgbaFromHsla(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::tqRgbaFromHsla(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
- tqDebug("CSSTokenizer: got token %d: '%s'", token, token == END ? "" : TQString( (TQChar *)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 = TQString( (TQChar *)t, length ).toDouble();
- //tqDebug("value = %s, converted=%.2f", TQString( (TQChar *)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 ) {
-// tqDebug("toHex( %c = %x", (char)*escape, toHex( *escape ) );
- uc *= 16;
- uc += toHex( *escape );
- escape++;
- }
-// tqDebug(" converting escape: string='%s', value=0x%x", TQString( (TQChar *)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 ) {
- // tqDebug("toHex( %c = %x", (char)*escape, toHex( *escape ) );
- uc *= 16;
- uc += toHex( *escape );
- escape++;
- }
- // tqDebug(" converting escape: string='%s', value=0x%x", TQString( (TQChar *)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 tqDebug( "%s", TQString( (TQChar *)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) tqFatal(a)
-#define BEGIN yy_start = 1 + 2 *
-#define COMMENT 1
-
-#include "tokenizer.cpp"