00001
00024 #include "dom/css_value.h"
00025 #include "dom/dom_exception.h"
00026 #include "dom/dom_string.h"
00027
00028 #include "css/css_valueimpl.h"
00029 #include "css/css_ruleimpl.h"
00030 #include "css/css_stylesheetimpl.h"
00031 #include "css/cssparser.h"
00032 #include "css/cssproperties.h"
00033 #include "css/cssvalues.h"
00034
00035 #include "xml/dom_stringimpl.h"
00036 #include "xml/dom_docimpl.h"
00037
00038 #include "misc/loader.h"
00039
00040 #include "rendering/font.h"
00041 #include "rendering/render_style.h"
00042
00043 #include <kdebug.h>
00044 #include <qregexp.h>
00045 #include <qpaintdevice.h>
00046 #include <qpaintdevicemetrics.h>
00047
00048
00049 extern DOM::DOMString getPropertyName(unsigned short id);
00050
00051 using khtml::FontDef;
00052
00053 using namespace DOM;
00054
00055
00056 static DOMString quoteStringIfNeeded(const DOMString &string)
00057 {
00058
00059 QString s = string.string();
00060 s.replace('\\', "\\\\");
00061 s.replace('\'', "\\'");
00062 return '\'' + s + '\'';
00063 }
00064
00065
00066 CSSStyleDeclarationImpl::CSSStyleDeclarationImpl(CSSRuleImpl *parent)
00067 : StyleBaseImpl(parent)
00068 {
00069 m_lstValues = 0;
00070 m_node = 0;
00071 }
00072
00073 CSSStyleDeclarationImpl::CSSStyleDeclarationImpl(CSSRuleImpl *parent, QPtrList<CSSProperty> *lstValues)
00074 : StyleBaseImpl(parent)
00075 {
00076 m_lstValues = lstValues;
00077 m_node = 0;
00078 }
00079
00080 CSSStyleDeclarationImpl& CSSStyleDeclarationImpl::operator= (const CSSStyleDeclarationImpl& o)
00081 {
00082
00083 delete m_lstValues;
00084 m_lstValues = 0;
00085 if (o.m_lstValues) {
00086 m_lstValues = new QPtrList<CSSProperty>;
00087 m_lstValues->setAutoDelete( true );
00088
00089 QPtrListIterator<CSSProperty> lstValuesIt(*o.m_lstValues);
00090 for (lstValuesIt.toFirst(); lstValuesIt.current(); ++lstValuesIt)
00091 m_lstValues->append(new CSSProperty(*lstValuesIt.current()));
00092 }
00093
00094 return *this;
00095 }
00096
00097 CSSStyleDeclarationImpl::~CSSStyleDeclarationImpl()
00098 {
00099 delete m_lstValues;
00100
00101 }
00102
00103 DOMString CSSStyleDeclarationImpl::getPropertyValue( int propertyID ) const
00104 {
00105 if(!m_lstValues) return DOMString();
00106 CSSValueImpl* value = getPropertyCSSValue( propertyID );
00107 if ( value )
00108 return value->cssText();
00109
00110
00111 switch ( propertyID ) {
00112 case CSS_PROP_BACKGROUND_POSITION:
00113 {
00114
00115 const int properties[2] = { CSS_PROP_BACKGROUND_POSITION_X,
00116 CSS_PROP_BACKGROUND_POSITION_Y };
00117 return getShortHandValue( properties, 2 );
00118 }
00119 case CSS_PROP_BACKGROUND:
00120 {
00121 const int properties[5] = { CSS_PROP_BACKGROUND_IMAGE, CSS_PROP_BACKGROUND_REPEAT,
00122 CSS_PROP_BACKGROUND_ATTACHMENT, CSS_PROP_BACKGROUND_POSITION,
00123 CSS_PROP_BACKGROUND_COLOR };
00124 return getShortHandValue( properties, 5 );
00125 }
00126 case CSS_PROP_BORDER:
00127 {
00128 const int properties[3] = { CSS_PROP_BORDER_WIDTH, CSS_PROP_BORDER_STYLE,
00129 CSS_PROP_BORDER_COLOR };
00130 return getShortHandValue( properties, 3 );
00131 }
00132 case CSS_PROP_BORDER_TOP:
00133 {
00134 const int properties[3] = { CSS_PROP_BORDER_TOP_WIDTH, CSS_PROP_BORDER_TOP_STYLE,
00135 CSS_PROP_BORDER_TOP_COLOR};
00136 return getShortHandValue( properties, 3 );
00137 }
00138 case CSS_PROP_BORDER_RIGHT:
00139 {
00140 const int properties[3] = { CSS_PROP_BORDER_RIGHT_WIDTH, CSS_PROP_BORDER_RIGHT_STYLE,
00141 CSS_PROP_BORDER_RIGHT_COLOR};
00142 return getShortHandValue( properties, 3 );
00143 }
00144 case CSS_PROP_BORDER_BOTTOM:
00145 {
00146 const int properties[3] = { CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_PROP_BORDER_BOTTOM_STYLE,
00147 CSS_PROP_BORDER_BOTTOM_COLOR};
00148 return getShortHandValue( properties, 3 );
00149 }
00150 case CSS_PROP_BORDER_LEFT:
00151 {
00152 const int properties[3] = { CSS_PROP_BORDER_LEFT_WIDTH, CSS_PROP_BORDER_LEFT_STYLE,
00153 CSS_PROP_BORDER_LEFT_COLOR};
00154 return getShortHandValue( properties, 3 );
00155 }
00156 case CSS_PROP_OUTLINE:
00157 {
00158 const int properties[3] = { CSS_PROP_OUTLINE_WIDTH, CSS_PROP_OUTLINE_STYLE,
00159 CSS_PROP_OUTLINE_COLOR };
00160 return getShortHandValue( properties, 3 );
00161 }
00162 case CSS_PROP_BORDER_COLOR:
00163 {
00164 const int properties[4] = { CSS_PROP_BORDER_TOP_COLOR, CSS_PROP_BORDER_RIGHT_COLOR,
00165 CSS_PROP_BORDER_BOTTOM_COLOR, CSS_PROP_BORDER_LEFT_COLOR };
00166 return get4Values( properties );
00167 }
00168 case CSS_PROP_BORDER_WIDTH:
00169 {
00170 const int properties[4] = { CSS_PROP_BORDER_TOP_WIDTH, CSS_PROP_BORDER_RIGHT_WIDTH,
00171 CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_PROP_BORDER_LEFT_WIDTH };
00172 return get4Values( properties );
00173 }
00174 case CSS_PROP_BORDER_STYLE:
00175 {
00176 const int properties[4] = { CSS_PROP_BORDER_TOP_STYLE, CSS_PROP_BORDER_RIGHT_STYLE,
00177 CSS_PROP_BORDER_BOTTOM_STYLE, CSS_PROP_BORDER_LEFT_STYLE };
00178 return get4Values( properties );
00179 }
00180 case CSS_PROP_MARGIN:
00181 {
00182 const int properties[4] = { CSS_PROP_MARGIN_TOP, CSS_PROP_MARGIN_RIGHT,
00183 CSS_PROP_MARGIN_BOTTOM, CSS_PROP_MARGIN_LEFT };
00184 return get4Values( properties );
00185 }
00186 case CSS_PROP_PADDING:
00187 {
00188 const int properties[4] = { CSS_PROP_PADDING_TOP, CSS_PROP_PADDING_RIGHT,
00189 CSS_PROP_PADDING_BOTTOM, CSS_PROP_PADDING_LEFT };
00190 return get4Values( properties );
00191 }
00192 case CSS_PROP_LIST_STYLE:
00193 {
00194 const int properties[3] = { CSS_PROP_LIST_STYLE_TYPE, CSS_PROP_LIST_STYLE_POSITION,
00195 CSS_PROP_LIST_STYLE_IMAGE };
00196 return getShortHandValue( properties, 3 );
00197 }
00198 }
00199
00200 return DOMString();
00201 }
00202
00203 DOMString CSSStyleDeclarationImpl::get4Values( const int* properties ) const
00204 {
00205 DOMString res;
00206 for ( int i = 0 ; i < 4 ; ++i ) {
00207 CSSValueImpl* value = getPropertyCSSValue( properties[i] );
00208 if ( !value ) {
00209 return DOMString();
00210 }
00211 if ( i > 0 )
00212 res += " ";
00213 res += value->cssText();
00214 }
00215 return res;
00216 }
00217
00218 DOMString CSSStyleDeclarationImpl::getShortHandValue( const int* properties, int number ) const
00219 {
00220 DOMString res;
00221 for ( int i = 0 ; i < number ; ++i ) {
00222 CSSValueImpl* value = getPropertyCSSValue( properties[i] );
00223 if ( value ) {
00224 if ( !res.isNull() )
00225 res += " ";
00226 res += value->cssText();
00227 }
00228 }
00229 return res;
00230 }
00231
00232 CSSValueImpl *CSSStyleDeclarationImpl::getPropertyCSSValue( int propertyID ) const
00233 {
00234 if(!m_lstValues) return 0;
00235
00236 QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues);
00237 CSSProperty *current;
00238 for ( lstValuesIt.toLast(); (current = lstValuesIt.current()); --lstValuesIt )
00239 if (current->m_id == propertyID && !current->nonCSSHint)
00240 return current->value();
00241 return 0;
00242 }
00243
00244 DOMString CSSStyleDeclarationImpl::removeProperty( int propertyID, bool NonCSSHint )
00245 {
00246 if(!m_lstValues) return DOMString();
00247 DOMString value;
00248
00249 QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues);
00250 CSSProperty *current;
00251 for ( lstValuesIt.toLast(); (current = lstValuesIt.current()); --lstValuesIt ) {
00252 if (current->m_id == propertyID && NonCSSHint == current->nonCSSHint) {
00253 value = current->value()->cssText();
00254 m_lstValues->removeRef(current);
00255 setChanged();
00256 break;
00257 }
00258 }
00259
00260 return value;
00261 }
00262
00263 void CSSStyleDeclarationImpl::setChanged()
00264 {
00265 if (m_node) {
00266 m_node->setChanged();
00267 return;
00268 }
00269
00270
00271 for (StyleBaseImpl* stylesheet = this; stylesheet; stylesheet = stylesheet->parent())
00272 if (stylesheet->isCSSStyleSheet()) {
00273 static_cast<CSSStyleSheetImpl*>(stylesheet)->doc()->updateStyleSelector();
00274 break;
00275 }
00276 }
00277
00278 void CSSStyleDeclarationImpl::removeCSSHints()
00279 {
00280 if (!m_lstValues)
00281 return;
00282
00283 for (int i = (int)m_lstValues->count()-1; i >= 0; i--) {
00284 if (!m_lstValues->at(i)->nonCSSHint)
00285 m_lstValues->remove(i);
00286 }
00287 }
00288
00289 bool CSSStyleDeclarationImpl::getPropertyPriority( int propertyID ) const
00290 {
00291 if ( m_lstValues) {
00292 QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues);
00293 CSSProperty *current;
00294 for ( lstValuesIt.toFirst(); (current = lstValuesIt.current()); ++lstValuesIt ) {
00295 if( propertyID == current->m_id )
00296 return current->m_important;
00297 }
00298 }
00299 return false;
00300 }
00301
00302 bool CSSStyleDeclarationImpl::setProperty(int id, const DOMString &value, bool important, bool nonCSSHint)
00303 {
00304 if(!m_lstValues) {
00305 m_lstValues = new QPtrList<CSSProperty>;
00306 m_lstValues->setAutoDelete(true);
00307 }
00308
00309 CSSParser parser( strictParsing );
00310 bool success = parser.parseValue( this, id, value, important, nonCSSHint );
00311 if(!success)
00312 kdDebug( 6080 ) << "CSSStyleDeclarationImpl::setProperty invalid property: [" << getPropertyName(id).string()
00313 << "] value: [" << value.string() << "]"<< endl;
00314 else
00315 setChanged();
00316 return success;
00317 }
00318
00319 void CSSStyleDeclarationImpl::setProperty(int id, int value, bool important, bool nonCSSHint)
00320 {
00321 if(!m_lstValues) {
00322 m_lstValues = new QPtrList<CSSProperty>;
00323 m_lstValues->setAutoDelete(true);
00324 }
00325 removeProperty(id, nonCSSHint );
00326
00327 CSSValueImpl * cssValue = new CSSPrimitiveValueImpl(value);
00328 setParsedValue(id, cssValue, important, nonCSSHint, m_lstValues);
00329 setChanged();
00330 }
00331
00332 void CSSStyleDeclarationImpl::setLengthProperty(int id, const DOM::DOMString &value, bool important, bool nonCSSHint, bool _multiLength )
00333 {
00334 bool parseMode = strictParsing;
00335 strictParsing = false;
00336 multiLength = _multiLength;
00337 setProperty( id, value, important, nonCSSHint);
00338 strictParsing = parseMode;
00339 multiLength = false;
00340 }
00341
00342 void CSSStyleDeclarationImpl::setProperty ( const DOMString &propertyString)
00343 {
00344 if(!m_lstValues) {
00345 m_lstValues = new QPtrList<CSSProperty>;
00346 m_lstValues->setAutoDelete( true );
00347 }
00348
00349 CSSParser parser( strictParsing );
00350 parser.parseDeclaration( this, propertyString, false );
00351 setChanged();
00352 }
00353
00354 unsigned long CSSStyleDeclarationImpl::length() const
00355 {
00356 return m_lstValues ? m_lstValues->count() : 0;
00357 }
00358
00359 DOMString CSSStyleDeclarationImpl::item( unsigned long index ) const
00360 {
00361 if(m_lstValues && index < m_lstValues->count() && m_lstValues->at(index))
00362 return getPropertyName(m_lstValues->at(index)->m_id);
00363 return DOMString();
00364 }
00365
00366 CSSRuleImpl *CSSStyleDeclarationImpl::parentRule() const
00367 {
00368 return (m_parent && m_parent->isRule() ) ?
00369 static_cast<CSSRuleImpl *>(m_parent) : 0;
00370 }
00371
00372 DOM::DOMString CSSStyleDeclarationImpl::cssText() const
00373 {
00374 DOMString result;
00375
00376 if ( m_lstValues) {
00377 QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues);
00378 CSSProperty *current;
00379 for ( lstValuesIt.toFirst(); (current = lstValuesIt.current()); ++lstValuesIt ) {
00380 result += current->cssText();
00381 }
00382 }
00383
00384 return result;
00385 }
00386
00387 void CSSStyleDeclarationImpl::setCssText(DOM::DOMString text)
00388 {
00389 if (m_lstValues) {
00390 m_lstValues->clear();
00391 } else {
00392 m_lstValues = new QPtrList<CSSProperty>;
00393 m_lstValues->setAutoDelete( true );
00394 }
00395
00396 CSSParser parser( strictParsing );
00397 parser.parseDeclaration( this, text, false );
00398 setChanged();
00399 }
00400
00401 bool CSSStyleDeclarationImpl::parseString( const DOMString &, bool )
00402 {
00403 kdDebug() << "WARNING: CSSStyleDeclarationImpl::parseString, unimplemented, was called" << endl;
00404 return false;
00405
00406 }
00407
00408
00409
00410
00411 unsigned short CSSInheritedValueImpl::cssValueType() const
00412 {
00413 return CSSValue::CSS_INHERIT;
00414 }
00415
00416 DOM::DOMString CSSInheritedValueImpl::cssText() const
00417 {
00418 return DOMString("inherit");
00419 }
00420
00421 unsigned short CSSInitialValueImpl::cssValueType() const
00422 {
00423 return CSSValue::CSS_INITIAL;
00424 }
00425
00426 DOM::DOMString CSSInitialValueImpl::cssText() const
00427 {
00428 return DOMString("initial");
00429 }
00430
00431
00432
00433 CSSValueListImpl::~CSSValueListImpl()
00434 {
00435 CSSValueImpl *val = m_values.first();
00436 while( val ) {
00437 val->deref();
00438 val = m_values.next();
00439 }
00440 }
00441
00442 unsigned short CSSValueListImpl::cssValueType() const
00443 {
00444 return CSSValue::CSS_VALUE_LIST;
00445 }
00446
00447 void CSSValueListImpl::append(CSSValueImpl *val)
00448 {
00449 m_values.append(val);
00450 val->ref();
00451 }
00452
00453 DOM::DOMString CSSValueListImpl::cssText() const
00454 {
00455 DOMString result = "";
00456
00457 for (QPtrListIterator<CSSValueImpl> iterator(m_values); iterator.current(); ++iterator) {
00458 result += iterator.current()->cssText();
00459 }
00460
00461 return result;
00462 }
00463
00464
00465
00466 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl()
00467 : CSSValueImpl()
00468 {
00469 m_type = 0;
00470 }
00471
00472 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(int ident)
00473 : CSSValueImpl()
00474 {
00475 m_value.ident = ident;
00476 m_type = CSSPrimitiveValue::CSS_IDENT;
00477 }
00478
00479 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(double num, CSSPrimitiveValue::UnitTypes type)
00480 {
00481 m_value.num = num;
00482 m_type = type;
00483 }
00484
00485 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(const DOMString &str, CSSPrimitiveValue::UnitTypes type)
00486 {
00487 m_value.string = str.implementation();
00488 if(m_value.string) m_value.string->ref();
00489 m_type = type;
00490 }
00491
00492 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(CounterImpl *c)
00493 {
00494 m_value.counter = c;
00495 if (m_value.counter)
00496 m_value.counter->ref();
00497 m_type = CSSPrimitiveValue::CSS_COUNTER;
00498 }
00499
00500 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl( RectImpl *r)
00501 {
00502 m_value.rect = r;
00503 if (m_value.rect)
00504 m_value.rect->ref();
00505 m_type = CSSPrimitiveValue::CSS_RECT;
00506 }
00507
00508 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(QRgb color)
00509 {
00510 m_value.rgbcolor = color;
00511 m_type = CSSPrimitiveValue::CSS_RGBCOLOR;
00512 }
00513
00514 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(PairImpl *p)
00515 {
00516 m_value.pair = p;
00517 if (m_value.pair)
00518 m_value.pair->ref();
00519 m_type = CSSPrimitiveValue::CSS_PAIR;
00520 }
00521
00522
00523 CSSPrimitiveValueImpl::~CSSPrimitiveValueImpl()
00524 {
00525 cleanup();
00526 }
00527
00528 void CSSPrimitiveValueImpl::cleanup()
00529 {
00530 switch(m_type) {
00531 case CSSPrimitiveValue::CSS_STRING:
00532 case CSSPrimitiveValue::CSS_URI:
00533 case CSSPrimitiveValue::CSS_ATTR:
00534 if(m_value.string) m_value.string->deref();
00535 break;
00536 case CSSPrimitiveValue::CSS_COUNTER:
00537 m_value.counter->deref();
00538 break;
00539 case CSSPrimitiveValue::CSS_RECT:
00540 m_value.rect->deref();
00541 break;
00542 case CSSPrimitiveValue::CSS_PAIR:
00543 m_value.pair->deref();
00544 break;
00545 default:
00546 break;
00547 }
00548
00549 m_type = 0;
00550 }
00551
00552 int CSSPrimitiveValueImpl::computeLength( khtml::RenderStyle *style, QPaintDeviceMetrics *devMetrics )
00553 {
00554 double result = computeLengthFloat( style, devMetrics );
00555
00556
00557 int intResult = (int)(result + (result < 0 ? -0.01 : +0.01));
00558 return intResult;
00559 }
00560
00561 double CSSPrimitiveValueImpl::computeLengthFloat( khtml::RenderStyle *style, QPaintDeviceMetrics *devMetrics )
00562 {
00563 unsigned short type = primitiveType();
00564
00565 double dpiY = 72.;
00566 if ( devMetrics )
00567 dpiY = devMetrics->logicalDpiY();
00568 if ( !khtml::printpainter && dpiY < 96 )
00569 dpiY = 96.;
00570
00571 double factor = 1.;
00572 switch(type)
00573 {
00574 case CSSPrimitiveValue::CSS_EMS:
00575 factor = style->font().pixelSize();
00576 break;
00577 case CSSPrimitiveValue::CSS_EXS:
00578 {
00579 QFontMetrics fm = style->fontMetrics();
00580 #ifdef APPLE_CHANGES
00581 factor = fm.xHeight();
00582 #else
00583 QRect b = fm.boundingRect('x');
00584 factor = b.height();
00585 #endif
00586 break;
00587 }
00588 case CSSPrimitiveValue::CSS_PX:
00589 break;
00590 case CSSPrimitiveValue::CSS_CM:
00591 factor = dpiY/2.54;
00592 break;
00593 case CSSPrimitiveValue::CSS_MM:
00594 factor = dpiY/25.4;
00595 break;
00596 case CSSPrimitiveValue::CSS_IN:
00597 factor = dpiY;
00598 break;
00599 case CSSPrimitiveValue::CSS_PT:
00600 factor = dpiY/72.;
00601 break;
00602 case CSSPrimitiveValue::CSS_PC:
00603
00604 factor = dpiY*12./72.;
00605 break;
00606 default:
00607 return -1;
00608 }
00609
00610 return floatValue(type)*factor;
00611 }
00612
00613 void CSSPrimitiveValueImpl::setFloatValue( unsigned short unitType, double floatValue, int &exceptioncode )
00614 {
00615 exceptioncode = 0;
00616 cleanup();
00617
00618 if(m_type > CSSPrimitiveValue::CSS_DIMENSION) {
00619 exceptioncode = CSSException::SYNTAX_ERR + CSSException::_EXCEPTION_OFFSET;
00620 return;
00621 }
00622
00623 m_value.num = floatValue;
00624 m_type = unitType;
00625 }
00626
00627 void CSSPrimitiveValueImpl::setStringValue( unsigned short stringType, const DOMString &stringValue, int &exceptioncode )
00628 {
00629 exceptioncode = 0;
00630 cleanup();
00631
00632
00633 if(m_type < CSSPrimitiveValue::CSS_STRING || m_type > CSSPrimitiveValue::CSS_ATTR) {
00634 exceptioncode = CSSException::SYNTAX_ERR + CSSException::_EXCEPTION_OFFSET;
00635 return;
00636 }
00637 if(stringType != CSSPrimitiveValue::CSS_IDENT)
00638 {
00639 m_value.string = stringValue.implementation();
00640 m_value.string->ref();
00641 m_type = stringType;
00642 }
00643
00644 }
00645
00646 unsigned short CSSPrimitiveValueImpl::cssValueType() const
00647 {
00648 return CSSValue::CSS_PRIMITIVE_VALUE;
00649 }
00650
00651 bool CSSPrimitiveValueImpl::parseString( const DOMString &, bool )
00652 {
00653
00654 kdDebug() << "WARNING: CSSPrimitiveValueImpl::parseString, unimplemented, was called" << endl;
00655 return false;
00656 }
00657
00658 int CSSPrimitiveValueImpl::getIdent()
00659 {
00660 if(m_type != CSSPrimitiveValue::CSS_IDENT) return 0;
00661 return m_value.ident;
00662 }
00663
00664 DOM::DOMString CSSPrimitiveValueImpl::cssText() const
00665 {
00666
00667
00668 DOMString text;
00669 switch ( m_type ) {
00670 case CSSPrimitiveValue::CSS_UNKNOWN:
00671
00672 break;
00673 case CSSPrimitiveValue::CSS_NUMBER:
00674 text = DOMString(QString::number( (int)m_value.num ));
00675 break;
00676 case CSSPrimitiveValue::CSS_PERCENTAGE:
00677 text = DOMString(QString::number( m_value.num ) + "%");
00678 break;
00679 case CSSPrimitiveValue::CSS_EMS:
00680 text = DOMString(QString::number( m_value.num ) + "em");
00681 break;
00682 case CSSPrimitiveValue::CSS_EXS:
00683 text = DOMString(QString::number( m_value.num ) + "ex");
00684 break;
00685 case CSSPrimitiveValue::CSS_PX:
00686 text = DOMString(QString::number( m_value.num ) + "px");
00687 break;
00688 case CSSPrimitiveValue::CSS_CM:
00689 text = DOMString(QString::number( m_value.num ) + "cm");
00690 break;
00691 case CSSPrimitiveValue::CSS_MM:
00692 text = DOMString(QString::number( m_value.num ) + "mm");
00693 break;
00694 case CSSPrimitiveValue::CSS_IN:
00695 text = DOMString(QString::number( m_value.num ) + "in");
00696 break;
00697 case CSSPrimitiveValue::CSS_PT:
00698 text = DOMString(QString::number( m_value.num ) + "pt");
00699 break;
00700 case CSSPrimitiveValue::CSS_PC:
00701 text = DOMString(QString::number( m_value.num ) + "pc");
00702 break;
00703 case CSSPrimitiveValue::CSS_DEG:
00704 text = DOMString(QString::number( m_value.num ) + "deg");
00705 break;
00706 case CSSPrimitiveValue::CSS_RAD:
00707 text = DOMString(QString::number( m_value.num ) + "rad");
00708 break;
00709 case CSSPrimitiveValue::CSS_GRAD:
00710 text = DOMString(QString::number( m_value.num ) + "grad");
00711 break;
00712 case CSSPrimitiveValue::CSS_MS:
00713 text = DOMString(QString::number( m_value.num ) + "ms");
00714 break;
00715 case CSSPrimitiveValue::CSS_S:
00716 text = DOMString(QString::number( m_value.num ) + "s");
00717 break;
00718 case CSSPrimitiveValue::CSS_HZ:
00719 text = DOMString(QString::number( m_value.num ) + "hz");
00720 break;
00721 case CSSPrimitiveValue::CSS_KHZ:
00722 text = DOMString(QString::number( m_value.num ) + "khz");
00723 break;
00724 case CSSPrimitiveValue::CSS_DIMENSION:
00725
00726 break;
00727 case CSSPrimitiveValue::CSS_STRING:
00728 text = quoteStringIfNeeded(m_value.string);
00729 break;
00730 case CSSPrimitiveValue::CSS_URI:
00731 text = "url(";
00732 text += DOMString( m_value.string );
00733 text += ")";
00734 break;
00735 case CSSPrimitiveValue::CSS_IDENT:
00736 text = getValueName(m_value.ident);
00737 break;
00738 case CSSPrimitiveValue::CSS_ATTR:
00739 text = "attr(";
00740 text += DOMString( m_value.string );
00741 text += ")";
00742 break;
00743 case CSSPrimitiveValue::CSS_COUNTER:
00744 text = "counter(";
00745 text += m_value.counter->m_identifier;
00746 text += ")";
00747
00748 break;
00749 case CSSPrimitiveValue::CSS_RECT:
00750 {
00751 RectImpl* rectVal = getRectValue();
00752 text = "rect(";
00753 text += rectVal->top()->cssText() + " ";
00754 text += rectVal->right()->cssText() + " ";
00755 text += rectVal->bottom()->cssText() + " ";
00756 text += rectVal->left()->cssText() + ")";
00757 break;
00758 }
00759 case CSSPrimitiveValue::CSS_RGBCOLOR:
00760 if (qAlpha(m_value.rgbcolor) != 0xFF) {
00761 if (m_value.rgbcolor == khtml::transparentColor)
00762 text = "transparent";
00763 else
00764 text = "rgba(" + QString::number(qRed (m_value.rgbcolor)) + ","
00765 + QString::number(qBlue (m_value.rgbcolor)) + ","
00766 + QString::number(qGreen(m_value.rgbcolor)) + ","
00767 + QString::number(qAlpha(m_value.rgbcolor)/255.0) + ")";
00768 } else {
00769 text = QColor(m_value.rgbcolor).name();
00770 }
00771 break;
00772 case CSSPrimitiveValue::CSS_PAIR:
00773 text = m_value.pair->first()->cssText();
00774 text += " ";
00775 text += m_value.pair->second()->cssText();
00776 break;
00777 default:
00778 break;
00779 }
00780 return text;
00781 }
00782
00783
00784
00785 RectImpl::RectImpl()
00786 {
00787 m_top = 0;
00788 m_right = 0;
00789 m_bottom = 0;
00790 m_left = 0;
00791 }
00792
00793 RectImpl::~RectImpl()
00794 {
00795 if (m_top) m_top->deref();
00796 if (m_right) m_right->deref();
00797 if (m_bottom) m_bottom->deref();
00798 if (m_left) m_left->deref();
00799 }
00800
00801 void RectImpl::setTop( CSSPrimitiveValueImpl *top )
00802 {
00803 if( top ) top->ref();
00804 if ( m_top ) m_top->deref();
00805 m_top = top;
00806 }
00807
00808 void RectImpl::setRight( CSSPrimitiveValueImpl *right )
00809 {
00810 if( right ) right->ref();
00811 if ( m_right ) m_right->deref();
00812 m_right = right;
00813 }
00814
00815 void RectImpl::setBottom( CSSPrimitiveValueImpl *bottom )
00816 {
00817 if( bottom ) bottom->ref();
00818 if ( m_bottom ) m_bottom->deref();
00819 m_bottom = bottom;
00820 }
00821
00822 void RectImpl::setLeft( CSSPrimitiveValueImpl *left )
00823 {
00824 if( left ) left->ref();
00825 if ( m_left ) m_left->deref();
00826 m_left = left;
00827 }
00828
00829
00830
00831 PairImpl::~PairImpl()
00832 {
00833 if (m_first) m_first->deref(); if (m_second) m_second->deref();
00834 }
00835
00836 void PairImpl::setFirst(CSSPrimitiveValueImpl* first)
00837 {
00838 if (first == m_first) return;
00839 if (m_first) m_first->deref();
00840 m_first = first;
00841 if (m_first) m_first->ref();
00842 }
00843
00844 void PairImpl::setSecond(CSSPrimitiveValueImpl* second)
00845 {
00846 if (second == m_second) return;
00847 if (m_second) m_second->deref();
00848 m_second = second;
00849 if (m_second) m_second->ref();
00850 }
00851
00852
00853
00854 CSSImageValueImpl::CSSImageValueImpl(const DOMString &url, const StyleBaseImpl* style)
00855 : CSSPrimitiveValueImpl(url, CSSPrimitiveValue::CSS_URI)
00856 {
00857 khtml::DocLoader *docLoader = 0;
00858 const StyleBaseImpl *root = style;
00859 while (root->parent())
00860 root = root->parent();
00861 if (root->isCSSStyleSheet())
00862 docLoader = static_cast<const CSSStyleSheetImpl*>(root)->docLoader();
00863
00864 m_image = docLoader->requestImage(url);
00865 if(m_image) m_image->ref(this);
00866 }
00867
00868 CSSImageValueImpl::CSSImageValueImpl()
00869 : CSSPrimitiveValueImpl(CSS_VAL_NONE)
00870 {
00871 m_image = 0;
00872 }
00873
00874 CSSImageValueImpl::~CSSImageValueImpl()
00875 {
00876 if(m_image) m_image->deref(this);
00877 }
00878
00879
00880
00881 FontFamilyValueImpl::FontFamilyValueImpl( const QString &string)
00882 : CSSPrimitiveValueImpl( DOMString(string), CSSPrimitiveValue::CSS_STRING)
00883 {
00884 static const QRegExp parenReg(" \\(.*\\)$");
00885 static const QRegExp braceReg(" \\[.*\\]$");
00886
00887 parsedFontName = string;
00888
00889 parsedFontName.replace(parenReg, QString::null);
00890
00891 parsedFontName.replace(braceReg, QString::null);
00892
00893 #ifndef APPLE_CHANGES
00894 const QString &available = KHTMLSettings::availableFamilies();
00895
00896 parsedFontName = parsedFontName.lower();
00897
00898
00899 int pos = available.find( ',' + parsedFontName + ',', 0, false );
00900 if ( pos == -1 ) {
00901
00902 if ( parsedFontName.startsWith( "ms " ) )
00903 parsedFontName = parsedFontName.mid( 3 );
00904 if ( parsedFontName.endsWith( " ms" ) )
00905 parsedFontName.truncate( parsedFontName.length() - 3 );
00906 pos = available.find( ",ms " + parsedFontName + ',', 0, false );
00907 if ( pos == -1 )
00908 pos = available.find( ',' + parsedFontName + " ms,", 0, false );
00909 }
00910
00911 if ( pos != -1 ) {
00912 ++pos;
00913 int p = available.find(',', pos);
00914 assert( p != -1 );
00915 parsedFontName = available.mid( pos, p - pos);
00916
00917 } else
00918 parsedFontName = QString::null;
00919
00920 #endif // !APPLE_CHANGES
00921 }
00922
00923 FontValueImpl::FontValueImpl()
00924 : style(0), variant(0), weight(0), size(0), lineHeight(0), family(0)
00925 {
00926 }
00927
00928 FontValueImpl::~FontValueImpl()
00929 {
00930 delete style;
00931 delete variant;
00932 delete weight;
00933 delete size;
00934 delete lineHeight;
00935 delete family;
00936 }
00937
00938 DOMString FontValueImpl::cssText() const
00939 {
00940
00941
00942 DOMString result("");
00943
00944 if (style) {
00945 result += style->cssText();
00946 }
00947 if (variant) {
00948 if (result.length() > 0) {
00949 result += " ";
00950 }
00951 result += variant->cssText();
00952 }
00953 if (weight) {
00954 if (result.length() > 0) {
00955 result += " ";
00956 }
00957 result += weight->cssText();
00958 }
00959 if (size) {
00960 if (result.length() > 0) {
00961 result += " ";
00962 }
00963 result += size->cssText();
00964 }
00965 if (lineHeight) {
00966 if (!size) {
00967 result += " ";
00968 }
00969 result += "/";
00970 result += lineHeight->cssText();
00971 }
00972 if (family) {
00973 if (result.length() > 0) {
00974 result += " ";
00975 }
00976 result += family->cssText();
00977 }
00978
00979 return result;
00980 }
00981
00982 QuotesValueImpl::QuotesValueImpl()
00983 : levels(0)
00984 {
00985 }
00986
00987 DOMString QuotesValueImpl::cssText() const
00988 {
00989 return "\"" + data.join("\" \"") + "\"";
00990 }
00991
00992 void QuotesValueImpl::addLevel(const QString& open, const QString& close)
00993 {
00994 data.append(open);
00995 data.append(close);
00996 levels++;
00997 }
00998
00999 QString QuotesValueImpl::openQuote(int level) const
01000 {
01001 if (levels == 0) return "";
01002 level--;
01003
01004 if (level < 0) level = 0;
01005 else
01006 if (level >= (int) levels) level = (int) (levels-1);
01007 return data[level*2];
01008 }
01009
01010 QString QuotesValueImpl::closeQuote(int level) const
01011 {
01012 if (levels == 0) return "";
01013
01014 if (level < 0) level = 0;
01015 else
01016 if (level >= (int) levels) level = (int) (levels-1);
01017 return data[level*2+1];
01018 }
01019
01020
01021 ShadowValueImpl::ShadowValueImpl(CSSPrimitiveValueImpl* _x, CSSPrimitiveValueImpl* _y,
01022 CSSPrimitiveValueImpl* _blur, CSSPrimitiveValueImpl* _color)
01023 :x(_x), y(_y), blur(_blur), color(_color)
01024 {}
01025
01026 ShadowValueImpl::~ShadowValueImpl()
01027 {
01028 delete x;
01029 delete y;
01030 delete blur;
01031 delete color;
01032 }
01033
01034 DOMString ShadowValueImpl::cssText() const
01035 {
01036 DOMString text("");
01037 if (color) {
01038 text += color->cssText();
01039 }
01040 if (x) {
01041 if (text.length() > 0) {
01042 text += " ";
01043 }
01044 text += x->cssText();
01045 }
01046 if (y) {
01047 if (text.length() > 0) {
01048 text += " ";
01049 }
01050 text += y->cssText();
01051 }
01052 if (blur) {
01053 if (text.length() > 0) {
01054 text += " ";
01055 }
01056 text += blur->cssText();
01057 }
01058
01059 return text;
01060 }
01061
01062 DOMString CounterActImpl::cssText() const
01063 {
01064 DOMString text(m_counter);
01065 text += DOMString(QString::number(m_value));
01066
01067 return text;
01068 }
01069
01070 DOMString CSSProperty::cssText() const
01071 {
01072 return getPropertyName(m_id) + DOMString(": ") + m_value->cssText() + (m_important ? DOMString(" !important") : DOMString()) + DOMString("; ");
01073 }