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