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_bImportant;
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()
00515 {
00516 cleanup();
00517 }
00518
00519 void CSSPrimitiveValueImpl::cleanup()
00520 {
00521 switch(m_type) {
00522 case CSSPrimitiveValue::CSS_STRING:
00523 case CSSPrimitiveValue::CSS_URI:
00524 case CSSPrimitiveValue::CSS_ATTR:
00525 if(m_value.string) m_value.string->deref();
00526 break;
00527 case CSSPrimitiveValue::CSS_COUNTER:
00528 m_value.counter->deref();
00529 break;
00530 case CSSPrimitiveValue::CSS_RECT:
00531 m_value.rect->deref();
00532 default:
00533 break;
00534 }
00535
00536 m_type = 0;
00537 }
00538
00539 int CSSPrimitiveValueImpl::computeLength( khtml::RenderStyle *style, QPaintDeviceMetrics *devMetrics )
00540 {
00541 double result = computeLengthFloat( style, devMetrics );
00542
00543
00544 int intResult = (int)(result + (result < 0 ? -0.01 : +0.01));
00545 return intResult;
00546 }
00547
00548 double CSSPrimitiveValueImpl::computeLengthFloat( khtml::RenderStyle *style, QPaintDeviceMetrics *devMetrics )
00549 {
00550 unsigned short type = primitiveType();
00551
00552 double dpiY = 72.;
00553 if ( devMetrics )
00554 dpiY = devMetrics->logicalDpiY();
00555 if ( !khtml::printpainter && dpiY < 96 )
00556 dpiY = 96.;
00557
00558 double factor = 1.;
00559 switch(type)
00560 {
00561 case CSSPrimitiveValue::CSS_EMS:
00562 factor = style->font().pixelSize();
00563 break;
00564 case CSSPrimitiveValue::CSS_EXS:
00565 {
00566 QFontMetrics fm = style->fontMetrics();
00567 #ifdef APPLE_CHANGES
00568 factor = fm.xHeight();
00569 #else
00570 QRect b = fm.boundingRect('x');
00571 factor = b.height();
00572 #endif
00573 break;
00574 }
00575 case CSSPrimitiveValue::CSS_PX:
00576 break;
00577 case CSSPrimitiveValue::CSS_CM:
00578 factor = dpiY/2.54;
00579 break;
00580 case CSSPrimitiveValue::CSS_MM:
00581 factor = dpiY/25.4;
00582 break;
00583 case CSSPrimitiveValue::CSS_IN:
00584 factor = dpiY;
00585 break;
00586 case CSSPrimitiveValue::CSS_PT:
00587 factor = dpiY/72.;
00588 break;
00589 case CSSPrimitiveValue::CSS_PC:
00590
00591 factor = dpiY*12./72.;
00592 break;
00593 default:
00594 return -1;
00595 }
00596
00597 return floatValue(type)*factor;
00598 }
00599
00600 void CSSPrimitiveValueImpl::setFloatValue( unsigned short unitType, double floatValue, int &exceptioncode )
00601 {
00602 exceptioncode = 0;
00603 cleanup();
00604
00605 if(m_type > CSSPrimitiveValue::CSS_DIMENSION) {
00606 exceptioncode = CSSException::SYNTAX_ERR + CSSException::_EXCEPTION_OFFSET;
00607 return;
00608 }
00609
00610 m_value.num = floatValue;
00611 m_type = unitType;
00612 }
00613
00614 void CSSPrimitiveValueImpl::setStringValue( unsigned short stringType, const DOMString &stringValue, int &exceptioncode )
00615 {
00616 exceptioncode = 0;
00617 cleanup();
00618
00619
00620 if(m_type < CSSPrimitiveValue::CSS_STRING || m_type > CSSPrimitiveValue::CSS_ATTR) {
00621 exceptioncode = CSSException::SYNTAX_ERR + CSSException::_EXCEPTION_OFFSET;
00622 return;
00623 }
00624 if(stringType != CSSPrimitiveValue::CSS_IDENT)
00625 {
00626 m_value.string = stringValue.implementation();
00627 m_value.string->ref();
00628 m_type = stringType;
00629 }
00630
00631 }
00632
00633 unsigned short CSSPrimitiveValueImpl::cssValueType() const
00634 {
00635 return CSSValue::CSS_PRIMITIVE_VALUE;
00636 }
00637
00638 bool CSSPrimitiveValueImpl::parseString( const DOMString &, bool )
00639 {
00640
00641 kdDebug() << "WARNING: CSSPrimitiveValueImpl::parseString, unimplemented, was called" << endl;
00642 return false;
00643 }
00644
00645 int CSSPrimitiveValueImpl::getIdent()
00646 {
00647 if(m_type != CSSPrimitiveValue::CSS_IDENT) return 0;
00648 return m_value.ident;
00649 }
00650
00651 DOM::DOMString CSSPrimitiveValueImpl::cssText() const
00652 {
00653
00654
00655 DOMString text;
00656 switch ( m_type ) {
00657 case CSSPrimitiveValue::CSS_UNKNOWN:
00658
00659 break;
00660 case CSSPrimitiveValue::CSS_NUMBER:
00661 text = DOMString(QString::number( (int)m_value.num ));
00662 break;
00663 case CSSPrimitiveValue::CSS_PERCENTAGE:
00664 text = DOMString(QString::number( m_value.num ) + "%");
00665 break;
00666 case CSSPrimitiveValue::CSS_EMS:
00667 text = DOMString(QString::number( m_value.num ) + "em");
00668 break;
00669 case CSSPrimitiveValue::CSS_EXS:
00670 text = DOMString(QString::number( m_value.num ) + "ex");
00671 break;
00672 case CSSPrimitiveValue::CSS_PX:
00673 text = DOMString(QString::number( m_value.num ) + "px");
00674 break;
00675 case CSSPrimitiveValue::CSS_CM:
00676 text = DOMString(QString::number( m_value.num ) + "cm");
00677 break;
00678 case CSSPrimitiveValue::CSS_MM:
00679 text = DOMString(QString::number( m_value.num ) + "mm");
00680 break;
00681 case CSSPrimitiveValue::CSS_IN:
00682 text = DOMString(QString::number( m_value.num ) + "in");
00683 break;
00684 case CSSPrimitiveValue::CSS_PT:
00685 text = DOMString(QString::number( m_value.num ) + "pt");
00686 break;
00687 case CSSPrimitiveValue::CSS_PC:
00688 text = DOMString(QString::number( m_value.num ) + "pc");
00689 break;
00690 case CSSPrimitiveValue::CSS_DEG:
00691 text = DOMString(QString::number( m_value.num ) + "deg");
00692 break;
00693 case CSSPrimitiveValue::CSS_RAD:
00694 text = DOMString(QString::number( m_value.num ) + "rad");
00695 break;
00696 case CSSPrimitiveValue::CSS_GRAD:
00697 text = DOMString(QString::number( m_value.num ) + "grad");
00698 break;
00699 case CSSPrimitiveValue::CSS_MS:
00700 text = DOMString(QString::number( m_value.num ) + "ms");
00701 break;
00702 case CSSPrimitiveValue::CSS_S:
00703 text = DOMString(QString::number( m_value.num ) + "s");
00704 break;
00705 case CSSPrimitiveValue::CSS_HZ:
00706 text = DOMString(QString::number( m_value.num ) + "hz");
00707 break;
00708 case CSSPrimitiveValue::CSS_KHZ:
00709 text = DOMString(QString::number( m_value.num ) + "khz");
00710 break;
00711 case CSSPrimitiveValue::CSS_DIMENSION:
00712
00713 break;
00714 case CSSPrimitiveValue::CSS_STRING:
00715 text = quoteStringIfNeeded(m_value.string);
00716 break;
00717 case CSSPrimitiveValue::CSS_URI:
00718 text = "url(";
00719 text += DOMString( m_value.string );
00720 text += ")";
00721 break;
00722 case CSSPrimitiveValue::CSS_IDENT:
00723 text = getValueName(m_value.ident);
00724 break;
00725 case CSSPrimitiveValue::CSS_ATTR:
00726
00727 break;
00728 case CSSPrimitiveValue::CSS_COUNTER:
00729 text = "counter(";
00730 text += m_value.counter->m_identifier;
00731 text += ")";
00732
00733 break;
00734 case CSSPrimitiveValue::CSS_RECT:
00735 {
00736 RectImpl* rectVal = getRectValue();
00737 text = "rect(";
00738 text += rectVal->top()->cssText() + " ";
00739 text += rectVal->right()->cssText() + " ";
00740 text += rectVal->bottom()->cssText() + " ";
00741 text += rectVal->left()->cssText() + ")";
00742 }
00743 break;
00744 case CSSPrimitiveValue::CSS_RGBCOLOR:
00745 text = QColor(m_value.rgbcolor).name();
00746 break;
00747 default:
00748 break;
00749 }
00750 return text;
00751 }
00752
00753
00754
00755 RectImpl::RectImpl()
00756 {
00757 m_top = 0;
00758 m_right = 0;
00759 m_bottom = 0;
00760 m_left = 0;
00761 }
00762
00763 RectImpl::~RectImpl()
00764 {
00765 if (m_top) m_top->deref();
00766 if (m_right) m_right->deref();
00767 if (m_bottom) m_bottom->deref();
00768 if (m_left) m_left->deref();
00769 }
00770
00771 void RectImpl::setTop( CSSPrimitiveValueImpl *top )
00772 {
00773 if( top ) top->ref();
00774 if ( m_top ) m_top->deref();
00775 m_top = top;
00776 }
00777
00778 void RectImpl::setRight( CSSPrimitiveValueImpl *right )
00779 {
00780 if( right ) right->ref();
00781 if ( m_right ) m_right->deref();
00782 m_right = right;
00783 }
00784
00785 void RectImpl::setBottom( CSSPrimitiveValueImpl *bottom )
00786 {
00787 if( bottom ) bottom->ref();
00788 if ( m_bottom ) m_bottom->deref();
00789 m_bottom = bottom;
00790 }
00791
00792 void RectImpl::setLeft( CSSPrimitiveValueImpl *left )
00793 {
00794 if( left ) left->ref();
00795 if ( m_left ) m_left->deref();
00796 m_left = left;
00797 }
00798
00799
00800
00801 CSSImageValueImpl::CSSImageValueImpl(const DOMString &url, const StyleBaseImpl* style)
00802 : CSSPrimitiveValueImpl(url, CSSPrimitiveValue::CSS_URI)
00803 {
00804 khtml::DocLoader *docLoader = 0;
00805 const StyleBaseImpl *root = style;
00806 while (root->parent())
00807 root = root->parent();
00808 if (root->isCSSStyleSheet())
00809 docLoader = static_cast<const CSSStyleSheetImpl*>(root)->docLoader();
00810
00811 m_image = docLoader->requestImage(url);
00812 if(m_image) m_image->ref(this);
00813 }
00814
00815 CSSImageValueImpl::CSSImageValueImpl()
00816 : CSSPrimitiveValueImpl(CSS_VAL_NONE)
00817 {
00818 m_image = 0;
00819 }
00820
00821 CSSImageValueImpl::~CSSImageValueImpl()
00822 {
00823 if(m_image) m_image->deref(this);
00824 }
00825
00826
00827
00828 FontFamilyValueImpl::FontFamilyValueImpl( const QString &string)
00829 : CSSPrimitiveValueImpl( DOMString(string), CSSPrimitiveValue::CSS_STRING)
00830 {
00831 static const QRegExp parenReg(" \\(.*\\)$");
00832 static const QRegExp braceReg(" \\[.*\\]$");
00833
00834 parsedFontName = string;
00835
00836 parsedFontName.replace(parenReg, QString::null);
00837
00838 parsedFontName.replace(braceReg, QString::null);
00839
00840 #ifndef APPLE_CHANGES
00841 const QString &available = KHTMLSettings::availableFamilies();
00842
00843 parsedFontName = parsedFontName.lower();
00844
00845
00846 int pos = available.find( ',' + parsedFontName + ',', 0, false );
00847 if ( pos == -1 ) {
00848
00849 if ( parsedFontName.startsWith( "ms " ) )
00850 parsedFontName = parsedFontName.mid( 3 );
00851 if ( parsedFontName.endsWith( " ms" ) )
00852 parsedFontName.truncate( parsedFontName.length() - 3 );
00853 pos = available.find( ",ms " + parsedFontName + ',', 0, false );
00854 if ( pos == -1 )
00855 pos = available.find( ',' + parsedFontName + " ms,", 0, false );
00856 }
00857
00858 if ( pos != -1 ) {
00859 ++pos;
00860 int p = available.find(',', pos);
00861 assert( p != -1 );
00862 parsedFontName = available.mid( pos, p - pos);
00863
00864 } else
00865 parsedFontName = QString::null;
00866
00867 #endif // !APPLE_CHANGES
00868 }
00869
00870 FontValueImpl::FontValueImpl()
00871 : style(0), variant(0), weight(0), size(0), lineHeight(0), family(0)
00872 {
00873 }
00874
00875 FontValueImpl::~FontValueImpl()
00876 {
00877 delete style;
00878 delete variant;
00879 delete weight;
00880 delete size;
00881 delete lineHeight;
00882 delete family;
00883 }
00884
00885 DOMString FontValueImpl::cssText() const
00886 {
00887
00888
00889 DOMString result("");
00890
00891 if (style) {
00892 result += style->cssText();
00893 }
00894 if (variant) {
00895 if (result.length() > 0) {
00896 result += " ";
00897 }
00898 result += variant->cssText();
00899 }
00900 if (weight) {
00901 if (result.length() > 0) {
00902 result += " ";
00903 }
00904 result += weight->cssText();
00905 }
00906 if (size) {
00907 if (result.length() > 0) {
00908 result += " ";
00909 }
00910 result += size->cssText();
00911 }
00912 if (lineHeight) {
00913 if (!size) {
00914 result += " ";
00915 }
00916 result += "/";
00917 result += lineHeight->cssText();
00918 }
00919 if (family) {
00920 if (result.length() > 0) {
00921 result += " ";
00922 }
00923 result += family->cssText();
00924 }
00925
00926 return result;
00927 }
00928
00929 QuotesValueImpl::QuotesValueImpl()
00930 : levels(0)
00931 {
00932 }
00933
00934 DOMString QuotesValueImpl::cssText() const
00935 {
00936 return "\"" + data.join("\" \"") + "\"";
00937 }
00938
00939 void QuotesValueImpl::addLevel(const QString& open, const QString& close)
00940 {
00941 data.append(open);
00942 data.append(close);
00943 levels++;
00944 }
00945
00946 QString QuotesValueImpl::openQuote(int level) const
00947 {
00948 if (levels == 0) return "";
00949 level--;
00950
00951 if (level < 0) level = 0;
00952 else
00953 if (level >= (int) levels) level = (int) (levels-1);
00954 return data[level*2];
00955 }
00956
00957 QString QuotesValueImpl::closeQuote(int level) const
00958 {
00959 if (levels == 0) return "";
00960
00961 if (level < 0) level = 0;
00962 else
00963 if (level >= (int) levels) level = (int) (levels-1);
00964 return data[level*2+1];
00965 }
00966
00967
00968 ShadowValueImpl::ShadowValueImpl(CSSPrimitiveValueImpl* _x, CSSPrimitiveValueImpl* _y,
00969 CSSPrimitiveValueImpl* _blur, CSSPrimitiveValueImpl* _color)
00970 :x(_x), y(_y), blur(_blur), color(_color)
00971 {}
00972
00973 ShadowValueImpl::~ShadowValueImpl()
00974 {
00975 delete x;
00976 delete y;
00977 delete blur;
00978 delete color;
00979 }
00980
00981 DOMString ShadowValueImpl::cssText() const
00982 {
00983 DOMString text("");
00984 if (color) {
00985 text += color->cssText();
00986 }
00987 if (x) {
00988 if (text.length() > 0) {
00989 text += " ";
00990 }
00991 text += x->cssText();
00992 }
00993 if (y) {
00994 if (text.length() > 0) {
00995 text += " ";
00996 }
00997 text += y->cssText();
00998 }
00999 if (blur) {
01000 if (text.length() > 0) {
01001 text += " ";
01002 }
01003 text += blur->cssText();
01004 }
01005
01006 return text;
01007 }
01008
01009 DOMString CounterActImpl::cssText() const
01010 {
01011 DOMString text(m_counter);
01012 text += DOMString(QString::number(m_value));
01013
01014 return text;
01015 }
01016
01017 DOMString CSSProperty::cssText() const
01018 {
01019 return getPropertyName(m_id) + DOMString(": ") + m_value->cssText() + (m_bImportant ? DOMString(" !important") : DOMString()) + DOMString("; ");
01020 }