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