khtml Library API Documentation

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("inherited");
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 }
KDE Logo
This file is part of the documentation for khtml Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed May 4 07:16:02 2005 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003