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