# khtml Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# css_valueimpl.cpp

    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 // Hack for debugging purposes
    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     // don't attach it to the same node, just leave the current m_node value
    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     // we don't use refcounting for m_node, to avoid cyclic references (see ElementImpl)
    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     // Shorthand and 4-values properties
    00100     switch ( propertyID ) {
    00101     case CSS_PROP_BACKGROUND_POSITION:
    00102     {
    00103         // ## Is this correct? The code in cssparser.cpp is confusing
    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     //kdDebug() << k_funcinfo << "property not found:" << propertyID << endl;
    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 ) { // apparently all 4 properties must be specified.
    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 ) { // TODO provide default value 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     // ### quick&dirty hack for KDE 3.0... make this MUCH better! (Dirk)
    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 &/*string*/, 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     // This conversion is imprecise, often resulting in values of e.g., 44.99998.  We
    00534     // need to go ahead and round if we're really close to the next integer value.
    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.; // fallback
    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; //72dpi/(2.54 cm/in)
    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         // 1 pc == 12 pt
    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     // ### check if property supports this type
    00600     if(m_type > CSSPrimitiveValue::CSS_DIMENSION) {
    00601     exceptioncode = CSSException::SYNTAX_ERR + CSSException::_EXCEPTION_OFFSET;
    00602     return;
    00603     }
    00604     //if(m_type > CSSPrimitiveValue::CSS_DIMENSION) throw DOMException(DOMException::INVALID_ACCESS_ERR);
    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     //if(m_type < CSSPrimitiveValue::CSS_STRING) throw DOMException(DOMException::INVALID_ACCESS_ERR);
    00614     //if(m_type > CSSPrimitiveValue::CSS_ATTR) throw DOMException(DOMException::INVALID_ACCESS_ERR);
    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     // ### parse ident
    00626 }
    00627
    00628 unsigned short CSSPrimitiveValueImpl::cssValueType() const
    00629 {
    00630     return CSSValue::CSS_PRIMITIVE_VALUE;
    00631 }
    00632
    00633 bool CSSPrimitiveValueImpl::parseString( const DOMString &/*string*/, 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     // ### return the original value instead of a generated one (e.g. color
    00649     // name if it was specified) - check what spec says about this
    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             // ### add list-style and separator
    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     // a language tag is often added in braces at the end. Remove it.
    00831     parsedFontName.replace(parenReg, QString::null);
    00832     // remove [Xft] qualifiers
    00833     parsedFontName.replace(braceReg, QString::null);
    00834
    00835 #ifndef APPLE_CHANGES
    00836     const QString &available = KHTMLSettings::availableFamilies();
    00837
    00838     parsedFontName = parsedFontName.lower();
    00839     // kdDebug(0) << "searching for face '" << parsedFontName << "'" << endl;
    00840
    00841     int pos = available.find( ',' + parsedFontName + ',', 0, false );
    00842     if ( pos == -1 ) {
    00843         // many pages add extra MSs to make sure it's windows only ;(
    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 ); // available is supposed to start and end with ,
    00857        parsedFontName = available.mid( pos, p - pos);
    00858        // kdDebug(0) << "going for '" << parsedFontName << "'" << endl;
    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     // font variant weight size / line-height family
    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--; // increments are calculated before openQuote is called
    00945 //     kdDebug( 6080 ) << "Open quote level:" << level << endl;
    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 //     kdDebug( 6080 ) << "Close quote level:" << level << endl;
    00956     if (level < 0) level = 0;
    00957     else
    00958     if (level >= levels) level = levels-1;
    00959     return data[level*2+1];
    00960 }
    00961
    00962 // Used for text-shadow and box-shadow
    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 }

This file is part of the documentation for khtml Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:33:08 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003