00001
00026 #include "css/cssstyleselector.h"
00027 #include "rendering/render_style.h"
00028 #include "css/css_stylesheetimpl.h"
00029 #include "css/css_ruleimpl.h"
00030 #include "css/css_valueimpl.h"
00031 #include "css/csshelper.h"
00032 #include "rendering/render_object.h"
00033 #include "html/html_documentimpl.h"
00034 #include "html/html_elementimpl.h"
00035 #include "xml/dom_elementimpl.h"
00036 #include "xml/dom_restyler.h"
00037 #include "dom/css_rule.h"
00038 #include "dom/css_value.h"
00039 #include "khtml_factory.h"
00040 #include "khtmlpart_p.h"
00041 using namespace khtml;
00042 using namespace DOM;
00043
00044 #include "css/cssproperties.h"
00045 #include "css/cssvalues.h"
00046
00047 #include "misc/khtmllayout.h"
00048 #include "khtml_settings.h"
00049 #include "misc/htmlhashes.h"
00050 #include "misc/helper.h"
00051 #include "misc/loader.h"
00052
00053 #include "rendering/font.h"
00054
00055 #include "khtmlview.h"
00056 #include "khtml_part.h"
00057
00058 #include <kstandarddirs.h>
00059 #include <kcharsets.h>
00060 #include <kglobal.h>
00061 #include <kconfig.h>
00062 #include <qfile.h>
00063 #include <qvaluelist.h>
00064 #include <qstring.h>
00065 #include <qtooltip.h>
00066 #include <kdebug.h>
00067 #include <kurl.h>
00068 #include <assert.h>
00069 #include <qpaintdevicemetrics.h>
00070 #include <stdlib.h>
00071
00072 #define HANDLE_INHERIT(prop, Prop) \
00073 if (isInherit) \
00074 {\
00075 style->set##Prop(parentStyle->prop());\
00076 return;\
00077 }
00078
00079 #define HANDLE_INHERIT_AND_INITIAL(prop, Prop) \
00080 HANDLE_INHERIT(prop, Prop) \
00081 else if (isInitial) \
00082 {\
00083 style->set##Prop(RenderStyle::initial##Prop());\
00084 return;\
00085 }
00086
00087 #define HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(prop, Prop, Value) \
00088 HANDLE_INHERIT(prop, Prop) \
00089 else if (isInitial) \
00090 {\
00091 style->set##Prop(RenderStyle::initial##Value());\
00092 return;\
00093 }
00094
00095 #define HANDLE_BACKGROUND_INHERIT_AND_INITIAL(prop, Prop) \
00096 if (isInherit) { \
00097 BackgroundLayer* currChild = style->accessBackgroundLayers(); \
00098 BackgroundLayer* prevChild = 0; \
00099 const BackgroundLayer* currParent = parentStyle->backgroundLayers(); \
00100 while (currParent && currParent->is##Prop##Set()) { \
00101 if (!currChild) { \
00102 \
00103 currChild = new BackgroundLayer(); \
00104 prevChild->setNext(currChild); \
00105 } \
00106 currChild->set##Prop(currParent->prop()); \
00107 prevChild = currChild; \
00108 currChild = prevChild->next(); \
00109 currParent = currParent->next(); \
00110 } \
00111 \
00112 while (currChild) { \
00113 \
00114 currChild->clear##Prop(); \
00115 currChild = currChild->next(); \
00116 } \
00117 return; \
00118 } \
00119 if (isInitial) { \
00120 BackgroundLayer* currChild = style->accessBackgroundLayers(); \
00121 currChild->set##Prop(RenderStyle::initial##Prop()); \
00122 for (currChild = currChild->next(); currChild; currChild = currChild->next()) \
00123 currChild->clear##Prop(); \
00124 return; \
00125 }
00126
00127 #define HANDLE_BACKGROUND_VALUE(prop, Prop, value) { \
00128 HANDLE_BACKGROUND_INHERIT_AND_INITIAL(prop, Prop) \
00129 if (!value->isPrimitiveValue() && !value->isValueList()) \
00130 return; \
00131 BackgroundLayer* currChild = style->accessBackgroundLayers(); \
00132 BackgroundLayer* prevChild = 0; \
00133 if (value->isPrimitiveValue()) { \
00134 map##Prop(currChild, value); \
00135 currChild = currChild->next(); \
00136 } \
00137 else { \
00138 \
00139 CSSValueListImpl* valueList = static_cast<CSSValueListImpl*>(value); \
00140 for (unsigned int i = 0; i < valueList->length(); i++) { \
00141 if (!currChild) { \
00142 \
00143 currChild = new BackgroundLayer(); \
00144 prevChild->setNext(currChild); \
00145 } \
00146 map##Prop(currChild, valueList->item(i)); \
00147 prevChild = currChild; \
00148 currChild = currChild->next(); \
00149 } \
00150 } \
00151 while (currChild) { \
00152 \
00153 currChild->clear##Prop(); \
00154 currChild = currChild->next(); \
00155 } }
00156
00157 #define HANDLE_INHERIT_COND(propID, prop, Prop) \
00158 if (id == propID) \
00159 {\
00160 style->set##Prop(parentStyle->prop());\
00161 return;\
00162 }
00163
00164 #define HANDLE_INITIAL_COND(propID, Prop) \
00165 if (id == propID) \
00166 {\
00167 style->set##Prop(RenderStyle::initial##Prop());\
00168 return;\
00169 }
00170
00171 #define HANDLE_INITIAL_COND_WITH_VALUE(propID, Prop, Value) \
00172 if (id == propID) \
00173 {\
00174 style->set##Prop(RenderStyle::initial##Value());\
00175 return;\
00176 }
00177
00178 namespace khtml {
00179
00180 CSSStyleSelectorList *CSSStyleSelector::s_defaultStyle;
00181 CSSStyleSelectorList *CSSStyleSelector::s_defaultQuirksStyle;
00182 CSSStyleSelectorList *CSSStyleSelector::s_defaultPrintStyle;
00183 CSSStyleSheetImpl *CSSStyleSelector::s_defaultSheet;
00184 RenderStyle* CSSStyleSelector::styleNotYetAvailable;
00185 CSSStyleSheetImpl *CSSStyleSelector::s_quirksSheet;
00186
00187 enum PseudoState { PseudoUnknown, PseudoNone, PseudoLink, PseudoVisited};
00188 static PseudoState pseudoState;
00189
00190
00191 CSSStyleSelector::CSSStyleSelector( DocumentImpl* doc, QString userStyleSheet, StyleSheetListImpl *styleSheets,
00192 const KURL &url, bool _strictParsing )
00193 {
00194 KHTMLView* view = doc->view();
00195
00196 init(view ? view->part()->settings() : 0, doc);
00197
00198 strictParsing = _strictParsing;
00199 m_medium = view ? view->mediaType() : QString("all");
00200
00201 selectors = 0;
00202 selectorCache = 0;
00203 properties = 0;
00204 userStyle = 0;
00205 userSheet = 0;
00206 paintDeviceMetrics = doc->paintDeviceMetrics();
00207
00208 if(paintDeviceMetrics)
00209 computeFontSizes(paintDeviceMetrics, view ? view->part()->zoomFactor() : 100);
00210
00211 if ( !userStyleSheet.isEmpty() ) {
00212 userSheet = new DOM::CSSStyleSheetImpl(doc);
00213 userSheet->parseString( DOMString( userStyleSheet ) );
00214
00215 userStyle = new CSSStyleSelectorList();
00216 userStyle->append( userSheet, m_medium );
00217 }
00218
00219
00220 authorStyle = new CSSStyleSelectorList();
00221
00222
00223 QPtrListIterator<StyleSheetImpl> it( styleSheets->styleSheets );
00224 for ( ; it.current(); ++it ) {
00225 if ( it.current()->isCSSStyleSheet() && !it.current()->disabled()) {
00226 authorStyle->append( static_cast<CSSStyleSheetImpl*>( it.current() ), m_medium );
00227 }
00228 }
00229
00230 buildLists();
00231
00232
00233
00234
00235 KURL u = url;
00236
00237 u.setQuery( QString::null );
00238 u.setRef( QString::null );
00239 encodedurl.file = u.url();
00240 int pos = encodedurl.file.findRev('/');
00241 encodedurl.path = encodedurl.file;
00242 if ( pos > 0 ) {
00243 encodedurl.path.truncate( pos );
00244 encodedurl.path += '/';
00245 }
00246 u.setPath( QString::null );
00247 encodedurl.host = u.url();
00248
00249
00250 }
00251
00252 CSSStyleSelector::CSSStyleSelector( CSSStyleSheetImpl *sheet )
00253 {
00254 init(0L, 0L);
00255
00256 KHTMLView *view = sheet->doc()->view();
00257 m_medium = view ? view->mediaType() : "screen";
00258
00259 authorStyle = new CSSStyleSelectorList();
00260 authorStyle->append( sheet, m_medium );
00261 }
00262
00263 void CSSStyleSelector::init(const KHTMLSettings* _settings, DocumentImpl* doc)
00264 {
00265 element = 0;
00266 settings = _settings;
00267 paintDeviceMetrics = 0;
00268 propsToApply = (CSSOrderedProperty **)malloc(128*sizeof(CSSOrderedProperty *));
00269 pseudoProps = (CSSOrderedProperty **)malloc(128*sizeof(CSSOrderedProperty *));
00270 propsToApplySize = 128;
00271 pseudoPropsSize = 128;
00272 if(!s_defaultStyle) loadDefaultStyle(settings, doc);
00273
00274 defaultStyle = s_defaultStyle;
00275 defaultPrintStyle = s_defaultPrintStyle;
00276 defaultQuirksStyle = s_defaultQuirksStyle;
00277 }
00278
00279 CSSStyleSelector::~CSSStyleSelector()
00280 {
00281 clearLists();
00282 delete authorStyle;
00283 delete userStyle;
00284 delete userSheet;
00285 free(propsToApply);
00286 free(pseudoProps);
00287 }
00288
00289 void CSSStyleSelector::addSheet( CSSStyleSheetImpl *sheet )
00290 {
00291 KHTMLView *view = sheet->doc()->view();
00292 m_medium = view ? view->mediaType() : "screen";
00293 authorStyle->append( sheet, m_medium );
00294 }
00295
00296 void CSSStyleSelector::loadDefaultStyle(const KHTMLSettings *s, DocumentImpl *doc)
00297 {
00298 if(s_defaultStyle) return;
00299
00300 {
00301 QFile f(locate( "data", "khtml/css/html4.css" ) );
00302 f.open(IO_ReadOnly);
00303
00304 QCString file( f.size()+1 );
00305 int readbytes = f.readBlock( file.data(), f.size() );
00306 f.close();
00307 if ( readbytes >= 0 )
00308 file[readbytes] = '\0';
00309
00310 QString style = QString::fromLatin1( file.data() );
00311 if(s)
00312 style += s->settingsToCSS();
00313 DOMString str(style);
00314
00315 s_defaultSheet = new DOM::CSSStyleSheetImpl(doc);
00316 s_defaultSheet->parseString( str );
00317
00318
00319 s_defaultStyle = new CSSStyleSelectorList();
00320 s_defaultStyle->append( s_defaultSheet, "screen" );
00321
00322 s_defaultPrintStyle = new CSSStyleSelectorList();
00323 s_defaultPrintStyle->append( s_defaultSheet, "print" );
00324 }
00325 {
00326 QFile f(locate( "data", "khtml/css/quirks.css" ) );
00327 f.open(IO_ReadOnly);
00328
00329 QCString file( f.size()+1 );
00330 int readbytes = f.readBlock( file.data(), f.size() );
00331 f.close();
00332 if ( readbytes >= 0 )
00333 file[readbytes] = '\0';
00334
00335 QString style = QString::fromLatin1( file.data() );
00336 DOMString str(style);
00337
00338 s_quirksSheet = new DOM::CSSStyleSheetImpl(doc);
00339 s_quirksSheet->parseString( str );
00340
00341
00342 s_defaultQuirksStyle = new CSSStyleSelectorList();
00343 s_defaultQuirksStyle->append( s_quirksSheet, "screen" );
00344 }
00345
00346
00347 }
00348
00349 void CSSStyleSelector::clear()
00350 {
00351 delete s_defaultStyle;
00352 delete s_defaultQuirksStyle;
00353 delete s_defaultPrintStyle;
00354 delete s_defaultSheet;
00355 delete styleNotYetAvailable;
00356 s_defaultStyle = 0;
00357 s_defaultQuirksStyle = 0;
00358 s_defaultPrintStyle = 0;
00359 s_defaultSheet = 0;
00360 styleNotYetAvailable = 0;
00361 }
00362
00363 void CSSStyleSelector::reparseConfiguration()
00364 {
00365
00366 s_defaultStyle = 0;
00367 s_defaultQuirksStyle = 0;
00368 s_defaultPrintStyle = 0;
00369 s_defaultSheet = 0;
00370 }
00371
00372 #define MAXFONTSIZES 8
00373
00374 void CSSStyleSelector::computeFontSizes(QPaintDeviceMetrics* paintDeviceMetrics, int zoomFactor)
00375 {
00376 computeFontSizesFor(paintDeviceMetrics, zoomFactor, m_fontSizes, false);
00377 computeFontSizesFor(paintDeviceMetrics, zoomFactor, m_fixedFontSizes, true);
00378 }
00379
00380 void CSSStyleSelector::computeFontSizesFor(QPaintDeviceMetrics* paintDeviceMetrics, int zoomFactor, QValueVector<int>& fontSizes, bool isFixed)
00381 {
00382 #ifdef APPLE_CHANGES
00383
00384 const float toPix = 1;
00385 #else
00386 Q_UNUSED( isFixed );
00387
00388
00389 float toPix = paintDeviceMetrics->logicalDpiY()/72.;
00390 if (toPix < 96./72.) toPix = 96./72.;
00391 #endif // ######### fix isFixed code again.
00392
00393 fontSizes.resize( MAXFONTSIZES );
00394 float scale = 1.0;
00395 static const float fontFactors[] = {3./5., 3./4., 8./9., 1., 6./5., 3./2., 2., 3.};
00396 static const float smallFontFactors[] = {3./4., 5./6., 8./9., 1., 6./5., 3./2., 2., 3.};
00397 float mediumFontSize, minFontSize, factor;
00398 if (!khtml::printpainter) {
00399 scale *= zoomFactor / 100.0;
00400 #ifdef APPLE_CHANGES
00401 if (isFixed)
00402 mediumFontSize = settings->mediumFixedFontSize() * toPix;
00403 else
00404 #endif
00405 mediumFontSize = settings->mediumFontSize() * toPix;
00406 minFontSize = settings->minFontSize() * toPix;
00407 }
00408 else {
00409
00410 mediumFontSize = 12;
00411 minFontSize = 6;
00412 }
00413 const float* factors = scale*mediumFontSize >= 12.5 ? fontFactors : smallFontFactors;
00414 for ( int i = 0; i < MAXFONTSIZES; i++ ) {
00415 factor = scale*factors[i];
00416 fontSizes[i] = int(KMAX( mediumFontSize*factor +.5f, minFontSize));
00417
00418 }
00419 }
00420
00421 #undef MAXFONTSIZES
00422
00423 static inline void bubbleSort( CSSOrderedProperty **b, CSSOrderedProperty **e )
00424 {
00425 while( b < e ) {
00426 bool swapped = false;
00427 CSSOrderedProperty **y = e+1;
00428 CSSOrderedProperty **x = e;
00429 CSSOrderedProperty **swappedPos = 0;
00430 do {
00431 if ( !((**(--x)) < (**(--y))) ) {
00432 swapped = true;
00433 swappedPos = x;
00434 CSSOrderedProperty *tmp = *y;
00435 *y = *x;
00436 *x = tmp;
00437 }
00438 } while( x != b );
00439 if ( !swapped ) break;
00440 b = swappedPos + 1;
00441 }
00442 }
00443
00444 RenderStyle *CSSStyleSelector::styleForElement(ElementImpl *e)
00445 {
00446 if (!e->getDocument()->haveStylesheetsLoaded() || !e->getDocument()->view()) {
00447 if (!styleNotYetAvailable) {
00448 styleNotYetAvailable = new RenderStyle();
00449 styleNotYetAvailable->setDisplay(NONE);
00450 styleNotYetAvailable->ref();
00451 }
00452 return styleNotYetAvailable;
00453 }
00454
00455
00456 pseudoState = PseudoUnknown;
00457
00458 element = e;
00459 parentNode = e->parentNode();
00460 parentStyle = ( parentNode && parentNode->renderer()) ? parentNode->renderer()->style() : 0;
00461 view = element->getDocument()->view();
00462 part = view->part();
00463 settings = part->settings();
00464 paintDeviceMetrics = element->getDocument()->paintDeviceMetrics();
00465
00466
00467 e->getDocument()->dynamicDomRestyler().resetDependencies(e);
00468
00469 style = new RenderStyle();
00470 if( parentStyle )
00471 style->inheritFrom( parentStyle );
00472 else
00473 parentStyle = style;
00474
00475 unsigned int numPropsToApply = 0;
00476 unsigned int numPseudoProps = 0;
00477
00478
00479 Q_UINT16 cssTagId = localNamePart(element->id());
00480 int smatch = 0;
00481 int schecked = 0;
00482
00483 for ( unsigned int i = 0; i < selectors_size; i++ ) {
00484 Q_UINT16 tag = localNamePart(selectors[i]->tag);
00485 if ( cssTagId == tag || tag == anyLocalName ) {
00486 ++schecked;
00487
00488 checkSelector( i, e );
00489
00490 if ( selectorCache[i].state == Applies ) {
00491 ++smatch;
00492
00493
00494 for ( unsigned int p = 0; p < selectorCache[i].props_size; p += 2 )
00495 for ( unsigned int j = 0; j < (unsigned int )selectorCache[i].props[p+1]; ++j ) {
00496 if (numPropsToApply >= propsToApplySize ) {
00497 propsToApplySize *= 2;
00498 propsToApply = (CSSOrderedProperty **)realloc( propsToApply, propsToApplySize*sizeof( CSSOrderedProperty * ) );
00499 }
00500 propsToApply[numPropsToApply++] = properties[selectorCache[i].props[p]+j];
00501 }
00502 } else if ( selectorCache[i].state == AppliesPseudo ) {
00503 for ( unsigned int p = 0; p < selectorCache[i].props_size; p += 2 )
00504 for ( unsigned int j = 0; j < (unsigned int) selectorCache[i].props[p+1]; ++j ) {
00505 if (numPseudoProps >= pseudoPropsSize ) {
00506 pseudoPropsSize *= 2;
00507 pseudoProps = (CSSOrderedProperty **)realloc( pseudoProps, pseudoPropsSize*sizeof( CSSOrderedProperty * ) );
00508 }
00509 pseudoProps[numPseudoProps++] = properties[selectorCache[i].props[p]+j];
00510 properties[selectorCache[i].props[p]+j]->pseudoId = (RenderStyle::PseudoId) selectors[i]->pseudoId;
00511 }
00512 }
00513 }
00514 else
00515 selectorCache[i].state = Invalid;
00516
00517 }
00518
00519
00520
00521 numPropsToApply = addInlineDeclarations( e, e->m_styleDecls, numPropsToApply );
00522
00523
00524
00525
00526
00527 bubbleSort( propsToApply, propsToApply+numPropsToApply-1 );
00528 bubbleSort( pseudoProps, pseudoProps+numPseudoProps-1 );
00529
00530
00531
00532 if ( part ) {
00533 fontDirty = false;
00534
00535 if (numPropsToApply ) {
00536 CSSStyleSelector::style = style;
00537 for (unsigned int i = 0; i < numPropsToApply; ++i) {
00538 if ( fontDirty && propsToApply[i]->priority >= (1 << 30) ) {
00539
00540
00541 #ifdef APPLE_CHANGES
00542 checkForGenericFamilyChange(style, parentStyle);
00543 #endif
00544 CSSStyleSelector::style->htmlFont().update( paintDeviceMetrics );
00545 fontDirty = false;
00546 }
00547 DOM::CSSProperty *prop = propsToApply[i]->prop;
00548
00549
00550 applyRule( prop->m_id, prop->value() );
00551 }
00552 if ( fontDirty ) {
00553 #ifdef APPLE_CHANGES
00554 checkForGenericFamilyChange(style, parentStyle);
00555 #endif
00556 CSSStyleSelector::style->htmlFont().update( paintDeviceMetrics );
00557 }
00558 }
00559
00560
00561 adjustRenderStyle(style, e);
00562
00563 if ( numPseudoProps ) {
00564 fontDirty = false;
00565
00566 for (unsigned int i = 0; i < numPseudoProps; ++i) {
00567 if ( fontDirty && pseudoProps[i]->priority >= (1 << 30) ) {
00568
00569
00570
00571 RenderStyle *pseudoStyle = style->pseudoStyle;
00572 while ( pseudoStyle ) {
00573 pseudoStyle->htmlFont().update( paintDeviceMetrics );
00574 pseudoStyle = pseudoStyle->pseudoStyle;
00575 }
00576 fontDirty = false;
00577 }
00578
00579 RenderStyle *pseudoStyle;
00580 pseudoStyle = style->getPseudoStyle(pseudoProps[i]->pseudoId);
00581 if (!pseudoStyle)
00582 {
00583 pseudoStyle = style->addPseudoStyle(pseudoProps[i]->pseudoId);
00584 if (pseudoStyle)
00585 pseudoStyle->inheritFrom( style );
00586 }
00587
00588 RenderStyle* oldStyle = style;
00589 RenderStyle* oldParentStyle = parentStyle;
00590 parentStyle = style;
00591 style = pseudoStyle;
00592 if ( pseudoStyle ) {
00593 DOM::CSSProperty *prop = pseudoProps[i]->prop;
00594 applyRule( prop->m_id, prop->value() );
00595 }
00596 style = oldStyle;
00597 parentStyle = oldParentStyle;
00598 }
00599
00600 if ( fontDirty ) {
00601 RenderStyle *pseudoStyle = style->pseudoStyle;
00602 while ( pseudoStyle ) {
00603 pseudoStyle->htmlFont().update( paintDeviceMetrics );
00604 pseudoStyle = pseudoStyle->pseudoStyle;
00605 }
00606 }
00607 }
00608 }
00609
00610
00611 RenderStyle *pseudoStyle = style->pseudoStyle;
00612 while (pseudoStyle) {
00613 adjustRenderStyle(pseudoStyle, 0);
00614 pseudoStyle = pseudoStyle->pseudoStyle;
00615 }
00616
00617
00618 return style;
00619 }
00620
00621 void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, DOM::ElementImpl *e)
00622 {
00623
00624 style->setOriginalDisplay(style->display());
00625
00626 if (style->display() != NONE) {
00627
00628
00629
00630
00631 if (!strictParsing && e) {
00632 if (e->id() == ID_TD) {
00633 style->setDisplay(TABLE_CELL);
00634 style->setFloating(FNONE);
00635 }
00636
00637
00638 }
00639
00640
00641 if (e && e->id() == ID_TH && style->textAlign() == TAAUTO)
00642 style->setTextAlign(CENTER);
00643
00644
00645
00646
00647
00648 if (style->display() != BLOCK && style->display() != TABLE &&
00649 (style->position() == ABSOLUTE || style->position() == FIXED || style->floating() != FNONE ||
00650 (e && e->getDocument()->documentElement() == e))) {
00651 if (style->display() == INLINE_TABLE)
00652 style->setDisplay(TABLE);
00653
00654
00655 else if (style->display() == LIST_ITEM) {
00656
00657
00658 if (!strictParsing && style->floating() != FNONE)
00659 style->setDisplay(BLOCK);
00660 }
00661 else
00662 style->setDisplay(BLOCK);
00663 }
00664
00665
00666
00667 if (style->position() == RELATIVE) {
00668 switch (style->display()) {
00669 case TABLE_ROW_GROUP:
00670 case TABLE_HEADER_GROUP:
00671 case TABLE_FOOTER_GROUP:
00672 case TABLE_ROW:
00673 style->setPosition(STATIC);
00674 default:
00675 break;
00676 }
00677 }
00678 }
00679
00680
00681
00682 if ( e ) {
00683
00684 if ( e->id() == ID_FRAME ) {
00685 style->setPosition( STATIC );
00686 style->setDisplay( BLOCK );
00687 }
00688 else if ( e->id() == ID_FRAMESET ) {
00689 style->setPosition( STATIC );
00690 }
00691 }
00692
00693
00694
00695 if (style->display() == TABLE || style->display() == INLINE_TABLE || style->display() == RUN_IN
00696 || style->display() == INLINE_BLOCK )
00697 style->setTextDecorationsInEffect(style->textDecoration());
00698 else
00699 style->addToTextDecorationsInEffect(style->textDecoration());
00700
00701
00702
00703 if (style->overflow() != OVISIBLE && style->overflow() != OHIDDEN &&
00704 (style->display() == TABLE || style->display() == INLINE_TABLE ||
00705 style->display() == TABLE_ROW_GROUP || style->display() == TABLE_ROW))
00706 style->setOverflow(OVISIBLE);
00707
00708
00709 style->adjustBackgroundLayers();
00710
00711
00712
00713
00714 if (style->hasFixedBackgroundImage() && view)
00715 view->useSlowRepaints();
00716 }
00717
00718 unsigned int CSSStyleSelector::addInlineDeclarations(DOM::ElementImpl* e,
00719 DOM::CSSStyleDeclarationImpl *decl,
00720 unsigned int numProps)
00721 {
00722 CSSStyleDeclarationImpl* addDecls = 0;
00723 #ifdef APPLE_CHANGES
00724 if (e->id() == ID_TD || e->id() == ID_TH)
00725 addDecls = e->getAdditionalStyleDecls();
00726 #else
00727 Q_UNUSED( e );
00728 #endif
00729
00730 if (!decl && !addDecls)
00731 return numProps;
00732
00733 QPtrList<CSSProperty>* values = decl ? decl->values() : 0;
00734 QPtrList<CSSProperty>* addValues = addDecls ? addDecls->values() : 0;
00735 if (!values && !addValues)
00736 return numProps;
00737
00738 int firstLen = values ? values->count() : 0;
00739 int secondLen = addValues ? addValues->count() : 0;
00740 int totalLen = firstLen + secondLen;
00741
00742 if (inlineProps.size() < (uint)totalLen)
00743 inlineProps.resize(totalLen + 1);
00744
00745 if (numProps + totalLen >= propsToApplySize ) {
00746 propsToApplySize += propsToApplySize;
00747 propsToApply = (CSSOrderedProperty **)realloc( propsToApply, propsToApplySize*sizeof( CSSOrderedProperty * ) );
00748 }
00749
00750 CSSOrderedProperty *array = (CSSOrderedProperty *)inlineProps.data();
00751 for(int i = 0; i < totalLen; i++)
00752 {
00753 if (i == firstLen)
00754 values = addValues;
00755
00756 CSSProperty *prop = values->at(i >= firstLen ? i - firstLen : i);
00757 Source source = Inline;
00758
00759 if( prop->m_important ) source = InlineImportant;
00760 if( prop->nonCSSHint ) source = NonCSSHint;
00761
00762 bool first;
00763
00764 switch(prop->m_id)
00765 {
00766 case CSS_PROP_FONT_STYLE:
00767 case CSS_PROP_FONT_SIZE:
00768 case CSS_PROP_FONT_WEIGHT:
00769 case CSS_PROP_FONT_FAMILY:
00770 case CSS_PROP_FONT_VARIANT:
00771 case CSS_PROP_FONT:
00772 case CSS_PROP_COLOR:
00773 case CSS_PROP_DIRECTION:
00774 case CSS_PROP_DISPLAY:
00775
00776
00777 first = true;
00778 break;
00779 default:
00780 first = false;
00781 break;
00782 }
00783
00784 array->prop = prop;
00785 array->pseudoId = RenderStyle::NOPSEUDO;
00786 array->selector = 0;
00787 array->position = i;
00788 array->priority = (!first << 30) | (source << 24);
00789 propsToApply[numProps++] = array++;
00790 }
00791 return numProps;
00792 }
00793
00794
00795 static void cleanpath(QString &path)
00796 {
00797 int pos;
00798 while ( (pos = path.find( "/../" )) != -1 ) {
00799 int prev = 0;
00800 if ( pos > 0 )
00801 prev = path.findRev( "/", pos -1 );
00802
00803 if (prev < 0 || (prev > 3 && path.findRev("://", prev-1) == prev-2))
00804 path.remove( pos, 3);
00805 else
00806
00807 path.remove( prev, pos- prev + 3 );
00808 }
00809 pos = 0;
00810
00811
00812
00813
00814
00815 int refPos = -2;
00816 while ( (pos = path.find( "//", pos )) != -1) {
00817 if (refPos == -2)
00818 refPos = path.find("#", 0);
00819 if (refPos > 0 && pos >= refPos)
00820 break;
00821
00822 if ( pos == 0 || path[pos-1] != ':' )
00823 path.remove( pos, 1 );
00824 else
00825 pos += 2;
00826 }
00827 while ( (pos = path.find( "/./" )) != -1)
00828 path.remove( pos, 2 );
00829
00830 }
00831
00832 static PseudoState checkPseudoState( const CSSStyleSelector::Encodedurl& encodedurl, DOM::ElementImpl *e )
00833 {
00834 if( e->id() != ID_A ) {
00835 return PseudoNone;
00836 }
00837 DOMString attr = e->getAttribute(ATTR_HREF);
00838 if( attr.isNull() ) {
00839 return PseudoNone;
00840 }
00841 QConstString cu(attr.unicode(), attr.length());
00842 QString u = cu.string();
00843 if ( !u.contains("://") ) {
00844 if ( u[0] == '/' )
00845 u = encodedurl.host + u;
00846 else if ( u[0] == '#' )
00847 u = encodedurl.file + u;
00848 else
00849 u = encodedurl.path + u;
00850 cleanpath( u );
00851 }
00852
00853 bool contains = KHTMLFactory::vLinks()->contains( u );
00854 if ( !contains && u.contains('/')==2 )
00855 contains = KHTMLFactory::vLinks()->contains( u+'/' );
00856 return contains ? PseudoVisited : PseudoLink;
00857 }
00858
00859
00860 static bool matchNth(int count, const QString& nth)
00861 {
00862 if (nth.isEmpty()) return false;
00863 int a = 0;
00864 int b = 0;
00865 if (nth == "odd") {
00866 a = 2;
00867 b = 1;
00868 }
00869 else if (nth == "even") {
00870 a = 2;
00871 b = 0;
00872 }
00873 else {
00874 int n = nth.find('n');
00875 if (n != -1) {
00876 if (nth[0] == '-')
00877 if (n==1)
00878 a = -1;
00879 else
00880 a = nth.mid(1,n-1).toInt();
00881 else
00882 if (n==0)
00883 a = 1;
00884 else
00885 a = nth.left(n).toInt();
00886
00887 int p = nth.find('+');
00888 if (p != -1)
00889 b = nth.mid(p+1).toInt();
00890 else {
00891 p = nth.find('-');
00892 b = -nth.mid(p+1).toInt();
00893 }
00894 }
00895 else {
00896 b = nth.toInt();
00897 }
00898 }
00899 if (a == 0)
00900 return count == b;
00901 else if (a > 0)
00902 if (count < b)
00903 return false;
00904 else
00905 return (count - b) % a == 0;
00906 else if (a < 0) {
00907 if (count > b)
00908 return false;
00909 else
00910 return (b - count) % (-a) == 0;
00911 }
00912 return false;
00913 }
00914
00915
00916
00917
00918 static void precomputeAttributeDependenciesAux(DOM::DocumentImpl* doc, DOM::CSSSelector* sel, bool isAncestor, bool isSubject)
00919 {
00920 if(sel->attr)
00921 {
00922
00923 if (isSubject)
00924 doc->dynamicDomRestyler().addDependency(sel->attr, PersonalDependency);
00925 else if (isAncestor)
00926 doc->dynamicDomRestyler().addDependency(sel->attr, AncestorDependency);
00927 else
00928 doc->dynamicDomRestyler().addDependency(sel->attr, PredecessorDependency);
00929 }
00930 if(sel->match == CSSSelector::PseudoClass)
00931 {
00932 switch (sel->pseudoType()) {
00933 case CSSSelector::PseudoNot:
00934 precomputeAttributeDependenciesAux(doc, sel->simpleSelector, isAncestor, true);
00935 break;
00936 default:
00937 break;
00938 }
00939 }
00940 CSSSelector::Relation relation = sel->relation;
00941 sel = sel->tagHistory;
00942 if (!sel) return;
00943
00944 switch(relation)
00945 {
00946 case CSSSelector::Descendant:
00947 case CSSSelector::Child:
00948 precomputeAttributeDependenciesAux(doc, sel, true, false);
00949 break;
00950 case CSSSelector::IndirectAdjacent:
00951 case CSSSelector::DirectAdjacent:
00952 precomputeAttributeDependenciesAux(doc, sel, false, false);
00953 break;
00954 case CSSSelector::SubSelector:
00955 precomputeAttributeDependenciesAux(doc, sel, isAncestor, isSubject);
00956 break;
00957 }
00958 }
00959
00960 void CSSStyleSelector::precomputeAttributeDependencies(DOM::DocumentImpl* doc, DOM::CSSSelector* sel)
00961 {
00962 precomputeAttributeDependenciesAux(doc, sel, false, true);
00963 }
00964
00965
00966 DOM::ElementImpl* CSSStyleSelector::checkSelector(DOM::CSSSelector *sel, DOM::ElementImpl *e, bool isAncestor, bool isSubSelector)
00967 {
00968
00969 if(!checkSimpleSelector(sel, e, isAncestor, isSubSelector)) return 0;
00970
00971
00972 CSSSelector::Relation relation = sel->relation;
00973
00974
00975 sel = sel->tagHistory;
00976 if (!sel) return e;
00977
00978 switch(relation) {
00979 case CSSSelector::Descendant:
00980 {
00981 while(true)
00982 {
00983 DOM::NodeImpl* n = e->parentNode();
00984 if(!n || !n->isElementNode()) return 0;
00985 e = static_cast<ElementImpl *>(n);
00986 if(checkSelector(sel, e, true)) return e;
00987 }
00988 break;
00989 }
00990 case CSSSelector::Child:
00991 {
00992 DOM::NodeImpl* n = e->parentNode();
00993 if (!strictParsing)
00994 while (n && n->implicitNode()) n = n->parentNode();
00995 if(!n || !n->isElementNode()) return 0;
00996 e = static_cast<ElementImpl *>(n);
00997 if(checkSelector(sel, e, true)) return e;
00998 break;
00999 }
01000 case CSSSelector::IndirectAdjacent:
01001 {
01002
01003
01004 if (e->parentNode()->isElementNode())
01005 addDependency(StructuralDependency, static_cast<ElementImpl*>(e->parentNode()));
01006 while(true)
01007 {
01008 DOM::NodeImpl* n = e->previousSibling();
01009 while( n && !n->isElementNode() )
01010 n = n->previousSibling();
01011 if( !n ) return 0;
01012 e = static_cast<ElementImpl *>(n);
01013 if(checkSelector(sel, e, false)) return e;
01014 };
01015 break;
01016 }
01017 case CSSSelector::DirectAdjacent:
01018 {
01019 if (e->parentNode()->isElementNode())
01020 addDependency(StructuralDependency, static_cast<ElementImpl*>(e->parentNode()));
01021 DOM::NodeImpl* n = e->previousSibling();
01022 while( n && !n->isElementNode() )
01023 n = n->previousSibling();
01024 if( !n ) return 0;
01025 e = static_cast<ElementImpl *>(n);
01026 if(checkSelector(sel, e, false)) return e;
01027 break;
01028 }
01029 case CSSSelector::SubSelector:
01030 return checkSelector(sel, e, isAncestor, true);
01031 }
01032 return 0;
01033 }
01034
01035 void CSSStyleSelector::checkSelector(int selIndex, DOM::ElementImpl * e)
01036 {
01037 assert(e == element);
01038
01039 dynamicPseudo = RenderStyle::NOPSEUDO;
01040
01041 selectorCache[ selIndex ].state = Invalid;
01042 CSSSelector *sel = selectors[ selIndex ];
01043
01044
01045 if(!checkSelector(sel, e, true)) return;
01046
01047 if ( dynamicPseudo != RenderStyle::NOPSEUDO ) {
01048 selectorCache[selIndex].state = AppliesPseudo;
01049 selectors[ selIndex ]->pseudoId = dynamicPseudo;
01050 } else
01051 selectorCache[ selIndex ].state = Applies;
01052
01053
01054 return;
01055 }
01056
01057 void CSSStyleSelector::addDependency(StructuralDependencyType dependencyType, ElementImpl* dependency)
01058 {
01059 element->getDocument()->dynamicDomRestyler().addDependency(element, dependency, dependencyType);
01060 }
01061
01062 bool CSSStyleSelector::checkSimpleSelector(DOM::CSSSelector *sel, DOM::ElementImpl *e, bool isAncestor, bool isSubSelector)
01063 {
01064 if(!e)
01065 return false;
01066
01067 if (sel->tag != anyQName) {
01068 int eltID = e->id();
01069 Q_UINT16 localName = localNamePart(eltID);
01070 Q_UINT16 ns = namespacePart(eltID);
01071 Q_UINT16 selLocalName = localNamePart(sel->tag);
01072 Q_UINT16 selNS = namespacePart(sel->tag);
01073
01074 if (localName <= ID_LAST_TAG && ns == defaultNamespace) {
01075 assert(e->isHTMLElement());
01076 ns = xhtmlNamespace;
01077 }
01078
01079
01080 if (selLocalName != anyLocalName && localName != selLocalName) return false;
01081
01082 if (selNS != anyNamespace && ns != selNS) return false;
01083 }
01084
01085 if(sel->attr)
01086 {
01087 DOMStringImpl* value = e->getAttributeImpl(sel->attr);
01088 if(!value) return false;
01089
01090 switch(sel->match)
01091 {
01092 case CSSSelector::Exact:
01093
01094
01095 if ( e->getDocument()->htmlMode() != DocumentImpl::XHtml ) {
01096 if ( strcasecmp(sel->value, value) )
01097 return false;
01098 } else {
01099 if ( strcmp(sel->value, value) )
01100 return false;
01101 }
01102 break;
01103 case CSSSelector::Id:
01104 if( (strictParsing && strcmp(sel->value, value) ) ||
01105 (!strictParsing && strcasecmp(sel->value, value)))
01106 return false;
01107 break;
01108 case CSSSelector::Set:
01109 break;
01110 case CSSSelector::Class:
01111
01112 case CSSSelector::List:
01113 {
01114 int sel_len = sel->value.length();
01115 int val_len = value->length();
01116
01117 if (sel_len > val_len) return false;
01118
01119 if ((sel->attr != ATTR_CLASS || e->hasClassList()) && sel->value.find(' ') != -1) return false;
01120 if (sel_len == val_len)
01121 return (strictParsing && !strcmp(sel->value, value)) ||
01122 (!strictParsing && !strcasecmp(sel->value, value));
01123
01124 if ( sel->match == CSSSelector::Class && !e->hasClassList() ) return false;
01125
01126 QChar* sel_uc = sel->value.unicode();
01127 QChar* val_uc = value->unicode();
01128
01129 QConstString sel_str(sel_uc, sel_len);
01130 QConstString val_str(val_uc, val_len);
01131
01132 int pos = 0;
01133 for ( ;; ) {
01134 pos = val_str.string().find(sel_str.string(), pos, strictParsing);
01135 if ( pos == -1 ) return false;
01136 if ( pos == 0 || val_uc[pos-1].isSpace() ) {
01137 int endpos = pos + sel_len;
01138 if ( endpos >= val_len || val_uc[endpos].isSpace() )
01139 break;
01140 }
01141 ++pos;
01142 }
01143 break;
01144 }
01145 case CSSSelector::Contain:
01146 {
01147
01148 QConstString val_str(value->unicode(), value->length());
01149 QConstString sel_str(sel->value.unicode(), sel->value.length());
01150 return val_str.string().contains(sel_str.string());
01151 }
01152 case CSSSelector::Begin:
01153 {
01154
01155 QConstString val_str(value->unicode(), value->length());
01156 QConstString sel_str(sel->value.unicode(), sel->value.length());
01157 return val_str.string().startsWith(sel_str.string());
01158 }
01159 case CSSSelector::End:
01160 {
01161
01162 QConstString val_str(value->unicode(), value->length());
01163 QConstString sel_str(sel->value.unicode(), sel->value.length());
01164 return val_str.string().endsWith(sel_str.string());
01165 }
01166 case CSSSelector::Hyphen:
01167 {
01168
01169 QConstString val_str(value->unicode(), value->length());
01170 QConstString sel_str(sel->value.unicode(), sel->value.length());
01171 const QString& str = val_str.string();
01172 const QString& selStr = sel_str.string();
01173 if(str.length() < selStr.length()) return false;
01174
01175 if(str.find(selStr, 0, strictParsing) != 0) return false;
01176
01177 if(str.length() != selStr.length()
01178 && str[selStr.length()] != '-') return false;
01179 break;
01180 }
01181 case CSSSelector::PseudoClass:
01182 case CSSSelector::PseudoElement:
01183 case CSSSelector::None:
01184 break;
01185 }
01186 }
01187
01188 if(sel->match == CSSSelector::PseudoClass || sel->match == CSSSelector::PseudoElement)
01189 {
01190 switch (sel->pseudoType()) {
01191
01192 case CSSSelector::PseudoEmpty:
01193 addDependency(BackwardsStructuralDependency, e);
01194
01195 if (!e->closed()) {
01196 return false;
01197 }
01198 if (!e->firstChild())
01199 return true;
01200 else {
01201
01202 NodeImpl *t = e->firstChild();
01203
01204 while (t && t->isTextNode() && static_cast<TextImpl*>(t)->length() == 0) t = t->nextSibling();
01205
01206 if (t == 0)
01207 return true;
01208 else
01209 return false;
01210 }
01211 break;
01212 case CSSSelector::PseudoFirstChild: {
01213
01214 if (e->parentNode() && e->parentNode()->isElementNode()) {
01215
01216 addDependency(StructuralDependency, static_cast<ElementImpl*>(e->parentNode()));
01217 DOM::NodeImpl* n = e->previousSibling();
01218 while ( n && !n->isElementNode() )
01219 n = n->previousSibling();
01220 if ( !n )
01221 return true;
01222 }
01223 break;
01224 }
01225 case CSSSelector::PseudoLastChild: {
01226
01227 if (e->parentNode() && e->parentNode()->isElementNode()) {
01228
01229 addDependency(BackwardsStructuralDependency, static_cast<ElementImpl*>(e->parentNode()));
01230 if (!e->parentNode()->closed()) {
01231
01232 return false;
01233 }
01234 DOM::NodeImpl* n = e->nextSibling();
01235 while ( n && !n->isElementNode() )
01236 n = n->nextSibling();
01237 if ( !n )
01238 return true;
01239 }
01240 break;
01241 }
01242 case CSSSelector::PseudoOnlyChild: {
01243
01244 if (e->parentNode() && e->parentNode()->isElementNode()) {
01245 addDependency(BackwardsStructuralDependency, static_cast<ElementImpl*>(e->parentNode()));
01246 if (!e->parentNode()->closed()) {
01247 return false;
01248 }
01249 DOM::NodeImpl* n = e->previousSibling();
01250 while ( n && !n->isElementNode() )
01251 n = n->previousSibling();
01252 if ( !n ) {
01253 n = e->nextSibling();
01254 while ( n && !n->isElementNode() )
01255 n = n->nextSibling();
01256 if ( !n )
01257 return true;
01258 }
01259 }
01260 break;
01261 }
01262 case CSSSelector::PseudoNthChild: {
01263
01264 if (e->parentNode() && e->parentNode()->isElementNode()) {
01265 addDependency(StructuralDependency, static_cast<ElementImpl*>(e->parentNode()));
01266 int count = 1;
01267 DOM::NodeImpl* n = e->previousSibling();
01268 while ( n ) {
01269 if (n->isElementNode()) count++;
01270 n = n->previousSibling();
01271 }
01272
01273 if (matchNth(count,sel->string_arg.string()))
01274 return true;
01275 }
01276 break;
01277 }
01278 case CSSSelector::PseudoNthLastChild: {
01279 if (e->parentNode() && e->parentNode()->isElementNode()) {
01280 addDependency(BackwardsStructuralDependency, static_cast<ElementImpl*>(e->parentNode()));
01281 if (!e->parentNode()->closed()) {
01282 return false;
01283 }
01284 int count = 1;
01285 DOM::NodeImpl* n = e->nextSibling();
01286 while ( n ) {
01287 if (n->isElementNode()) count++;
01288 n = n->nextSibling();
01289 }
01290
01291 if (matchNth(count,sel->string_arg.string()))
01292 return true;
01293 }
01294 break;
01295 }
01296 case CSSSelector::PseudoFirstOfType: {
01297
01298 if (e->parentNode() && e->parentNode()->isElementNode()) {
01299 addDependency(StructuralDependency, static_cast<ElementImpl*>(e->parentNode()));
01300 const DOMString& type = e->tagName();
01301 DOM::NodeImpl* n = e->previousSibling();
01302 while ( n ) {
01303 if (n->isElementNode())
01304 if (static_cast<ElementImpl*>(n)->tagName() == type) break;
01305 n = n->previousSibling();
01306 }
01307 if ( !n )
01308 return true;
01309 }
01310 break;
01311 }
01312 case CSSSelector::PseudoLastOfType: {
01313
01314 if (e->parentNode() && e->parentNode()->isElementNode()) {
01315 addDependency(BackwardsStructuralDependency, static_cast<ElementImpl*>(e->parentNode()));
01316 if (!e->parentNode()->closed()) {
01317 return false;
01318 }
01319 const DOMString& type = e->tagName();
01320 DOM::NodeImpl* n = e->nextSibling();
01321 while ( n ) {
01322 if (n->isElementNode())
01323 if (static_cast<ElementImpl*>(n)->tagName() == type) break;
01324 n = n->nextSibling();
01325 }
01326 if ( !n )
01327 return true;
01328 }
01329 break;
01330 }
01331 case CSSSelector::PseudoOnlyOfType: {
01332
01333 if (e->parentNode() && e->parentNode()->isElementNode()) {
01334 addDependency(BackwardsStructuralDependency, static_cast<ElementImpl*>(e->parentNode()));
01335 if (!e->parentNode()->closed()) {
01336 return false;
01337 }
01338 const DOMString& type = e->tagName();
01339 DOM::NodeImpl* n = e->previousSibling();
01340 while ( n && !(n->isElementNode() && static_cast<ElementImpl*>(n)->tagName() == type))
01341 n = n->previousSibling();
01342 if ( !n ) {
01343 n = e->nextSibling();
01344 while ( n && !(n->isElementNode() && static_cast<ElementImpl*>(n)->tagName() == type))
01345 n = n->nextSibling();
01346 if ( !n )
01347 return true;
01348 }
01349 }
01350 break;
01351 }
01352 case CSSSelector::PseudoNthOfType: {
01353
01354 if (e->parentNode() && e->parentNode()->isElementNode()) {
01355 addDependency(StructuralDependency, static_cast<ElementImpl*>(e->parentNode()));
01356 int count = 1;
01357 const DOMString& type = e->tagName();
01358 DOM::NodeImpl* n = e->previousSibling();
01359 while ( n ) {
01360 if (n->isElementNode() && static_cast<ElementImpl*>(n)->tagName() == type) count++;
01361 n = n->previousSibling();
01362 }
01363
01364 if (matchNth(count,sel->string_arg.string()))
01365 return true;
01366 }
01367 break;
01368 }
01369 case CSSSelector::PseudoNthLastOfType: {
01370 if (e->parentNode() && e->parentNode()->isElementNode()) {
01371 addDependency(BackwardsStructuralDependency, static_cast<ElementImpl*>(e->parentNode()));
01372 if (!e->parentNode()->closed()) {
01373 return false;
01374 }
01375 int count = 1;
01376 const DOMString& type = e->tagName();
01377 DOM::NodeImpl* n = e->nextSibling();
01378 while ( n ) {
01379 if (n->isElementNode() && static_cast<ElementImpl*>(n)->tagName() == type) count++;
01380 n = n->nextSibling();
01381 }
01382
01383 if (matchNth(count,sel->string_arg.string()))
01384 return true;
01385 }
01386 break;
01387 }
01388 case CSSSelector::PseudoTarget:
01389 if (e == e->getDocument()->getCSSTarget())
01390 return true;
01391 break;
01392 case CSSSelector::PseudoRoot:
01393 if (e == e->getDocument()->documentElement())
01394 return true;
01395 break;
01396 case CSSSelector::PseudoLink:
01397 if (e == element) {
01398
01399 if ( pseudoState == PseudoUnknown )
01400 pseudoState = checkPseudoState( encodedurl, e );
01401 if ( pseudoState == PseudoLink )
01402 return true;
01403 } else
01404 return checkPseudoState( encodedurl, e ) == PseudoLink;
01405 break;
01406 case CSSSelector::PseudoVisited:
01407 if (e == element) {
01408
01409 if ( pseudoState == PseudoUnknown )
01410 pseudoState = checkPseudoState( encodedurl, e );
01411 if ( pseudoState == PseudoVisited )
01412 return true;
01413 } else
01414 return checkPseudoState( encodedurl, e ) == PseudoVisited;
01415 break;
01416 case CSSSelector::PseudoHover: {
01417
01418 if (strictParsing || (sel->tag != anyQName) || isSubSelector || e->isFocusable() ) {
01419 addDependency(HoverDependency, e);
01420
01421 if (e->hovered())
01422 return true;
01423 }
01424 break;
01425 }
01426 case CSSSelector::PseudoActive:
01427
01428 if (strictParsing || (sel->tag != anyQName) || isSubSelector || e->isFocusable()) {
01429 addDependency(ActiveDependency, e);
01430
01431 if (e->active())
01432 return true;
01433 }
01434 break;
01435 case CSSSelector::PseudoFocus:
01436 if (e != element && e->isFocusable()) {
01437
01438 addDependency(OtherStateDependency, e);
01439 }
01440 if (e->focused()) return true;
01441 break;
01442 case CSSSelector::PseudoLang: {
01443
01444 if (e == element) {
01445 e->getDocument()->dynamicDomRestyler().addDependency(ATTR_LANG, PersonalDependency);
01446 e->getDocument()->dynamicDomRestyler().addDependency(ATTR_LANG, AncestorDependency);
01447 }
01448 else if (isAncestor)
01449 e->getDocument()->dynamicDomRestyler().addDependency(ATTR_LANG, AncestorDependency);
01450 else
01451 e->getDocument()->dynamicDomRestyler().addDependency(ATTR_LANG, PredecessorDependency);
01452
01453 DOMString value = e->getAttribute(ATTR_LANG);
01454
01455 NodeImpl *n = e->parent();;
01456 while (n && value.isEmpty()) {
01457 if (n->isElementNode()) {
01458 value = static_cast<ElementImpl*>(n)->getAttribute(ATTR_LANG);
01459 } else
01460 if (n->isDocumentNode()) {
01461 value = static_cast<DocumentImpl*>(n)->contentLanguage();
01462 }
01463 n = n->parent();
01464 }
01465 if (value.isEmpty()) return false;
01466
01467 QString langAttr = value.string();
01468 QString langSel = sel->string_arg.string();
01469
01470 if(langAttr.length() < langSel.length()) return false;
01471
01472 langAttr = langAttr.lower();
01473 langSel = langSel.lower();
01474
01475 return (langAttr == langSel || langAttr.startsWith(langSel+"-"));
01476 }
01477 case CSSSelector::PseudoNot: {
01478
01479 for (CSSSelector* subSel = sel->simpleSelector; subSel;
01480 subSel = subSel->tagHistory) {
01481
01482
01483 if (subSel->simpleSelector)
01484 break;
01485 if (!checkSimpleSelector(subSel, e, isAncestor, true))
01486 return true;
01487 }
01488 break;
01489 }
01490 case CSSSelector::PseudoEnabled: {
01491 if (e->isGenericFormElement()) {
01492 addDependency(OtherStateDependency, e);
01493 HTMLGenericFormElementImpl *form;
01494 form = static_cast<HTMLGenericFormElementImpl*>(e);
01495 return !form->disabled();
01496 }
01497 break;
01498 }
01499 case CSSSelector::PseudoDisabled: {
01500 if (e->isGenericFormElement()) {
01501 addDependency(OtherStateDependency, e);
01502 HTMLGenericFormElementImpl *form;
01503 form = static_cast<HTMLGenericFormElementImpl*>(e);
01504 return form->disabled();
01505 }
01506 break;
01507 }
01508 case CSSSelector::PseudoContains: {
01509 if (e->isHTMLElement()) {
01510 addDependency(BackwardsStructuralDependency, e);
01511 if (!e->closed()) {
01512 return false;
01513 }
01514 HTMLElementImpl *elem;
01515 elem = static_cast<HTMLElementImpl*>(e);
01516 DOMString s = elem->innerText();
01517 QString selStr = sel->string_arg.string();
01518
01519 return s.string().contains(selStr);
01520 }
01521 break;
01522 }
01523 case CSSSelector::PseudoChecked: {
01524 if (e->isHTMLElement() && e->id() == ID_INPUT) {
01525 addDependency(OtherStateDependency, e);
01526 return (static_cast<HTMLInputElementImpl*>(e)->checked());
01527 }
01528 return false;
01529 }
01530 case CSSSelector::PseudoIndeterminate: {
01531 #if 0
01532 if (e->isHTMLElement() && e->id() == ID_INPUT) {
01533 return (static_cast<HTMLInputElementImpl*>(e)->indeterminate() &&
01534 !static_cast<HTMLInputElementImpl*>(e)->checked());
01535 }
01536 return false;
01537 #endif
01538 }
01539 case CSSSelector::PseudoOther:
01540 break;
01541
01542
01543 case CSSSelector::PseudoFirstLine:
01544 case CSSSelector::PseudoFirstLetter:
01545 case CSSSelector::PseudoSelection:
01546 case CSSSelector::PseudoBefore:
01547 case CSSSelector::PseudoAfter:
01548 case CSSSelector::PseudoMarker:
01549 case CSSSelector::PseudoReplaced:
01550
01551 if ( e == element ) {
01552
01553 if (sel->tagHistory && sel->relation == CSSSelector::SubSelector) return false;
01554
01555 assert(dynamicPseudo == RenderStyle::NOPSEUDO);
01556
01557 switch (sel->pseudoType()) {
01558 case CSSSelector::PseudoFirstLine:
01559 dynamicPseudo = RenderStyle::FIRST_LINE;
01560 break;
01561 case CSSSelector::PseudoFirstLetter:
01562 dynamicPseudo = RenderStyle::FIRST_LETTER;
01563 break;
01564 case CSSSelector::PseudoSelection:
01565 dynamicPseudo = RenderStyle::SELECTION;
01566 break;
01567 case CSSSelector::PseudoBefore:
01568 dynamicPseudo = RenderStyle::BEFORE;
01569 break;
01570 case CSSSelector::PseudoAfter:
01571 dynamicPseudo = RenderStyle::AFTER;
01572 break;
01573 case CSSSelector::PseudoMarker:
01574 dynamicPseudo = RenderStyle::MARKER;
01575 break;
01576 case CSSSelector::PseudoReplaced:
01577 dynamicPseudo = RenderStyle::REPLACED;
01578 break;
01579 default:
01580 assert(false);
01581 }
01582 return true;
01583 }
01584 break;
01585 case CSSSelector::PseudoNotParsed:
01586 assert(false);
01587 break;
01588 }
01589 return false;
01590 }
01591
01592 return true;
01593 }
01594
01595 void CSSStyleSelector::clearLists()
01596 {
01597 delete [] selectors;
01598 if ( selectorCache ) {
01599 for ( unsigned int i = 0; i < selectors_size; i++ )
01600 delete [] selectorCache[i].props;
01601
01602 delete [] selectorCache;
01603 }
01604 if ( properties ) {
01605 CSSOrderedProperty **prop = properties;
01606 while ( *prop ) {
01607 delete (*prop);
01608 prop++;
01609 }
01610 delete [] properties;
01611 }
01612 selectors = 0;
01613 properties = 0;
01614 selectorCache = 0;
01615 }
01616
01617
01618 void CSSStyleSelector::buildLists()
01619 {
01620 clearLists();
01621
01622
01623 QPtrList<CSSSelector> selectorList;
01624 CSSOrderedPropertyList propertyList;
01625
01626 if(m_medium == "print" && defaultPrintStyle)
01627 defaultPrintStyle->collect( &selectorList, &propertyList, Default,
01628 Default );
01629 else if(defaultStyle) defaultStyle->collect( &selectorList, &propertyList,
01630 Default, Default );
01631
01632 if (!strictParsing && defaultQuirksStyle)
01633 defaultQuirksStyle->collect( &selectorList, &propertyList, Default, Default );
01634
01635 if(userStyle) userStyle->collect(&selectorList, &propertyList, User, UserImportant );
01636 if(authorStyle) authorStyle->collect(&selectorList, &propertyList, Author, AuthorImportant );
01637
01638 selectors_size = selectorList.count();
01639 selectors = new CSSSelector *[selectors_size];
01640 CSSSelector *s = selectorList.first();
01641 CSSSelector **sel = selectors;
01642 while ( s ) {
01643 *sel = s;
01644 s = selectorList.next();
01645 ++sel;
01646 }
01647
01648 selectorCache = new SelectorCache[selectors_size];
01649 for ( unsigned int i = 0; i < selectors_size; i++ ) {
01650 selectorCache[i].state = Unknown;
01651 selectorCache[i].props_size = 0;
01652 selectorCache[i].props = 0;
01653 }
01654
01655
01656 propertyList.sort();
01657 properties_size = propertyList.count() + 1;
01658 properties = new CSSOrderedProperty *[ properties_size ];
01659 CSSOrderedProperty *p = propertyList.first();
01660 CSSOrderedProperty **prop = properties;
01661 while ( p ) {
01662 *prop = p;
01663 p = propertyList.next();
01664 ++prop;
01665 }
01666 *prop = 0;
01667
01668 unsigned int* offsets = new unsigned int[selectors_size];
01669 if(properties[0])
01670 offsets[properties[0]->selector] = 0;
01671 for(unsigned int p = 1; p < properties_size; ++p) {
01672
01673 if(!properties[p] || (properties[p]->selector != properties[p - 1]->selector)) {
01674 unsigned int sel = properties[p - 1]->selector;
01675 int* newprops = new int[selectorCache[sel].props_size+2];
01676 for ( unsigned int i=0; i < selectorCache[sel].props_size; i++ )
01677 newprops[i] = selectorCache[sel].props[i];
01678
01679 newprops[selectorCache[sel].props_size] = offsets[sel];
01680 newprops[selectorCache[sel].props_size+1] = p - offsets[sel];
01681 delete [] selectorCache[sel].props;
01682 selectorCache[sel].props = newprops;
01683 selectorCache[sel].props_size += 2;
01684
01685 if(properties[p]) {
01686 sel = properties[p]->selector;
01687 offsets[sel] = p;
01688 }
01689 }
01690 }
01691 delete [] offsets;
01692 }
01693
01694
01695
01696
01697
01698 CSSOrderedRule::CSSOrderedRule(DOM::CSSStyleRuleImpl *r, DOM::CSSSelector *s, int _index)
01699 {
01700 rule = r;
01701 if(rule) r->ref();
01702 index = _index;
01703 selector = s;
01704 }
01705
01706 CSSOrderedRule::~CSSOrderedRule()
01707 {
01708 if(rule) rule->deref();
01709 }
01710
01711
01712
01713 CSSStyleSelectorList::CSSStyleSelectorList()
01714 : QPtrList<CSSOrderedRule>()
01715 {
01716 setAutoDelete(true);
01717 }
01718 CSSStyleSelectorList::~CSSStyleSelectorList()
01719 {
01720 }
01721
01722 void CSSStyleSelectorList::append( CSSStyleSheetImpl *sheet,
01723 const DOMString &medium )
01724 {
01725 if(!sheet || !sheet->isCSSStyleSheet()) return;
01726
01727
01728
01729 if( sheet->media() && !sheet->media()->contains( medium ) )
01730 return;
01731
01732 int len = sheet->length();
01733
01734 for(int i = 0; i< len; i++)
01735 {
01736 StyleBaseImpl *item = sheet->item(i);
01737 if(item->isStyleRule())
01738 {
01739 CSSStyleRuleImpl *r = static_cast<CSSStyleRuleImpl *>(item);
01740 QPtrList<CSSSelector> *s = r->selector();
01741 for(int j = 0; j < (int)s->count(); j++)
01742 {
01743 CSSOrderedRule *rule = new CSSOrderedRule(r, s->at(j), count());
01744 QPtrList<CSSOrderedRule>::append(rule);
01745
01746 }
01747 }
01748 else if(item->isImportRule())
01749 {
01750 CSSImportRuleImpl *import = static_cast<CSSImportRuleImpl *>(item);
01751
01752
01753
01754
01755 if( !import->media() || import->media()->contains( medium ) )
01756 {
01757 CSSStyleSheetImpl *importedSheet = import->styleSheet();
01758 append( importedSheet, medium );
01759 }
01760 }
01761 else if( item->isMediaRule() )
01762 {
01763 CSSMediaRuleImpl *r = static_cast<CSSMediaRuleImpl *>( item );
01764 CSSRuleListImpl *rules = r->cssRules();
01765
01766
01767
01768
01769
01770 if( ( !r->media() || r->media()->contains( medium ) ) && rules)
01771 {
01772
01773
01774
01775 for( unsigned j = 0; j < rules->length(); j++ )
01776 {
01777
01778
01779 CSSRuleImpl *childItem = rules->item( j );
01780 if( childItem->isStyleRule() )
01781 {
01782
01783 CSSStyleRuleImpl *styleRule =
01784 static_cast<CSSStyleRuleImpl *>( childItem );
01785
01786 QPtrList<CSSSelector> *s = styleRule->selector();
01787 for( int j = 0; j < ( int ) s->count(); j++ )
01788 {
01789 CSSOrderedRule *orderedRule = new CSSOrderedRule(
01790 styleRule, s->at( j ), count() );
01791 QPtrList<CSSOrderedRule>::append( orderedRule );
01792 }
01793 }
01794 else
01795 {
01796
01797
01798 }
01799 }
01800 }
01801 else
01802 {
01803
01804
01805 }
01806 }
01807
01808 }
01809 }
01810
01811
01812 void CSSStyleSelectorList::collect( QPtrList<CSSSelector> *selectorList, CSSOrderedPropertyList *propList,
01813 Source regular, Source important )
01814 {
01815 CSSOrderedRule *r = first();
01816 while( r ) {
01817 CSSSelector *sel = selectorList->first();
01818 int selectorNum = 0;
01819 while( sel ) {
01820 if ( *sel == *(r->selector) )
01821 break;
01822 sel = selectorList->next();
01823 selectorNum++;
01824 }
01825 if ( !sel )
01826 selectorList->append( r->selector );
01827
01828
01829 propList->append(r->rule->declaration(), selectorNum, r->selector->specificity(), regular, important );
01830 r = next();
01831 }
01832 }
01833
01834
01835
01836 int CSSOrderedPropertyList::compareItems(QPtrCollection::Item i1, QPtrCollection::Item i2)
01837 {
01838 int diff = static_cast<CSSOrderedProperty *>(i1)->priority
01839 - static_cast<CSSOrderedProperty *>(i2)->priority;
01840 return diff ? diff : static_cast<CSSOrderedProperty *>(i1)->position
01841 - static_cast<CSSOrderedProperty *>(i2)->position;
01842 }
01843
01844 void CSSOrderedPropertyList::append(DOM::CSSStyleDeclarationImpl *decl, uint selector, uint specificity,
01845 Source regular, Source important )
01846 {
01847 QPtrList<CSSProperty> *values = decl->values();
01848 if(!values) return;
01849 int len = values->count();
01850 for(int i = 0; i < len; i++)
01851 {
01852 CSSProperty *prop = values->at(i);
01853 Source source = regular;
01854
01855 if( prop->m_important ) source = important;
01856 if( prop->nonCSSHint ) source = NonCSSHint;
01857
01858 bool first = false;
01859
01860 switch(prop->m_id)
01861 {
01862 case CSS_PROP_FONT_STYLE:
01863 case CSS_PROP_FONT_SIZE:
01864 case CSS_PROP_FONT_WEIGHT:
01865 case CSS_PROP_FONT_FAMILY:
01866 case CSS_PROP_FONT_VARIANT:
01867 case CSS_PROP_FONT:
01868 case CSS_PROP_COLOR:
01869 case CSS_PROP_DIRECTION:
01870 case CSS_PROP_DISPLAY:
01871
01872
01873 first = true;
01874 break;
01875 default:
01876 break;
01877 }
01878
01879 QPtrList<CSSOrderedProperty>::append(new CSSOrderedProperty(prop, selector,
01880 first, source, specificity,
01881 count() ));
01882 }
01883 }
01884
01885
01886
01887
01888 static Length convertToLength( CSSPrimitiveValueImpl *primitiveValue, RenderStyle *style, QPaintDeviceMetrics *paintDeviceMetrics, bool *ok = 0 )
01889 {
01890 Length l;
01891 if ( !primitiveValue ) {
01892 if ( ok )
01893 *ok = false;
01894 } else {
01895 int type = primitiveValue->primitiveType();
01896 if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
01897 l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
01898 else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
01899 l = Length(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE)), Percent);
01900 else if(type == CSSPrimitiveValue::CSS_NUMBER)
01901 l = Length(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER)*100), Percent);
01902 else if (type == CSSPrimitiveValue::CSS_HTML_RELATIVE)
01903 l = Length(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_HTML_RELATIVE)), Relative);
01904 else if ( ok )
01905 *ok = false;
01906 }
01907 return l;
01908 }
01909
01910
01911
01912 struct colorMap {
01913 int css_value;
01914 QRgb color;
01915 };
01916
01917 static const colorMap cmap[] = {
01918 { CSS_VAL_AQUA, 0xFF00FFFF },
01919 { CSS_VAL_BLACK, 0xFF000000 },
01920 { CSS_VAL_BLUE, 0xFF0000FF },
01921 { CSS_VAL_CRIMSON, 0xFFDC143C },
01922 { CSS_VAL_FUCHSIA, 0xFFFF00FF },
01923 { CSS_VAL_GRAY, 0xFF808080 },
01924 { CSS_VAL_GREEN, 0xFF008000 },
01925 { CSS_VAL_INDIGO, 0xFF4B0082 },
01926 { CSS_VAL_LIME, 0xFF00FF00 },
01927 { CSS_VAL_MAROON, 0xFF800000 },
01928 { CSS_VAL_NAVY, 0xFF000080 },
01929 { CSS_VAL_OLIVE, 0xFF808000 },
01930 { CSS_VAL_ORANGE, 0xFFFFA500 },
01931 { CSS_VAL_PURPLE, 0xFF800080 },
01932 { CSS_VAL_RED, 0xFFFF0000 },
01933 { CSS_VAL_SILVER, 0xFFC0C0C0 },
01934 { CSS_VAL_TEAL, 0xFF008080 },
01935 { CSS_VAL_WHITE, 0xFFFFFFFF },
01936 { CSS_VAL_YELLOW, 0xFFFFFF00 },
01937 { CSS_VAL_INVERT, invertedColor },
01938 { CSS_VAL_TRANSPARENT, transparentColor },
01939 { CSS_VAL_GREY, 0xff808080 },
01940 { 0, 0 }
01941 };
01942
01943 struct uiColors {
01944 int css_value;
01945 const char * configGroup;
01946 const char * configEntry;
01947 QPalette::ColorGroup group;
01948 QColorGroup::ColorRole role;
01949 };
01950
01951 const char * const wmgroup = "WM";
01952 const char * const generalgroup = "General";
01953
01954
01955
01956
01957 static const uiColors uimap[] = {
01958
01959 { CSS_VAL_ACTIVEBORDER, wmgroup, "background", QPalette::Active, QColorGroup::Light },
01960
01961 { CSS_VAL_ACTIVECAPTION, wmgroup, "background", QPalette::Active, QColorGroup::Text },
01962
01963 { CSS_VAL_CAPTIONTEXT, wmgroup, "activeForeground", QPalette::Active, QColorGroup::Text },
01964
01965 { CSS_VAL_BUTTONFACE, wmgroup, 0, QPalette::Inactive, QColorGroup::Button },
01966
01967 { CSS_VAL_BUTTONHIGHLIGHT, wmgroup, 0, QPalette::Inactive, QColorGroup::Light },
01968
01969 { CSS_VAL_BUTTONSHADOW, wmgroup, 0, QPalette::Inactive, QColorGroup::Shadow },
01970
01971 { CSS_VAL_BUTTONTEXT, wmgroup, "buttonForeground", QPalette::Inactive, QColorGroup::ButtonText },
01972
01973 { CSS_VAL_THREEDDARKSHADOW, wmgroup, 0, QPalette::Inactive, QColorGroup::Dark },
01974
01975 { CSS_VAL_THREEDFACE, wmgroup, 0, QPalette::Inactive, QColorGroup::Button },
01976
01977 { CSS_VAL_THREEDHIGHLIGHT, wmgroup, 0, QPalette::Inactive, QColorGroup::Light },
01978
01979 { CSS_VAL_THREEDLIGHTSHADOW, wmgroup, 0, QPalette::Inactive, QColorGroup::Midlight },
01980
01981 { CSS_VAL_THREEDSHADOW, wmgroup, 0, QPalette::Inactive, QColorGroup::Shadow },
01982
01983
01984 { CSS_VAL_INACTIVEBORDER, wmgroup, "background", QPalette::Disabled, QColorGroup::Background },
01985
01986 { CSS_VAL_INACTIVECAPTION, wmgroup, "inactiveBackground", QPalette::Disabled, QColorGroup::Background },
01987
01988 { CSS_VAL_INACTIVECAPTIONTEXT, wmgroup, "inactiveForeground", QPalette::Disabled, QColorGroup::Text },
01989 { CSS_VAL_GRAYTEXT, wmgroup, 0, QPalette::Disabled, QColorGroup::Text },
01990
01991
01992 { CSS_VAL_MENU, generalgroup, "background", QPalette::Inactive, QColorGroup::Background },
01993
01994 { CSS_VAL_MENUTEXT, generalgroup, "foreground", QPalette::Inactive, QColorGroup::Background },
01995
01996
01997 { CSS_VAL_HIGHLIGHT, generalgroup, "selectBackground", QPalette::Inactive, QColorGroup::Background },
01998
01999
02000 { CSS_VAL_HIGHLIGHTTEXT, generalgroup, "selectForeground", QPalette::Inactive, QColorGroup::Background },
02001
02002
02003 { CSS_VAL_APPWORKSPACE, generalgroup, "background", QPalette::Inactive, QColorGroup::Text },
02004
02005
02006 { CSS_VAL_SCROLLBAR, generalgroup, "background", QPalette::Inactive, QColorGroup::Background },
02007
02008
02009 { CSS_VAL_WINDOW, generalgroup, "windowBackground", QPalette::Inactive, QColorGroup::Background },
02010
02011 { CSS_VAL_WINDOWFRAME, generalgroup, "windowBackground", QPalette::Inactive, QColorGroup::Background },
02012
02013 { CSS_VAL_WINDOWTEXT, generalgroup, "windowForeground", QPalette::Inactive, QColorGroup::Text },
02014 { CSS_VAL_TEXT, generalgroup, 0, QPalette::Inactive, QColorGroup::Text },
02015 { 0, 0, 0, QPalette::NColorGroups, QColorGroup::NColorRoles }
02016 };
02017
02018 static QColor colorForCSSValue( int css_value )
02019 {
02020
02021 const colorMap *col = cmap;
02022 while ( col->css_value && col->css_value != css_value )
02023 ++col;
02024 if ( col->css_value )
02025 return col->color;
02026
02027 const uiColors *uicol = uimap;
02028 while ( uicol->css_value && uicol->css_value != css_value )
02029 ++uicol;
02030 #ifndef APPLE_CHANGES
02031 if ( !uicol->css_value ) {
02032 if ( css_value == CSS_VAL_INFOBACKGROUND )
02033 return QToolTip::palette().inactive().background();
02034 else if ( css_value == CSS_VAL_INFOTEXT )
02035 return QToolTip::palette().inactive().foreground();
02036 else if ( css_value == CSS_VAL_BACKGROUND ) {
02037 KConfig bckgrConfig("kdesktoprc", true, false);
02038 bckgrConfig.setGroup("Desktop0");
02039
02040 return bckgrConfig.readColorEntry("Color1", &qApp->palette().disabled().background());
02041 }
02042 return QColor();
02043 }
02044 #endif
02045
02046 const QPalette &pal = qApp->palette();
02047 QColor c = pal.color( uicol->group, uicol->role );
02048 #ifndef APPLE_CHANGES
02049 if ( uicol->configEntry ) {
02050 KConfig *globalConfig = KGlobal::config();
02051 globalConfig->setGroup( uicol->configGroup );
02052 c = globalConfig->readColorEntry( uicol->configEntry, &c );
02053 }
02054 #endif
02055
02056 return c;
02057 }
02058
02059 static inline int nextFontSize(const QValueVector<int>& a, int v, bool smaller)
02060 {
02061
02062
02063 int m, l = 0, r = a.count()-1;
02064 while (l <= r) {
02065 m = (l+r)/2;
02066 if (a[m] == v)
02067 return smaller ? ( m ? a[m-1] : (v*5)/6 ) :
02068 ( m+1<int(a.count()) ? a[m+1] : (v*6)/5 );
02069 else if (v < a[m])
02070 r = m-1;
02071 else
02072 l = m+1;
02073 }
02074 if (!l)
02075 return smaller ? (v*5)/6 : kMin((v*6)/5, a[0]);
02076 if (l == int(a.count()))
02077 return smaller ? kMax((v*5)/6, a[r]) : (v*6)/5;
02078
02079 return smaller ? a[r] : a[l];
02080 }
02081
02082 void CSSStyleSelector::applyRule( int id, DOM::CSSValueImpl *value )
02083 {
02084
02085
02086 CSSPrimitiveValueImpl *primitiveValue = 0;
02087 if(value->isPrimitiveValue()) primitiveValue = static_cast<CSSPrimitiveValueImpl *>(value);
02088
02089 Length l;
02090 bool apply = false;
02091
02092 bool isInherit = (parentNode && value->cssValueType() == CSSValue::CSS_INHERIT);
02093 bool isInitial = (value->cssValueType() == CSSValue::CSS_INITIAL) ||
02094 (!parentNode && value->cssValueType() == CSSValue::CSS_INHERIT);
02095
02096
02097 if (id == CSS_PROP__KHTML_MARGIN_START)
02098 id = style->direction() == LTR ? CSS_PROP_MARGIN_LEFT : CSS_PROP_MARGIN_RIGHT;
02099 else if (id == CSS_PROP__KHTML_PADDING_START)
02100 id = style->direction() == LTR ? CSS_PROP_PADDING_LEFT : CSS_PROP_PADDING_RIGHT;
02101
02102
02103
02104
02105 switch(id)
02106 {
02107
02108 case CSS_PROP_BACKGROUND_ATTACHMENT:
02109 HANDLE_BACKGROUND_VALUE(backgroundAttachment, BackgroundAttachment, value)
02110 break;
02111 case CSS_PROP__KHTML_BACKGROUND_CLIP:
02112 HANDLE_BACKGROUND_VALUE(backgroundClip, BackgroundClip, value)
02113 break;
02114 case CSS_PROP__KHTML_BACKGROUND_ORIGIN:
02115 HANDLE_BACKGROUND_VALUE(backgroundOrigin, BackgroundOrigin, value)
02116 break;
02117 case CSS_PROP_BACKGROUND_REPEAT:
02118 HANDLE_BACKGROUND_VALUE(backgroundRepeat, BackgroundRepeat, value)
02119 break;
02120 case CSS_PROP__KHTML_BACKGROUND_SIZE:
02121 HANDLE_BACKGROUND_VALUE(backgroundSize, BackgroundSize, value)
02122 break;
02123 case CSS_PROP_BORDER_COLLAPSE:
02124 HANDLE_INHERIT_AND_INITIAL(borderCollapse, BorderCollapse)
02125 if(!primitiveValue) break;
02126 switch(primitiveValue->getIdent())
02127 {
02128 case CSS_VAL_COLLAPSE:
02129 style->setBorderCollapse(true);
02130 break;
02131 case CSS_VAL_SEPARATE:
02132 style->setBorderCollapse(false);
02133 break;
02134 default:
02135 return;
02136 }
02137 break;
02138
02139 case CSS_PROP_BORDER_TOP_STYLE:
02140 HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderTopStyle, BorderTopStyle, BorderStyle)
02141 if (!primitiveValue) return;
02142 style->setBorderTopStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL__KHTML_NATIVE));
02143 break;
02144 case CSS_PROP_BORDER_RIGHT_STYLE:
02145 HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderRightStyle, BorderRightStyle, BorderStyle)
02146 if (!primitiveValue) return;
02147 style->setBorderRightStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL__KHTML_NATIVE));
02148 break;
02149 case CSS_PROP_BORDER_BOTTOM_STYLE:
02150 HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderBottomStyle, BorderBottomStyle, BorderStyle)
02151 if (!primitiveValue) return;
02152 style->setBorderBottomStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL__KHTML_NATIVE));
02153 break;
02154 case CSS_PROP_BORDER_LEFT_STYLE:
02155 HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderLeftStyle, BorderLeftStyle, BorderStyle)
02156 if (!primitiveValue) return;
02157 style->setBorderLeftStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL__KHTML_NATIVE));
02158 break;
02159 case CSS_PROP_OUTLINE_STYLE:
02160 HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(outlineStyle, OutlineStyle, BorderStyle)
02161 if (!primitiveValue) return;
02162 style->setOutlineStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL__KHTML_NATIVE));
02163 break;
02164 case CSS_PROP_CAPTION_SIDE:
02165 {
02166 HANDLE_INHERIT_AND_INITIAL(captionSide, CaptionSide)
02167 if(!primitiveValue) break;
02168 ECaptionSide c = RenderStyle::initialCaptionSide();
02169 switch(primitiveValue->getIdent())
02170 {
02171 case CSS_VAL_LEFT:
02172 c = CAPLEFT; break;
02173 case CSS_VAL_RIGHT:
02174 c = CAPRIGHT; break;
02175 case CSS_VAL_TOP:
02176 c = CAPTOP; break;
02177 case CSS_VAL_BOTTOM:
02178 c = CAPBOTTOM; break;
02179 default:
02180 return;
02181 }
02182 style->setCaptionSide(c);
02183 return;
02184 }
02185 case CSS_PROP_CLEAR:
02186 {
02187 HANDLE_INHERIT_AND_INITIAL(clear, Clear)
02188 if(!primitiveValue) break;
02189 EClear c = CNONE;
02190 switch(primitiveValue->getIdent())
02191 {
02192 case CSS_VAL_LEFT:
02193 c = CLEFT; break;
02194 case CSS_VAL_RIGHT:
02195 c = CRIGHT; break;
02196 case CSS_VAL_BOTH:
02197 c = CBOTH; break;
02198 case CSS_VAL_NONE:
02199 c = CNONE; break;
02200 default:
02201 return;
02202 }
02203 style->setClear(c);
02204 return;
02205 }
02206 case CSS_PROP_DIRECTION:
02207 {
02208 HANDLE_INHERIT_AND_INITIAL(direction, Direction)
02209 if(!primitiveValue) break;
02210 style->setDirection( (EDirection) (primitiveValue->getIdent() - CSS_VAL_LTR) );
02211 return;
02212 }
02213 case CSS_PROP_DISPLAY:
02214 {
02215 HANDLE_INHERIT_AND_INITIAL(display, Display)
02216 if(!primitiveValue) break;
02217 int id = primitiveValue->getIdent();
02218 style->setDisplay( id == CSS_VAL_NONE ? NONE : EDisplay(id - CSS_VAL_INLINE) );
02219 break;
02220 }
02221
02222 case CSS_PROP_EMPTY_CELLS:
02223 {
02224 HANDLE_INHERIT(emptyCells, EmptyCells);
02225 if (!primitiveValue) break;
02226 int id = primitiveValue->getIdent();
02227 if (id == CSS_VAL_SHOW)
02228 style->setEmptyCells(SHOW);
02229 else if (id == CSS_VAL_HIDE)
02230 style->setEmptyCells(HIDE);
02231 break;
02232 }
02233 case CSS_PROP_FLOAT:
02234 {
02235 HANDLE_INHERIT_AND_INITIAL(floating, Floating)
02236 if(!primitiveValue) return;
02237 EFloat f;
02238 switch(primitiveValue->getIdent())
02239 {
02240 case CSS_VAL__KHTML_LEFT:
02241 f = FLEFT_ALIGN; break;
02242 case CSS_VAL_LEFT:
02243 f = FLEFT; break;
02244 case CSS_VAL__KHTML_RIGHT:
02245 f = FRIGHT_ALIGN; break;
02246 case CSS_VAL_RIGHT:
02247 f = FRIGHT; break;
02248 case CSS_VAL_NONE:
02249 case CSS_VAL_CENTER:
02250 f = FNONE; break;
02251 default:
02252 return;
02253 }
02254 if (f!=FNONE && style->display()==LIST_ITEM)
02255 style->setDisplay(BLOCK);
02256
02257 style->setFloating(f);
02258 break;
02259 }
02260
02261 case CSS_PROP_FONT_STYLE:
02262 {
02263 FontDef fontDef = style->htmlFont().fontDef;
02264 if (isInherit)
02265 fontDef.italic = parentStyle->htmlFont().fontDef.italic;
02266 else if (isInitial)
02267 fontDef.italic = false;
02268 else {
02269 if(!primitiveValue) return;
02270 switch(primitiveValue->getIdent()) {
02271 case CSS_VAL_OBLIQUE:
02272
02273 case CSS_VAL_ITALIC:
02274 fontDef.italic = true;
02275 break;
02276 case CSS_VAL_NORMAL:
02277 fontDef.italic = false;
02278 break;
02279 default:
02280 return;
02281 }
02282 }
02283 fontDirty |= style->setFontDef( fontDef );
02284 break;
02285 }
02286
02287
02288 case CSS_PROP_FONT_VARIANT:
02289 {
02290 FontDef fontDef = style->htmlFont().fontDef;
02291 if (isInherit)
02292 fontDef.smallCaps = parentStyle->htmlFont().fontDef.weight;
02293 else if (isInitial)
02294 fontDef.smallCaps = false;
02295 else {
02296 if(!primitiveValue) return;
02297 int id = primitiveValue->getIdent();
02298 if ( id == CSS_VAL_NORMAL )
02299 fontDef.smallCaps = false;
02300 else if ( id == CSS_VAL_SMALL_CAPS )
02301 fontDef.smallCaps = true;
02302 else
02303 return;
02304 }
02305 fontDirty |= style->setFontDef( fontDef );
02306 break;
02307 }
02308
02309 case CSS_PROP_FONT_WEIGHT:
02310 {
02311 FontDef fontDef = style->htmlFont().fontDef;
02312 if (isInherit)
02313 fontDef.weight = parentStyle->htmlFont().fontDef.weight;
02314 else if (isInitial)
02315 fontDef.weight = QFont::Normal;
02316 else {
02317 if(!primitiveValue) return;
02318 if(primitiveValue->getIdent())
02319 {
02320 switch(primitiveValue->getIdent()) {
02321
02322
02323 case CSS_VAL_BOLD:
02324 case CSS_VAL_BOLDER:
02325 case CSS_VAL_600:
02326 case CSS_VAL_700:
02327 case CSS_VAL_800:
02328 case CSS_VAL_900:
02329 fontDef.weight = QFont::Bold;
02330 break;
02331 case CSS_VAL_NORMAL:
02332 case CSS_VAL_LIGHTER:
02333 case CSS_VAL_100:
02334 case CSS_VAL_200:
02335 case CSS_VAL_300:
02336 case CSS_VAL_400:
02337 case CSS_VAL_500:
02338 fontDef.weight = QFont::Normal;
02339 break;
02340 default:
02341 return;
02342 }
02343 }
02344 else
02345 {
02346
02347 }
02348 }
02349 fontDirty |= style->setFontDef( fontDef );
02350 break;
02351 }
02352
02353 case CSS_PROP_LIST_STYLE_POSITION:
02354 {
02355 HANDLE_INHERIT_AND_INITIAL(listStylePosition, ListStylePosition)
02356 if (!primitiveValue) return;
02357 if (primitiveValue->getIdent())
02358 style->setListStylePosition( (EListStylePosition) (primitiveValue->getIdent() - CSS_VAL_OUTSIDE) );
02359 return;
02360 }
02361
02362 case CSS_PROP_LIST_STYLE_TYPE:
02363 {
02364 HANDLE_INHERIT_AND_INITIAL(listStyleType, ListStyleType)
02365 if (!primitiveValue) return;
02366 if (primitiveValue->getIdent())
02367 {
02368 EListStyleType t;
02369 int id = primitiveValue->getIdent();
02370 if ( id == CSS_VAL_NONE) {
02371 t = LNONE;
02372 } else {
02373 t = EListStyleType(id - CSS_VAL_DISC);
02374 }
02375 style->setListStyleType(t);
02376 }
02377 return;
02378 }
02379
02380 case CSS_PROP_OVERFLOW:
02381 {
02382 HANDLE_INHERIT_AND_INITIAL(overflow, Overflow)
02383 if (!primitiveValue) return;
02384 EOverflow o;
02385 switch(primitiveValue->getIdent())
02386 {
02387 case CSS_VAL_VISIBLE:
02388 o = OVISIBLE; break;
02389 case CSS_VAL_HIDDEN:
02390 o = OHIDDEN; break;
02391 case CSS_VAL_SCROLL:
02392 o = OSCROLL; break;
02393 case CSS_VAL_AUTO:
02394 o = OAUTO; break;
02395 case CSS_VAL_MARQUEE:
02396 o = OMARQUEE; break;
02397 default:
02398 return;
02399 }
02400 style->setOverflow(o);
02401 return;
02402 }
02403 break;
02404 case CSS_PROP_PAGE_BREAK_BEFORE:
02405 {
02406 HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(pageBreakBefore, PageBreakBefore, PageBreak)
02407 if (!primitiveValue) return;
02408 switch (primitiveValue->getIdent()) {
02409 case CSS_VAL_AUTO:
02410 style->setPageBreakBefore(PBAUTO);
02411 break;
02412 case CSS_VAL_LEFT:
02413 case CSS_VAL_RIGHT:
02414
02415 case CSS_VAL_ALWAYS:
02416 style->setPageBreakBefore(PBALWAYS);
02417 break;
02418 case CSS_VAL_AVOID:
02419 style->setPageBreakBefore(PBAVOID);
02420 break;
02421 }
02422 break;
02423 }
02424
02425 case CSS_PROP_PAGE_BREAK_AFTER:
02426 {
02427 HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(pageBreakAfter, PageBreakAfter, PageBreak)
02428 if (!primitiveValue) return;
02429 switch (primitiveValue->getIdent()) {
02430 case CSS_VAL_AUTO:
02431 style->setPageBreakAfter(PBAUTO);
02432 break;
02433 case CSS_VAL_LEFT:
02434 case CSS_VAL_RIGHT:
02435
02436 case CSS_VAL_ALWAYS:
02437 style->setPageBreakAfter(PBALWAYS);
02438 break;
02439 case CSS_VAL_AVOID:
02440 style->setPageBreakAfter(PBAVOID);
02441 break;
02442 }
02443 break;
02444 }
02445
02446 case CSS_PROP_PAGE_BREAK_INSIDE: {
02447 HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(pageBreakInside, PageBreakInside, PageBreak)
02448 if (!primitiveValue) return;
02449 if (primitiveValue->getIdent() == CSS_VAL_AUTO)
02450 style->setPageBreakInside(true);
02451 else if (primitiveValue->getIdent() == CSS_VAL_AVOID)
02452 style->setPageBreakInside(false);
02453 return;
02454 }
02455
02456
02457 break;
02458
02459 case CSS_PROP_POSITION:
02460 {
02461 HANDLE_INHERIT_AND_INITIAL(position, Position)
02462 if (!primitiveValue) return;
02463 EPosition p;
02464 switch(primitiveValue->getIdent())
02465 {
02466 case CSS_VAL_STATIC:
02467 p = STATIC; break;
02468 case CSS_VAL_RELATIVE:
02469 p = RELATIVE; break;
02470 case CSS_VAL_ABSOLUTE:
02471 p = ABSOLUTE; break;
02472 case CSS_VAL_FIXED:
02473 {
02474 view->useSlowRepaints();
02475 p = FIXED;
02476 break;
02477 }
02478 default:
02479 return;
02480 }
02481 style->setPosition(p);
02482 return;
02483 }
02484
02485 case CSS_PROP_TABLE_LAYOUT: {
02486 HANDLE_INHERIT_AND_INITIAL(tableLayout, TableLayout)
02487
02488 if ( !primitiveValue )
02489 return;
02490
02491 ETableLayout l = RenderStyle::initialTableLayout();
02492 switch( primitiveValue->getIdent() ) {
02493 case CSS_VAL_FIXED:
02494 l = TFIXED;
02495
02496 case CSS_VAL_AUTO:
02497 style->setTableLayout( l );
02498 default:
02499 break;
02500 }
02501 break;
02502 }
02503
02504 case CSS_PROP_UNICODE_BIDI: {
02505 HANDLE_INHERIT_AND_INITIAL(unicodeBidi, UnicodeBidi)
02506 if(!primitiveValue) break;
02507 switch (primitiveValue->getIdent()) {
02508 case CSS_VAL_NORMAL:
02509 style->setUnicodeBidi(UBNormal);
02510 break;
02511 case CSS_VAL_EMBED:
02512 style->setUnicodeBidi(Embed);
02513 break;
02514 case CSS_VAL_BIDI_OVERRIDE:
02515 style->setUnicodeBidi(Override);
02516 break;
02517 default:
02518 return;
02519 }
02520 break;
02521 }
02522 case CSS_PROP_TEXT_TRANSFORM: {
02523 HANDLE_INHERIT_AND_INITIAL(textTransform, TextTransform)
02524
02525 if(!primitiveValue) break;
02526 if(!primitiveValue->getIdent()) return;
02527
02528 ETextTransform tt;
02529 switch(primitiveValue->getIdent()) {
02530 case CSS_VAL_CAPITALIZE: tt = CAPITALIZE; break;
02531 case CSS_VAL_UPPERCASE: tt = UPPERCASE; break;
02532 case CSS_VAL_LOWERCASE: tt = LOWERCASE; break;
02533 case CSS_VAL_NONE:
02534 default: tt = TTNONE; break;
02535 }
02536 style->setTextTransform(tt);
02537 break;
02538 }
02539
02540 case CSS_PROP_VISIBILITY:
02541 {
02542 HANDLE_INHERIT_AND_INITIAL(visibility, Visibility)
02543
02544 if(!primitiveValue) break;
02545 switch( primitiveValue->getIdent() ) {
02546 case CSS_VAL_HIDDEN:
02547 style->setVisibility( HIDDEN );
02548 break;
02549 case CSS_VAL_VISIBLE:
02550 style->setVisibility( VISIBLE );
02551 break;
02552 case CSS_VAL_COLLAPSE:
02553 style->setVisibility( COLLAPSE );
02554 default:
02555 break;
02556 }
02557 break;
02558 }
02559 case CSS_PROP_WHITE_SPACE:
02560 HANDLE_INHERIT_AND_INITIAL(whiteSpace, WhiteSpace)
02561
02562 if(!primitiveValue) break;
02563 if(!primitiveValue->getIdent()) return;
02564
02565 EWhiteSpace s;
02566 switch(primitiveValue->getIdent()) {
02567 case CSS_VAL__KHTML_NOWRAP:
02568 s = KHTML_NOWRAP;
02569 break;
02570 case CSS_VAL_NOWRAP:
02571 s = NOWRAP;
02572 break;
02573 case CSS_VAL_PRE:
02574 s = PRE;
02575 break;
02576 case CSS_VAL_PRE_WRAP:
02577 s = PRE_WRAP;
02578 break;
02579 case CSS_VAL_PRE_LINE:
02580 s = PRE_LINE;
02581 break;
02582 case CSS_VAL_NORMAL:
02583 default:
02584 s = NORMAL;
02585 break;
02586 }
02587 style->setWhiteSpace(s);
02588 break;
02589
02590 case CSS_PROP_BACKGROUND_POSITION:
02591 HANDLE_BACKGROUND_INHERIT_AND_INITIAL(backgroundXPosition, BackgroundXPosition);
02592 HANDLE_BACKGROUND_INHERIT_AND_INITIAL(backgroundYPosition, BackgroundYPosition);
02593 break;
02594 case CSS_PROP_BACKGROUND_POSITION_X: {
02595 HANDLE_BACKGROUND_VALUE(backgroundXPosition, BackgroundXPosition, value)
02596 break;
02597 }
02598 case CSS_PROP_BACKGROUND_POSITION_Y: {
02599 HANDLE_BACKGROUND_VALUE(backgroundYPosition, BackgroundYPosition, value)
02600 break;
02601 }
02602 case CSS_PROP_BORDER_SPACING: {
02603 if(value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return;
02604 style->setBorderHorizontalSpacing(parentStyle->borderHorizontalSpacing());
02605 style->setBorderVerticalSpacing(parentStyle->borderVerticalSpacing());
02606 break;
02607 }
02608 case CSS_PROP__KHTML_BORDER_HORIZONTAL_SPACING: {
02609 HANDLE_INHERIT_AND_INITIAL(borderHorizontalSpacing, BorderHorizontalSpacing)
02610 if (!primitiveValue) break;
02611 short spacing = primitiveValue->computeLength(style, paintDeviceMetrics);
02612 style->setBorderHorizontalSpacing(spacing);
02613 break;
02614 }
02615 case CSS_PROP__KHTML_BORDER_VERTICAL_SPACING: {
02616 HANDLE_INHERIT_AND_INITIAL(borderVerticalSpacing, BorderVerticalSpacing)
02617 if (!primitiveValue) break;
02618 short spacing = primitiveValue->computeLength(style, paintDeviceMetrics);
02619 style->setBorderVerticalSpacing(spacing);
02620 break;
02621 }
02622
02623 case CSS_PROP_CURSOR:
02624 HANDLE_INHERIT_AND_INITIAL(cursor, Cursor)
02625 if(primitiveValue)
02626 style->setCursor( (ECursor) (primitiveValue->getIdent() - CSS_VAL_AUTO) );
02627 break;
02628
02629 case CSS_PROP_BACKGROUND_COLOR:
02630 case CSS_PROP_BORDER_TOP_COLOR:
02631 case CSS_PROP_BORDER_RIGHT_COLOR:
02632 case CSS_PROP_BORDER_BOTTOM_COLOR:
02633 case CSS_PROP_BORDER_LEFT_COLOR:
02634 case CSS_PROP_COLOR:
02635 case CSS_PROP_OUTLINE_COLOR:
02636
02637 case CSS_PROP_SCROLLBAR_BASE_COLOR:
02638 case CSS_PROP_SCROLLBAR_FACE_COLOR:
02639 case CSS_PROP_SCROLLBAR_SHADOW_COLOR:
02640 case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR:
02641 case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR:
02642 case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR:
02643 case CSS_PROP_SCROLLBAR_TRACK_COLOR:
02644 case CSS_PROP_SCROLLBAR_ARROW_COLOR:
02645 {
02646 QColor col;
02647 if (isInherit) {
02648 HANDLE_INHERIT_COND(CSS_PROP_BACKGROUND_COLOR, backgroundColor, BackgroundColor)
02649 HANDLE_INHERIT_COND(CSS_PROP_BORDER_TOP_COLOR, borderTopColor, BorderTopColor)
02650 HANDLE_INHERIT_COND(CSS_PROP_BORDER_BOTTOM_COLOR, borderBottomColor, BorderBottomColor)
02651 HANDLE_INHERIT_COND(CSS_PROP_BORDER_RIGHT_COLOR, borderRightColor, BorderRightColor)
02652 HANDLE_INHERIT_COND(CSS_PROP_BORDER_LEFT_COLOR, borderLeftColor, BorderLeftColor)
02653 HANDLE_INHERIT_COND(CSS_PROP_COLOR, color, Color)
02654 HANDLE_INHERIT_COND(CSS_PROP_OUTLINE_COLOR, outlineColor, OutlineColor)
02655 return;
02656 } else if (isInitial) {
02657
02658
02659
02660 if (id == CSS_PROP_COLOR)
02661 col = RenderStyle::initialColor();
02662 } else {
02663 if(!primitiveValue )
02664 return;
02665 int ident = primitiveValue->getIdent();
02666 if ( ident ) {
02667 if ( ident == CSS_VAL__KHTML_TEXT )
02668 col = element->getDocument()->textColor();
02669
02670 else if ( ident == CSS_VAL_TRANSPARENT
02671 && id != CSS_PROP_BORDER_TOP_COLOR
02672 && id != CSS_PROP_BORDER_RIGHT_COLOR
02673 && id != CSS_PROP_BORDER_BOTTOM_COLOR
02674 && id != CSS_PROP_BORDER_LEFT_COLOR )
02675 col = QColor();
02676 else
02677 col = colorForCSSValue( ident );
02678 } else if ( primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_RGBCOLOR ) {
02679 #ifndef APPLE_CHANGES
02680 if(qAlpha(primitiveValue->getRGBColorValue()))
02681 #endif
02682 col.setRgb(primitiveValue->getRGBColorValue());
02683 } else {
02684 return;
02685 }
02686 }
02687
02688 switch(id)
02689 {
02690 case CSS_PROP_BACKGROUND_COLOR:
02691 style->setBackgroundColor(col); break;
02692 case CSS_PROP_BORDER_TOP_COLOR:
02693 style->setBorderTopColor(col); break;
02694 case CSS_PROP_BORDER_RIGHT_COLOR:
02695 style->setBorderRightColor(col); break;
02696 case CSS_PROP_BORDER_BOTTOM_COLOR:
02697 style->setBorderBottomColor(col); break;
02698 case CSS_PROP_BORDER_LEFT_COLOR:
02699 style->setBorderLeftColor(col); break;
02700 case CSS_PROP_COLOR:
02701 style->setColor(col); break;
02702 case CSS_PROP_OUTLINE_COLOR:
02703 style->setOutlineColor(col); break;
02704 #ifndef APPLE_CHANGES
02705 case CSS_PROP_SCROLLBAR_FACE_COLOR:
02706 style->setPaletteColor(QPalette::Active, QColorGroup::Button, col);
02707 style->setPaletteColor(QPalette::Inactive, QColorGroup::Button, col);
02708 break;
02709 case CSS_PROP_SCROLLBAR_SHADOW_COLOR:
02710 style->setPaletteColor(QPalette::Active, QColorGroup::Shadow, col);
02711 style->setPaletteColor(QPalette::Inactive, QColorGroup::Shadow, col);
02712 break;
02713 case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR:
02714 style->setPaletteColor(QPalette::Active, QColorGroup::Light, col);
02715 style->setPaletteColor(QPalette::Inactive, QColorGroup::Light, col);
02716 break;
02717 case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR:
02718 break;
02719 case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR:
02720 style->setPaletteColor(QPalette::Active, QColorGroup::Dark, col);
02721 style->setPaletteColor(QPalette::Inactive, QColorGroup::Dark, col);
02722 break;
02723 case CSS_PROP_SCROLLBAR_TRACK_COLOR:
02724 style->setPaletteColor(QPalette::Active, QColorGroup::Mid, col);
02725 style->setPaletteColor(QPalette::Inactive, QColorGroup::Mid, col);
02726 style->setPaletteColor(QPalette::Active, QColorGroup::Background, col);
02727 style->setPaletteColor(QPalette::Inactive, QColorGroup::Background, col);
02728
02729 case CSS_PROP_SCROLLBAR_BASE_COLOR:
02730 style->setPaletteColor(QPalette::Active, QColorGroup::Base, col);
02731 style->setPaletteColor(QPalette::Inactive, QColorGroup::Base, col);
02732 break;
02733 case CSS_PROP_SCROLLBAR_ARROW_COLOR:
02734 style->setPaletteColor(QPalette::Active, QColorGroup::ButtonText, col);
02735 style->setPaletteColor(QPalette::Inactive, QColorGroup::ButtonText, col);
02736 break;
02737 #endif
02738 default:
02739 return;
02740 }
02741 return;
02742 }
02743 break;
02744
02745 case CSS_PROP_BACKGROUND_IMAGE:
02746 HANDLE_BACKGROUND_VALUE(backgroundImage, BackgroundImage, value)
02747 break;
02748 case CSS_PROP_LIST_STYLE_IMAGE:
02749 {
02750 HANDLE_INHERIT_AND_INITIAL(listStyleImage, ListStyleImage)
02751 if (!primitiveValue) return;
02752 style->setListStyleImage(static_cast<CSSImageValueImpl *>(primitiveValue)->image());
02753
02754 break;
02755 }
02756
02757
02758 case CSS_PROP_BORDER_TOP_WIDTH:
02759 case CSS_PROP_BORDER_RIGHT_WIDTH:
02760 case CSS_PROP_BORDER_BOTTOM_WIDTH:
02761 case CSS_PROP_BORDER_LEFT_WIDTH:
02762 case CSS_PROP_OUTLINE_WIDTH:
02763 {
02764 if (isInherit) {
02765 HANDLE_INHERIT_COND(CSS_PROP_BORDER_TOP_WIDTH, borderTopWidth, BorderTopWidth)
02766 HANDLE_INHERIT_COND(CSS_PROP_BORDER_RIGHT_WIDTH, borderRightWidth, BorderRightWidth)
02767 HANDLE_INHERIT_COND(CSS_PROP_BORDER_BOTTOM_WIDTH, borderBottomWidth, BorderBottomWidth)
02768 HANDLE_INHERIT_COND(CSS_PROP_BORDER_LEFT_WIDTH, borderLeftWidth, BorderLeftWidth)
02769 HANDLE_INHERIT_COND(CSS_PROP_OUTLINE_WIDTH, outlineWidth, OutlineWidth)
02770 return;
02771 }
02772 else if (isInitial) {
02773 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_TOP_WIDTH, BorderTopWidth, BorderWidth)
02774 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_RIGHT_WIDTH, BorderRightWidth, BorderWidth)
02775 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_BOTTOM_WIDTH, BorderBottomWidth, BorderWidth)
02776 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_LEFT_WIDTH, BorderLeftWidth, BorderWidth)
02777 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_OUTLINE_WIDTH, OutlineWidth, BorderWidth)
02778 return;
02779 }
02780
02781 if(!primitiveValue) break;
02782 short width = 3;
02783 switch(primitiveValue->getIdent())
02784 {
02785 case CSS_VAL_THIN:
02786 width = 1;
02787 break;
02788 case CSS_VAL_MEDIUM:
02789 width = 3;
02790 break;
02791 case CSS_VAL_THICK:
02792 width = 5;
02793 break;
02794 case CSS_VAL_INVALID:
02795 {
02796 double widthd = primitiveValue->computeLengthFloat(style, paintDeviceMetrics);
02797 width = (int)widthd;
02798
02799
02800 if (width == 0 && widthd >= 0.025) width++;
02801 break;
02802 }
02803 default:
02804 return;
02805 }
02806
02807 if(width < 0) return;
02808 switch(id)
02809 {
02810 case CSS_PROP_BORDER_TOP_WIDTH:
02811 style->setBorderTopWidth(width);
02812 break;
02813 case CSS_PROP_BORDER_RIGHT_WIDTH:
02814 style->setBorderRightWidth(width);
02815 break;
02816 case CSS_PROP_BORDER_BOTTOM_WIDTH:
02817 style->setBorderBottomWidth(width);
02818 break;
02819 case CSS_PROP_BORDER_LEFT_WIDTH:
02820 style->setBorderLeftWidth(width);
02821 break;
02822 case CSS_PROP_OUTLINE_WIDTH:
02823 style->setOutlineWidth(width);
02824 break;
02825 default:
02826 return;
02827 }
02828 return;
02829 }
02830
02831 case CSS_PROP_LETTER_SPACING:
02832 case CSS_PROP_WORD_SPACING:
02833 {
02834 if (isInherit) {
02835 HANDLE_INHERIT_COND(CSS_PROP_LETTER_SPACING, letterSpacing, LetterSpacing)
02836 HANDLE_INHERIT_COND(CSS_PROP_WORD_SPACING, wordSpacing, WordSpacing)
02837 return;
02838 } else if (isInitial) {
02839 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_LETTER_SPACING, LetterSpacing, LetterWordSpacing)
02840 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_WORD_SPACING, WordSpacing, LetterWordSpacing)
02841 return;
02842 }
02843 if(!primitiveValue) return;
02844
02845 int width = 0;
02846 if (primitiveValue->getIdent() != CSS_VAL_NORMAL)
02847 width = primitiveValue->computeLength(style, paintDeviceMetrics);
02848
02849 switch(id)
02850 {
02851 case CSS_PROP_LETTER_SPACING:
02852 style->setLetterSpacing(width);
02853 break;
02854 case CSS_PROP_WORD_SPACING:
02855 style->setWordSpacing(width);
02856 break;
02857
02858 default: break;
02859 }
02860 return;
02861 }
02862
02863
02864 case CSS_PROP_MAX_WIDTH:
02865
02866 if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE)
02867 apply = true;
02868 case CSS_PROP_TOP:
02869 case CSS_PROP_LEFT:
02870 case CSS_PROP_RIGHT:
02871 case CSS_PROP_BOTTOM:
02872 case CSS_PROP_WIDTH:
02873 case CSS_PROP_MIN_WIDTH:
02874 case CSS_PROP_MARGIN_TOP:
02875 case CSS_PROP_MARGIN_RIGHT:
02876 case CSS_PROP_MARGIN_BOTTOM:
02877 case CSS_PROP_MARGIN_LEFT:
02878
02879 if(id != CSS_PROP_MAX_WIDTH && primitiveValue &&
02880 primitiveValue->getIdent() == CSS_VAL_AUTO)
02881 {
02882
02883 apply = true;
02884 }
02885 case CSS_PROP_PADDING_TOP:
02886 case CSS_PROP_PADDING_RIGHT:
02887 case CSS_PROP_PADDING_BOTTOM:
02888 case CSS_PROP_PADDING_LEFT:
02889 case CSS_PROP_TEXT_INDENT:
02890
02891 {
02892 if (isInherit) {
02893 HANDLE_INHERIT_COND(CSS_PROP_MAX_WIDTH, maxWidth, MaxWidth)
02894 HANDLE_INHERIT_COND(CSS_PROP_BOTTOM, bottom, Bottom)
02895 HANDLE_INHERIT_COND(CSS_PROP_TOP, top, Top)
02896 HANDLE_INHERIT_COND(CSS_PROP_LEFT, left, Left)
02897 HANDLE_INHERIT_COND(CSS_PROP_RIGHT, right, Right)
02898 HANDLE_INHERIT_COND(CSS_PROP_WIDTH, width, Width)
02899 HANDLE_INHERIT_COND(CSS_PROP_MIN_WIDTH, minWidth, MinWidth)
02900 HANDLE_INHERIT_COND(CSS_PROP_PADDING_TOP, paddingTop, PaddingTop)
02901 HANDLE_INHERIT_COND(CSS_PROP_PADDING_RIGHT, paddingRight, PaddingRight)
02902 HANDLE_INHERIT_COND(CSS_PROP_PADDING_BOTTOM, paddingBottom, PaddingBottom)
02903 HANDLE_INHERIT_COND(CSS_PROP_PADDING_LEFT, paddingLeft, PaddingLeft)
02904 HANDLE_INHERIT_COND(CSS_PROP_MARGIN_TOP, marginTop, MarginTop)
02905 HANDLE_INHERIT_COND(CSS_PROP_MARGIN_RIGHT, marginRight, MarginRight)
02906 HANDLE_INHERIT_COND(CSS_PROP_MARGIN_BOTTOM, marginBottom, MarginBottom)
02907 HANDLE_INHERIT_COND(CSS_PROP_MARGIN_LEFT, marginLeft, MarginLeft)
02908 HANDLE_INHERIT_COND(CSS_PROP_TEXT_INDENT, textIndent, TextIndent)
02909 return;
02910 } else if (isInitial) {
02911 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MAX_WIDTH, MaxWidth, MaxSize)
02912 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BOTTOM, Bottom, Offset)
02913 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_TOP, Top, Offset)
02914 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_LEFT, Left, Offset)
02915 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_RIGHT, Right, Offset)
02916 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_WIDTH, Width, Size)
02917 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MIN_WIDTH, MinWidth, MinSize)
02918 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_TOP, PaddingTop, Padding)
02919 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_RIGHT, PaddingRight, Padding)
02920 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_BOTTOM, PaddingBottom, Padding)
02921 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_LEFT, PaddingLeft, Padding)
02922 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_TOP, MarginTop, Margin)
02923 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_RIGHT, MarginRight, Margin)
02924 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_BOTTOM, MarginBottom, Margin)
02925 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_LEFT, MarginLeft, Margin)
02926 HANDLE_INITIAL_COND(CSS_PROP_TEXT_INDENT, TextIndent)
02927 return;
02928 }
02929
02930 if (primitiveValue && !apply) {
02931 int type = primitiveValue->primitiveType();
02932 if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
02933
02934 l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed,
02935 primitiveValue->isQuirkValue());
02936 else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
02937 l = Length((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
02938 else if (type == CSSPrimitiveValue::CSS_HTML_RELATIVE)
02939 l = Length(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_HTML_RELATIVE)), Relative);
02940 else
02941 return;
02942 apply = true;
02943 }
02944 if(!apply) return;
02945 switch(id)
02946 {
02947 case CSS_PROP_MAX_WIDTH:
02948 style->setMaxWidth(l); break;
02949 case CSS_PROP_BOTTOM:
02950 style->setBottom(l); break;
02951 case CSS_PROP_TOP:
02952 style->setTop(l); break;
02953 case CSS_PROP_LEFT:
02954 style->setLeft(l); break;
02955 case CSS_PROP_RIGHT:
02956 style->setRight(l); break;
02957 case CSS_PROP_WIDTH:
02958 style->setWidth(l); break;
02959 case CSS_PROP_MIN_WIDTH:
02960 style->setMinWidth(l); break;
02961 case CSS_PROP_PADDING_TOP:
02962 style->setPaddingTop(l); break;
02963 case CSS_PROP_PADDING_RIGHT:
02964 style->setPaddingRight(l); break;
02965 case CSS_PROP_PADDING_BOTTOM:
02966 style->setPaddingBottom(l); break;
02967 case CSS_PROP_PADDING_LEFT:
02968 style->setPaddingLeft(l); break;
02969 case CSS_PROP_MARGIN_TOP:
02970 style->setMarginTop(l); break;
02971 case CSS_PROP_MARGIN_RIGHT:
02972 style->setMarginRight(l); break;
02973 case CSS_PROP_MARGIN_BOTTOM:
02974 style->setMarginBottom(l); break;
02975 case CSS_PROP_MARGIN_LEFT:
02976 style->setMarginLeft(l); break;
02977 case CSS_PROP_TEXT_INDENT:
02978 style->setTextIndent(l); break;
02979 default: break;
02980 }
02981 return;
02982 }
02983
02984 case CSS_PROP_MAX_HEIGHT:
02985 if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE)
02986 apply = true;
02987 case CSS_PROP_HEIGHT:
02988 case CSS_PROP_MIN_HEIGHT:
02989 if(id != CSS_PROP_MAX_HEIGHT && primitiveValue &&
02990 primitiveValue->getIdent() == CSS_VAL_AUTO)
02991 apply = true;
02992 if (isInherit) {
02993 HANDLE_INHERIT_COND(CSS_PROP_MAX_HEIGHT, maxHeight, MaxHeight)
02994 HANDLE_INHERIT_COND(CSS_PROP_HEIGHT, height, Height)
02995 HANDLE_INHERIT_COND(CSS_PROP_MIN_HEIGHT, minHeight, MinHeight)
02996 return;
02997 }
02998 else if (isInitial) {
02999 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MAX_HEIGHT, MaxHeight, MaxSize)
03000 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_HEIGHT, Height, Size)
03001 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MIN_HEIGHT, MinHeight, MinSize)
03002 return;
03003 }
03004
03005 if (primitiveValue && !apply)
03006 {
03007 int type = primitiveValue->primitiveType();
03008 if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
03009 l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
03010 else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
03011 l = Length((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
03012 else
03013 return;
03014 apply = true;
03015 }
03016 if(!apply) return;
03017 switch(id)
03018 {
03019 case CSS_PROP_MAX_HEIGHT:
03020 style->setMaxHeight(l); break;
03021 case CSS_PROP_HEIGHT:
03022 style->setHeight(l); break;
03023 case CSS_PROP_MIN_HEIGHT:
03024 style->setMinHeight(l); break;
03025 default:
03026 return;
03027 }
03028 return;
03029
03030 break;
03031
03032 case CSS_PROP_VERTICAL_ALIGN:
03033 HANDLE_INHERIT_AND_INITIAL(verticalAlign, VerticalAlign)
03034 if (!primitiveValue) return;
03035 if (primitiveValue->getIdent()) {
03036 khtml::EVerticalAlign align;
03037
03038 switch(primitiveValue->getIdent())
03039 {
03040 case CSS_VAL_TOP:
03041 align = TOP; break;
03042 case CSS_VAL_BOTTOM:
03043 align = BOTTOM; break;
03044 case CSS_VAL_MIDDLE:
03045 align = MIDDLE; break;
03046 case CSS_VAL_BASELINE:
03047 align = BASELINE; break;
03048 case CSS_VAL_TEXT_BOTTOM:
03049 align = TEXT_BOTTOM; break;
03050 case CSS_VAL_TEXT_TOP:
03051 align = TEXT_TOP; break;
03052 case CSS_VAL_SUB:
03053 align = SUB; break;
03054 case CSS_VAL_SUPER:
03055 align = SUPER; break;
03056 case CSS_VAL__KHTML_BASELINE_MIDDLE:
03057 align = BASELINE_MIDDLE; break;
03058 default:
03059 return;
03060 }
03061 style->setVerticalAlign(align);
03062 return;
03063 } else {
03064 int type = primitiveValue->primitiveType();
03065 Length l;
03066 if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
03067 l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed );
03068 else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
03069 l = Length( int( primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE) ), Percent );
03070
03071 style->setVerticalAlign( LENGTH );
03072 style->setVerticalAlignLength( l );
03073 }
03074 break;
03075
03076 case CSS_PROP_FONT_SIZE:
03077 {
03078 FontDef fontDef = style->htmlFont().fontDef;
03079 int oldSize;
03080 int size = 0;
03081
03082 float toPix = paintDeviceMetrics->logicalDpiY()/72.;
03083 if (toPix < 96./72.) toPix = 96./72.;
03084
03085 int minFontSize = int(settings->minFontSize() * toPix);
03086
03087 if(parentNode) {
03088 oldSize = parentStyle->font().pixelSize();
03089 } else
03090 oldSize = m_fontSizes[3];
03091
03092 if (isInherit )
03093 size = oldSize;
03094 else if (isInitial)
03095 size = m_fontSizes[3];
03096 else if(primitiveValue->getIdent()) {
03097
03098
03099 #ifdef APPLE_CHANGES
03100 const QValueVector<int>& fontSizes = (fontDef.genericFamily == FontDef::eMonospace) ?
03101 m_fixedFontSizes : m_fontSizes;
03102 #else
03103 const QValueVector<int>& fontSizes = m_fontSizes;
03104 #endif
03105 switch(primitiveValue->getIdent())
03106 {
03107 case CSS_VAL_XX_SMALL: size = int( fontSizes[0] ); break;
03108 case CSS_VAL_X_SMALL: size = int( fontSizes[1] ); break;
03109 case CSS_VAL_SMALL: size = int( fontSizes[2] ); break;
03110 case CSS_VAL_MEDIUM: size = int( fontSizes[3] ); break;
03111 case CSS_VAL_LARGE: size = int( fontSizes[4] ); break;
03112 case CSS_VAL_X_LARGE: size = int( fontSizes[5] ); break;
03113 case CSS_VAL_XX_LARGE: size = int( fontSizes[6] ); break;
03114 case CSS_VAL__KHTML_XXX_LARGE: size = int( fontSizes[7] ); break;
03115 case CSS_VAL_LARGER:
03116 size = nextFontSize(fontSizes, oldSize, false);
03117 break;
03118 case CSS_VAL_SMALLER:
03119 size = nextFontSize(fontSizes, oldSize, true);
03120 break;
03121 default:
03122 return;
03123 }
03124
03125 } else {
03126 int type = primitiveValue->primitiveType();
03127 if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) {
03128 if ( !khtml::printpainter && type != CSSPrimitiveValue::CSS_EMS && type != CSSPrimitiveValue::CSS_EXS &&
03129 view && view->part())
03130 size = int( primitiveValue->computeLengthFloat(parentStyle, paintDeviceMetrics) *
03131 view->part()->zoomFactor() ) / 100;
03132 else
03133 size = int( primitiveValue->computeLengthFloat(parentStyle, paintDeviceMetrics) );
03134 }
03135 else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
03136 size = int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE)
03137 * parentStyle->font().pixelSize()) / 100;
03138 else
03139 return;
03140 }
03141
03142 if (size < 0) return;
03143
03144
03145
03146 if (size && size < minFontSize) size = minFontSize;
03147
03148
03149
03150 fontDef.size = size;
03151 fontDirty |= style->setFontDef( fontDef );
03152 return;
03153 }
03154
03155 case CSS_PROP_Z_INDEX:
03156 {
03157 HANDLE_INHERIT(zIndex, ZIndex)
03158 else if (isInitial) {
03159 style->setHasAutoZIndex();
03160 return;
03161 }
03162
03163 if (!primitiveValue)
03164 return;
03165
03166 if (primitiveValue->getIdent() == CSS_VAL_AUTO) {
03167 style->setHasAutoZIndex();
03168 return;
03169 }
03170
03171 if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
03172 return;
03173
03174 style->setZIndex((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER));
03175 return;
03176 }
03177
03178 case CSS_PROP_WIDOWS:
03179 {
03180 HANDLE_INHERIT_AND_INITIAL(widows, Widows)
03181 if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
03182 return;
03183 style->setWidows((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER));
03184 break;
03185 }
03186
03187 case CSS_PROP_ORPHANS:
03188 {
03189 HANDLE_INHERIT_AND_INITIAL(orphans, Orphans)
03190 if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
03191 return;
03192 style->setOrphans((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER));
03193 break;
03194 }
03195
03196
03197 case CSS_PROP_LINE_HEIGHT:
03198 {
03199 HANDLE_INHERIT_AND_INITIAL(lineHeight, LineHeight)
03200 if(!primitiveValue) return;
03201 Length lineHeight;
03202 int type = primitiveValue->primitiveType();
03203 if (primitiveValue->getIdent() == CSS_VAL_NORMAL)
03204 lineHeight = Length( -100, Percent );
03205 else if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) {
03206
03207
03208 if ( !khtml::printpainter && type != CSSPrimitiveValue::CSS_EMS && type != CSSPrimitiveValue::CSS_EXS &&
03209 view && view->part())
03210 lineHeight = Length(primitiveValue->computeLength(style, paintDeviceMetrics) *
03211 view->part()->zoomFactor()/100, Fixed );
03212 else
03213 lineHeight = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed );
03214 } else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
03215 lineHeight = Length( ( style->font().pixelSize() * int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE)) ) / 100, Fixed );
03216 else if (type == CSSPrimitiveValue::CSS_NUMBER)
03217 lineHeight = Length(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER)*100), Percent);
03218 else
03219 return;
03220 style->setLineHeight(lineHeight);
03221 return;
03222 }
03223
03224
03225 case CSS_PROP_TEXT_ALIGN:
03226 {
03227 HANDLE_INHERIT_AND_INITIAL(textAlign, TextAlign)
03228 if (!primitiveValue) return;
03229 if (primitiveValue->getIdent())
03230 style->setTextAlign( (ETextAlign) (primitiveValue->getIdent() - CSS_VAL__KHTML_AUTO) );
03231 return;
03232 }
03233
03234
03235 case CSS_PROP_CLIP:
03236 {
03237 Length top = Length();
03238 Length right = Length();
03239 Length bottom = Length();
03240 Length left = Length();
03241
03242 bool hasClip = false;
03243
03244 if (isInherit && parentStyle->hasClip()) {
03245 hasClip = true;
03246 top = parentStyle->clipTop();
03247 right = parentStyle->clipRight();
03248 bottom = parentStyle->clipBottom();
03249 left = parentStyle->clipLeft();
03250 } else if (primitiveValue && primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_RECT) {
03251 RectImpl *rect = primitiveValue->getRectValue();
03252 if (rect) {
03253 hasClip = true;
03254 top = convertToLength( rect->top(), style, paintDeviceMetrics );
03255 right = convertToLength( rect->right(), style, paintDeviceMetrics );
03256 bottom = convertToLength( rect->bottom(), style, paintDeviceMetrics );
03257 left = convertToLength( rect->left(), style, paintDeviceMetrics );
03258 }
03259 }
03260
03261 style->setClip(top, right, bottom, left);
03262 style->setHasClip(hasClip);
03263
03264
03265 break;
03266 }
03267
03268
03269 case CSS_PROP_CONTENT:
03270
03271 {
03272
03273
03274
03275
03276 if ( style->styleType()==RenderStyle::FIRST_LETTER ||
03277 style->styleType()==RenderStyle::FIRST_LINE ||
03278 style->styleType()==RenderStyle::SELECTION )
03279 break;
03280
03281 if (isInitial) {
03282 style->setContentNormal();
03283 return;
03284 }
03285
03286 if (primitiveValue && primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_IDENT) {
03287
03288 if (primitiveValue->getIdent() == CSS_VAL_NORMAL)
03289 style->setContentNormal();
03290 else
03291 if (primitiveValue->getIdent() == CSS_VAL_NONE)
03292 style->setContentNone();
03293 else
03294 assert(false);
03295 return;
03296 }
03297
03298 if(!value->isValueList()) return;
03299 CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value);
03300 int len = list->length();
03301
03302 style->setContentNormal();
03303
03304 for(int i = 0; i < len; i++) {
03305 CSSValueImpl *item = list->item(i);
03306 if(!item->isPrimitiveValue()) continue;
03307 CSSPrimitiveValueImpl *val = static_cast<CSSPrimitiveValueImpl *>(item);
03308 if(val->primitiveType()==CSSPrimitiveValue::CSS_STRING)
03309 {
03310 style->addContent(val->getStringValue());
03311 }
03312 else if (val->primitiveType()==CSSPrimitiveValue::CSS_ATTR)
03313 {
03314
03315 int attrID = element->getDocument()->getId(NodeImpl::AttributeId, val->getStringValue(), false, true);
03316 if (attrID)
03317 style->addContent(element->getAttribute(attrID).implementation());
03318 else
03319 kdDebug(6080) << "Attribute \"" << val->getStringValue() << "\" not found" << endl;
03320 }
03321 else if (val->primitiveType()==CSSPrimitiveValue::CSS_URI)
03322 {
03323 CSSImageValueImpl *image = static_cast<CSSImageValueImpl *>(val);
03324 style->addContent(image->image());
03325 }
03326 else if (val->primitiveType()==CSSPrimitiveValue::CSS_COUNTER)
03327 {
03328 style->addContent(val->getCounterValue());
03329 }
03330 else if (val->primitiveType()==CSSPrimitiveValue::CSS_IDENT)
03331 {
03332 EQuoteContent quote;
03333 switch (val->getIdent()) {
03334 case CSS_VAL_OPEN_QUOTE:
03335 quote = OPEN_QUOTE;
03336 break;
03337 case CSS_VAL_NO_OPEN_QUOTE:
03338 quote = NO_OPEN_QUOTE;
03339 break;
03340 case CSS_VAL_CLOSE_QUOTE:
03341 quote = CLOSE_QUOTE;
03342 break;
03343 case CSS_VAL_NO_CLOSE_QUOTE:
03344 quote = NO_CLOSE_QUOTE;
03345 break;
03346 default:
03347 assert(false);
03348 }
03349 style->addContent(quote);
03350 } else
03351 kdDebug(6080) << "Unrecognized CSS content" << endl;
03352
03353 }
03354 break;
03355 }
03356
03357 case CSS_PROP_COUNTER_INCREMENT: {
03358 if(!value->isValueList()) return;
03359
03360 CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value);
03361 style->setCounterIncrement(list);
03362 break;
03363 }
03364 case CSS_PROP_COUNTER_RESET: {
03365 if(!value->isValueList()) return;
03366
03367 CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value);
03368 style->setCounterReset(list);
03369 break;
03370 }
03371 case CSS_PROP_FONT_FAMILY:
03372
03373 {
03374 if (isInherit) {
03375 FontDef parentFontDef = parentStyle->htmlFont().fontDef;
03376 FontDef fontDef = style->htmlFont().fontDef;
03377 fontDef.family = parentFontDef.family;
03378 if (style->setFontDef(fontDef))
03379 fontDirty = true;
03380 return;
03381 }
03382 else if (isInitial) {
03383 FontDef fontDef = style->htmlFont().fontDef;
03384 FontDef initialDef = FontDef();
03385 #ifdef APPLE_CHANGES
03386 fontDef.family = initialDef.firstFamily();
03387 #else
03388 fontDef.family = QString::null;
03389 #endif
03390 if (style->setFontDef(fontDef))
03391 fontDirty = true;
03392 return;
03393 }
03394 if(!value->isValueList()) return;
03395 FontDef fontDef = style->htmlFont().fontDef;
03396 CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value);
03397 int len = list->length();
03398 for(int i = 0; i < len; i++) {
03399 CSSValueImpl *item = list->item(i);
03400 if(!item->isPrimitiveValue()) continue;
03401 CSSPrimitiveValueImpl *val = static_cast<CSSPrimitiveValueImpl *>(item);
03402 QString face;
03403 if( val->primitiveType() == CSSPrimitiveValue::CSS_STRING )
03404 face = static_cast<FontFamilyValueImpl *>(val)->fontName();
03405 else if ( val->primitiveType() == CSSPrimitiveValue::CSS_IDENT ) {
03406 switch( val->getIdent() ) {
03407 case CSS_VAL_SERIF:
03408 face = settings->serifFontName();
03409 break;
03410 case CSS_VAL_SANS_SERIF:
03411 face = settings->sansSerifFontName();
03412 break;
03413 case CSS_VAL_CURSIVE:
03414 face = settings->cursiveFontName();
03415 break;
03416 case CSS_VAL_FANTASY:
03417 face = settings->fantasyFontName();
03418 break;
03419 case CSS_VAL_MONOSPACE:
03420 face = settings->fixedFontName();
03421 break;
03422 default:
03423 return;
03424 }
03425 } else {
03426 return;
03427 }
03428 if ( !face.isEmpty() ) {
03429 fontDef.family = face;
03430 fontDirty |= style->setFontDef( fontDef );
03431 return;
03432 }
03433 }
03434 break;
03435 }
03436 case CSS_PROP_QUOTES:
03437 HANDLE_INHERIT_AND_INITIAL(quotes, Quotes)
03438 if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE) {
03439
03440 QuotesValueImpl* quotes = new QuotesValueImpl();
03441 style->setQuotes(quotes);
03442 } else {
03443 QuotesValueImpl* quotes = static_cast<QuotesValueImpl *>(value);
03444 style->setQuotes(quotes);
03445 }
03446 break;
03447 case CSS_PROP_SIZE:
03448
03449 break;
03450 case CSS_PROP_TEXT_DECORATION: {
03451
03452 HANDLE_INHERIT_AND_INITIAL(textDecoration, TextDecoration)
03453 int t = RenderStyle::initialTextDecoration();
03454 if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE) {
03455
03456 } else {
03457 if(!value->isValueList()) return;
03458 CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value);
03459 int len = list->length();
03460 for(int i = 0; i < len; i++)
03461 {
03462 CSSValueImpl *item = list->item(i);
03463 if(!item->isPrimitiveValue()) continue;
03464 primitiveValue = static_cast<CSSPrimitiveValueImpl *>(item);
03465 switch(primitiveValue->getIdent())
03466 {
03467 case CSS_VAL_NONE:
03468 t = TDNONE; break;
03469 case CSS_VAL_UNDERLINE:
03470 t |= UNDERLINE; break;
03471 case CSS_VAL_OVERLINE:
03472 t |= OVERLINE; break;
03473 case CSS_VAL_LINE_THROUGH:
03474 t |= LINE_THROUGH; break;
03475 case CSS_VAL_BLINK:
03476 t |= BLINK; break;
03477 default:
03478 return;
03479 }
03480 }
03481 }
03482 style->setTextDecoration(t);
03483 break;
03484 }
03485 case CSS_PROP__KHTML_FLOW_MODE:
03486 HANDLE_INHERIT_AND_INITIAL(flowAroundFloats, FlowAroundFloats)
03487 if (!primitiveValue) return;
03488 if (primitiveValue->getIdent()) {
03489 style->setFlowAroundFloats( primitiveValue->getIdent() == CSS_VAL__KHTML_AROUND_FLOATS );
03490 return;
03491 }
03492 break;
03493 case CSS_PROP__KHTML_USER_INPUT: {
03494 if(value->cssValueType() == CSSValue::CSS_INHERIT)
03495 {
03496 if(!parentNode) return;
03497 style->setUserInput(parentStyle->userInput());
03498
03499 return;
03500 }
03501 if(!primitiveValue) return;
03502 int id = primitiveValue->getIdent();
03503 if (id == CSS_VAL_NONE)
03504 style->setUserInput(UI_NONE);
03505 else
03506 style->setUserInput(EUserInput(id - CSS_VAL_ENABLED));
03507
03508 return;
03509 }
03510
03511
03512 case CSS_PROP_BACKGROUND:
03513 if (isInitial) {
03514 style->clearBackgroundLayers();
03515 return;
03516 }
03517 else if (isInherit) {
03518 if (parentStyle)
03519 style->inheritBackgroundLayers(*parentStyle->backgroundLayers());
03520 else
03521 style->clearBackgroundLayers();
03522 return;
03523 }
03524 break;
03525 case CSS_PROP_BORDER:
03526 case CSS_PROP_BORDER_STYLE:
03527 case CSS_PROP_BORDER_WIDTH:
03528 case CSS_PROP_BORDER_COLOR:
03529 if(id == CSS_PROP_BORDER || id == CSS_PROP_BORDER_COLOR)
03530 {
03531 if (isInherit) {
03532 style->setBorderTopColor(parentStyle->borderTopColor());
03533 style->setBorderBottomColor(parentStyle->borderBottomColor());
03534 style->setBorderLeftColor(parentStyle->borderLeftColor());
03535 style->setBorderRightColor(parentStyle->borderRightColor());
03536 }
03537 else if (isInitial) {
03538 style->setBorderTopColor(QColor());
03539 style->setBorderBottomColor(QColor());
03540 style->setBorderLeftColor(QColor());
03541 style->setBorderRightColor(QColor());
03542 }
03543 }
03544 if (id == CSS_PROP_BORDER || id == CSS_PROP_BORDER_STYLE)
03545 {
03546 if (isInherit) {
03547 style->setBorderTopStyle(parentStyle->borderTopStyle());
03548 style->setBorderBottomStyle(parentStyle->borderBottomStyle());
03549 style->setBorderLeftStyle(parentStyle->borderLeftStyle());
03550 style->setBorderRightStyle(parentStyle->borderRightStyle());
03551 }
03552 else if (isInitial) {
03553 style->setBorderTopStyle(RenderStyle::initialBorderStyle());
03554 style->setBorderBottomStyle(RenderStyle::initialBorderStyle());
03555 style->setBorderLeftStyle(RenderStyle::initialBorderStyle());
03556 style->setBorderRightStyle(RenderStyle::initialBorderStyle());
03557 }
03558 }
03559 if (id == CSS_PROP_BORDER || id == CSS_PROP_BORDER_WIDTH)
03560 {
03561 if (isInherit) {
03562 style->setBorderTopWidth(parentStyle->borderTopWidth());
03563 style->setBorderBottomWidth(parentStyle->borderBottomWidth());
03564 style->setBorderLeftWidth(parentStyle->borderLeftWidth());
03565 style->setBorderRightWidth(parentStyle->borderRightWidth());
03566 }
03567 else if (isInitial) {
03568 style->setBorderTopWidth(RenderStyle::initialBorderWidth());
03569 style->setBorderBottomWidth(RenderStyle::initialBorderWidth());
03570 style->setBorderLeftWidth(RenderStyle::initialBorderWidth());
03571 style->setBorderRightWidth(RenderStyle::initialBorderWidth());
03572 }
03573 }
03574 return;
03575 case CSS_PROP_BORDER_TOP:
03576 if ( isInherit ) {
03577 style->setBorderTopColor(parentStyle->borderTopColor());
03578 style->setBorderTopStyle(parentStyle->borderTopStyle());
03579 style->setBorderTopWidth(parentStyle->borderTopWidth());
03580 } else if (isInitial)
03581 style->resetBorderTop();
03582 return;
03583 case CSS_PROP_BORDER_RIGHT:
03584 if (isInherit) {
03585 style->setBorderRightColor(parentStyle->borderRightColor());
03586 style->setBorderRightStyle(parentStyle->borderRightStyle());
03587 style->setBorderRightWidth(parentStyle->borderRightWidth());
03588 }
03589 else if (isInitial)
03590 style->resetBorderRight();
03591 return;
03592 case CSS_PROP_BORDER_BOTTOM:
03593 if (isInherit) {
03594 style->setBorderBottomColor(parentStyle->borderBottomColor());
03595 style->setBorderBottomStyle(parentStyle->borderBottomStyle());
03596 style->setBorderBottomWidth(parentStyle->borderBottomWidth());
03597 }
03598 else if (isInitial)
03599 style->resetBorderBottom();
03600 return;
03601 case CSS_PROP_BORDER_LEFT:
03602 if (isInherit) {
03603 style->setBorderLeftColor(parentStyle->borderLeftColor());
03604 style->setBorderLeftStyle(parentStyle->borderLeftStyle());
03605 style->setBorderLeftWidth(parentStyle->borderLeftWidth());
03606 }
03607 else if (isInitial)
03608 style->resetBorderLeft();
03609 return;
03610 case CSS_PROP_MARGIN:
03611 if (isInherit) {
03612 style->setMarginTop(parentStyle->marginTop());
03613 style->setMarginBottom(parentStyle->marginBottom());
03614 style->setMarginLeft(parentStyle->marginLeft());
03615 style->setMarginRight(parentStyle->marginRight());
03616 }
03617 else if (isInitial)
03618 style->resetMargin();
03619 return;
03620 case CSS_PROP_PADDING:
03621 if (isInherit) {
03622 style->setPaddingTop(parentStyle->paddingTop());
03623 style->setPaddingBottom(parentStyle->paddingBottom());
03624 style->setPaddingLeft(parentStyle->paddingLeft());
03625 style->setPaddingRight(parentStyle->paddingRight());
03626 }
03627 else if (isInitial)
03628 style->resetPadding();
03629 return;
03630 case CSS_PROP_FONT:
03631 if ( isInherit ) {
03632 FontDef fontDef = parentStyle->htmlFont().fontDef;
03633 style->setLineHeight( parentStyle->lineHeight() );
03634 fontDirty |= style->setFontDef( fontDef );
03635 } else if (isInitial) {
03636 FontDef fontDef;
03637 style->setLineHeight(RenderStyle::initialLineHeight());
03638 if (style->setFontDef( fontDef ))
03639 fontDirty = true;
03640 } else if ( value->isFontValue() ) {
03641 FontValueImpl *font = static_cast<FontValueImpl *>(value);
03642 if ( !font->style || !font->variant || !font->weight ||
03643 !font->size || !font->lineHeight || !font->family )
03644 return;
03645 applyRule( CSS_PROP_FONT_STYLE, font->style );
03646 applyRule( CSS_PROP_FONT_VARIANT, font->variant );
03647 applyRule( CSS_PROP_FONT_WEIGHT, font->weight );
03648 applyRule( CSS_PROP_FONT_SIZE, font->size );
03649
03650
03651
03652
03653 if (fontDirty)
03654 CSSStyleSelector::style->htmlFont().update( paintDeviceMetrics );
03655
03656 applyRule( CSS_PROP_LINE_HEIGHT, font->lineHeight );
03657 applyRule( CSS_PROP_FONT_FAMILY, font->family );
03658 }
03659 return;
03660
03661 case CSS_PROP_LIST_STYLE:
03662 if (isInherit) {
03663 style->setListStyleType(parentStyle->listStyleType());
03664 style->setListStyleImage(parentStyle->listStyleImage());
03665 style->setListStylePosition(parentStyle->listStylePosition());
03666 }
03667 else if (isInitial) {
03668 style->setListStyleType(RenderStyle::initialListStyleType());
03669 style->setListStyleImage(RenderStyle::initialListStyleImage());
03670 style->setListStylePosition(RenderStyle::initialListStylePosition());
03671 }
03672 break;
03673 case CSS_PROP_OUTLINE:
03674 if (isInherit) {
03675 style->setOutlineWidth(parentStyle->outlineWidth());
03676 style->setOutlineColor(parentStyle->outlineColor());
03677 style->setOutlineStyle(parentStyle->outlineStyle());
03678 }
03679 else if (isInitial)
03680 style->resetOutline();
03681 break;
03682
03683 case CSS_PROP_BOX_SIZING:
03684 HANDLE_INHERIT(boxSizing, BoxSizing)
03685 if (!primitiveValue) return;
03686 if (primitiveValue->getIdent() == CSS_VAL_CONTENT_BOX)
03687 style->setBoxSizing(CONTENT_BOX);
03688 else
03689 if (primitiveValue->getIdent() == CSS_VAL_BORDER_BOX)
03690 style->setBoxSizing(BORDER_BOX);
03691 break;
03692 case CSS_PROP_OUTLINE_OFFSET: {
03693 HANDLE_INHERIT_AND_INITIAL(outlineOffset, OutlineOffset)
03694
03695 int offset = primitiveValue->computeLength(style, paintDeviceMetrics);
03696 if (offset < 0) return;
03697
03698 style->setOutlineOffset(offset);
03699 break;
03700 }
03701 case CSS_PROP_TEXT_SHADOW: {
03702 if (isInherit) {
03703 style->setTextShadow(parentStyle->textShadow() ? new ShadowData(*parentStyle->textShadow()) : 0);
03704 return;
03705 }
03706 else if (isInitial) {
03707 style->setTextShadow(0);
03708 return;
03709 }
03710
03711 if (primitiveValue) {
03712 style->setTextShadow(0);
03713 return;
03714 }
03715
03716 if (!value->isValueList()) return;
03717 CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value);
03718 int len = list->length();
03719 for (int i = 0; i < len; i++) {
03720 ShadowValueImpl *item = static_cast<ShadowValueImpl*>(list->item(i));
03721
03722 int x = item->x->computeLength(style, paintDeviceMetrics);
03723 int y = item->y->computeLength(style, paintDeviceMetrics);
03724 int blur = item->blur ? item->blur->computeLength(style, paintDeviceMetrics) : 0;
03725 QColor col = khtml::transparentColor;
03726 if (item->color) {
03727 int ident = item->color->getIdent();
03728 if (ident)
03729 col = colorForCSSValue( ident );
03730 else if (item->color->primitiveType() == CSSPrimitiveValue::CSS_RGBCOLOR)
03731 col.setRgb(item->color->getRGBColorValue());
03732 }
03733 ShadowData* shadowData = new ShadowData(x, y, blur, col);
03734 style->setTextShadow(shadowData, i != 0);
03735 }
03736
03737 break;
03738 }
03739 case CSS_PROP_OPACITY:
03740 HANDLE_INHERIT_AND_INITIAL(opacity, Opacity)
03741 if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
03742 return;
03743
03744
03745 style->setOpacity(kMin(1.0f, kMax(0.0f, (float)primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER))));
03746 break;
03747 case CSS_PROP__KHTML_MARQUEE:
03748 if (value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return;
03749 style->setMarqueeDirection(parentStyle->marqueeDirection());
03750 style->setMarqueeIncrement(parentStyle->marqueeIncrement());
03751 style->setMarqueeSpeed(parentStyle->marqueeSpeed());
03752 style->setMarqueeLoopCount(parentStyle->marqueeLoopCount());
03753 style->setMarqueeBehavior(parentStyle->marqueeBehavior());
03754 break;
03755 case CSS_PROP__KHTML_MARQUEE_REPETITION: {
03756 HANDLE_INHERIT_AND_INITIAL(marqueeLoopCount, MarqueeLoopCount)
03757 if (!primitiveValue) return;
03758 if (primitiveValue->getIdent() == CSS_VAL_INFINITE)
03759 style->setMarqueeLoopCount(-1);
03760 else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER)
03761 style->setMarqueeLoopCount((int)(primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER)));
03762 break;
03763 }
03764 case CSS_PROP__KHTML_MARQUEE_SPEED: {
03765 HANDLE_INHERIT_AND_INITIAL(marqueeSpeed, MarqueeSpeed)
03766 if (!primitiveValue) return;
03767 if (primitiveValue->getIdent()) {
03768 switch (primitiveValue->getIdent())
03769 {
03770 case CSS_VAL_SLOW:
03771 style->setMarqueeSpeed(500);
03772 break;
03773 case CSS_VAL_NORMAL:
03774 style->setMarqueeSpeed(85);
03775 break;
03776 case CSS_VAL_FAST:
03777 style->setMarqueeSpeed(10);
03778 break;
03779 }
03780 }
03781 else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_S)
03782 style->setMarqueeSpeed(int(1000*primitiveValue->floatValue(CSSPrimitiveValue::CSS_S)));
03783 else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_MS)
03784 style->setMarqueeSpeed(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_MS)));
03785 else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER)
03786 style->setMarqueeSpeed(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER)));
03787 break;
03788 }
03789 case CSS_PROP__KHTML_MARQUEE_INCREMENT: {
03790 HANDLE_INHERIT_AND_INITIAL(marqueeIncrement, MarqueeIncrement)
03791 if (!primitiveValue) return;
03792 if (primitiveValue->getIdent()) {
03793 switch (primitiveValue->getIdent())
03794 {
03795 case CSS_VAL_SMALL:
03796 style->setMarqueeIncrement(Length(1, Fixed));
03797 break;
03798 case CSS_VAL_NORMAL:
03799 style->setMarqueeIncrement(Length(6, Fixed));
03800 break;
03801 case CSS_VAL_LARGE:
03802 style->setMarqueeIncrement(Length(36, Fixed));
03803 break;
03804 }
03805 }
03806 else {
03807 bool ok = true;
03808 Length l = convertToLength(primitiveValue, style, paintDeviceMetrics, &ok);
03809 if (ok)
03810 style->setMarqueeIncrement(l);
03811 }
03812 break;
03813 }
03814 case CSS_PROP__KHTML_MARQUEE_STYLE: {
03815 HANDLE_INHERIT_AND_INITIAL(marqueeBehavior, MarqueeBehavior)
03816 if (!primitiveValue || !primitiveValue->getIdent()) return;
03817 switch (primitiveValue->getIdent())
03818 {
03819 case CSS_VAL_NONE:
03820 style->setMarqueeBehavior(MNONE);
03821 break;
03822 case CSS_VAL_SCROLL:
03823 style->setMarqueeBehavior(MSCROLL);
03824 break;
03825 case CSS_VAL_SLIDE:
03826 style->setMarqueeBehavior(MSLIDE);
03827 break;
03828 case CSS_VAL_ALTERNATE:
03829 style->setMarqueeBehavior(MALTERNATE);
03830 break;
03831 case CSS_VAL_UNFURL:
03832 style->setMarqueeBehavior(MUNFURL);
03833 break;
03834 }
03835 break;
03836 }
03837 case CSS_PROP__KHTML_MARQUEE_DIRECTION: {
03838 HANDLE_INHERIT_AND_INITIAL(marqueeDirection, MarqueeDirection)
03839 if (!primitiveValue || !primitiveValue->getIdent()) return;
03840 switch (primitiveValue->getIdent())
03841 {
03842 case CSS_VAL_FORWARDS:
03843 style->setMarqueeDirection(MFORWARD);
03844 break;
03845 case CSS_VAL_BACKWARDS:
03846 style->setMarqueeDirection(MBACKWARD);
03847 break;
03848 case CSS_VAL_AUTO:
03849 style->setMarqueeDirection(MAUTO);
03850 break;
03851 case CSS_VAL_AHEAD:
03852 case CSS_VAL_UP:
03853 style->setMarqueeDirection(MUP);
03854 break;
03855 case CSS_VAL_REVERSE:
03856 case CSS_VAL_DOWN:
03857 style->setMarqueeDirection(MDOWN);
03858 break;
03859 case CSS_VAL_LEFT:
03860 style->setMarqueeDirection(MLEFT);
03861 break;
03862 case CSS_VAL_RIGHT:
03863 style->setMarqueeDirection(MRIGHT);
03864 break;
03865 }
03866 break;
03867 }
03868 default:
03869 return;
03870 }
03871 }
03872
03873 void CSSStyleSelector::mapBackgroundAttachment(BackgroundLayer* layer, DOM::CSSValueImpl* value)
03874 {
03875 if (value->cssValueType() == CSSValue::CSS_INITIAL) {
03876 layer->setBackgroundAttachment(RenderStyle::initialBackgroundAttachment());
03877 return;
03878 }
03879
03880 if (!value->isPrimitiveValue()) return;
03881 CSSPrimitiveValueImpl* primitiveValue = static_cast<CSSPrimitiveValueImpl*>(value);
03882 switch (primitiveValue->getIdent()) {
03883 case CSS_VAL_FIXED:
03884 layer->setBackgroundAttachment(false);
03885 break;
03886 case CSS_VAL_SCROLL:
03887 layer->setBackgroundAttachment(true);
03888 break;
03889 default:
03890 return;
03891 }
03892 }
03893
03894 void CSSStyleSelector::mapBackgroundClip(BackgroundLayer* layer, CSSValueImpl* value)
03895 {
03896 if (value->cssValueType() == CSSValue::CSS_INITIAL) {
03897 layer->setBackgroundClip(RenderStyle::initialBackgroundClip());
03898 return;
03899 }
03900
03901 if (!value->isPrimitiveValue()) return;
03902 CSSPrimitiveValueImpl* primitiveValue = static_cast<CSSPrimitiveValueImpl*>(value);
03903 switch (primitiveValue->getIdent()) {
03904 case CSS_VAL_BORDER:
03905 layer->setBackgroundClip(BGBORDER);
03906 break;
03907 case CSS_VAL_PADDING:
03908 layer->setBackgroundClip(BGPADDING);
03909 break;
03910 default:
03911 layer->setBackgroundClip(BGCONTENT);
03912 break;
03913 }
03914 }
03915
03916 void CSSStyleSelector::mapBackgroundOrigin(BackgroundLayer* layer, CSSValueImpl* value)
03917 {
03918 if (value->cssValueType() == CSSValue::CSS_INITIAL) {
03919 layer->setBackgroundOrigin(RenderStyle::initialBackgroundOrigin());
03920 return;
03921 }
03922
03923 if (!value->isPrimitiveValue()) return;
03924 CSSPrimitiveValueImpl* primitiveValue = static_cast<CSSPrimitiveValueImpl*>(value);
03925 switch (primitiveValue->getIdent()) {
03926 case CSS_VAL_BORDER:
03927 layer->setBackgroundOrigin(BGBORDER);
03928 break;
03929 case CSS_VAL_PADDING:
03930 layer->setBackgroundOrigin(BGPADDING);
03931 break;
03932 default:
03933 layer->setBackgroundOrigin(BGCONTENT);
03934 break;
03935 }
03936 }
03937
03938 void CSSStyleSelector::mapBackgroundImage(BackgroundLayer* layer, DOM::CSSValueImpl* value)
03939 {
03940 if (value->cssValueType() == CSSValue::CSS_INITIAL) {
03941 layer->setBackgroundImage(RenderStyle::initialBackgroundImage());
03942 return;
03943 }
03944
03945 if (!value->isPrimitiveValue()) return;
03946 CSSPrimitiveValueImpl* primitiveValue = static_cast<CSSPrimitiveValueImpl*>(value);
03947 layer->setBackgroundImage(static_cast<CSSImageValueImpl *>(primitiveValue)->image());
03948 }
03949
03950 void CSSStyleSelector::mapBackgroundRepeat(BackgroundLayer* layer, DOM::CSSValueImpl* value)
03951 {
03952 if (value->cssValueType() == CSSValue::CSS_INITIAL) {
03953 layer->setBackgroundRepeat(RenderStyle::initialBackgroundRepeat());
03954 return;
03955 }
03956
03957 if (!value->isPrimitiveValue()) return;
03958 CSSPrimitiveValueImpl* primitiveValue = static_cast<CSSPrimitiveValueImpl*>(value);
03959 switch(primitiveValue->getIdent()) {
03960 case CSS_VAL_REPEAT:
03961 layer->setBackgroundRepeat(REPEAT);
03962 break;
03963 case CSS_VAL_REPEAT_X:
03964 layer->setBackgroundRepeat(REPEAT_X);
03965 break;
03966 case CSS_VAL_REPEAT_Y:
03967 layer->setBackgroundRepeat(REPEAT_Y);
03968 break;
03969 case CSS_VAL_NO_REPEAT:
03970 layer->setBackgroundRepeat(NO_REPEAT);
03971 break;
03972 default:
03973 return;
03974 }
03975 }
03976
03977
03978 void CSSStyleSelector::mapBackgroundSize(BackgroundLayer* layer, CSSValueImpl* value)
03979 {
03980 LengthSize b = RenderStyle::initialBackgroundSize();
03981
03982 if (value->cssValueType() == CSSValue::CSS_INITIAL) {
03983 layer->setBackgroundSize(b);
03984 return;
03985 }
03986
03987 if (!value->isPrimitiveValue())
03988 return;
03989
03990 CSSPrimitiveValueImpl* primitiveValue = static_cast<CSSPrimitiveValueImpl*>(value);
03991 PairImpl* pair = primitiveValue->getPairValue();
03992 if (!pair)
03993 return;
03994
03995 CSSPrimitiveValueImpl* first = static_cast<CSSPrimitiveValueImpl*>(pair->first());
03996 CSSPrimitiveValueImpl* second = static_cast<CSSPrimitiveValueImpl*>(pair->second());
03997
03998 if (!first || !second)
03999 return;
04000
04001 Length firstLength, secondLength;
04002 int firstType = first->primitiveType();
04003 int secondType = second->primitiveType();
04004
04005 if (firstType == CSSPrimitiveValue::CSS_UNKNOWN)
04006 firstLength = Length(Variable);
04007 else if (firstType > CSSPrimitiveValue::CSS_PERCENTAGE && firstType < CSSPrimitiveValue::CSS_DEG)
04008 firstLength = Length(first->computeLength(style, paintDeviceMetrics), Fixed);
04009 else if (firstType == CSSPrimitiveValue::CSS_PERCENTAGE)
04010 firstLength = Length((int)first->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
04011 else
04012 return;
04013
04014 if (secondType == CSSPrimitiveValue::CSS_UNKNOWN)
04015 secondLength = Length(Variable);
04016 else if (secondType > CSSPrimitiveValue::CSS_PERCENTAGE && secondType < CSSPrimitiveValue::CSS_DEG)
04017 secondLength = Length(second->computeLength(style, paintDeviceMetrics), Fixed);
04018 else if (secondType == CSSPrimitiveValue::CSS_PERCENTAGE)
04019 secondLength = Length((int)second->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
04020 else
04021 return;
04022
04023 b.width = firstLength;
04024 b.height = secondLength;
04025 layer->setBackgroundSize(b);
04026 }
04027
04028 void CSSStyleSelector::mapBackgroundXPosition(BackgroundLayer* layer, DOM::CSSValueImpl* value)
04029 {
04030 if (value->cssValueType() == CSSValue::CSS_INITIAL) {
04031 layer->setBackgroundXPosition(RenderStyle::initialBackgroundXPosition());
04032 return;
04033 }
04034
04035 if (!value->isPrimitiveValue()) return;
04036 CSSPrimitiveValueImpl* primitiveValue = static_cast<CSSPrimitiveValueImpl*>(value);
04037 Length l;
04038 int type = primitiveValue->primitiveType();
04039 if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
04040 l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
04041 else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
04042 l = Length((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
04043 else
04044 return;
04045 layer->setBackgroundXPosition(l);
04046 }
04047
04048 void CSSStyleSelector::mapBackgroundYPosition(BackgroundLayer* layer, DOM::CSSValueImpl* value)
04049 {
04050 if (value->cssValueType() == CSSValue::CSS_INITIAL) {
04051 layer->setBackgroundYPosition(RenderStyle::initialBackgroundYPosition());
04052 return;
04053 }
04054
04055 if (!value->isPrimitiveValue()) return;
04056 CSSPrimitiveValueImpl* primitiveValue = static_cast<CSSPrimitiveValueImpl*>(value);
04057 Length l;
04058 int type = primitiveValue->primitiveType();
04059 if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
04060 l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
04061 else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
04062 l = Length((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
04063 else
04064 return;
04065 layer->setBackgroundYPosition(l);
04066 }
04067
04068 #ifdef APPLE_CHANGES
04069 void CSSStyleSelector::checkForGenericFamilyChange(RenderStyle* aStyle, RenderStyle* aParentStyle)
04070 {
04071 const FontDef& childFont = aStyle->htmlFont().fontDef;
04072
04073 if (childFont.sizeSpecified || !aParentStyle)
04074 return;
04075
04076 const FontDef& parentFont = aParentStyle->htmlFont().fontDef;
04077
04078 if (childFont.genericFamily == parentFont.genericFamily)
04079 return;
04080
04081
04082 if (childFont.genericFamily != FontDef::eMonospace &&
04083 parentFont.genericFamily != FontDef::eMonospace)
04084 return;
04085
04086
04087
04088
04089 float size = 0;
04090 int minFontSize = settings->minFontSize();
04091 size = (childFont.genericFamily == FontDef::eMonospace) ? m_fixedFontSizes[3] : m_fontSizes[3];
04092 int isize = (int)size;
04093 if (isize < minFontSize)
04094 isize = minFontSize;
04095
04096 FontDef newFontDef(childFont);
04097 newFontDef.size = isize;
04098 aStyle->setFontDef(newFontDef);
04099 }
04100 #endif
04101
04102 }