2 * This file is part of the DOM implementation for KDE.
4 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
5 * Copyright (C) 2002 Apple Computer, Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
23 #include "dom/css_value.h"
24 #include "dom/dom_exception.h"
25 #include "dom/dom_string.h"
27 #include "css/css_valueimpl.h"
28 #include "css/css_ruleimpl.h"
29 #include "css/css_stylesheetimpl.h"
30 #include "css/cssparser.h"
31 #include "css/cssproperties.h"
32 #include "css/cssvalues.h"
33 #include "css/cssstyleselector.h"
35 #include "xml/dom_stringimpl.h"
36 #include "xml/dom_docimpl.h"
38 #include "misc/loader.h"
40 #include "rendering/font.h"
41 #include "rendering/render_style.h"
45 #include <qpaintdevice.h>
46 #include <qpaintdevicemetrics.h>
48 // Hack for debugging purposes
49 extern DOM::DOMString getPropertyName(unsigned short id);
52 using khtml::CSSStyleSelector;
56 CSSStyleDeclarationImpl::CSSStyleDeclarationImpl(CSSRuleImpl *parent)
57 : StyleBaseImpl(parent)
63 CSSStyleDeclarationImpl::CSSStyleDeclarationImpl(CSSRuleImpl *parent, QPtrList<CSSProperty> *lstValues)
64 : StyleBaseImpl(parent)
66 m_lstValues = lstValues;
70 CSSStyleDeclarationImpl& CSSStyleDeclarationImpl::operator= (const CSSStyleDeclarationImpl& o)
72 // don't attach it to the same node, just leave the current m_node value
76 m_lstValues = new QPtrList<CSSProperty>;
77 m_lstValues->setAutoDelete( true );
79 QPtrListIterator<CSSProperty> lstValuesIt(*o.m_lstValues);
80 for (lstValuesIt.toFirst(); lstValuesIt.current(); ++lstValuesIt)
81 m_lstValues->append(new CSSProperty(*lstValuesIt.current()));
87 CSSStyleDeclarationImpl::~CSSStyleDeclarationImpl()
90 // we don't use refcounting for m_node, to avoid cyclic references (see ElementImpl)
93 DOMString CSSStyleDeclarationImpl::getPropertyValue( int propertyID ) const
95 if(!m_lstValues) return DOMString();
97 CSSValueImpl* value = getPropertyCSSValue( propertyID );
99 return value->cssText();
101 // Shorthand and 4-values properties
102 switch ( propertyID ) {
103 case CSS_PROP_BACKGROUND_POSITION:
105 // ## Is this correct? The code in cssparser.cpp is confusing
106 const int properties[2] = { CSS_PROP_BACKGROUND_POSITION_X,
107 CSS_PROP_BACKGROUND_POSITION_Y };
108 return getShortHandValue( properties, 2 );
110 case CSS_PROP_BACKGROUND:
112 const int properties[5] = { CSS_PROP_BACKGROUND_IMAGE, CSS_PROP_BACKGROUND_REPEAT,
113 CSS_PROP_BACKGROUND_ATTACHMENT, CSS_PROP_BACKGROUND_POSITION,
114 CSS_PROP_BACKGROUND_COLOR };
115 return getShortHandValue( properties, 5 );
117 case CSS_PROP_BORDER:
119 const int properties[3] = { CSS_PROP_BORDER_WIDTH, CSS_PROP_BORDER_STYLE,
120 CSS_PROP_BORDER_COLOR };
121 return getShortHandValue( properties, 3 );
123 case CSS_PROP_BORDER_TOP:
125 const int properties[3] = { CSS_PROP_BORDER_TOP_WIDTH, CSS_PROP_BORDER_TOP_STYLE,
126 CSS_PROP_BORDER_TOP_COLOR};
127 return getShortHandValue( properties, 3 );
129 case CSS_PROP_BORDER_RIGHT:
131 const int properties[3] = { CSS_PROP_BORDER_RIGHT_WIDTH, CSS_PROP_BORDER_RIGHT_STYLE,
132 CSS_PROP_BORDER_RIGHT_COLOR};
133 return getShortHandValue( properties, 3 );
135 case CSS_PROP_BORDER_BOTTOM:
137 const int properties[3] = { CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_PROP_BORDER_BOTTOM_STYLE,
138 CSS_PROP_BORDER_BOTTOM_COLOR};
139 return getShortHandValue( properties, 3 );
141 case CSS_PROP_BORDER_LEFT:
143 const int properties[3] = { CSS_PROP_BORDER_LEFT_WIDTH, CSS_PROP_BORDER_LEFT_STYLE,
144 CSS_PROP_BORDER_LEFT_COLOR};
145 return getShortHandValue( properties, 3 );
147 case CSS_PROP_OUTLINE:
149 const int properties[3] = { CSS_PROP_OUTLINE_WIDTH, CSS_PROP_OUTLINE_STYLE,
150 CSS_PROP_OUTLINE_COLOR };
151 return getShortHandValue( properties, 3 );
153 case CSS_PROP_BORDER_COLOR:
155 const int properties[4] = { CSS_PROP_BORDER_TOP_COLOR, CSS_PROP_BORDER_RIGHT_COLOR,
156 CSS_PROP_BORDER_BOTTOM_COLOR, CSS_PROP_BORDER_LEFT_COLOR };
157 return get4Values( properties );
159 case CSS_PROP_BORDER_WIDTH:
161 const int properties[4] = { CSS_PROP_BORDER_TOP_WIDTH, CSS_PROP_BORDER_RIGHT_WIDTH,
162 CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_PROP_BORDER_LEFT_WIDTH };
163 return get4Values( properties );
165 case CSS_PROP_BORDER_STYLE:
167 const int properties[4] = { CSS_PROP_BORDER_TOP_STYLE, CSS_PROP_BORDER_RIGHT_STYLE,
168 CSS_PROP_BORDER_BOTTOM_STYLE, CSS_PROP_BORDER_LEFT_STYLE };
169 return get4Values( properties );
171 case CSS_PROP_MARGIN:
173 const int properties[4] = { CSS_PROP_MARGIN_TOP, CSS_PROP_MARGIN_RIGHT,
174 CSS_PROP_MARGIN_BOTTOM, CSS_PROP_MARGIN_LEFT };
175 return get4Values( properties );
177 case CSS_PROP_PADDING:
179 const int properties[4] = { CSS_PROP_PADDING_TOP, CSS_PROP_PADDING_RIGHT,
180 CSS_PROP_PADDING_BOTTOM, CSS_PROP_PADDING_LEFT };
181 return get4Values( properties );
183 case CSS_PROP_LIST_STYLE:
185 const int properties[3] = { CSS_PROP_LIST_STYLE_TYPE, CSS_PROP_LIST_STYLE_POSITION,
186 CSS_PROP_LIST_STYLE_IMAGE };
187 return getShortHandValue( properties, 3 );
190 //kdDebug() << k_funcinfo << "property not found:" << propertyID << endl;
194 DOMString CSSStyleDeclarationImpl::get4Values( const int* properties ) const
197 for ( int i = 0 ; i < 4 ; ++i ) {
198 CSSValueImpl* value = getPropertyCSSValue( properties[i] );
199 if ( !value ) { // apparently all 4 properties must be specified.
204 res += value->cssText();
209 DOMString CSSStyleDeclarationImpl::getShortHandValue( const int* properties, int number ) const
212 for ( int i = 0 ; i < number ; ++i ) {
213 CSSValueImpl* value = getPropertyCSSValue( properties[i] );
214 if ( value ) { // TODO provide default value if !value
217 res += value->cssText();
223 CSSValueImpl *CSSStyleDeclarationImpl::getPropertyCSSValue( int propertyID ) const
225 if(!m_lstValues) return 0;
227 QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues);
228 CSSProperty *current;
229 for ( lstValuesIt.toLast(); (current = lstValuesIt.current()); --lstValuesIt )
230 if (current->m_id == propertyID)
231 return current->value();
235 DOMString CSSStyleDeclarationImpl::removeProperty(int propertyID, bool notifyChanged)
237 if(!m_lstValues) return DOMString();
240 QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues);
241 CSSProperty *current;
242 for ( lstValuesIt.toLast(); (current = lstValuesIt.current()); --lstValuesIt )
243 if (current->m_id == propertyID) {
244 value = current->value()->cssText();
245 m_lstValues->removeRef(current);
254 void CSSStyleDeclarationImpl::setChanged()
257 m_node->setChanged();
261 // ### quick&dirty hack for KDE 3.0... make this MUCH better! (Dirk)
262 for (StyleBaseImpl* stylesheet = this; stylesheet; stylesheet = stylesheet->parent())
263 if (stylesheet->isCSSStyleSheet()) {
264 static_cast<CSSStyleSheetImpl*>(stylesheet)->doc()->updateStyleSelector();
269 bool CSSStyleDeclarationImpl::getPropertyPriority( int propertyID ) const
272 QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues);
273 CSSProperty *current;
274 for ( lstValuesIt.toFirst(); (current = lstValuesIt.current()); ++lstValuesIt ) {
275 if( propertyID == current->m_id )
276 return current->m_bImportant;
282 bool CSSStyleDeclarationImpl::setProperty(int id, const DOMString &value, bool important, bool notifyChanged)
285 m_lstValues = new QPtrList<CSSProperty>;
286 m_lstValues->setAutoDelete(true);
290 CSSParser parser( strictParsing );
291 bool success = parser.parseValue(this, id, value, important);
293 kdDebug( 6080 ) << "CSSStyleDeclarationImpl::setProperty invalid property: [" << getPropertyName(id).string()
294 << "] value: [" << value.string() << "]"<< endl;
295 else if (notifyChanged)
300 void CSSStyleDeclarationImpl::setProperty(int id, int value, bool important, bool notifyChanged)
303 m_lstValues = new QPtrList<CSSProperty>;
304 m_lstValues->setAutoDelete(true);
308 CSSValueImpl * cssValue = new CSSPrimitiveValueImpl(value);
309 setParsedValue(id, cssValue, important, m_lstValues);
314 void CSSStyleDeclarationImpl::setStringProperty(int propertyId, const DOMString &value, CSSPrimitiveValue::UnitTypes type, bool important)
317 m_lstValues = new QPtrList<CSSProperty>;
318 m_lstValues->setAutoDelete(true);
320 removeProperty(propertyId);
321 setParsedValue(propertyId, new CSSPrimitiveValueImpl(value, type), important, m_lstValues);
325 void CSSStyleDeclarationImpl::setImageProperty(int propertyId, const DOMString &URL, bool important)
328 m_lstValues = new QPtrList<CSSProperty>;
329 m_lstValues->setAutoDelete(true);
331 removeProperty(propertyId);
332 setParsedValue(propertyId, new CSSImageValueImpl(URL, this), important, m_lstValues);
336 void CSSStyleDeclarationImpl::setProperty ( const DOMString &propertyString)
339 m_lstValues = new QPtrList<CSSProperty>;
340 m_lstValues->setAutoDelete( true );
343 CSSParser parser(strictParsing);
344 parser.parseDeclaration(this, propertyString);
348 void CSSStyleDeclarationImpl::setLengthProperty(int id, const DOM::DOMString &value, bool important, bool _multiLength )
350 bool parseMode = strictParsing;
351 strictParsing = false;
352 multiLength = _multiLength;
353 setProperty( id, value, important);
354 strictParsing = parseMode;
358 unsigned long CSSStyleDeclarationImpl::length() const
360 return m_lstValues ? m_lstValues->count() : 0;
363 DOMString CSSStyleDeclarationImpl::item( unsigned long /*index*/ )
366 //return m_lstValues->at(index);
370 CSSRuleImpl *CSSStyleDeclarationImpl::parentRule() const
372 return (m_parent && m_parent->isRule() ) ?
373 static_cast<CSSRuleImpl *>(m_parent) : 0;
376 DOM::DOMString CSSStyleDeclarationImpl::cssText() const
381 QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues);
382 CSSProperty *current;
383 for ( lstValuesIt.toFirst(); (current = lstValuesIt.current()); ++lstValuesIt )
384 result += current->cssText();
390 void CSSStyleDeclarationImpl::setCssText(const DOM::DOMString& text)
393 m_lstValues->clear();
395 m_lstValues = new QPtrList<CSSProperty>;
396 m_lstValues->setAutoDelete(true);
399 CSSParser parser(strictParsing);
400 parser.parseDeclaration(this, text);
404 bool CSSStyleDeclarationImpl::parseString( const DOMString &/*string*/, bool )
410 void CSSStyleDeclarationImpl::merge(CSSStyleDeclarationImpl *other, bool argOverridesOnConflict)
412 for (QPtrListIterator<CSSProperty> it(*(other->values())); it.current(); ++it) {
413 CSSProperty *property = it.current();
414 if (getPropertyCSSValue(property->id())) {
415 if (!argOverridesOnConflict)
417 removeProperty(property->id());
420 m_lstValues = new QPtrList<CSSProperty>;
421 m_lstValues->setAutoDelete(true);
423 m_lstValues->append(new CSSProperty(*property));
427 void CSSStyleDeclarationImpl::diff(CSSStyleDeclarationImpl *style) const
432 QValueList<int> properties;
433 for (QPtrListIterator<CSSProperty> it(*style->values()); it.current(); ++it) {
434 CSSProperty *property = it.current();
435 CSSValueImpl *value = getPropertyCSSValue(property->id());
436 if (value && value->cssText() == property->value()->cssText()) {
437 properties.append(property->id());
441 for (QValueListIterator<int> it(properties.begin()); it != properties.end(); ++it)
442 style->removeProperty(*it);
445 // This is the list of properties we want to copy in the copyBlockProperties() function.
446 // It is the list of CSS properties that apply to specially to block-level elements.
447 static const int BlockProperties[] = {
449 CSS_PROP_OVERFLOW, // This can be also be applied to replaced elements
450 CSS_PROP_PAGE_BREAK_AFTER,
451 CSS_PROP_PAGE_BREAK_BEFORE,
452 CSS_PROP_PAGE_BREAK_INSIDE,
454 CSS_PROP_TEXT_INDENT,
458 CSSStyleDeclarationImpl *CSSStyleDeclarationImpl::copyBlockProperties() const
460 return copyPropertiesInSet(BlockProperties, sizeof(BlockProperties) / sizeof(BlockProperties[0]));
463 CSSStyleDeclarationImpl *CSSStyleDeclarationImpl::copyPropertiesInSet(const int *set, unsigned length) const
465 QPtrList<CSSProperty> *list = new QPtrList<CSSProperty>;
466 list->setAutoDelete(true);
467 for (unsigned i = 0; i < length; i++) {
468 CSSValueImpl *value = getPropertyCSSValue(set[i]);
470 CSSProperty *property = new CSSProperty;
471 property->m_id = set[i];
472 property->setValue(value);
473 list->append(property);
476 return new CSSStyleDeclarationImpl(0, list);
479 // --------------------------------------------------------------------------------------
481 CSSValueImpl::CSSValueImpl()
486 CSSValueImpl::~CSSValueImpl()
490 unsigned short CSSInheritedValueImpl::cssValueType() const
492 return CSSValue::CSS_INHERIT;
495 DOM::DOMString CSSInheritedValueImpl::cssText() const
497 return DOMString("inherit");
500 unsigned short CSSInitialValueImpl::cssValueType() const
502 return CSSValue::CSS_INITIAL;
505 DOM::DOMString CSSInitialValueImpl::cssText() const
507 return DOMString("initial");
510 // ----------------------------------------------------------------------------------------
512 CSSValueListImpl::CSSValueListImpl()
517 CSSValueListImpl::~CSSValueListImpl()
519 CSSValueImpl *val = m_values.first();
522 val = m_values.next();
526 unsigned short CSSValueListImpl::cssValueType() const
528 return CSSValue::CSS_VALUE_LIST;
531 void CSSValueListImpl::append(CSSValueImpl *val)
533 m_values.append(val);
537 DOM::DOMString CSSValueListImpl::cssText() const
539 DOMString result = "";
541 for (QPtrListIterator<CSSValueImpl> iterator(m_values); iterator.current(); ++iterator) {
542 if (result.length() != 0) {
545 result += iterator.current()->cssText();
551 // -------------------------------------------------------------------------------------
553 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl()
559 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(int ident)
562 m_value.ident = ident;
563 m_type = CSSPrimitiveValue::CSS_IDENT;
566 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(double num, CSSPrimitiveValue::UnitTypes type)
572 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(const DOMString &str, CSSPrimitiveValue::UnitTypes type)
574 m_value.string = str.implementation();
575 if(m_value.string) m_value.string->ref();
579 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(const Counter &c)
581 m_value.counter = c.handle();
583 m_value.counter->ref();
584 m_type = CSSPrimitiveValue::CSS_COUNTER;
587 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl( RectImpl *r)
592 m_type = CSSPrimitiveValue::CSS_RECT;
595 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl( DashboardRegionImpl *r)
599 m_value.region->ref();
600 m_type = CSSPrimitiveValue::CSS_DASHBOARD_REGION;
603 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(QRgb color)
605 m_value.rgbcolor = color;
606 m_type = CSSPrimitiveValue::CSS_RGBCOLOR;
609 CSSPrimitiveValueImpl::~CSSPrimitiveValueImpl()
614 void CSSPrimitiveValueImpl::cleanup()
617 case CSSPrimitiveValue::CSS_STRING:
618 case CSSPrimitiveValue::CSS_URI:
619 case CSSPrimitiveValue::CSS_ATTR:
620 if(m_value.string) m_value.string->deref();
622 case CSSPrimitiveValue::CSS_COUNTER:
623 m_value.counter->deref();
625 case CSSPrimitiveValue::CSS_RECT:
626 m_value.rect->deref();
634 int CSSPrimitiveValueImpl::computeLength( khtml::RenderStyle *style, QPaintDeviceMetrics *devMetrics )
636 double result = computeLengthFloat( style, devMetrics );
638 // This conversion is imprecise, often resulting in values of, e.g., 44.99998. We
639 // need to go ahead and round if we're really close to the next integer value.
640 int intResult = (int)(result + (result < 0 ? -0.01 : +0.01));
642 int intResult = (int)result;
647 int CSSPrimitiveValueImpl::computeLength( khtml::RenderStyle *style, QPaintDeviceMetrics *devMetrics,
650 double result = multiplier * computeLengthFloat( style, devMetrics );
652 // This conversion is imprecise, often resulting in values of, e.g., 44.99998. We
653 // need to go ahead and round if we're really close to the next integer value.
654 int intResult = (int)(result + (result < 0 ? -0.01 : +0.01));
656 int intResult = (int)result;
661 double CSSPrimitiveValueImpl::computeLengthFloat( khtml::RenderStyle *style, QPaintDeviceMetrics *devMetrics,
662 bool applyZoomFactor )
664 unsigned short type = primitiveType();
666 double dpiY = 72.; // fallback
668 dpiY = devMetrics->logicalDpiY();
669 if ( !khtml::printpainter && dpiY < 96 )
675 case CSSPrimitiveValue::CSS_EMS:
676 factor = applyZoomFactor ?
677 style->htmlFont().getFontDef().computedSize :
678 style->htmlFont().getFontDef().specifiedSize;
680 case CSSPrimitiveValue::CSS_EXS:
681 // FIXME: We have a bug right now where the zoom will be applied multiple times to EX units.
682 // We really need to compute EX using fontMetrics for the original specifiedSize and not use
683 // our actual constructed rendering font.
685 QFontMetrics fm = style->fontMetrics();
687 factor = fm.xHeight();
689 QRect b = fm.boundingRect('x');
694 case CSSPrimitiveValue::CSS_PX:
696 case CSSPrimitiveValue::CSS_CM:
697 factor = dpiY/2.54; //72dpi/(2.54 cm/in)
699 case CSSPrimitiveValue::CSS_MM:
702 case CSSPrimitiveValue::CSS_IN:
705 case CSSPrimitiveValue::CSS_PT:
708 case CSSPrimitiveValue::CSS_PC:
710 factor = dpiY*12./72.;
716 return getFloatValue(type)*factor;
719 void CSSPrimitiveValueImpl::setFloatValue( unsigned short unitType, double floatValue, int &exceptioncode )
723 // ### check if property supports this type
724 if(m_type > CSSPrimitiveValue::CSS_DIMENSION) {
725 exceptioncode = CSSException::SYNTAX_ERR + CSSException::_EXCEPTION_OFFSET;
728 //if(m_type > CSSPrimitiveValue::CSS_DIMENSION) throw DOMException(DOMException::INVALID_ACCESS_ERR);
729 m_value.num = floatValue;
733 void CSSPrimitiveValueImpl::setStringValue( unsigned short stringType, const DOMString &stringValue, int &exceptioncode )
737 //if(m_type < CSSPrimitiveValue::CSS_STRING) throw DOMException(DOMException::INVALID_ACCESS_ERR);
738 //if(m_type > CSSPrimitiveValue::CSS_ATTR) throw DOMException(DOMException::INVALID_ACCESS_ERR);
739 if(m_type < CSSPrimitiveValue::CSS_STRING || m_type >> CSSPrimitiveValue::CSS_ATTR) {
740 exceptioncode = CSSException::SYNTAX_ERR + CSSException::_EXCEPTION_OFFSET;
743 if(stringType != CSSPrimitiveValue::CSS_IDENT)
745 m_value.string = stringValue.implementation();
746 m_value.string->ref();
752 DOMString CSSPrimitiveValueImpl::getStringValue() const
755 case CSSPrimitiveValue::CSS_STRING:
756 case CSSPrimitiveValue::CSS_ATTR:
757 case CSSPrimitiveValue::CSS_URI:
758 return m_value.string;
759 case CSSPrimitiveValue::CSS_IDENT:
760 return getValueName(m_value.ident);
762 // FIXME: The CSS 2.1 spec says you should throw an exception here.
769 unsigned short CSSPrimitiveValueImpl::cssValueType() const
771 return CSSValue::CSS_PRIMITIVE_VALUE;
774 bool CSSPrimitiveValueImpl::parseString( const DOMString &/*string*/, bool )
780 int CSSPrimitiveValueImpl::getIdent()
782 if(m_type != CSSPrimitiveValue::CSS_IDENT) return 0;
783 return m_value.ident;
786 DOM::DOMString CSSPrimitiveValueImpl::cssText() const
788 // ### return the original value instead of a generated one (e.g. color
789 // name if it was specified) - check what spec says about this
792 case CSSPrimitiveValue::CSS_UNKNOWN:
795 case CSSPrimitiveValue::CSS_NUMBER:
796 text = DOMString(QString::number( (int)m_value.num ));
798 case CSSPrimitiveValue::CSS_PERCENTAGE:
799 text = DOMString(QString::number( m_value.num ) + "%");
801 case CSSPrimitiveValue::CSS_EMS:
802 text = DOMString(QString::number( m_value.num ) + "em");
804 case CSSPrimitiveValue::CSS_EXS:
805 text = DOMString(QString::number( m_value.num ) + "ex");
807 case CSSPrimitiveValue::CSS_PX:
808 text = DOMString(QString::number( m_value.num ) + "px");
810 case CSSPrimitiveValue::CSS_CM:
811 text = DOMString(QString::number( m_value.num ) + "cm");
813 case CSSPrimitiveValue::CSS_MM:
814 text = DOMString(QString::number( m_value.num ) + "mm");
816 case CSSPrimitiveValue::CSS_IN:
817 text = DOMString(QString::number( m_value.num ) + "in");
819 case CSSPrimitiveValue::CSS_PT:
820 text = DOMString(QString::number( m_value.num ) + "pt");
822 case CSSPrimitiveValue::CSS_PC:
823 text = DOMString(QString::number( m_value.num ) + "pc");
825 case CSSPrimitiveValue::CSS_DEG:
826 text = DOMString(QString::number( m_value.num ) + "deg");
828 case CSSPrimitiveValue::CSS_RAD:
829 text = DOMString(QString::number( m_value.num ) + "rad");
831 case CSSPrimitiveValue::CSS_GRAD:
832 text = DOMString(QString::number( m_value.num ) + "grad");
834 case CSSPrimitiveValue::CSS_MS:
835 text = DOMString(QString::number( m_value.num ) + "ms");
837 case CSSPrimitiveValue::CSS_S:
838 text = DOMString(QString::number( m_value.num ) + "s");
840 case CSSPrimitiveValue::CSS_HZ:
841 text = DOMString(QString::number( m_value.num ) + "hz");
843 case CSSPrimitiveValue::CSS_KHZ:
844 text = DOMString(QString::number( m_value.num ) + "khz");
846 case CSSPrimitiveValue::CSS_DIMENSION:
849 case CSSPrimitiveValue::CSS_STRING:
850 text = DOMString(m_value.string);
852 case CSSPrimitiveValue::CSS_URI:
854 text += DOMString( m_value.string );
857 case CSSPrimitiveValue::CSS_IDENT:
858 text = getValueName(m_value.ident);
860 case CSSPrimitiveValue::CSS_ATTR:
863 case CSSPrimitiveValue::CSS_COUNTER:
866 case CSSPrimitiveValue::CSS_RECT: {
867 RectImpl* rectVal = getRectValue();
869 text += rectVal->top()->cssText() + " ";
870 text += rectVal->right()->cssText() + " ";
871 text += rectVal->bottom()->cssText() + " ";
872 text += rectVal->left()->cssText() + ")";
875 case CSSPrimitiveValue::CSS_RGBCOLOR: {
876 QColor color(m_value.rgbcolor);
877 if (qAlpha(m_value.rgbcolor) < 0xFF)
881 text += QString::number(color.red()) + ", ";
882 text += QString::number(color.green()) + ", ";
883 text += QString::number(color.blue());
884 if (qAlpha(m_value.rgbcolor) < 0xFF)
885 text += ", " + QString::number((float)qAlpha(m_value.rgbcolor) / 0xFF);
890 case CSSPrimitiveValue::CSS_DASHBOARD_REGION: {
891 DashboardRegionImpl *region = getDashboardRegionValue();
893 text = "dashboard-region(";
894 text += region->m_label;
895 if (region->m_isCircle){
898 else if (region->m_isRectangle){
899 text += " rectangle ";
903 text += region->top()->cssText() + " ";
904 text += region->right()->cssText() + " ";
905 text += region->bottom()->cssText() + " ";
906 text += region->left()->cssText();
908 region = region->m_next;
917 // -----------------------------------------------------------------
927 RectImpl::~RectImpl()
929 if (m_top) m_top->deref();
930 if (m_right) m_right->deref();
931 if (m_bottom) m_bottom->deref();
932 if (m_left) m_left->deref();
935 void RectImpl::setTop( CSSPrimitiveValueImpl *top )
937 if( top ) top->ref();
938 if ( m_top ) m_top->deref();
942 void RectImpl::setRight( CSSPrimitiveValueImpl *right )
944 if( right ) right->ref();
945 if ( m_right ) m_right->deref();
949 void RectImpl::setBottom( CSSPrimitiveValueImpl *bottom )
951 if( bottom ) bottom->ref();
952 if ( m_bottom ) m_bottom->deref();
956 void RectImpl::setLeft( CSSPrimitiveValueImpl *left )
958 if( left ) left->ref();
959 if ( m_left ) m_left->deref();
963 // -----------------------------------------------------------------
965 CSSImageValueImpl::CSSImageValueImpl(const DOMString &url, StyleBaseImpl *style)
966 : CSSPrimitiveValueImpl(url, CSSPrimitiveValue::CSS_URI), m_image(0), m_accessedImage(false)
970 CSSImageValueImpl::CSSImageValueImpl()
971 : CSSPrimitiveValueImpl(CSS_VAL_NONE), m_image(0), m_accessedImage(true)
975 CSSImageValueImpl::~CSSImageValueImpl()
977 if(m_image) m_image->deref(this);
980 khtml::CachedImage* CSSImageValueImpl::image(khtml::DocLoader* loader)
982 if (!m_accessedImage) {
983 m_accessedImage = true;
986 m_image = loader->requestImage(getStringValue());
988 m_image = khtml::Cache::requestImage(0, getStringValue());
990 if(m_image) m_image->ref(this);
996 // ------------------------------------------------------------------------
998 FontFamilyValueImpl::FontFamilyValueImpl( const QString &string)
999 : CSSPrimitiveValueImpl( DOMString(), CSSPrimitiveValue::CSS_STRING)
1001 static const QRegExp parenReg(" \\(.*\\)$");
1002 static const QRegExp braceReg(" \\[.*\\]$");
1005 parsedFontName = string;
1006 // a language tag is often added in braces at the end. Remove it.
1007 parsedFontName.replace(parenReg, "");
1008 // remove [Xft] qualifiers
1009 parsedFontName.replace(braceReg, "");
1011 const QString &available = KHTMLSettings::availableFamilies();
1013 QString face = string.lower();
1014 // a languge tag is often added in braces at the end. Remove it.
1015 face = face.replace(parenReg, "");
1016 // remove [Xft] qualifiers
1017 face = face.replace(braceReg, "");
1018 //kdDebug(0) << "searching for face '" << face << "'" << endl;
1020 int pos = available.find( face, 0, false );
1023 int p = face.find(' ');
1024 // Arial Blk --> Arial
1025 // MS Sans Serif --> Sans Serif
1027 if(p > 0 && (int)str.length() - p > p + 1)
1028 str = str.mid( p+1 );
1031 pos = available.find( str, 0, false);
1036 int pos1 = available.findRev( ',', pos ) + 1;
1037 pos = available.find( ',', pos );
1039 pos = available.length();
1040 parsedFontName = available.mid( pos1, pos - pos1 );
1042 #endif // !APPLE_CHANGES
1045 DOM::DOMString FontFamilyValueImpl::cssText() const
1047 return parsedFontName;
1050 FontValueImpl::FontValueImpl()
1051 : style(0), variant(0), weight(0), size(0), lineHeight(0), family(0)
1055 FontValueImpl::~FontValueImpl()
1065 DOMString FontValueImpl::cssText() const
1067 // font variant weight size / line-height family
1069 DOMString result("");
1072 result += style->cssText();
1075 if (result.length() > 0) {
1078 result += variant->cssText();
1081 if (result.length() > 0) {
1084 result += weight->cssText();
1087 if (result.length() > 0) {
1090 result += size->cssText();
1097 result += lineHeight->cssText();
1100 if (result.length() > 0) {
1103 result += family->cssText();
1110 // Used for text-shadow and box-shadow
1111 ShadowValueImpl::ShadowValueImpl(CSSPrimitiveValueImpl* _x, CSSPrimitiveValueImpl* _y,
1112 CSSPrimitiveValueImpl* _blur, CSSPrimitiveValueImpl* _color)
1113 :x(_x), y(_y), blur(_blur), color(_color)
1116 ShadowValueImpl::~ShadowValueImpl()
1124 DOMString ShadowValueImpl::cssText() const
1128 text += color->cssText();
1131 if (text.length() > 0) {
1134 text += x->cssText();
1137 if (text.length() > 0) {
1140 text += y->cssText();
1143 if (text.length() > 0) {
1146 text += blur->cssText();
1152 // Used for box-flex-transition-group
1153 FlexGroupTransitionValueImpl::FlexGroupTransitionValueImpl()
1154 :autoValue(true), group1(0), group2(0), length(0)
1157 FlexGroupTransitionValueImpl::FlexGroupTransitionValueImpl(unsigned int _group1,
1158 unsigned int _group2,
1159 CSSPrimitiveValueImpl* _length)
1160 :autoValue(false), group1(_group1), group2(_group2), length(_length)
1163 FlexGroupTransitionValueImpl::~FlexGroupTransitionValueImpl()
1168 DOMString FlexGroupTransitionValueImpl::cssText() const
1170 DOMString text(QString::number(group1));
1173 text += QString::number(group2);
1177 text += length->cssText();
1182 DOMString CSSProperty::cssText() const
1184 return getPropertyName(m_id) + DOMString(": ") + m_value->cssText() + (m_bImportant ? DOMString(" !important") : DOMString()) + DOMString("; ");