khtml Library API Documentation

css_valueimpl.cpp

00001 00023 #include "dom/css_value.h" 00024 #include "dom/dom_exception.h" 00025 #include "dom/dom_string.h" 00026 00027 #include "css/css_valueimpl.h" 00028 #include "css/css_ruleimpl.h" 00029 #include "css/css_stylesheetimpl.h" 00030 #include "css/cssparser.h" 00031 #include "css/cssproperties.h" 00032 #include "css/cssvalues.h" 00033 00034 #include "xml/dom_stringimpl.h" 00035 #include "xml/dom_docimpl.h" 00036 00037 #include "misc/loader.h" 00038 00039 #include "rendering/font.h" 00040 #include "rendering/render_style.h" 00041 00042 #include <kdebug.h> 00043 #include <qregexp.h> 00044 #include <qpaintdevice.h> 00045 #include <qpaintdevicemetrics.h> 00046 00047 // Hack for debugging purposes 00048 extern DOM::DOMString getPropertyName(unsigned short id); 00049 00050 using khtml::FontDef; 00051 00052 using namespace DOM; 00053 00054 CSSStyleDeclarationImpl::CSSStyleDeclarationImpl(CSSRuleImpl *parent) 00055 : StyleBaseImpl(parent) 00056 { 00057 m_lstValues = 0; 00058 m_node = 0; 00059 } 00060 00061 CSSStyleDeclarationImpl::CSSStyleDeclarationImpl(CSSRuleImpl *parent, QPtrList<CSSProperty> *lstValues) 00062 : StyleBaseImpl(parent) 00063 { 00064 m_lstValues = lstValues; 00065 m_node = 0; 00066 } 00067 00068 CSSStyleDeclarationImpl& CSSStyleDeclarationImpl::operator= (const CSSStyleDeclarationImpl& o) 00069 { 00070 // don't attach it to the same node, just leave the current m_node value 00071 delete m_lstValues; 00072 m_lstValues = 0; 00073 if (o.m_lstValues) { 00074 m_lstValues = new QPtrList<CSSProperty>; 00075 m_lstValues->setAutoDelete( true ); 00076 00077 QPtrListIterator<CSSProperty> lstValuesIt(*o.m_lstValues); 00078 for (lstValuesIt.toFirst(); lstValuesIt.current(); ++lstValuesIt) 00079 m_lstValues->append(new CSSProperty(*lstValuesIt.current())); 00080 } 00081 00082 return *this; 00083 } 00084 00085 CSSStyleDeclarationImpl::~CSSStyleDeclarationImpl() 00086 { 00087 delete m_lstValues; 00088 // we don't use refcounting for m_node, to avoid cyclic references (see ElementImpl) 00089 } 00090 00091 DOMString CSSStyleDeclarationImpl::getPropertyValue( int propertyID ) const 00092 { 00093 if(!m_lstValues) return DOMString(); 00094 CSSValueImpl* value = getPropertyCSSValue( propertyID ); 00095 if ( value ) 00096 return value->cssText(); 00097 00098 // Shorthand and 4-values properties 00099 switch ( propertyID ) { 00100 case CSS_PROP_BACKGROUND_POSITION: 00101 { 00102 // ## Is this correct? The code in cssparser.cpp is confusing 00103 const int properties[2] = { CSS_PROP_BACKGROUND_POSITION_X, 00104 CSS_PROP_BACKGROUND_POSITION_Y }; 00105 return getShortHandValue( properties, 2 ); 00106 } 00107 case CSS_PROP_BACKGROUND: 00108 { 00109 const int properties[5] = { CSS_PROP_BACKGROUND_IMAGE, CSS_PROP_BACKGROUND_REPEAT, 00110 CSS_PROP_BACKGROUND_ATTACHMENT, CSS_PROP_BACKGROUND_POSITION, 00111 CSS_PROP_BACKGROUND_COLOR }; 00112 return getShortHandValue( properties, 5 ); 00113 } 00114 case CSS_PROP_BORDER: 00115 { 00116 const int properties[3] = { CSS_PROP_BORDER_WIDTH, CSS_PROP_BORDER_STYLE, 00117 CSS_PROP_BORDER_COLOR }; 00118 return getShortHandValue( properties, 3 ); 00119 } 00120 case CSS_PROP_BORDER_TOP: 00121 { 00122 const int properties[3] = { CSS_PROP_BORDER_TOP_WIDTH, CSS_PROP_BORDER_TOP_STYLE, 00123 CSS_PROP_BORDER_TOP_COLOR}; 00124 return getShortHandValue( properties, 3 ); 00125 } 00126 case CSS_PROP_BORDER_RIGHT: 00127 { 00128 const int properties[3] = { CSS_PROP_BORDER_RIGHT_WIDTH, CSS_PROP_BORDER_RIGHT_STYLE, 00129 CSS_PROP_BORDER_RIGHT_COLOR}; 00130 return getShortHandValue( properties, 3 ); 00131 } 00132 case CSS_PROP_BORDER_BOTTOM: 00133 { 00134 const int properties[3] = { CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_PROP_BORDER_BOTTOM_STYLE, 00135 CSS_PROP_BORDER_BOTTOM_COLOR}; 00136 return getShortHandValue( properties, 3 ); 00137 } 00138 case CSS_PROP_BORDER_LEFT: 00139 { 00140 const int properties[3] = { CSS_PROP_BORDER_LEFT_WIDTH, CSS_PROP_BORDER_LEFT_STYLE, 00141 CSS_PROP_BORDER_LEFT_COLOR}; 00142 return getShortHandValue( properties, 3 ); 00143 } 00144 case CSS_PROP_OUTLINE: 00145 { 00146 const int properties[3] = { CSS_PROP_OUTLINE_WIDTH, CSS_PROP_OUTLINE_STYLE, 00147 CSS_PROP_OUTLINE_COLOR }; 00148 return getShortHandValue( properties, 3 ); 00149 } 00150 case CSS_PROP_BORDER_COLOR: 00151 { 00152 const int properties[4] = { CSS_PROP_BORDER_TOP_COLOR, CSS_PROP_BORDER_RIGHT_COLOR, 00153 CSS_PROP_BORDER_BOTTOM_COLOR, CSS_PROP_BORDER_LEFT_COLOR }; 00154 return get4Values( properties ); 00155 } 00156 case CSS_PROP_BORDER_WIDTH: 00157 { 00158 const int properties[4] = { CSS_PROP_BORDER_TOP_WIDTH, CSS_PROP_BORDER_RIGHT_WIDTH, 00159 CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_PROP_BORDER_LEFT_WIDTH }; 00160 return get4Values( properties ); 00161 } 00162 case CSS_PROP_BORDER_STYLE: 00163 { 00164 const int properties[4] = { CSS_PROP_BORDER_TOP_STYLE, CSS_PROP_BORDER_RIGHT_STYLE, 00165 CSS_PROP_BORDER_BOTTOM_STYLE, CSS_PROP_BORDER_LEFT_STYLE }; 00166 return get4Values( properties ); 00167 } 00168 case CSS_PROP_MARGIN: 00169 { 00170 const int properties[4] = { CSS_PROP_MARGIN_TOP, CSS_PROP_MARGIN_RIGHT, 00171 CSS_PROP_MARGIN_BOTTOM, CSS_PROP_MARGIN_LEFT }; 00172 return get4Values( properties ); 00173 } 00174 case CSS_PROP_PADDING: 00175 { 00176 const int properties[4] = { CSS_PROP_PADDING_TOP, CSS_PROP_PADDING_RIGHT, 00177 CSS_PROP_PADDING_BOTTOM, CSS_PROP_PADDING_LEFT }; 00178 return get4Values( properties ); 00179 } 00180 case CSS_PROP_LIST_STYLE: 00181 { 00182 const int properties[3] = { CSS_PROP_LIST_STYLE_TYPE, CSS_PROP_LIST_STYLE_POSITION, 00183 CSS_PROP_LIST_STYLE_IMAGE }; 00184 return getShortHandValue( properties, 3 ); 00185 } 00186 } 00187 //kdDebug() << k_funcinfo << "property not found:" << propertyID << endl; 00188 return DOMString(); 00189 } 00190 00191 DOMString CSSStyleDeclarationImpl::get4Values( const int* properties ) const 00192 { 00193 DOMString res; 00194 for ( int i = 0 ; i < 4 ; ++i ) { 00195 CSSValueImpl* value = getPropertyCSSValue( properties[i] ); 00196 if ( !value ) { // apparently all 4 properties must be specified. 00197 return DOMString(); 00198 } 00199 if ( i > 0 ) 00200 res += " "; 00201 res += value->cssText(); 00202 } 00203 return res; 00204 } 00205 00206 DOMString CSSStyleDeclarationImpl::getShortHandValue( const int* properties, int number ) const 00207 { 00208 DOMString res; 00209 for ( int i = 0 ; i < number ; ++i ) { 00210 CSSValueImpl* value = getPropertyCSSValue( properties[i] ); 00211 if ( value ) { // TODO provide default value if !value 00212 if ( !res.isNull() ) 00213 res += " "; 00214 res += value->cssText(); 00215 } 00216 } 00217 return res; 00218 } 00219 00220 CSSValueImpl *CSSStyleDeclarationImpl::getPropertyCSSValue( int propertyID ) const 00221 { 00222 if(!m_lstValues) return 0; 00223 00224 QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues); 00225 CSSProperty *current; 00226 for ( lstValuesIt.toLast(); (current = lstValuesIt.current()); --lstValuesIt ) 00227 if (current->m_id == propertyID && !current->nonCSSHint) 00228 return current->value(); 00229 return 0; 00230 } 00231 00232 DOMString CSSStyleDeclarationImpl::removeProperty( int propertyID, bool NonCSSHint ) 00233 { 00234 if(!m_lstValues) return DOMString(); 00235 DOMString value; 00236 00237 QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues); 00238 CSSProperty *current; 00239 for ( lstValuesIt.toLast(); (current = lstValuesIt.current()); --lstValuesIt ) { 00240 if (current->m_id == propertyID && NonCSSHint == current->nonCSSHint) { 00241 value = current->value()->cssText(); 00242 m_lstValues->removeRef(current); 00243 setChanged(); 00244 break; 00245 } 00246 } 00247 00248 return value; 00249 } 00250 00251 void CSSStyleDeclarationImpl::setChanged() 00252 { 00253 if (m_node) { 00254 m_node->setChanged(); 00255 return; 00256 } 00257 00258 // ### quick&dirty hack for KDE 3.0... make this MUCH better! (Dirk) 00259 for (StyleBaseImpl* stylesheet = this; stylesheet; stylesheet = stylesheet->parent()) 00260 if (stylesheet->isCSSStyleSheet()) { 00261 static_cast<CSSStyleSheetImpl*>(stylesheet)->doc()->updateStyleSelector(); 00262 break; 00263 } 00264 } 00265 00266 void CSSStyleDeclarationImpl::removeCSSHints() 00267 { 00268 if (!m_lstValues) 00269 return; 00270 00271 for (int i = (int)m_lstValues->count()-1; i >= 0; i--) { 00272 if (!m_lstValues->at(i)->nonCSSHint) 00273 m_lstValues->remove(i); 00274 } 00275 } 00276 00277 bool CSSStyleDeclarationImpl::getPropertyPriority( int propertyID ) const 00278 { 00279 if ( m_lstValues) { 00280 QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues); 00281 CSSProperty *current; 00282 for ( lstValuesIt.toFirst(); (current = lstValuesIt.current()); ++lstValuesIt ) { 00283 if( propertyID == current->m_id ) 00284 return current->m_bImportant; 00285 } 00286 } 00287 return false; 00288 } 00289 00290 bool CSSStyleDeclarationImpl::setProperty(int id, const DOMString &value, bool important, bool nonCSSHint) 00291 { 00292 if(!m_lstValues) { 00293 m_lstValues = new QPtrList<CSSProperty>; 00294 m_lstValues->setAutoDelete(true); 00295 } 00296 00297 CSSParser parser( strictParsing ); 00298 bool success = parser.parseValue( this, id, value, important, nonCSSHint ); 00299 if(!success) 00300 kdDebug( 6080 ) << "CSSStyleDeclarationImpl::setProperty invalid property: [" << getPropertyName(id).string() 00301 << "] value: [" << value.string() << "]"<< endl; 00302 else 00303 setChanged(); 00304 return success; 00305 } 00306 00307 void CSSStyleDeclarationImpl::setProperty(int id, int value, bool important, bool nonCSSHint) 00308 { 00309 if(!m_lstValues) { 00310 m_lstValues = new QPtrList<CSSProperty>; 00311 m_lstValues->setAutoDelete(true); 00312 } 00313 removeProperty(id, nonCSSHint ); 00314 00315 CSSValueImpl * cssValue = new CSSPrimitiveValueImpl(value); 00316 setParsedValue(id, cssValue, important, nonCSSHint, m_lstValues); 00317 setChanged(); 00318 } 00319 00320 void CSSStyleDeclarationImpl::setLengthProperty(int id, const DOM::DOMString &value, bool important, bool nonCSSHint, bool _multiLength ) 00321 { 00322 bool parseMode = strictParsing; 00323 strictParsing = false; 00324 multiLength = _multiLength; 00325 setProperty( id, value, important, nonCSSHint); 00326 strictParsing = parseMode; 00327 multiLength = false; 00328 } 00329 00330 void CSSStyleDeclarationImpl::setProperty ( const DOMString &propertyString) 00331 { 00332 if(!m_lstValues) { 00333 m_lstValues = new QPtrList<CSSProperty>; 00334 m_lstValues->setAutoDelete( true ); 00335 } 00336 00337 CSSParser parser( strictParsing ); 00338 parser.parseDeclaration( this, propertyString, false ); 00339 setChanged(); 00340 } 00341 00342 unsigned long CSSStyleDeclarationImpl::length() const 00343 { 00344 return m_lstValues ? m_lstValues->count() : 0; 00345 } 00346 00347 DOMString CSSStyleDeclarationImpl::item( unsigned long index ) const 00348 { 00349 if(m_lstValues && index < m_lstValues->count() && m_lstValues->at(index)) 00350 return getPropertyName(m_lstValues->at(index)->m_id); 00351 return DOMString(); 00352 } 00353 00354 CSSRuleImpl *CSSStyleDeclarationImpl::parentRule() const 00355 { 00356 return (m_parent && m_parent->isRule() ) ? 00357 static_cast<CSSRuleImpl *>(m_parent) : 0; 00358 } 00359 00360 DOM::DOMString CSSStyleDeclarationImpl::cssText() const 00361 { 00362 DOMString result; 00363 00364 if ( m_lstValues) { 00365 QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues); 00366 CSSProperty *current; 00367 for ( lstValuesIt.toFirst(); (current = lstValuesIt.current()); ++lstValuesIt ) { 00368 result += current->cssText(); 00369 } 00370 } 00371 00372 return result; 00373 } 00374 00375 void CSSStyleDeclarationImpl::setCssText(DOM::DOMString text) 00376 { 00377 if (m_lstValues) { 00378 m_lstValues->clear(); 00379 } else { 00380 m_lstValues = new QPtrList<CSSProperty>; 00381 m_lstValues->setAutoDelete( true ); 00382 } 00383 00384 CSSParser parser( strictParsing ); 00385 parser.parseDeclaration( this, text, false ); 00386 setChanged(); 00387 } 00388 00389 bool CSSStyleDeclarationImpl::parseString( const DOMString &/*string*/, bool ) 00390 { 00391 kdDebug() << "WARNING: CSSStyleDeclarationImpl::parseString, unimplemented, was called" << endl; 00392 return false; 00393 // ### 00394 } 00395 00396 00397 // -------------------------------------------------------------------------------------- 00398 00399 unsigned short CSSInheritedValueImpl::cssValueType() const 00400 { 00401 return CSSValue::CSS_INHERIT; 00402 } 00403 00404 DOM::DOMString CSSInheritedValueImpl::cssText() const 00405 { 00406 return DOMString("inherited"); 00407 } 00408 00409 unsigned short CSSInitialValueImpl::cssValueType() const 00410 { 00411 return CSSValue::CSS_INITIAL; 00412 } 00413 00414 DOM::DOMString CSSInitialValueImpl::cssText() const 00415 { 00416 return DOMString("initial"); 00417 } 00418 00419 // ---------------------------------------------------------------------------------------- 00420 00421 CSSValueListImpl::~CSSValueListImpl() 00422 { 00423 CSSValueImpl *val = m_values.first(); 00424 while( val ) { 00425 val->deref(); 00426 val = m_values.next(); 00427 } 00428 } 00429 00430 unsigned short CSSValueListImpl::cssValueType() const 00431 { 00432 return CSSValue::CSS_VALUE_LIST; 00433 } 00434 00435 void CSSValueListImpl::append(CSSValueImpl *val) 00436 { 00437 m_values.append(val); 00438 val->ref(); 00439 } 00440 00441 DOM::DOMString CSSValueListImpl::cssText() const 00442 { 00443 DOMString result = ""; 00444 00445 for (QPtrListIterator<CSSValueImpl> iterator(m_values); iterator.current(); ++iterator) { 00446 result += iterator.current()->cssText(); 00447 } 00448 00449 return result; 00450 } 00451 00452 // ------------------------------------------------------------------------------------- 00453 00454 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl() 00455 : CSSValueImpl() 00456 { 00457 m_type = 0; 00458 } 00459 00460 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(int ident) 00461 : CSSValueImpl() 00462 { 00463 m_value.ident = ident; 00464 m_type = CSSPrimitiveValue::CSS_IDENT; 00465 } 00466 00467 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(double num, CSSPrimitiveValue::UnitTypes type) 00468 { 00469 m_value.num = num; 00470 m_type = type; 00471 } 00472 00473 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(const DOMString &str, CSSPrimitiveValue::UnitTypes type) 00474 { 00475 m_value.string = str.implementation(); 00476 if(m_value.string) m_value.string->ref(); 00477 m_type = type; 00478 } 00479 00480 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(const Counter &c) 00481 { 00482 m_value.counter = c.handle(); 00483 if (m_value.counter) 00484 m_value.counter->ref(); 00485 m_type = CSSPrimitiveValue::CSS_COUNTER; 00486 } 00487 00488 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl( RectImpl *r) 00489 { 00490 m_value.rect = r; 00491 if (m_value.rect) 00492 m_value.rect->ref(); 00493 m_type = CSSPrimitiveValue::CSS_RECT; 00494 } 00495 00496 CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(QRgb color) 00497 { 00498 m_value.rgbcolor = color; 00499 m_type = CSSPrimitiveValue::CSS_RGBCOLOR; 00500 } 00501 00502 CSSPrimitiveValueImpl::~CSSPrimitiveValueImpl() 00503 { 00504 cleanup(); 00505 } 00506 00507 void CSSPrimitiveValueImpl::cleanup() 00508 { 00509 switch(m_type) { 00510 case CSSPrimitiveValue::CSS_STRING: 00511 case CSSPrimitiveValue::CSS_URI: 00512 case CSSPrimitiveValue::CSS_ATTR: 00513 if(m_value.string) m_value.string->deref(); 00514 break; 00515 case CSSPrimitiveValue::CSS_COUNTER: 00516 m_value.counter->deref(); 00517 break; 00518 case CSSPrimitiveValue::CSS_RECT: 00519 m_value.rect->deref(); 00520 default: 00521 break; 00522 } 00523 00524 m_type = 0; 00525 } 00526 00527 int CSSPrimitiveValueImpl::computeLength( khtml::RenderStyle *style, QPaintDeviceMetrics *devMetrics ) 00528 { 00529 double result = computeLengthFloat( style, devMetrics ); 00530 int intResult = (int)result; 00531 #ifdef APPLE_CHANGES 00532 // This conversion is imprecise, often resulting in values of e.g., 44.99998. We 00533 // need to go ahead and round if we're really close to the next integer value. 00534 double newResult = (intResult < 0) ? result-0.01 : result+0.01; 00535 int secondIntResult = (int)newResult; 00536 if (secondIntResult != intResult) 00537 return secondIntResult; 00538 #endif 00539 return intResult; 00540 } 00541 00542 double CSSPrimitiveValueImpl::computeLengthFloat( khtml::RenderStyle *style, QPaintDeviceMetrics *devMetrics ) 00543 { 00544 unsigned short type = primitiveType(); 00545 00546 double dpiY = 72.; // fallback 00547 if ( devMetrics ) 00548 dpiY = devMetrics->logicalDpiY(); 00549 if ( !khtml::printpainter && dpiY < 96 ) 00550 dpiY = 96.; 00551 00552 double factor = 1.; 00553 switch(type) 00554 { 00555 case CSSPrimitiveValue::CSS_EMS: 00556 factor = style->font().pixelSize(); 00557 break; 00558 case CSSPrimitiveValue::CSS_EXS: 00559 { 00560 QFontMetrics fm = style->fontMetrics(); 00561 #ifdef APPLE_CHANGES 00562 factor = fm.xHeight(); 00563 #else 00564 QRect b = fm.boundingRect('x'); 00565 factor = b.height(); 00566 #endif 00567 break; 00568 } 00569 case CSSPrimitiveValue::CSS_PX: 00570 break; 00571 case CSSPrimitiveValue::CSS_CM: 00572 factor = dpiY/2.54; //72dpi/(2.54 cm/in) 00573 break; 00574 case CSSPrimitiveValue::CSS_MM: 00575 factor = dpiY/25.4; 00576 break; 00577 case CSSPrimitiveValue::CSS_IN: 00578 factor = dpiY; 00579 break; 00580 case CSSPrimitiveValue::CSS_PT: 00581 factor = dpiY/72.; 00582 break; 00583 case CSSPrimitiveValue::CSS_PC: 00584 // 1 pc == 12 pt 00585 factor = dpiY*12./72.; 00586 break; 00587 default: 00588 return -1; 00589 } 00590 00591 return floatValue(type)*factor; 00592 } 00593 00594 void CSSPrimitiveValueImpl::setFloatValue( unsigned short unitType, double floatValue, int &exceptioncode ) 00595 { 00596 exceptioncode = 0; 00597 cleanup(); 00598 // ### check if property supports this type 00599 if(m_type > CSSPrimitiveValue::CSS_DIMENSION) { 00600 exceptioncode = CSSException::SYNTAX_ERR + CSSException::_EXCEPTION_OFFSET; 00601 return; 00602 } 00603 //if(m_type > CSSPrimitiveValue::CSS_DIMENSION) throw DOMException(DOMException::INVALID_ACCESS_ERR); 00604 m_value.num = floatValue; 00605 m_type = unitType; 00606 } 00607 00608 void CSSPrimitiveValueImpl::setStringValue( unsigned short stringType, const DOMString &stringValue, int &exceptioncode ) 00609 { 00610 exceptioncode = 0; 00611 cleanup(); 00612 //if(m_type < CSSPrimitiveValue::CSS_STRING) throw DOMException(DOMException::INVALID_ACCESS_ERR); 00613 //if(m_type > CSSPrimitiveValue::CSS_ATTR) throw DOMException(DOMException::INVALID_ACCESS_ERR); 00614 if(m_type < CSSPrimitiveValue::CSS_STRING || m_type > CSSPrimitiveValue::CSS_ATTR) { 00615 exceptioncode = CSSException::SYNTAX_ERR + CSSException::_EXCEPTION_OFFSET; 00616 return; 00617 } 00618 if(stringType != CSSPrimitiveValue::CSS_IDENT) 00619 { 00620 m_value.string = stringValue.implementation(); 00621 m_value.string->ref(); 00622 m_type = stringType; 00623 } 00624 // ### parse ident 00625 } 00626 00627 unsigned short CSSPrimitiveValueImpl::cssValueType() const 00628 { 00629 return CSSValue::CSS_PRIMITIVE_VALUE; 00630 } 00631 00632 bool CSSPrimitiveValueImpl::parseString( const DOMString &/*string*/, bool ) 00633 { 00634 // ### 00635 kdDebug() << "WARNING: CSSPrimitiveValueImpl::parseString, unimplemented, was called" << endl; 00636 return false; 00637 } 00638 00639 int CSSPrimitiveValueImpl::getIdent() 00640 { 00641 if(m_type != CSSPrimitiveValue::CSS_IDENT) return 0; 00642 return m_value.ident; 00643 } 00644 00645 DOM::DOMString CSSPrimitiveValueImpl::cssText() const 00646 { 00647 // ### return the original value instead of a generated one (e.g. color 00648 // name if it was specified) - check what spec says about this 00649 DOMString text; 00650 switch ( m_type ) { 00651 case CSSPrimitiveValue::CSS_UNKNOWN: 00652 // ### 00653 break; 00654 case CSSPrimitiveValue::CSS_NUMBER: 00655 text = DOMString(QString::number( (int)m_value.num )); 00656 break; 00657 case CSSPrimitiveValue::CSS_PERCENTAGE: 00658 text = DOMString(QString::number( m_value.num ) + "%"); 00659 break; 00660 case CSSPrimitiveValue::CSS_EMS: 00661 text = DOMString(QString::number( m_value.num ) + "em"); 00662 break; 00663 case CSSPrimitiveValue::CSS_EXS: 00664 text = DOMString(QString::number( m_value.num ) + "ex"); 00665 break; 00666 case CSSPrimitiveValue::CSS_PX: 00667 text = DOMString(QString::number( m_value.num ) + "px"); 00668 break; 00669 case CSSPrimitiveValue::CSS_CM: 00670 text = DOMString(QString::number( m_value.num ) + "cm"); 00671 break; 00672 case CSSPrimitiveValue::CSS_MM: 00673 text = DOMString(QString::number( m_value.num ) + "mm"); 00674 break; 00675 case CSSPrimitiveValue::CSS_IN: 00676 text = DOMString(QString::number( m_value.num ) + "in"); 00677 break; 00678 case CSSPrimitiveValue::CSS_PT: 00679 text = DOMString(QString::number( m_value.num ) + "pt"); 00680 break; 00681 case CSSPrimitiveValue::CSS_PC: 00682 text = DOMString(QString::number( m_value.num ) + "pc"); 00683 break; 00684 case CSSPrimitiveValue::CSS_DEG: 00685 text = DOMString(QString::number( m_value.num ) + "deg"); 00686 break; 00687 case CSSPrimitiveValue::CSS_RAD: 00688 text = DOMString(QString::number( m_value.num ) + "rad"); 00689 break; 00690 case CSSPrimitiveValue::CSS_GRAD: 00691 text = DOMString(QString::number( m_value.num ) + "grad"); 00692 break; 00693 case CSSPrimitiveValue::CSS_MS: 00694 text = DOMString(QString::number( m_value.num ) + "ms"); 00695 break; 00696 case CSSPrimitiveValue::CSS_S: 00697 text = DOMString(QString::number( m_value.num ) + "s"); 00698 break; 00699 case CSSPrimitiveValue::CSS_HZ: 00700 text = DOMString(QString::number( m_value.num ) + "hz"); 00701 break; 00702 case CSSPrimitiveValue::CSS_KHZ: 00703 text = DOMString(QString::number( m_value.num ) + "khz"); 00704 break; 00705 case CSSPrimitiveValue::CSS_DIMENSION: 00706 // ### 00707 break; 00708 case CSSPrimitiveValue::CSS_STRING: 00709 // ### 00710 break; 00711 case CSSPrimitiveValue::CSS_URI: 00712 text = "url("; 00713 text += DOMString( m_value.string ); 00714 text += ")"; 00715 break; 00716 case CSSPrimitiveValue::CSS_IDENT: 00717 text = getValueName(m_value.ident); 00718 break; 00719 case CSSPrimitiveValue::CSS_ATTR: 00720 // ### 00721 break; 00722 case CSSPrimitiveValue::CSS_COUNTER: 00723 // ### 00724 break; 00725 case CSSPrimitiveValue::CSS_RECT: 00726 { 00727 RectImpl* rectVal = getRectValue(); 00728 text = "rect("; 00729 text += rectVal->top()->cssText() + " "; 00730 text += rectVal->right()->cssText() + " "; 00731 text += rectVal->bottom()->cssText() + " "; 00732 text += rectVal->left()->cssText() + ")"; 00733 } 00734 break; 00735 case CSSPrimitiveValue::CSS_RGBCOLOR: 00736 text = QColor(m_value.rgbcolor).name(); 00737 break; 00738 default: 00739 break; 00740 } 00741 return text; 00742 } 00743 00744 // ----------------------------------------------------------------- 00745 00746 RectImpl::RectImpl() 00747 { 00748 m_top = 0; 00749 m_right = 0; 00750 m_bottom = 0; 00751 m_left = 0; 00752 } 00753 00754 RectImpl::~RectImpl() 00755 { 00756 if (m_top) m_top->deref(); 00757 if (m_right) m_right->deref(); 00758 if (m_bottom) m_bottom->deref(); 00759 if (m_left) m_left->deref(); 00760 } 00761 00762 void RectImpl::setTop( CSSPrimitiveValueImpl *top ) 00763 { 00764 if( top ) top->ref(); 00765 if ( m_top ) m_top->deref(); 00766 m_top = top; 00767 } 00768 00769 void RectImpl::setRight( CSSPrimitiveValueImpl *right ) 00770 { 00771 if( right ) right->ref(); 00772 if ( m_right ) m_right->deref(); 00773 m_right = right; 00774 } 00775 00776 void RectImpl::setBottom( CSSPrimitiveValueImpl *bottom ) 00777 { 00778 if( bottom ) bottom->ref(); 00779 if ( m_bottom ) m_bottom->deref(); 00780 m_bottom = bottom; 00781 } 00782 00783 void RectImpl::setLeft( CSSPrimitiveValueImpl *left ) 00784 { 00785 if( left ) left->ref(); 00786 if ( m_left ) m_left->deref(); 00787 m_left = left; 00788 } 00789 00790 // ----------------------------------------------------------------- 00791 00792 CSSImageValueImpl::CSSImageValueImpl(const DOMString &url, const StyleBaseImpl* style) 00793 : CSSPrimitiveValueImpl(url, CSSPrimitiveValue::CSS_URI) 00794 { 00795 khtml::DocLoader *docLoader = 0; 00796 const StyleBaseImpl *root = style; 00797 while (root->parent()) 00798 root = root->parent(); 00799 if (root->isCSSStyleSheet()) 00800 docLoader = static_cast<const CSSStyleSheetImpl*>(root)->docLoader(); 00801 00802 m_image = docLoader->requestImage(url); 00803 if(m_image) m_image->ref(this); 00804 } 00805 00806 CSSImageValueImpl::CSSImageValueImpl() 00807 : CSSPrimitiveValueImpl(CSS_VAL_NONE) 00808 { 00809 m_image = 0; 00810 } 00811 00812 CSSImageValueImpl::~CSSImageValueImpl() 00813 { 00814 if(m_image) m_image->deref(this); 00815 } 00816 00817 // ------------------------------------------------------------------------ 00818 00819 FontFamilyValueImpl::FontFamilyValueImpl( const QString &string) 00820 : CSSPrimitiveValueImpl( DOMString(string), CSSPrimitiveValue::CSS_STRING) 00821 { 00822 static const QRegExp parenReg(" \\(.*\\)$"); 00823 static const QRegExp braceReg(" \\[.*\\]$"); 00824 00825 parsedFontName = string; 00826 // a language tag is often added in braces at the end. Remove it. 00827 parsedFontName.replace(parenReg, QString::null); 00828 // remove [Xft] qualifiers 00829 parsedFontName.replace(braceReg, QString::null); 00830 00831 #ifndef APPLE_CHANGES 00832 const QString &available = KHTMLSettings::availableFamilies(); 00833 00834 parsedFontName = parsedFontName.lower(); 00835 // kdDebug(0) << "searching for face '" << parsedFontName << "'" << endl; 00836 00837 int pos = available.find( ',' + parsedFontName + ',', 0, false ); 00838 if ( pos == -1 ) { 00839 // many pages add extra MSs to make sure it's windows only ;( 00840 if ( parsedFontName.startsWith( "ms " ) ) 00841 parsedFontName = parsedFontName.mid( 3 ); 00842 if ( parsedFontName.endsWith( " ms" ) ) 00843 parsedFontName.truncate( parsedFontName.length() - 3 ); 00844 pos = available.find( ",ms " + parsedFontName + ',', 0, false ); 00845 if ( pos == -1 ) 00846 pos = available.find( ',' + parsedFontName + " ms,", 0, false ); 00847 } 00848 00849 if ( pos != -1 ) { 00850 ++pos; 00851 int p = available.find(',', pos); 00852 assert( p != -1 ); // available is supposed to start and end with , 00853 parsedFontName = available.mid( pos, p - pos); 00854 // kdDebug(0) << "going for '" << parsedFontName << "'" << endl; 00855 } else 00856 parsedFontName = QString::null; 00857 00858 #endif // !APPLE_CHANGES 00859 } 00860 00861 FontValueImpl::FontValueImpl() 00862 : style(0), variant(0), weight(0), size(0), lineHeight(0), family(0) 00863 { 00864 } 00865 00866 FontValueImpl::~FontValueImpl() 00867 { 00868 delete style; 00869 delete variant; 00870 delete weight; 00871 delete size; 00872 delete lineHeight; 00873 delete family; 00874 } 00875 00876 DOMString FontValueImpl::cssText() const 00877 { 00878 // font variant weight size / line-height family 00879 00880 DOMString result(""); 00881 00882 if (style) { 00883 result += style->cssText(); 00884 } 00885 if (variant) { 00886 if (result.length() > 0) { 00887 result += " "; 00888 } 00889 result += variant->cssText(); 00890 } 00891 if (weight) { 00892 if (result.length() > 0) { 00893 result += " "; 00894 } 00895 result += weight->cssText(); 00896 } 00897 if (size) { 00898 if (result.length() > 0) { 00899 result += " "; 00900 } 00901 result += size->cssText(); 00902 } 00903 if (lineHeight) { 00904 if (!size) { 00905 result += " "; 00906 } 00907 result += "/"; 00908 result += lineHeight->cssText(); 00909 } 00910 if (family) { 00911 if (result.length() > 0) { 00912 result += " "; 00913 } 00914 result += family->cssText(); 00915 } 00916 00917 return result; 00918 } 00919 00920 DOMString CSSProperty::cssText() const 00921 { 00922 return getPropertyName(m_id) + DOMString(": ") + m_value->cssText() + (m_bImportant ? DOMString(" !important") : DOMString()) + DOMString("; "); 00923 }
KDE Logo
This file is part of the documentation for khtml Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Oct 10 18:56:11 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003