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 9
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, QValueList<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.clear();
00324 float scale = 1.0;
00325 static const float fontFactors[] = {3./5., 3./4., 8./9., 1., 6./5., 3./2., 2., 3., 4.};
00326 static const float smallFontFactors[] = {3./4., 5./6., 8./9., 1., 6./5., 3./2., 2., 3., 4.};
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 << 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 void CSSStyleSelector::checkSelector(int selIndex, DOM::ElementImpl *e)
00763 {
00764 dynamicPseudo = RenderStyle::NOPSEUDO;
00765
00766 NodeImpl *n = e;
00767
00768 selectorCache[ selIndex ].state = Invalid;
00769 CSSSelector *sel = selectors[ selIndex ];
00770
00771
00772 subject = true;
00773
00774
00775
00776
00777 bool onlyHoverActive = (((sel->tag & NodeImpl_IdLocalMask) == NodeImpl_IdLocalMask) &&
00778 (sel->match == CSSSelector::Pseudo &&
00779 (sel->pseudoType() == CSSSelector::PseudoHover ||
00780 sel->pseudoType() == CSSSelector::PseudoActive)));
00781 bool affectedByHover = style->affectedByHoverRules();
00782 bool affectedByActive = style->affectedByActiveRules();
00783
00784
00785 if(!checkOneSelector(sel, e)) return;
00786
00787
00788 CSSSelector::Relation relation = sel->relation;
00789 while((sel = sel->tagHistory))
00790 {
00791 if(!n->isElementNode()) return;
00792 switch(relation)
00793 {
00794 case CSSSelector::Descendant:
00795 {
00796 bool found = false;
00797 while(!found)
00798 {
00799 subject = false;
00800 n = n->parentNode();
00801 if(!n || !n->isElementNode()) return;
00802 ElementImpl *elem = static_cast<ElementImpl *>(n);
00803 if(checkOneSelector(sel, elem)) found = true;
00804 }
00805 break;
00806 }
00807 case CSSSelector::Child:
00808 {
00809 subject = false;
00810 n = n->parentNode();
00811 if (!strictParsing)
00812 while (n && n->implicitNode()) n = n->parentNode();
00813 if(!n || !n->isElementNode()) return;
00814 ElementImpl *elem = static_cast<ElementImpl *>(n);
00815 if(!checkOneSelector(sel, elem)) return;
00816 break;
00817 }
00818 case CSSSelector::Sibling:
00819 {
00820 subject = false;
00821 n = n->previousSibling();
00822 while( n && !n->isElementNode() )
00823 n = n->previousSibling();
00824 if( !n ) return;
00825 ElementImpl *elem = static_cast<ElementImpl *>(n);
00826 if(!checkOneSelector(sel, elem)) return;
00827 break;
00828 }
00829 case CSSSelector::Cousin:
00830 {
00831 subject = false;
00832 ElementImpl *elem = 0;
00833 do {
00834 n = n->previousSibling();
00835 while( n && !n->isElementNode() )
00836 n = n->previousSibling();
00837 if( !n ) return;
00838 elem = static_cast<ElementImpl *>(n);
00839 } while (!checkOneSelector(sel, elem));
00840 break;
00841 }
00842 case CSSSelector::SubSelector:
00843 {
00844 if (onlyHoverActive)
00845 onlyHoverActive = (sel->match == CSSSelector::Pseudo &&
00846 (sel->pseudoType() == CSSSelector::PseudoHover ||
00847 sel->pseudoType() == CSSSelector::PseudoActive));
00848
00849
00850 ElementImpl *elem = static_cast<ElementImpl *>(n);
00851
00852 if ( dynamicPseudo != RenderStyle::NOPSEUDO ) {
00853 return;
00854 }
00855 if(!checkOneSelector(sel, elem)) return;
00856
00857 break;
00858 }
00859 }
00860 relation = sel->relation;
00861 }
00862
00863
00864 if (onlyHoverActive && subject) {
00865 if (pseudoState == PseudoUnknown)
00866 checkPseudoState( encodedurl, e );
00867
00868 if (pseudoState == PseudoNone) {
00869 if (!affectedByHover && style->affectedByHoverRules())
00870 style->setAffectedByHoverRules(false);
00871 if (!affectedByActive && style->affectedByActiveRules())
00872 style->setAffectedByActiveRules(false);
00873 return;
00874 }
00875 }
00876
00877 if ( dynamicPseudo != RenderStyle::NOPSEUDO ) {
00878 selectorCache[selIndex].state = AppliesPseudo;
00879 selectors[ selIndex ]->pseudoId = dynamicPseudo;
00880 } else
00881 selectorCache[ selIndex ].state = Applies;
00882
00883
00884 return;
00885 }
00886
00887 bool CSSStyleSelector::checkOneSelector(DOM::CSSSelector *sel, DOM::ElementImpl *e)
00888 {
00889 if(!e)
00890 return false;
00891
00892 unsigned int element_id = e->id();
00893 if ( (sel->tag & NodeImpl_IdNSMask) == NodeImpl_IdNSMask ) {
00894
00895 unsigned int sel_id = sel->tag & NodeImpl_IdLocalMask;
00896 if ( (element_id & NodeImpl_IdLocalMask) != sel_id &&
00897 sel_id != NodeImpl_IdLocalMask )
00898 return false;
00899 } else {
00900
00901 if( (element_id & NodeImpl_IdNSMask) != (sel->tag & NodeImpl_IdNSMask) )
00902 return false;
00903 if ( element_id != sel->tag &&
00904 (sel->tag & NodeImpl_IdLocalMask) != NodeImpl_IdLocalMask )
00905 return false;
00906 }
00907
00908 if(sel->attr)
00909 {
00910 unsigned int attr_id = sel->attr;
00911 if ( (attr_id & NodeImpl_IdNSMask ) == NodeImpl_IdNSMask ) {
00912
00913
00914
00915
00916
00917
00918
00919
00920 attr_id &= NodeImpl_IdLocalMask;
00921 }
00922 DOMString value = e->getAttribute(attr_id);
00923 if(value.isNull()) return false;
00924
00925 switch(sel->match)
00926 {
00927 case CSSSelector::Exact:
00928
00929
00930 if ( e->getDocument()->htmlMode() != DocumentImpl::XHtml ) {
00931 if ( strcasecmp(sel->value, value) )
00932 return false;
00933 } else {
00934 if ( strcmp(sel->value, value) )
00935 return false;
00936 }
00937 break;
00938 case CSSSelector::Id:
00939 if( (strictParsing && strcmp(sel->value, value) ) ||
00940 (!strictParsing && strcasecmp(sel->value, value)))
00941 return false;
00942 break;
00943 case CSSSelector::Set:
00944 break;
00945 case CSSSelector::List:
00946 {
00947 int spacePos = value.find(' ', 0);
00948 if (spacePos == -1) {
00949
00950
00951
00952 if( (strictParsing && strcmp(sel->value, value) ) ||
00953 (!strictParsing && strcasecmp(sel->value, value)))
00954 return false;
00955 break;
00956 }
00957
00958
00959 spacePos = sel->value.find(' ');
00960 if (spacePos != -1)
00961 return false;
00962
00963 QString str = value.string();
00964 QString selStr = sel->value.string();
00965 const int selStrlen = selStr.length();
00966 int pos = 0;
00967 for ( ;; ) {
00968 pos = str.find(selStr, pos, strictParsing);
00969 if ( pos == -1 ) return false;
00970 if ( pos == 0 || str[pos-1] == ' ' ) {
00971 uint endpos = pos + selStrlen;
00972 if ( endpos >= str.length() || str[endpos] == ' ' )
00973 break;
00974 }
00975 ++pos;
00976 }
00977 break;
00978 }
00979 case CSSSelector::Contain:
00980 {
00981
00982 QString str = value.string();
00983 QString selStr = sel->value.string();
00984 int pos = str.find(selStr, 0, strictParsing);
00985 if(pos == -1) return false;
00986 break;
00987 }
00988 case CSSSelector::Begin:
00989 {
00990
00991 QString str = value.string();
00992 QString selStr = sel->value.string();
00993 int pos = str.find(selStr, 0, strictParsing);
00994 if(pos != 0) return false;
00995 break;
00996 }
00997 case CSSSelector::End:
00998 {
00999
01000 QString str = value.string();
01001 QString selStr = sel->value.string();
01002 if (strictParsing && !str.endsWith(selStr)) return false;
01003 if (!strictParsing) {
01004 int pos = str.length() - selStr.length();
01005 if (pos < 0 || pos != str.find(selStr, pos, false) )
01006 return false;
01007 }
01008 break;
01009 }
01010 case CSSSelector::Hyphen:
01011 {
01012
01013 QString str = value.string();
01014 QString selStr = sel->value.string();
01015 if(str.length() < selStr.length()) return false;
01016
01017 if(str.find(selStr, 0, strictParsing) != 0) return false;
01018
01019 if(str.length() != selStr.length()
01020 && str[selStr.length()] != '-') return false;
01021 break;
01022 }
01023 case CSSSelector::Pseudo:
01024 case CSSSelector::None:
01025 break;
01026 }
01027 }
01028 if(sel->match == CSSSelector::Pseudo)
01029 {
01030
01031
01032
01033 switch (sel->pseudoType()) {
01034 case CSSSelector::PseudoEmpty:
01035 if (!e->firstChild())
01036 return true;
01037 break;
01038 case CSSSelector::PseudoFirstChild: {
01039
01040 if (e->parentNode() && e->parentNode()->isElementNode()) {
01041 DOM::NodeImpl* n = e->previousSibling();
01042 while ( n && !n->isElementNode() )
01043 n = n->previousSibling();
01044 if ( !n )
01045 return true;
01046 }
01047 break;
01048 }
01049 case CSSSelector::PseudoLastChild: {
01050
01051 if (e->parentNode() && e->parentNode()->isElementNode()) {
01052 DOM::NodeImpl* n = e->nextSibling();
01053 while ( n && !n->isElementNode() )
01054 n = n->nextSibling();
01055 if ( !n )
01056 return true;
01057 }
01058 break;
01059 }
01060 case CSSSelector::PseudoOnlyChild: {
01061
01062 if (e->parentNode() && e->parentNode()->isElementNode()) {
01063 DOM::NodeImpl* n = e->previousSibling();
01064 while ( n && !n->isElementNode() )
01065 n = n->previousSibling();
01066 if ( !n ) {
01067 n = e->nextSibling();
01068 while ( n && !n->isElementNode() )
01069 n = n->nextSibling();
01070 if ( !n )
01071 return true;
01072 }
01073 }
01074 break;
01075 }
01076 case CSSSelector::PseudoFirstLine:
01077 if ( subject ) {
01078 dynamicPseudo=RenderStyle::FIRST_LINE;
01079 return true;
01080 }
01081 break;
01082 case CSSSelector::PseudoFirstLetter:
01083 if ( subject ) {
01084 dynamicPseudo=RenderStyle::FIRST_LETTER;
01085 return true;
01086 }
01087 break;
01088 case CSSSelector::PseudoTarget:
01089 #ifdef APPLE_CHANGES
01090 if (!e->getDocument()->getCSSTarget() &&
01091 e == e->getDocument()->documentElement())
01092 return true;
01093 if (e == e->getDocument()->getCSSTarget())
01094 return true;
01095 #endif
01096 break;
01097 case CSSSelector::PseudoLink:
01098 if ( pseudoState == PseudoUnknown )
01099 checkPseudoState( encodedurl, e );
01100 if ( pseudoState == PseudoLink )
01101 return true;
01102 break;
01103 case CSSSelector::PseudoVisited:
01104 if ( pseudoState == PseudoUnknown )
01105 checkPseudoState( encodedurl, e );
01106 if ( pseudoState == PseudoVisited )
01107 return true;
01108 break;
01109 case CSSSelector::PseudoHover: {
01110
01111
01112 if (strictParsing || e->id() != ID_A || e->hasAnchor()) {
01113 if (element == e)
01114 style->setAffectedByHoverRules(true);
01115 if (e->renderer()) {
01116 if (element != e)
01117 e->renderer()->style()->setAffectedByHoverRules(true);
01118 if (e->renderer()->mouseInside())
01119 return true;
01120 }
01121 }
01122 break;
01123 }
01124 case CSSSelector::PseudoFocus:
01125 if (e && e->focused()) {
01126 return true;
01127 }
01128 break;
01129 case CSSSelector::PseudoActive:
01130
01131
01132 if (strictParsing || e->id() != ID_A || e->hasAnchor()) {
01133 if (element == e)
01134 style->setAffectedByActiveRules(true);
01135 else if (e->renderer())
01136 e->renderer()->style()->setAffectedByActiveRules(true);
01137 if (e->active())
01138 return true;
01139 }
01140 break;
01141 case CSSSelector::PseudoRoot:
01142 if (e == e->getDocument()->documentElement())
01143 return true;
01144 break;
01145 case CSSSelector::PseudoNot: {
01146
01147 for (CSSSelector* subSel = sel->simpleSelector; subSel;
01148 subSel = subSel->tagHistory) {
01149
01150
01151 if (subSel->simpleSelector)
01152 break;
01153 if (!checkOneSelector(subSel, e))
01154 return true;
01155 }
01156 break;
01157 }
01158 case CSSSelector::PseudoSelection:
01159 dynamicPseudo = RenderStyle::SELECTION;
01160 return true;
01161 case CSSSelector::PseudoBefore:
01162 dynamicPseudo = RenderStyle::BEFORE;
01163 return true;
01164 case CSSSelector::PseudoAfter:
01165 dynamicPseudo = RenderStyle::AFTER;
01166 return true;
01167
01168 case CSSSelector::PseudoNotParsed:
01169 assert(false);
01170 break;
01171 case CSSSelector::PseudoLang:
01172
01173 case CSSSelector::PseudoOther:
01174 break;
01175 }
01176 return false;
01177 }
01178
01179 return true;
01180 }
01181
01182 void CSSStyleSelector::clearLists()
01183 {
01184 delete [] selectors;
01185 if ( selectorCache ) {
01186 for ( unsigned int i = 0; i < selectors_size; i++ )
01187 delete [] selectorCache[i].props;
01188
01189 delete [] selectorCache;
01190 }
01191 if ( properties ) {
01192 CSSOrderedProperty **prop = properties;
01193 while ( *prop ) {
01194 delete (*prop);
01195 prop++;
01196 }
01197 delete [] properties;
01198 }
01199 selectors = 0;
01200 properties = 0;
01201 selectorCache = 0;
01202 }
01203
01204
01205 void CSSStyleSelector::buildLists()
01206 {
01207 clearLists();
01208
01209
01210 QPtrList<CSSSelector> selectorList;
01211 CSSOrderedPropertyList propertyList;
01212
01213 if(m_medium == "print" && defaultPrintStyle)
01214 defaultPrintStyle->collect( &selectorList, &propertyList, Default,
01215 Default );
01216 else if(defaultStyle) defaultStyle->collect( &selectorList, &propertyList,
01217 Default, Default );
01218
01219 if (!strictParsing && defaultQuirksStyle)
01220 defaultQuirksStyle->collect( &selectorList, &propertyList, Default, Default );
01221
01222 if(userStyle) userStyle->collect(&selectorList, &propertyList, User, UserImportant );
01223 if(authorStyle) authorStyle->collect(&selectorList, &propertyList, Author, AuthorImportant );
01224
01225 selectors_size = selectorList.count();
01226 selectors = new CSSSelector *[selectors_size];
01227 CSSSelector *s = selectorList.first();
01228 CSSSelector **sel = selectors;
01229 while ( s ) {
01230 *sel = s;
01231 s = selectorList.next();
01232 ++sel;
01233 }
01234
01235 selectorCache = new SelectorCache[selectors_size];
01236 for ( unsigned int i = 0; i < selectors_size; i++ ) {
01237 selectorCache[i].state = Unknown;
01238 selectorCache[i].props_size = 0;
01239 selectorCache[i].props = 0;
01240 }
01241
01242
01243 propertyList.sort();
01244 properties_size = propertyList.count() + 1;
01245 properties = new CSSOrderedProperty *[ properties_size ];
01246 CSSOrderedProperty *p = propertyList.first();
01247 CSSOrderedProperty **prop = properties;
01248 while ( p ) {
01249 *prop = p;
01250 p = propertyList.next();
01251 ++prop;
01252 }
01253 *prop = 0;
01254
01255 unsigned int* offsets = new unsigned int[selectors_size];
01256 if(properties[0])
01257 offsets[properties[0]->selector] = 0;
01258 for(unsigned int p = 1; p < properties_size; ++p) {
01259
01260 if(!properties[p] || (properties[p]->selector != properties[p - 1]->selector)) {
01261 unsigned int sel = properties[p - 1]->selector;
01262 int* newprops = new int[selectorCache[sel].props_size+2];
01263 for ( unsigned int i=0; i < selectorCache[sel].props_size; i++ )
01264 newprops[i] = selectorCache[sel].props[i];
01265
01266 newprops[selectorCache[sel].props_size] = offsets[sel];
01267 newprops[selectorCache[sel].props_size+1] = p - offsets[sel];
01268 delete [] selectorCache[sel].props;
01269 selectorCache[sel].props = newprops;
01270 selectorCache[sel].props_size += 2;
01271
01272 if(properties[p]) {
01273 sel = properties[p]->selector;
01274 offsets[sel] = p;
01275 }
01276 }
01277 }
01278 delete [] offsets;
01279
01280
01281 #if 0
01282
01283 for ( unsigned int sel = 0; sel < selectors_size; ++sel ) {
01284 kdDebug( 6080 ) << "trying for sel: " << sel << endl;
01285 int len = 0;
01286 int offset = 0;
01287 bool matches = false;
01288 for ( unsigned int i = 0; i < selectors_size; i++ ) {
01289 int tag = selectors[i]->tag;
01290 if ( sel != tag && tag != -1 )
01291 selectorCache[i].state = Invalid;
01292 else
01293 selectorCache[i].state = Unknown;
01294
01295 if ( matches != ( selectorCache[i].state == Unknown ) ) {
01296 if ( matches ) {
01297 kdDebug( 6080 ) << "new: offs: " << offset << " len: " << len << endl;
01298 matches = false;
01299 }
01300 else {
01301 matches = true;
01302
01303 len = 0;
01304 }
01305 }
01306 ++len;
01307 }
01308 }
01309 #endif
01310 }
01311
01312
01313
01314
01315
01316 CSSOrderedRule::CSSOrderedRule(DOM::CSSStyleRuleImpl *r, DOM::CSSSelector *s, int _index)
01317 {
01318 rule = r;
01319 if(rule) r->ref();
01320 index = _index;
01321 selector = s;
01322 }
01323
01324 CSSOrderedRule::~CSSOrderedRule()
01325 {
01326 if(rule) rule->deref();
01327 }
01328
01329
01330
01331 CSSStyleSelectorList::CSSStyleSelectorList()
01332 : QPtrList<CSSOrderedRule>()
01333 {
01334 setAutoDelete(true);
01335 }
01336 CSSStyleSelectorList::~CSSStyleSelectorList()
01337 {
01338 }
01339
01340 void CSSStyleSelectorList::append( CSSStyleSheetImpl *sheet,
01341 const DOMString &medium )
01342 {
01343 if(!sheet || !sheet->isCSSStyleSheet()) return;
01344
01345
01346
01347 if( sheet->media() && !sheet->media()->contains( medium ) )
01348 return;
01349
01350 int len = sheet->length();
01351
01352 for(int i = 0; i< len; i++)
01353 {
01354 StyleBaseImpl *item = sheet->item(i);
01355 if(item->isStyleRule())
01356 {
01357 CSSStyleRuleImpl *r = static_cast<CSSStyleRuleImpl *>(item);
01358 QPtrList<CSSSelector> *s = r->selector();
01359 for(int j = 0; j < (int)s->count(); j++)
01360 {
01361 CSSOrderedRule *rule = new CSSOrderedRule(r, s->at(j), count());
01362 QPtrList<CSSOrderedRule>::append(rule);
01363
01364 }
01365 }
01366 else if(item->isImportRule())
01367 {
01368 CSSImportRuleImpl *import = static_cast<CSSImportRuleImpl *>(item);
01369
01370
01371
01372
01373 if( !import->media() || import->media()->contains( medium ) )
01374 {
01375 CSSStyleSheetImpl *importedSheet = import->styleSheet();
01376 append( importedSheet, medium );
01377 }
01378 }
01379 else if( item->isMediaRule() )
01380 {
01381 CSSMediaRuleImpl *r = static_cast<CSSMediaRuleImpl *>( item );
01382 CSSRuleListImpl *rules = r->cssRules();
01383
01384
01385
01386
01387
01388 if( ( !r->media() || r->media()->contains( medium ) ) && rules)
01389 {
01390
01391
01392
01393 for( unsigned j = 0; j < rules->length(); j++ )
01394 {
01395
01396
01397 CSSRuleImpl *childItem = rules->item( j );
01398 if( childItem->isStyleRule() )
01399 {
01400
01401 CSSStyleRuleImpl *styleRule =
01402 static_cast<CSSStyleRuleImpl *>( childItem );
01403
01404 QPtrList<CSSSelector> *s = styleRule->selector();
01405 for( int j = 0; j < ( int ) s->count(); j++ )
01406 {
01407 CSSOrderedRule *orderedRule = new CSSOrderedRule(
01408 styleRule, s->at( j ), count() );
01409 QPtrList<CSSOrderedRule>::append( orderedRule );
01410 }
01411 }
01412 else
01413 {
01414
01415
01416 }
01417 }
01418 }
01419 else
01420 {
01421
01422
01423 }
01424 }
01425
01426 }
01427 }
01428
01429
01430 void CSSStyleSelectorList::collect( QPtrList<CSSSelector> *selectorList, CSSOrderedPropertyList *propList,
01431 Source regular, Source important )
01432 {
01433 CSSOrderedRule *r = first();
01434 while( r ) {
01435 CSSSelector *sel = selectorList->first();
01436 int selectorNum = 0;
01437 while( sel ) {
01438 if ( *sel == *(r->selector) )
01439 break;
01440 sel = selectorList->next();
01441 selectorNum++;
01442 }
01443 if ( !sel )
01444 selectorList->append( r->selector );
01445
01446
01447 propList->append(r->rule->declaration(), selectorNum, r->selector->specificity(), regular, important );
01448 r = next();
01449 }
01450 }
01451
01452
01453
01454 int CSSOrderedPropertyList::compareItems(QPtrCollection::Item i1, QPtrCollection::Item i2)
01455 {
01456 int diff = static_cast<CSSOrderedProperty *>(i1)->priority
01457 - static_cast<CSSOrderedProperty *>(i2)->priority;
01458 return diff ? diff : static_cast<CSSOrderedProperty *>(i1)->position
01459 - static_cast<CSSOrderedProperty *>(i2)->position;
01460 }
01461
01462 void CSSOrderedPropertyList::append(DOM::CSSStyleDeclarationImpl *decl, uint selector, uint specificity,
01463 Source regular, Source important )
01464 {
01465 QPtrList<CSSProperty> *values = decl->values();
01466 if(!values) return;
01467 int len = values->count();
01468 for(int i = 0; i < len; i++)
01469 {
01470 CSSProperty *prop = values->at(i);
01471 Source source = regular;
01472
01473 if( prop->m_bImportant ) source = important;
01474 if( prop->nonCSSHint ) source = NonCSSHint;
01475
01476 bool first = false;
01477
01478 switch(prop->m_id)
01479 {
01480 case CSS_PROP_FONT_STYLE:
01481 case CSS_PROP_FONT_SIZE:
01482 case CSS_PROP_FONT_WEIGHT:
01483 case CSS_PROP_FONT_FAMILY:
01484 case CSS_PROP_FONT:
01485 case CSS_PROP_COLOR:
01486 case CSS_PROP_BACKGROUND_IMAGE:
01487 case CSS_PROP_DISPLAY:
01488
01489
01490 first = true;
01491 break;
01492 default:
01493 break;
01494 }
01495
01496 QPtrList<CSSOrderedProperty>::append(new CSSOrderedProperty(prop, selector,
01497 first, source, specificity,
01498 count() ));
01499 }
01500 }
01501
01502
01503
01504
01505 static Length convertToLength( CSSPrimitiveValueImpl *primitiveValue, RenderStyle *style, QPaintDeviceMetrics *paintDeviceMetrics, bool *ok = 0 )
01506 {
01507 Length l;
01508 if ( !primitiveValue ) {
01509 if ( ok )
01510 *ok = false;
01511 } else {
01512 int type = primitiveValue->primitiveType();
01513 if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
01514 l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
01515 else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
01516 l = Length(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE)), Percent);
01517 else if(type == CSSPrimitiveValue::CSS_NUMBER)
01518 l = Length(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER)*100), Percent);
01519 else if (type == CSSPrimitiveValue::CSS_HTML_RELATIVE)
01520 l = Length(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_HTML_RELATIVE)), Relative);
01521 else if ( ok )
01522 *ok = false;
01523 }
01524 return l;
01525 }
01526
01527
01528
01529 struct colorMap {
01530 int css_value;
01531 QRgb color;
01532 };
01533
01534 static const colorMap cmap[] = {
01535 { CSS_VAL_AQUA, 0xFF00FFFF },
01536 { CSS_VAL_BLACK, 0xFF000000 },
01537 { CSS_VAL_BLUE, 0xFF0000FF },
01538 { CSS_VAL_CRIMSON, 0xFFDC143C },
01539 { CSS_VAL_FUCHSIA, 0xFFFF00FF },
01540 { CSS_VAL_GRAY, 0xFF808080 },
01541 { CSS_VAL_GREEN, 0xFF008000 },
01542 { CSS_VAL_INDIGO, 0xFF4B0082 },
01543 { CSS_VAL_LIME, 0xFF00FF00 },
01544 { CSS_VAL_MAROON, 0xFF800000 },
01545 { CSS_VAL_NAVY, 0xFF000080 },
01546 { CSS_VAL_OLIVE, 0xFF808000 },
01547 { CSS_VAL_ORANGE, 0xFFFFA500 },
01548 { CSS_VAL_PURPLE, 0xFF800080 },
01549 { CSS_VAL_RED, 0xFFFF0000 },
01550 { CSS_VAL_SILVER, 0xFFC0C0C0 },
01551 { CSS_VAL_TEAL, 0xFF008080 },
01552 { CSS_VAL_WHITE, 0xFFFFFFFF },
01553 { CSS_VAL_YELLOW, 0xFFFFFF00 },
01554 { CSS_VAL_INVERT, invertedColor },
01555 { CSS_VAL_TRANSPARENT, transparentColor },
01556 { CSS_VAL_GREY, 0xff808080 },
01557 { 0, 0 }
01558 };
01559
01560 struct uiColors {
01561 int css_value;
01562 const char * configGroup;
01563 const char * configEntry;
01564 QPalette::ColorGroup group;
01565 QColorGroup::ColorRole role;
01566 };
01567
01568 const char * const wmgroup = "WM";
01569 const char * const generalgroup = "General";
01570
01571
01572
01573
01574 static const uiColors uimap[] = {
01575
01576 { CSS_VAL_ACTIVEBORDER, wmgroup, "background", QPalette::Active, QColorGroup::Light },
01577
01578 { CSS_VAL_ACTIVECAPTION, wmgroup, "background", QPalette::Active, QColorGroup::Text },
01579
01580 { CSS_VAL_CAPTIONTEXT, wmgroup, "activeForeground", QPalette::Active, QColorGroup::Text },
01581
01582 { CSS_VAL_BUTTONFACE, wmgroup, 0, QPalette::Inactive, QColorGroup::Button },
01583
01584 { CSS_VAL_BUTTONHIGHLIGHT, wmgroup, 0, QPalette::Inactive, QColorGroup::Light },
01585
01586 { CSS_VAL_BUTTONSHADOW, wmgroup, 0, QPalette::Inactive, QColorGroup::Shadow },
01587
01588 { CSS_VAL_BUTTONTEXT, wmgroup, "buttonForeground", QPalette::Inactive, QColorGroup::ButtonText },
01589
01590 { CSS_VAL_THREEDDARKSHADOW, wmgroup, 0, QPalette::Inactive, QColorGroup::Dark },
01591
01592 { CSS_VAL_THREEDFACE, wmgroup, 0, QPalette::Inactive, QColorGroup::Button },
01593
01594 { CSS_VAL_THREEDHIGHLIGHT, wmgroup, 0, QPalette::Inactive, QColorGroup::Light },
01595
01596 { CSS_VAL_THREEDLIGHTSHADOW, wmgroup, 0, QPalette::Inactive, QColorGroup::Midlight },
01597
01598 { CSS_VAL_THREEDSHADOW, wmgroup, 0, QPalette::Inactive, QColorGroup::Shadow },
01599
01600
01601 { CSS_VAL_INACTIVEBORDER, wmgroup, "background", QPalette::Disabled, QColorGroup::Background },
01602
01603 { CSS_VAL_INACTIVECAPTION, wmgroup, "inactiveBackground", QPalette::Disabled, QColorGroup::Background },
01604
01605 { CSS_VAL_INACTIVECAPTIONTEXT, wmgroup, "inactiveForeground", QPalette::Disabled, QColorGroup::Text },
01606 { CSS_VAL_GRAYTEXT, wmgroup, 0, QPalette::Disabled, QColorGroup::Text },
01607
01608
01609 { CSS_VAL_MENU, generalgroup, "background", QPalette::Inactive, QColorGroup::Background },
01610
01611 { CSS_VAL_MENUTEXT, generalgroup, "foreground", QPalette::Inactive, QColorGroup::Background },
01612
01613
01614 { CSS_VAL_HIGHLIGHT, generalgroup, "selectBackground", QPalette::Inactive, QColorGroup::Background },
01615
01616
01617 { CSS_VAL_HIGHLIGHTTEXT, generalgroup, "selectForeground", QPalette::Inactive, QColorGroup::Background },
01618
01619
01620 { CSS_VAL_APPWORKSPACE, generalgroup, "background", QPalette::Inactive, QColorGroup::Text },
01621
01622
01623 { CSS_VAL_SCROLLBAR, generalgroup, "background", QPalette::Inactive, QColorGroup::Background },
01624
01625
01626 { CSS_VAL_WINDOW, generalgroup, "windowBackground", QPalette::Inactive, QColorGroup::Background },
01627
01628 { CSS_VAL_WINDOWFRAME, generalgroup, "windowBackground", QPalette::Inactive, QColorGroup::Background },
01629
01630 { CSS_VAL_WINDOWTEXT, generalgroup, "windowForeground", QPalette::Inactive, QColorGroup::Text },
01631 { CSS_VAL_TEXT, generalgroup, 0, QPalette::Inactive, QColorGroup::Text },
01632 { 0, 0, 0, QPalette::NColorGroups, QColorGroup::NColorRoles }
01633 };
01634
01635 static QColor colorForCSSValue( int css_value )
01636 {
01637
01638 const colorMap *col = cmap;
01639 while ( col->css_value && col->css_value != css_value )
01640 ++col;
01641 if ( col->css_value )
01642 return col->color;
01643
01644 const uiColors *uicol = uimap;
01645 while ( uicol->css_value && uicol->css_value != css_value )
01646 ++uicol;
01647 #ifndef APPLE_CHANGES
01648 if ( !uicol->css_value ) {
01649 if ( css_value == CSS_VAL_INFOBACKGROUND )
01650 return QToolTip::palette().inactive().background();
01651 else if ( css_value == CSS_VAL_INFOTEXT )
01652 return QToolTip::palette().inactive().foreground();
01653 else if ( css_value == CSS_VAL_BACKGROUND ) {
01654 KConfig bckgrConfig("kdesktoprc", true, false);
01655 bckgrConfig.setGroup("Desktop0");
01656
01657 return bckgrConfig.readColorEntry("Color1", &qApp->palette().disabled().background());
01658 }
01659 return QColor();
01660 }
01661 #endif
01662
01663 const QPalette &pal = qApp->palette();
01664 QColor c = pal.color( uicol->group, uicol->role );
01665 #ifndef APPLE_CHANGES
01666 if ( uicol->configEntry ) {
01667 KConfig *globalConfig = KGlobal::config();
01668 globalConfig->setGroup( uicol->configGroup );
01669 c = globalConfig->readColorEntry( uicol->configEntry, &c );
01670 }
01671 #endif
01672
01673 return c;
01674 }
01675
01676
01677 void CSSStyleSelector::applyRule( int id, DOM::CSSValueImpl *value )
01678 {
01679
01680
01681 CSSPrimitiveValueImpl *primitiveValue = 0;
01682 if(value->isPrimitiveValue()) primitiveValue = static_cast<CSSPrimitiveValueImpl *>(value);
01683
01684 Length l;
01685 bool apply = false;
01686
01687 bool isInherit = (parentNode && value->cssValueType() == CSSValue::CSS_INHERIT);
01688 bool isInitial = (value->cssValueType() == CSSValue::CSS_INITIAL) ||
01689 (!parentNode && value->cssValueType() == CSSValue::CSS_INHERIT);
01690
01691
01692
01693
01694 switch(id)
01695 {
01696
01697 case CSS_PROP_BACKGROUND_ATTACHMENT:
01698 HANDLE_INHERIT_AND_INITIAL(backgroundAttachment, BackgroundAttachment)
01699 if(!primitiveValue) break;
01700 switch(primitiveValue->getIdent())
01701 {
01702 case CSS_VAL_FIXED:
01703 {
01704 style->setBackgroundAttachment(false);
01705
01706 if( style->backgroundImage() )
01707 view->useSlowRepaints();
01708 break;
01709 }
01710 case CSS_VAL_SCROLL:
01711 style->setBackgroundAttachment(true);
01712 break;
01713 default:
01714 return;
01715 }
01716 case CSS_PROP_BACKGROUND_REPEAT:
01717 {
01718 HANDLE_INHERIT_AND_INITIAL(backgroundRepeat, BackgroundRepeat)
01719 if(!primitiveValue) return;
01720 switch(primitiveValue->getIdent())
01721 {
01722 case CSS_VAL_REPEAT:
01723 style->setBackgroundRepeat( REPEAT );
01724 break;
01725 case CSS_VAL_REPEAT_X:
01726 style->setBackgroundRepeat( REPEAT_X );
01727 break;
01728 case CSS_VAL_REPEAT_Y:
01729 style->setBackgroundRepeat( REPEAT_Y );
01730 break;
01731 case CSS_VAL_NO_REPEAT:
01732 style->setBackgroundRepeat( NO_REPEAT );
01733 break;
01734 default:
01735 return;
01736 }
01737 }
01738 case CSS_PROP_BORDER_COLLAPSE:
01739 HANDLE_INHERIT_AND_INITIAL(borderCollapse, BorderCollapse)
01740 if(!primitiveValue) break;
01741 switch(primitiveValue->getIdent())
01742 {
01743 case CSS_VAL_COLLAPSE:
01744 style->setBorderCollapse(true);
01745 break;
01746 case CSS_VAL_SEPARATE:
01747 style->setBorderCollapse(false);
01748 break;
01749 default:
01750 return;
01751 }
01752 break;
01753
01754 case CSS_PROP_BORDER_TOP_STYLE:
01755 HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderTopStyle, BorderTopStyle, BorderStyle)
01756 if (!primitiveValue) return;
01757 style->setBorderTopStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL_NONE));
01758 break;
01759 case CSS_PROP_BORDER_RIGHT_STYLE:
01760 HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderRightStyle, BorderRightStyle, BorderStyle)
01761 if (!primitiveValue) return;
01762 style->setBorderRightStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL_NONE));
01763 break;
01764 case CSS_PROP_BORDER_BOTTOM_STYLE:
01765 HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderBottomStyle, BorderBottomStyle, BorderStyle)
01766 if (!primitiveValue) return;
01767 style->setBorderBottomStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL_NONE));
01768 break;
01769 case CSS_PROP_BORDER_LEFT_STYLE:
01770 HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderLeftStyle, BorderLeftStyle, BorderStyle)
01771 if (!primitiveValue) return;
01772 style->setBorderLeftStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL_NONE));
01773 break;
01774 case CSS_PROP_OUTLINE_STYLE:
01775 HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(outlineStyle, OutlineStyle, BorderStyle)
01776 if (!primitiveValue) return;
01777 style->setOutlineStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL_NONE));
01778 break;
01779 case CSS_PROP_CAPTION_SIDE:
01780 {
01781 HANDLE_INHERIT_AND_INITIAL(captionSide, CaptionSide)
01782 if(!primitiveValue) break;
01783 ECaptionSide c = RenderStyle::initialCaptionSide();
01784 switch(primitiveValue->getIdent())
01785 {
01786 case CSS_VAL_LEFT:
01787 c = CAPLEFT; break;
01788 case CSS_VAL_RIGHT:
01789 c = CAPRIGHT; break;
01790 case CSS_VAL_TOP:
01791 c = CAPTOP; break;
01792 case CSS_VAL_BOTTOM:
01793 c = CAPBOTTOM; break;
01794 default:
01795 return;
01796 }
01797 style->setCaptionSide(c);
01798 return;
01799 }
01800 case CSS_PROP_CLEAR:
01801 {
01802 HANDLE_INHERIT_AND_INITIAL(clear, Clear)
01803 if(!primitiveValue) break;
01804 EClear c = CNONE;
01805 switch(primitiveValue->getIdent())
01806 {
01807 case CSS_VAL_LEFT:
01808 c = CLEFT; break;
01809 case CSS_VAL_RIGHT:
01810 c = CRIGHT; break;
01811 case CSS_VAL_BOTH:
01812 c = CBOTH; break;
01813 case CSS_VAL_NONE:
01814 c = CNONE; break;
01815 default:
01816 return;
01817 }
01818 style->setClear(c);
01819 return;
01820 }
01821 case CSS_PROP_DIRECTION:
01822 {
01823 HANDLE_INHERIT_AND_INITIAL(direction, Direction)
01824 if(!primitiveValue) break;
01825 style->setDirection( (EDirection) (primitiveValue->getIdent() - CSS_VAL_LTR) );
01826 return;
01827 }
01828 case CSS_PROP_DISPLAY:
01829 {
01830 HANDLE_INHERIT_AND_INITIAL(display, Display)
01831 if(!primitiveValue) break;
01832 int id = primitiveValue->getIdent();
01833 style->setDisplay( id == CSS_VAL_NONE ? NONE : EDisplay(id - CSS_VAL_INLINE) );
01834 break;
01835 }
01836
01837 case CSS_PROP_EMPTY_CELLS:
01838 {
01839 HANDLE_INHERIT(emptyCells, EmptyCells);
01840 if (!primitiveValue) break;
01841 int id = primitiveValue->getIdent();
01842 if (id == CSS_VAL_SHOW)
01843 style->setEmptyCells(SHOW);
01844 else if (id == CSS_VAL_HIDE)
01845 style->setEmptyCells(HIDE);
01846 break;
01847 }
01848 case CSS_PROP_FLOAT:
01849 {
01850 HANDLE_INHERIT_AND_INITIAL(floating, Floating)
01851 if(!primitiveValue) return;
01852 EFloat f;
01853 switch(primitiveValue->getIdent())
01854 {
01855 case CSS_VAL_LEFT:
01856 f = FLEFT; break;
01857 case CSS_VAL_RIGHT:
01858 f = FRIGHT; break;
01859 case CSS_VAL_NONE:
01860 case CSS_VAL_CENTER:
01861 f = FNONE; break;
01862 default:
01863 return;
01864 }
01865 if (f!=FNONE && style->display()==LIST_ITEM)
01866 style->setDisplay(BLOCK);
01867
01868 style->setFloating(f);
01869 break;
01870 }
01871
01872 case CSS_PROP_FONT_STYLE:
01873 {
01874 FontDef fontDef = style->htmlFont().fontDef;
01875 if (isInherit)
01876 fontDef.italic = parentStyle->htmlFont().fontDef.italic;
01877 else if (isInitial)
01878 fontDef.italic = false;
01879 else {
01880 if(!primitiveValue) return;
01881 switch(primitiveValue->getIdent()) {
01882 case CSS_VAL_OBLIQUE:
01883
01884 case CSS_VAL_ITALIC:
01885 fontDef.italic = true;
01886 break;
01887 case CSS_VAL_NORMAL:
01888 fontDef.italic = false;
01889 break;
01890 default:
01891 return;
01892 }
01893 }
01894 fontDirty |= style->setFontDef( fontDef );
01895 break;
01896 }
01897
01898
01899 case CSS_PROP_FONT_VARIANT:
01900 {
01901 FontDef fontDef = style->htmlFont().fontDef;
01902 if (isInherit)
01903 fontDef.smallCaps = parentStyle->htmlFont().fontDef.weight;
01904 else if (isInitial)
01905 fontDef.smallCaps = false;
01906 else {
01907 if(!primitiveValue) return;
01908 int id = primitiveValue->getIdent();
01909 if ( id == CSS_VAL_NORMAL )
01910 fontDef.smallCaps = false;
01911 else if ( id == CSS_VAL_SMALL_CAPS )
01912 fontDef.smallCaps = true;
01913 else
01914 return;
01915 }
01916 fontDirty |= style->setFontDef( fontDef );
01917 break;
01918 }
01919
01920 case CSS_PROP_FONT_WEIGHT:
01921 {
01922 FontDef fontDef = style->htmlFont().fontDef;
01923 if (isInherit)
01924 fontDef.weight = parentStyle->htmlFont().fontDef.weight;
01925 else if (isInitial)
01926 fontDef.weight = QFont::Normal;
01927 else {
01928 if(!primitiveValue) return;
01929 if(primitiveValue->getIdent())
01930 {
01931 switch(primitiveValue->getIdent()) {
01932
01933
01934 case CSS_VAL_BOLD:
01935 case CSS_VAL_BOLDER:
01936 case CSS_VAL_600:
01937 case CSS_VAL_700:
01938 case CSS_VAL_800:
01939 case CSS_VAL_900:
01940 fontDef.weight = QFont::Bold;
01941 break;
01942 case CSS_VAL_NORMAL:
01943 case CSS_VAL_LIGHTER:
01944 case CSS_VAL_100:
01945 case CSS_VAL_200:
01946 case CSS_VAL_300:
01947 case CSS_VAL_400:
01948 case CSS_VAL_500:
01949 fontDef.weight = QFont::Normal;
01950 break;
01951 default:
01952 return;
01953 }
01954 }
01955 else
01956 {
01957
01958 }
01959 }
01960 fontDirty |= style->setFontDef( fontDef );
01961 break;
01962 }
01963
01964 case CSS_PROP_LIST_STYLE_POSITION:
01965 {
01966 HANDLE_INHERIT_AND_INITIAL(listStylePosition, ListStylePosition)
01967 if (!primitiveValue) return;
01968 if (primitiveValue->getIdent())
01969 style->setListStylePosition( (EListStylePosition) (primitiveValue->getIdent() - CSS_VAL_OUTSIDE) );
01970 return;
01971 }
01972
01973 case CSS_PROP_LIST_STYLE_TYPE:
01974 {
01975 HANDLE_INHERIT_AND_INITIAL(listStyleType, ListStyleType)
01976 if (!primitiveValue) return;
01977 if (primitiveValue->getIdent())
01978 {
01979 EListStyleType t;
01980 int id = primitiveValue->getIdent();
01981 if ( id == CSS_VAL_NONE) {
01982 t = LNONE;
01983 } else {
01984 t = EListStyleType(id - CSS_VAL_DISC);
01985 }
01986 style->setListStyleType(t);
01987 }
01988 return;
01989 }
01990
01991 case CSS_PROP_OVERFLOW:
01992 {
01993 HANDLE_INHERIT_AND_INITIAL(overflow, Overflow)
01994 if (!primitiveValue) return;
01995 EOverflow o;
01996 switch(primitiveValue->getIdent())
01997 {
01998 case CSS_VAL_VISIBLE:
01999 o = OVISIBLE; break;
02000 case CSS_VAL_HIDDEN:
02001 o = OHIDDEN; break;
02002 case CSS_VAL_SCROLL:
02003 o = OSCROLL; break;
02004 case CSS_VAL_AUTO:
02005 o = OAUTO; break;
02006 case CSS_VAL_MARQUEE:
02007 o = OMARQUEE; break;
02008 default:
02009 return;
02010 }
02011 style->setOverflow(o);
02012 return;
02013 }
02014 break;
02015 case CSS_PROP_PAGE_BREAK_BEFORE:
02016 {
02017 HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(pageBreakBefore, PageBreakBefore, PageBreak)
02018 if (!primitiveValue) return;
02019 switch (primitiveValue->getIdent()) {
02020 case CSS_VAL_AUTO:
02021 style->setPageBreakBefore(PBAUTO);
02022 break;
02023 case CSS_VAL_LEFT:
02024 case CSS_VAL_RIGHT:
02025 case CSS_VAL_ALWAYS:
02026 style->setPageBreakBefore(PBALWAYS);
02027 break;
02028 case CSS_VAL_AVOID:
02029 style->setPageBreakBefore(PBAVOID);
02030 break;
02031 }
02032 break;
02033 }
02034
02035 case CSS_PROP_PAGE_BREAK_AFTER:
02036 {
02037 HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(pageBreakAfter, PageBreakAfter, PageBreak)
02038 if (!primitiveValue) return;
02039 switch (primitiveValue->getIdent()) {
02040 case CSS_VAL_AUTO:
02041 style->setPageBreakAfter(PBAUTO);
02042 break;
02043 case CSS_VAL_LEFT:
02044 case CSS_VAL_RIGHT:
02045 case CSS_VAL_ALWAYS:
02046 style->setPageBreakAfter(PBALWAYS);
02047 break;
02048 case CSS_VAL_AVOID:
02049 style->setPageBreakAfter(PBAVOID);
02050 break;
02051 }
02052 break;
02053 }
02054
02055 case CSS_PROP_PAGE_BREAK_INSIDE: {
02056 HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(pageBreakInside, PageBreakInside, PageBreak)
02057 if (!primitiveValue) return;
02058 if (primitiveValue->getIdent() == CSS_VAL_AUTO)
02059 style->setPageBreakInside(PBAUTO);
02060 else if (primitiveValue->getIdent() == CSS_VAL_AVOID)
02061 style->setPageBreakInside(PBAVOID);
02062 return;
02063 }
02064
02065
02066 break;
02067
02068 case CSS_PROP_POSITION:
02069 {
02070 HANDLE_INHERIT_AND_INITIAL(position, Position)
02071 if (!primitiveValue) return;
02072 EPosition p;
02073 switch(primitiveValue->getIdent())
02074 {
02075 case CSS_VAL_STATIC:
02076 p = STATIC; break;
02077 case CSS_VAL_RELATIVE:
02078 p = RELATIVE; break;
02079 case CSS_VAL_ABSOLUTE:
02080 p = ABSOLUTE; break;
02081 case CSS_VAL_FIXED:
02082 {
02083 view->useSlowRepaints();
02084 p = FIXED;
02085 break;
02086 }
02087 default:
02088 return;
02089 }
02090 style->setPosition(p);
02091 return;
02092 }
02093
02094 case CSS_PROP_TABLE_LAYOUT: {
02095 HANDLE_INHERIT_AND_INITIAL(tableLayout, TableLayout)
02096
02097 if ( !primitiveValue )
02098 return;
02099
02100 ETableLayout l = RenderStyle::initialTableLayout();
02101 switch( primitiveValue->getIdent() ) {
02102 case CSS_VAL_FIXED:
02103 l = TFIXED;
02104
02105 case CSS_VAL_AUTO:
02106 style->setTableLayout( l );
02107 default:
02108 break;
02109 }
02110 break;
02111 }
02112
02113 case CSS_PROP_UNICODE_BIDI: {
02114 HANDLE_INHERIT_AND_INITIAL(unicodeBidi, UnicodeBidi)
02115 if(!primitiveValue) break;
02116 switch (primitiveValue->getIdent()) {
02117 case CSS_VAL_NORMAL:
02118 style->setUnicodeBidi(UBNormal);
02119 break;
02120 case CSS_VAL_EMBED:
02121 style->setUnicodeBidi(Embed);
02122 break;
02123 case CSS_VAL_BIDI_OVERRIDE:
02124 style->setUnicodeBidi(Override);
02125 break;
02126 default:
02127 return;
02128 }
02129 break;
02130 }
02131 case CSS_PROP_TEXT_TRANSFORM: {
02132 HANDLE_INHERIT_AND_INITIAL(textTransform, TextTransform)
02133
02134 if(!primitiveValue) break;
02135 if(!primitiveValue->getIdent()) return;
02136
02137 ETextTransform tt;
02138 switch(primitiveValue->getIdent()) {
02139 case CSS_VAL_CAPITALIZE: tt = CAPITALIZE; break;
02140 case CSS_VAL_UPPERCASE: tt = UPPERCASE; break;
02141 case CSS_VAL_LOWERCASE: tt = LOWERCASE; break;
02142 case CSS_VAL_NONE:
02143 default: tt = TTNONE; break;
02144 }
02145 style->setTextTransform(tt);
02146 break;
02147 }
02148
02149 case CSS_PROP_VISIBILITY:
02150 {
02151 HANDLE_INHERIT_AND_INITIAL(visibility, Visibility)
02152
02153 if(!primitiveValue) break;
02154 switch( primitiveValue->getIdent() ) {
02155 case CSS_VAL_HIDDEN:
02156 style->setVisibility( HIDDEN );
02157 break;
02158 case CSS_VAL_VISIBLE:
02159 style->setVisibility( VISIBLE );
02160 break;
02161 case CSS_VAL_COLLAPSE:
02162 style->setVisibility( COLLAPSE );
02163 default:
02164 break;
02165 }
02166 break;
02167 }
02168 case CSS_PROP_WHITE_SPACE:
02169 HANDLE_INHERIT_AND_INITIAL(whiteSpace, WhiteSpace)
02170
02171 if(!primitiveValue) break;
02172 if(!primitiveValue->getIdent()) return;
02173
02174 EWhiteSpace s;
02175 switch(primitiveValue->getIdent()) {
02176 case CSS_VAL__KHTML_NOWRAP:
02177 s = KHTML_NOWRAP;
02178 break;
02179 case CSS_VAL_NOWRAP:
02180 s = NOWRAP;
02181 break;
02182 case CSS_VAL_PRE:
02183 s = PRE;
02184 break;
02185 case CSS_VAL_NORMAL:
02186 default:
02187 s = NORMAL;
02188 break;
02189 }
02190 style->setWhiteSpace(s);
02191 break;
02192
02193 case CSS_PROP_BACKGROUND_POSITION:
02194 if (isInherit) {
02195 style->setBackgroundXPosition(parentStyle->backgroundXPosition());
02196 style->setBackgroundYPosition(parentStyle->backgroundYPosition());
02197 }
02198 else if (isInitial) {
02199 style->setBackgroundXPosition(RenderStyle::initialBackgroundXPosition());
02200 style->setBackgroundYPosition(RenderStyle::initialBackgroundYPosition());
02201 }
02202 break;
02203 case CSS_PROP_BACKGROUND_POSITION_X: {
02204 HANDLE_INHERIT_AND_INITIAL(backgroundXPosition, BackgroundXPosition)
02205 if(!primitiveValue) break;
02206 Length l;
02207 int type = primitiveValue->primitiveType();
02208 if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
02209 l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
02210 else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
02211 l = Length((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
02212 else
02213 return;
02214 style->setBackgroundXPosition(l);
02215 break;
02216 }
02217 case CSS_PROP_BACKGROUND_POSITION_Y: {
02218 HANDLE_INHERIT_AND_INITIAL(backgroundYPosition, BackgroundYPosition)
02219 if(!primitiveValue) break;
02220 Length l;
02221 int type = primitiveValue->primitiveType();
02222 if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
02223 l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
02224 else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
02225 l = Length((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
02226 else
02227 return;
02228 style->setBackgroundYPosition(l);
02229 break;
02230 }
02231 case CSS_PROP_BORDER_SPACING: {
02232 if(value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return;
02233 style->setBorderHorizontalSpacing(parentStyle->borderHorizontalSpacing());
02234 style->setBorderVerticalSpacing(parentStyle->borderVerticalSpacing());
02235 break;
02236 }
02237 case CSS_PROP__KHTML_BORDER_HORIZONTAL_SPACING: {
02238 HANDLE_INHERIT_AND_INITIAL(borderHorizontalSpacing, BorderHorizontalSpacing)
02239 if (!primitiveValue) break;
02240 short spacing = primitiveValue->computeLength(style, paintDeviceMetrics);
02241 style->setBorderHorizontalSpacing(spacing);
02242 break;
02243 }
02244 case CSS_PROP__KHTML_BORDER_VERTICAL_SPACING: {
02245 HANDLE_INHERIT_AND_INITIAL(borderVerticalSpacing, BorderVerticalSpacing)
02246 if (!primitiveValue) break;
02247 short spacing = primitiveValue->computeLength(style, paintDeviceMetrics);
02248 style->setBorderVerticalSpacing(spacing);
02249 break;
02250 }
02251
02252 case CSS_PROP_CURSOR:
02253 HANDLE_INHERIT_AND_INITIAL(cursor, Cursor)
02254 if(primitiveValue)
02255 style->setCursor( (ECursor) (primitiveValue->getIdent() - CSS_VAL_AUTO) );
02256 break;
02257
02258 case CSS_PROP_BACKGROUND_COLOR:
02259 case CSS_PROP_BORDER_TOP_COLOR:
02260 case CSS_PROP_BORDER_RIGHT_COLOR:
02261 case CSS_PROP_BORDER_BOTTOM_COLOR:
02262 case CSS_PROP_BORDER_LEFT_COLOR:
02263 case CSS_PROP_COLOR:
02264 case CSS_PROP_OUTLINE_COLOR:
02265
02266 case CSS_PROP_SCROLLBAR_FACE_COLOR:
02267 case CSS_PROP_SCROLLBAR_SHADOW_COLOR:
02268 case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR:
02269 case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR:
02270 case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR:
02271 case CSS_PROP_SCROLLBAR_TRACK_COLOR:
02272 case CSS_PROP_SCROLLBAR_ARROW_COLOR:
02273 {
02274 QColor col;
02275 if (isInherit) {
02276 HANDLE_INHERIT_COND(CSS_PROP_BACKGROUND_COLOR, backgroundColor, BackgroundColor)
02277 HANDLE_INHERIT_COND(CSS_PROP_BORDER_TOP_COLOR, borderTopColor, BorderTopColor)
02278 HANDLE_INHERIT_COND(CSS_PROP_BORDER_BOTTOM_COLOR, borderBottomColor, BorderBottomColor)
02279 HANDLE_INHERIT_COND(CSS_PROP_BORDER_RIGHT_COLOR, borderRightColor, BorderRightColor)
02280 HANDLE_INHERIT_COND(CSS_PROP_BORDER_LEFT_COLOR, borderLeftColor, BorderLeftColor)
02281 HANDLE_INHERIT_COND(CSS_PROP_COLOR, color, Color)
02282 HANDLE_INHERIT_COND(CSS_PROP_OUTLINE_COLOR, outlineColor, OutlineColor)
02283 return;
02284 } else if (isInitial) {
02285
02286
02287
02288 if (id == CSS_PROP_COLOR)
02289 col = RenderStyle::initialColor();
02290 } else {
02291 if(!primitiveValue )
02292 return;
02293 int ident = primitiveValue->getIdent();
02294 if ( ident ) {
02295 if ( ident == CSS_VAL__KHTML_TEXT )
02296 col = element->getDocument()->textColor();
02297
02298 else if ( ident == CSS_VAL_TRANSPARENT
02299 && id != CSS_PROP_BORDER_TOP_COLOR
02300 && id != CSS_PROP_BORDER_RIGHT_COLOR
02301 && id != CSS_PROP_BORDER_BOTTOM_COLOR
02302 && id != CSS_PROP_BORDER_LEFT_COLOR )
02303 col = QColor();
02304 else
02305 col = colorForCSSValue( ident );
02306 } else if ( primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_RGBCOLOR ) {
02307 #ifndef APPLE_CHANGES
02308 if(qAlpha(primitiveValue->getRGBColorValue()))
02309 #endif
02310 col.setRgb(primitiveValue->getRGBColorValue());
02311 } else {
02312 return;
02313 }
02314 }
02315
02316 switch(id)
02317 {
02318 case CSS_PROP_BACKGROUND_COLOR:
02319 style->setBackgroundColor(col); break;
02320 case CSS_PROP_BORDER_TOP_COLOR:
02321 style->setBorderTopColor(col); break;
02322 case CSS_PROP_BORDER_RIGHT_COLOR:
02323 style->setBorderRightColor(col); break;
02324 case CSS_PROP_BORDER_BOTTOM_COLOR:
02325 style->setBorderBottomColor(col); break;
02326 case CSS_PROP_BORDER_LEFT_COLOR:
02327 style->setBorderLeftColor(col); break;
02328 case CSS_PROP_COLOR:
02329 style->setColor(col); break;
02330 case CSS_PROP__KHTML_TEXT_DECORATION_COLOR:
02331 style->setTextDecorationColor(col); break;
02332 case CSS_PROP_OUTLINE_COLOR:
02333 style->setOutlineColor(col); break;
02334 #ifndef APPLE_CHANGES
02335 case CSS_PROP_SCROLLBAR_FACE_COLOR:
02336 style->setPaletteColor(QPalette::Active, QColorGroup::Button, col);
02337 style->setPaletteColor(QPalette::Inactive, QColorGroup::Button, col);
02338 break;
02339 case CSS_PROP_SCROLLBAR_SHADOW_COLOR:
02340 style->setPaletteColor(QPalette::Active, QColorGroup::Shadow, col);
02341 style->setPaletteColor(QPalette::Inactive, QColorGroup::Shadow, col);
02342 break;
02343 case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR:
02344 style->setPaletteColor(QPalette::Active, QColorGroup::Light, col);
02345 style->setPaletteColor(QPalette::Inactive, QColorGroup::Light, col);
02346 break;
02347 case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR:
02348 break;
02349 case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR:
02350 style->setPaletteColor(QPalette::Active, QColorGroup::Dark, col);
02351 style->setPaletteColor(QPalette::Inactive, QColorGroup::Dark, col);
02352 break;
02353 case CSS_PROP_SCROLLBAR_TRACK_COLOR:
02354 style->setPaletteColor(QPalette::Active, QColorGroup::Mid, col);
02355 style->setPaletteColor(QPalette::Inactive, QColorGroup::Mid, col);
02356 style->setPaletteColor(QPalette::Active, QColorGroup::Background, col);
02357 style->setPaletteColor(QPalette::Inactive, QColorGroup::Background, col);
02358
02359 case CSS_PROP_SCROLLBAR_BASE_COLOR:
02360 style->setPaletteColor(QPalette::Active, QColorGroup::Base, col);
02361 style->setPaletteColor(QPalette::Inactive, QColorGroup::Base, col);
02362 break;
02363 case CSS_PROP_SCROLLBAR_ARROW_COLOR:
02364 style->setPaletteColor(QPalette::Active, QColorGroup::ButtonText, col);
02365 style->setPaletteColor(QPalette::Inactive, QColorGroup::ButtonText, col);
02366 break;
02367 #endif
02368 default:
02369 return;
02370 }
02371 return;
02372 }
02373 break;
02374
02375 case CSS_PROP_BACKGROUND_IMAGE:
02376 {
02377 HANDLE_INHERIT_AND_INITIAL(backgroundImage, BackgroundImage)
02378 if (!primitiveValue) return;
02379 style->setBackgroundImage(static_cast<CSSImageValueImpl *>(primitiveValue)->image());
02380
02381 break;
02382 }
02383 case CSS_PROP_LIST_STYLE_IMAGE:
02384 {
02385 HANDLE_INHERIT_AND_INITIAL(listStyleImage, ListStyleImage)
02386 if (!primitiveValue) return;
02387 style->setListStyleImage(static_cast<CSSImageValueImpl *>(primitiveValue)->image());
02388
02389 break;
02390 }
02391
02392
02393 case CSS_PROP_BORDER_TOP_WIDTH:
02394 case CSS_PROP_BORDER_RIGHT_WIDTH:
02395 case CSS_PROP_BORDER_BOTTOM_WIDTH:
02396 case CSS_PROP_BORDER_LEFT_WIDTH:
02397 case CSS_PROP_OUTLINE_WIDTH:
02398 {
02399 if (isInherit) {
02400 HANDLE_INHERIT_COND(CSS_PROP_BORDER_TOP_WIDTH, borderTopWidth, BorderTopWidth)
02401 HANDLE_INHERIT_COND(CSS_PROP_BORDER_RIGHT_WIDTH, borderRightWidth, BorderRightWidth)
02402 HANDLE_INHERIT_COND(CSS_PROP_BORDER_BOTTOM_WIDTH, borderBottomWidth, BorderBottomWidth)
02403 HANDLE_INHERIT_COND(CSS_PROP_BORDER_LEFT_WIDTH, borderLeftWidth, BorderLeftWidth)
02404 HANDLE_INHERIT_COND(CSS_PROP_OUTLINE_WIDTH, outlineWidth, OutlineWidth)
02405 return;
02406 }
02407 else if (isInitial) {
02408 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_TOP_WIDTH, BorderTopWidth, BorderWidth)
02409 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_RIGHT_WIDTH, BorderRightWidth, BorderWidth)
02410 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_BOTTOM_WIDTH, BorderBottomWidth, BorderWidth)
02411 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_LEFT_WIDTH, BorderLeftWidth, BorderWidth)
02412 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_OUTLINE_WIDTH, OutlineWidth, BorderWidth)
02413 return;
02414 }
02415
02416 if(!primitiveValue) break;
02417 short width = 3;
02418 switch(primitiveValue->getIdent())
02419 {
02420 case CSS_VAL_THIN:
02421 width = 1;
02422 break;
02423 case CSS_VAL_MEDIUM:
02424 width = 3;
02425 break;
02426 case CSS_VAL_THICK:
02427 width = 5;
02428 break;
02429 case CSS_VAL_INVALID:
02430 {
02431 double widthd = primitiveValue->computeLengthFloat(style, paintDeviceMetrics);
02432 width = (int)widthd;
02433
02434
02435 if (width == 0 && widthd >= 0.025) width++;
02436 break;
02437 }
02438 default:
02439 return;
02440 }
02441
02442 if(width < 0) return;
02443 switch(id)
02444 {
02445 case CSS_PROP_BORDER_TOP_WIDTH:
02446 style->setBorderTopWidth(width);
02447 break;
02448 case CSS_PROP_BORDER_RIGHT_WIDTH:
02449 style->setBorderRightWidth(width);
02450 break;
02451 case CSS_PROP_BORDER_BOTTOM_WIDTH:
02452 style->setBorderBottomWidth(width);
02453 break;
02454 case CSS_PROP_BORDER_LEFT_WIDTH:
02455 style->setBorderLeftWidth(width);
02456 break;
02457 case CSS_PROP_OUTLINE_WIDTH:
02458 style->setOutlineWidth(width);
02459 break;
02460 default:
02461 return;
02462 }
02463 return;
02464 }
02465
02466 case CSS_PROP_LETTER_SPACING:
02467 case CSS_PROP_WORD_SPACING:
02468 {
02469 if (isInherit) {
02470 HANDLE_INHERIT_COND(CSS_PROP_LETTER_SPACING, letterSpacing, LetterSpacing)
02471 HANDLE_INHERIT_COND(CSS_PROP_WORD_SPACING, wordSpacing, WordSpacing)
02472 return;
02473 } else if (isInitial) {
02474 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_LETTER_SPACING, LetterSpacing, LetterWordSpacing)
02475 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_WORD_SPACING, WordSpacing, LetterWordSpacing)
02476 return;
02477 }
02478 if(!primitiveValue) return;
02479
02480 int width = 0;
02481 if (primitiveValue->getIdent() != CSS_VAL_NORMAL)
02482 width = primitiveValue->computeLength(style, paintDeviceMetrics);
02483
02484 switch(id)
02485 {
02486 case CSS_PROP_LETTER_SPACING:
02487 style->setLetterSpacing(width);
02488 break;
02489 case CSS_PROP_WORD_SPACING:
02490 style->setWordSpacing(width);
02491 break;
02492
02493 default: break;
02494 }
02495 return;
02496 }
02497
02498
02499 case CSS_PROP_MAX_WIDTH:
02500
02501 if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE)
02502 apply = true;
02503 case CSS_PROP_TOP:
02504 case CSS_PROP_LEFT:
02505 case CSS_PROP_RIGHT:
02506 case CSS_PROP_BOTTOM:
02507 case CSS_PROP_WIDTH:
02508 case CSS_PROP_MIN_WIDTH:
02509 case CSS_PROP_MARGIN_TOP:
02510 case CSS_PROP_MARGIN_RIGHT:
02511 case CSS_PROP_MARGIN_BOTTOM:
02512 case CSS_PROP_MARGIN_LEFT:
02513
02514 if(id != CSS_PROP_MAX_WIDTH && primitiveValue &&
02515 primitiveValue->getIdent() == CSS_VAL_AUTO)
02516 {
02517
02518 apply = true;
02519 }
02520 case CSS_PROP_PADDING_TOP:
02521 case CSS_PROP_PADDING_RIGHT:
02522 case CSS_PROP_PADDING_BOTTOM:
02523 case CSS_PROP_PADDING_LEFT:
02524 case CSS_PROP_TEXT_INDENT:
02525
02526 {
02527 if (isInherit) {
02528 HANDLE_INHERIT_COND(CSS_PROP_MAX_WIDTH, maxWidth, MaxWidth)
02529 HANDLE_INHERIT_COND(CSS_PROP_BOTTOM, bottom, Bottom)
02530 HANDLE_INHERIT_COND(CSS_PROP_TOP, top, Top)
02531 HANDLE_INHERIT_COND(CSS_PROP_LEFT, left, Left)
02532 HANDLE_INHERIT_COND(CSS_PROP_RIGHT, right, Right)
02533 HANDLE_INHERIT_COND(CSS_PROP_WIDTH, width, Width)
02534 HANDLE_INHERIT_COND(CSS_PROP_MIN_WIDTH, minWidth, MinWidth)
02535 HANDLE_INHERIT_COND(CSS_PROP_PADDING_TOP, paddingTop, PaddingTop)
02536 HANDLE_INHERIT_COND(CSS_PROP_PADDING_RIGHT, paddingRight, PaddingRight)
02537 HANDLE_INHERIT_COND(CSS_PROP_PADDING_BOTTOM, paddingBottom, PaddingBottom)
02538 HANDLE_INHERIT_COND(CSS_PROP_PADDING_LEFT, paddingLeft, PaddingLeft)
02539 HANDLE_INHERIT_COND(CSS_PROP_MARGIN_TOP, marginTop, MarginTop)
02540 HANDLE_INHERIT_COND(CSS_PROP_MARGIN_RIGHT, marginRight, MarginRight)
02541 HANDLE_INHERIT_COND(CSS_PROP_MARGIN_BOTTOM, marginBottom, MarginBottom)
02542 HANDLE_INHERIT_COND(CSS_PROP_MARGIN_LEFT, marginLeft, MarginLeft)
02543 HANDLE_INHERIT_COND(CSS_PROP_TEXT_INDENT, textIndent, TextIndent)
02544 return;
02545 } else if (isInitial) {
02546 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MAX_WIDTH, MaxWidth, MaxSize)
02547 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BOTTOM, Bottom, Offset)
02548 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_TOP, Top, Offset)
02549 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_LEFT, Left, Offset)
02550 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_RIGHT, Right, Offset)
02551 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_WIDTH, Width, Size)
02552 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MIN_WIDTH, MinWidth, MinSize)
02553 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_TOP, PaddingTop, Padding)
02554 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_RIGHT, PaddingRight, Padding)
02555 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_BOTTOM, PaddingBottom, Padding)
02556 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_LEFT, PaddingLeft, Padding)
02557 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_TOP, MarginTop, Margin)
02558 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_RIGHT, MarginRight, Margin)
02559 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_BOTTOM, MarginBottom, Margin)
02560 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_LEFT, MarginLeft, Margin)
02561 HANDLE_INITIAL_COND(CSS_PROP_TEXT_INDENT, TextIndent)
02562 return;
02563 }
02564
02565 if (primitiveValue && !apply) {
02566 int type = primitiveValue->primitiveType();
02567 if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
02568
02569 l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed,
02570 primitiveValue->isQuirkValue());
02571 else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
02572 l = Length((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
02573 else if (type == CSSPrimitiveValue::CSS_HTML_RELATIVE)
02574 l = Length(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_HTML_RELATIVE)), Relative);
02575 else
02576 return;
02577 apply = true;
02578 }
02579 if(!apply) return;
02580 switch(id)
02581 {
02582 case CSS_PROP_MAX_WIDTH:
02583 style->setMaxWidth(l); break;
02584 case CSS_PROP_BOTTOM:
02585 style->setBottom(l); break;
02586 case CSS_PROP_TOP:
02587 style->setTop(l); break;
02588 case CSS_PROP_LEFT:
02589 style->setLeft(l); break;
02590 case CSS_PROP_RIGHT:
02591 style->setRight(l); break;
02592 case CSS_PROP_WIDTH:
02593 style->setWidth(l); break;
02594 case CSS_PROP_MIN_WIDTH:
02595 style->setMinWidth(l); break;
02596 case CSS_PROP_PADDING_TOP:
02597 style->setPaddingTop(l); break;
02598 case CSS_PROP_PADDING_RIGHT:
02599 style->setPaddingRight(l); break;
02600 case CSS_PROP_PADDING_BOTTOM:
02601 style->setPaddingBottom(l); break;
02602 case CSS_PROP_PADDING_LEFT:
02603 style->setPaddingLeft(l); break;
02604 case CSS_PROP_MARGIN_TOP:
02605 style->setMarginTop(l); break;
02606 case CSS_PROP_MARGIN_RIGHT:
02607 style->setMarginRight(l); break;
02608 case CSS_PROP_MARGIN_BOTTOM:
02609 style->setMarginBottom(l); break;
02610 case CSS_PROP_MARGIN_LEFT:
02611 style->setMarginLeft(l); break;
02612 case CSS_PROP_TEXT_INDENT:
02613 style->setTextIndent(l); break;
02614 default: break;
02615 }
02616 return;
02617 }
02618
02619 case CSS_PROP_MAX_HEIGHT:
02620 if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE)
02621 apply = true;
02622 case CSS_PROP_HEIGHT:
02623 case CSS_PROP_MIN_HEIGHT:
02624 if(id != CSS_PROP_MAX_HEIGHT && primitiveValue &&
02625 primitiveValue->getIdent() == CSS_VAL_AUTO)
02626 apply = true;
02627 if (isInherit) {
02628 HANDLE_INHERIT_COND(CSS_PROP_MAX_HEIGHT, maxHeight, MaxHeight)
02629 HANDLE_INHERIT_COND(CSS_PROP_HEIGHT, height, Height)
02630 HANDLE_INHERIT_COND(CSS_PROP_MIN_HEIGHT, minHeight, MinHeight)
02631 return;
02632 }
02633 else if (isInitial) {
02634 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MAX_HEIGHT, MaxHeight, MaxSize)
02635 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_HEIGHT, Height, Size)
02636 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MIN_HEIGHT, MinHeight, MinSize)
02637 return;
02638 }
02639
02640 if (primitiveValue && !apply)
02641 {
02642 int type = primitiveValue->primitiveType();
02643 if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
02644 l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
02645 else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
02646 l = Length((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent);
02647 else
02648 return;
02649 apply = true;
02650 }
02651 if(!apply) return;
02652 switch(id)
02653 {
02654 case CSS_PROP_MAX_HEIGHT:
02655 style->setMaxHeight(l); break;
02656 case CSS_PROP_HEIGHT:
02657 style->setHeight(l); break;
02658 case CSS_PROP_MIN_HEIGHT:
02659 style->setMinHeight(l); break;
02660 default:
02661 return;
02662 }
02663 return;
02664
02665 break;
02666
02667 case CSS_PROP_VERTICAL_ALIGN:
02668 HANDLE_INHERIT_AND_INITIAL(verticalAlign, VerticalAlign)
02669 if (!primitiveValue) return;
02670 if (primitiveValue->getIdent()) {
02671 khtml::EVerticalAlign align;
02672
02673 switch(primitiveValue->getIdent())
02674 {
02675 case CSS_VAL_TOP:
02676 align = TOP; break;
02677 case CSS_VAL_BOTTOM:
02678 align = BOTTOM; break;
02679 case CSS_VAL_MIDDLE:
02680 align = MIDDLE; break;
02681 case CSS_VAL_BASELINE:
02682 align = BASELINE; break;
02683 case CSS_VAL_TEXT_BOTTOM:
02684 align = TEXT_BOTTOM; break;
02685 case CSS_VAL_TEXT_TOP:
02686 align = TEXT_TOP; break;
02687 case CSS_VAL_SUB:
02688 align = SUB; break;
02689 case CSS_VAL_SUPER:
02690 align = SUPER; break;
02691 case CSS_VAL__KHTML_BASELINE_MIDDLE:
02692 align = BASELINE_MIDDLE; break;
02693 default:
02694 return;
02695 }
02696 style->setVerticalAlign(align);
02697 return;
02698 } else {
02699 int type = primitiveValue->primitiveType();
02700 Length l;
02701 if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
02702 l = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed );
02703 else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
02704 l = Length( int( primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE) ), Percent );
02705
02706 style->setVerticalAlign( LENGTH );
02707 style->setVerticalAlignLength( l );
02708 }
02709 break;
02710
02711 case CSS_PROP_FONT_SIZE:
02712 {
02713 FontDef fontDef = style->htmlFont().fontDef;
02714 int oldSize;
02715 int size = 0;
02716
02717 float toPix = paintDeviceMetrics->logicalDpiY()/72.;
02718 if (toPix < 96./72.) toPix = 96./72.;
02719
02720 int minFontSize = int(settings->minFontSize() * toPix);
02721
02722 if(parentNode) {
02723 oldSize = parentStyle->font().pixelSize();
02724 } else
02725 oldSize = m_fontSizes[3];
02726
02727 if (isInherit )
02728 size = oldSize;
02729 else if (isInitial)
02730 size = m_fontSizes[3];
02731 else if(primitiveValue->getIdent()) {
02732
02733
02734 #ifdef APPLE_CHANGES
02735 QValueList<int>& fontSizes = (fontDef.genericFamily == FontDef::eMonospace) ?
02736 m_fixedFontSizes : m_fontSizes;
02737 #else
02738 QValueList<int>& fontSizes = m_fontSizes;
02739 #endif
02740 switch(primitiveValue->getIdent())
02741 {
02742 case CSS_VAL_XX_SMALL: size = int( fontSizes[0] ); break;
02743 case CSS_VAL_X_SMALL: size = int( fontSizes[1] ); break;
02744 case CSS_VAL_SMALL: size = int( fontSizes[2] ); break;
02745 case CSS_VAL_MEDIUM: size = int( fontSizes[3] ); break;
02746 case CSS_VAL_LARGE: size = int( fontSizes[4] ); break;
02747 case CSS_VAL_X_LARGE: size = int( fontSizes[5] ); break;
02748 case CSS_VAL_XX_LARGE: size = int( fontSizes[6] ); break;
02749 case CSS_VAL__KHTML_XXX_LARGE: size = int( fontSizes[7] ); break;
02750 case CSS_VAL_LARGER:
02751
02752 size = ( oldSize * 5 ) / 4;
02753 break;
02754 case CSS_VAL_SMALLER:
02755 size = ( oldSize * 4 ) / 5;
02756 break;
02757 default:
02758 return;
02759 }
02760
02761 } else {
02762 int type = primitiveValue->primitiveType();
02763 if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) {
02764 if ( !khtml::printpainter && type != CSSPrimitiveValue::CSS_EMS && type != CSSPrimitiveValue::CSS_EXS &&
02765 element && element->getDocument()->view())
02766 size = int( primitiveValue->computeLengthFloat(parentStyle, paintDeviceMetrics) *
02767 element->getDocument()->view()->part()->zoomFactor() ) / 100;
02768 else
02769 size = int( primitiveValue->computeLengthFloat(parentStyle, paintDeviceMetrics) );
02770 }
02771 else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
02772 size = int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE)
02773 * parentStyle->font().pixelSize()) / 100;
02774 else
02775 return;
02776 }
02777
02778 if(size < 1) return;
02779
02780
02781 if(size < minFontSize ) size = minFontSize;
02782
02783
02784
02785 fontDef.size = size;
02786 fontDirty |= style->setFontDef( fontDef );
02787 return;
02788 }
02789
02790 case CSS_PROP_Z_INDEX:
02791 {
02792 HANDLE_INHERIT(zIndex, ZIndex)
02793 else if (isInitial) {
02794 style->setHasAutoZIndex();
02795 return;
02796 }
02797
02798 if (!primitiveValue)
02799 return;
02800
02801 if (primitiveValue->getIdent() == CSS_VAL_AUTO) {
02802 style->setHasAutoZIndex();
02803 return;
02804 }
02805
02806 if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
02807 return;
02808
02809 style->setZIndex((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER));
02810 return;
02811 }
02812
02813 case CSS_PROP_WIDOWS:
02814 {
02815 HANDLE_INHERIT_AND_INITIAL(widows, Widows)
02816 if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
02817 return;
02818 style->setWidows((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER));
02819 break;
02820 }
02821
02822 case CSS_PROP_ORPHANS:
02823 {
02824 HANDLE_INHERIT_AND_INITIAL(orphans, Orphans)
02825 if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
02826 return;
02827 style->setOrphans((int)primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER));
02828 break;
02829 }
02830
02831
02832 case CSS_PROP_LINE_HEIGHT:
02833 {
02834 HANDLE_INHERIT_AND_INITIAL(lineHeight, LineHeight)
02835 if(!primitiveValue) return;
02836 Length lineHeight;
02837 int type = primitiveValue->primitiveType();
02838 if (primitiveValue->getIdent() == CSS_VAL_NORMAL)
02839 lineHeight = Length( -100, Percent );
02840 else if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) {
02841 #ifdef APPLE_CHANGES
02842 double multiplier = 1.0;
02843
02844
02845 if (type != CSSPrimitiveValue::CSS_EMS && type != CSSPrimitiveValue::CSS_EXS && view && view->part()) {
02846 multiplier = view->part()->zoomFactor() / 100.0;
02847 }
02848 lineHeight = Length(primitiveValue->computeLength(style, paintDeviceMetrics, multiplier), Fixed);
02849 #else
02850 lineHeight = Length(primitiveValue->computeLength(style, paintDeviceMetrics), Fixed);
02851 #endif
02852 } else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
02853 lineHeight = Length( ( style->font().pixelSize() * int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE)) ) / 100, Fixed );
02854 else if (type == CSSPrimitiveValue::CSS_NUMBER)
02855 lineHeight = Length(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER)*100), Percent);
02856 else
02857 return;
02858 style->setLineHeight(lineHeight);
02859 return;
02860 }
02861
02862
02863 case CSS_PROP_TEXT_ALIGN:
02864 {
02865 HANDLE_INHERIT_AND_INITIAL(textAlign, TextAlign)
02866 if (!primitiveValue) return;
02867 if (primitiveValue->getIdent())
02868 style->setTextAlign( (ETextAlign) (primitiveValue->getIdent() - CSS_VAL__KHTML_AUTO) );
02869 return;
02870 }
02871
02872
02873 case CSS_PROP_CLIP:
02874 {
02875 Length top;
02876 Length right;
02877 Length bottom;
02878 Length left;
02879 bool hasClip = true;
02880 if (isInherit) {
02881 if (parentStyle->hasClip()) {
02882 top = parentStyle->clipTop();
02883 right = parentStyle->clipRight();
02884 bottom = parentStyle->clipBottom();
02885 left = parentStyle->clipLeft();
02886 }
02887 else {
02888 hasClip = false;
02889 top = right = bottom = left = Length();
02890 }
02891 } else if (isInitial) {
02892 hasClip = false;
02893 top = right = bottom = left = Length();
02894 } else if ( !primitiveValue ) {
02895 break;
02896 } else if ( primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_RECT ) {
02897 RectImpl *rect = primitiveValue->getRectValue();
02898 if ( !rect )
02899 break;
02900 top = convertToLength( rect->top(), style, paintDeviceMetrics );
02901 right = convertToLength( rect->right(), style, paintDeviceMetrics );
02902 bottom = convertToLength( rect->bottom(), style, paintDeviceMetrics );
02903 left = convertToLength( rect->left(), style, paintDeviceMetrics );
02904
02905 } else if ( primitiveValue->getIdent() != CSS_VAL_AUTO ) {
02906 break;
02907 }
02908
02909
02910
02911
02912 style->setClip(top, right, bottom, left );
02913 style->setHasClip(hasClip);
02914
02915 break;
02916 }
02917
02918
02919 case CSS_PROP_CONTENT:
02920
02921 {
02922
02923
02924 if (!(style->styleType()==RenderStyle::BEFORE ||
02925 style->styleType()==RenderStyle::AFTER))
02926 break;
02927
02928 if (isInitial) {
02929 if (style->contentData())
02930 style->contentData()->clearContent();
02931 return;
02932 }
02933
02934 if(!value->isValueList()) return;
02935 CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value);
02936 int len = list->length();
02937
02938 for(int i = 0; i < len; i++) {
02939 CSSValueImpl *item = list->item(i);
02940 if(!item->isPrimitiveValue()) continue;
02941 CSSPrimitiveValueImpl *val = static_cast<CSSPrimitiveValueImpl *>(item);
02942 if(val->primitiveType()==CSSPrimitiveValue::CSS_STRING)
02943 {
02944 style->setContent(val->getStringValue(), i != 0);
02945 }
02946 else if (val->primitiveType()==CSSPrimitiveValue::CSS_ATTR)
02947 {
02948 #ifdef APPLE_CHANGES
02949 int attrID = element->getDocument()->attrId(0, val->getStringValue(), false);
02950 if (attrID)
02951 style->setContent(element->getAttribute(attrID).implementation(), i != 0);
02952 #else
02953 int attrID = element->getDocument()->getId(NodeImpl::AttributeId, val->getStringValue(), false, true);
02954 if (attrID)
02955 style->setContent(element->getAttribute(attrID).implementation(), i != 0);
02956 #endif
02957 }
02958 else if (val->primitiveType()==CSSPrimitiveValue::CSS_URI)
02959 {
02960 CSSImageValueImpl *image = static_cast<CSSImageValueImpl *>(val);
02961 style->setContent(image->image(), i != 0);
02962 }
02963
02964 }
02965 break;
02966 }
02967
02968 case CSS_PROP_COUNTER_INCREMENT:
02969
02970 case CSS_PROP_COUNTER_RESET:
02971
02972 break;
02973 case CSS_PROP_FONT_FAMILY:
02974
02975 {
02976 if (isInherit) {
02977 FontDef parentFontDef = parentStyle->htmlFont().fontDef;
02978 FontDef fontDef = style->htmlFont().fontDef;
02979 fontDef.family = parentFontDef.family;
02980 if (style->setFontDef(fontDef))
02981 fontDirty = true;
02982 return;
02983 }
02984 else if (isInitial) {
02985 FontDef fontDef = style->htmlFont().fontDef;
02986 FontDef initialDef = FontDef();
02987 #ifdef APPLE_CHANGES
02988 fontDef.family = initialDef.firstFamily();
02989 #else
02990 fontDef.family = QString::null;
02991 #endif
02992 if (style->setFontDef(fontDef))
02993 fontDirty = true;
02994 return;
02995 }
02996 if(!value->isValueList()) return;
02997 FontDef fontDef = style->htmlFont().fontDef;
02998 CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value);
02999 int len = list->length();
03000 for(int i = 0; i < len; i++) {
03001 CSSValueImpl *item = list->item(i);
03002 if(!item->isPrimitiveValue()) continue;
03003 CSSPrimitiveValueImpl *val = static_cast<CSSPrimitiveValueImpl *>(item);
03004 QString face;
03005 if( val->primitiveType() == CSSPrimitiveValue::CSS_STRING )
03006 face = static_cast<FontFamilyValueImpl *>(val)->fontName();
03007 else if ( val->primitiveType() == CSSPrimitiveValue::CSS_IDENT ) {
03008 switch( val->getIdent() ) {
03009 case CSS_VAL_SERIF:
03010 face = settings->serifFontName();
03011 break;
03012 case CSS_VAL_SANS_SERIF:
03013 face = settings->sansSerifFontName();
03014 break;
03015 case CSS_VAL_CURSIVE:
03016 face = settings->cursiveFontName();
03017 break;
03018 case CSS_VAL_FANTASY:
03019 face = settings->fantasyFontName();
03020 break;
03021 case CSS_VAL_MONOSPACE:
03022 face = settings->fixedFontName();
03023 break;
03024 default:
03025 return;
03026 }
03027 } else {
03028 return;
03029 }
03030 if ( !face.isEmpty() ) {
03031 fontDef.family = face;
03032 fontDirty |= style->setFontDef( fontDef );
03033 return;
03034 }
03035 }
03036 break;
03037 }
03038 case CSS_PROP_QUOTES:
03039
03040 case CSS_PROP_SIZE:
03041
03042 break;
03043 case CSS_PROP_TEXT_DECORATION: {
03044
03045 HANDLE_INHERIT_AND_INITIAL(textDecoration, TextDecoration)
03046 int t = RenderStyle::initialTextDecoration();
03047 if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE) {
03048
03049 } else {
03050 if(!value->isValueList()) return;
03051 CSSValueListImpl *list = static_cast<CSSValueListImpl *>(value);
03052 int len = list->length();
03053 for(int i = 0; i < len; i++)
03054 {
03055 CSSValueImpl *item = list->item(i);
03056 if(!item->isPrimitiveValue()) continue;
03057 primitiveValue = static_cast<CSSPrimitiveValueImpl *>(item);
03058 switch(primitiveValue->getIdent())
03059 {
03060 case CSS_VAL_NONE:
03061 t = TDNONE; break;
03062 case CSS_VAL_UNDERLINE:
03063 t |= UNDERLINE; break;
03064 case CSS_VAL_OVERLINE:
03065 t |= OVERLINE; break;
03066 case CSS_VAL_LINE_THROUGH:
03067 t |= LINE_THROUGH; break;
03068 case CSS_VAL_BLINK:
03069 t |= BLINK; break;
03070 default:
03071 return;
03072 }
03073 }
03074 }
03075 style->setTextDecoration(t);
03076 break;
03077 }
03078 case CSS_PROP__KHTML_FLOW_MODE:
03079 HANDLE_INHERIT_AND_INITIAL(flowAroundFloats, FlowAroundFloats)
03080 if (!primitiveValue) return;
03081 if (primitiveValue->getIdent()) {
03082 style->setFlowAroundFloats( primitiveValue->getIdent() == CSS_VAL__KHTML_AROUND_FLOATS );
03083 return;
03084 }
03085 break;
03086 case CSS_PROP__KHTML_USER_INPUT: {
03087 if(value->cssValueType() == CSSValue::CSS_INHERIT)
03088 {
03089 if(!parentNode) return;
03090 style->setUserInput(parentStyle->userInput());
03091
03092 return;
03093 }
03094 if(!primitiveValue) return;
03095 int id = primitiveValue->getIdent();
03096 if (id == CSS_VAL_NONE)
03097 style->setUserInput(UI_NONE);
03098 else
03099 style->setUserInput(EUserInput(id - CSS_VAL_ENABLED));
03100
03101 return;
03102 }
03103
03104
03105 case CSS_PROP_BACKGROUND:
03106 if (isInherit) {
03107 style->setBackgroundColor(parentStyle->backgroundColor());
03108 style->setBackgroundImage(parentStyle->backgroundImage());
03109 style->setBackgroundRepeat(parentStyle->backgroundRepeat());
03110 style->setBackgroundAttachment(parentStyle->backgroundAttachment());
03111 style->setBackgroundXPosition(parentStyle->backgroundXPosition());
03112 style->setBackgroundYPosition(parentStyle->backgroundYPosition());
03113 }
03114 else if (isInitial) {
03115 style->setBackgroundColor(QColor());
03116 style->setBackgroundImage(RenderStyle::initialBackgroundImage());
03117 style->setBackgroundRepeat(RenderStyle::initialBackgroundRepeat());
03118 style->setBackgroundAttachment(RenderStyle::initialBackgroundAttachment());
03119 style->setBackgroundXPosition(RenderStyle::initialBackgroundXPosition());
03120 style->setBackgroundYPosition(RenderStyle::initialBackgroundYPosition());
03121 }
03122 break;
03123 case CSS_PROP_BORDER:
03124 case CSS_PROP_BORDER_STYLE:
03125 case CSS_PROP_BORDER_WIDTH:
03126 case CSS_PROP_BORDER_COLOR:
03127 if(id == CSS_PROP_BORDER || id == CSS_PROP_BORDER_COLOR)
03128 {
03129 if (isInherit) {
03130 style->setBorderTopColor(parentStyle->borderTopColor());
03131 style->setBorderBottomColor(parentStyle->borderBottomColor());
03132 style->setBorderLeftColor(parentStyle->borderLeftColor());
03133 style->setBorderRightColor(parentStyle->borderRightColor());
03134 }
03135 else if (isInitial) {
03136 style->setBorderTopColor(QColor());
03137 style->setBorderBottomColor(QColor());
03138 style->setBorderLeftColor(QColor());
03139 style->setBorderRightColor(QColor());
03140 }
03141 }
03142 if (id == CSS_PROP_BORDER || id == CSS_PROP_BORDER_STYLE)
03143 {
03144 if (isInherit) {
03145 style->setBorderTopStyle(parentStyle->borderTopStyle());
03146 style->setBorderBottomStyle(parentStyle->borderBottomStyle());
03147 style->setBorderLeftStyle(parentStyle->borderLeftStyle());
03148 style->setBorderRightStyle(parentStyle->borderRightStyle());
03149 }
03150 else if (isInitial) {
03151 style->setBorderTopStyle(RenderStyle::initialBorderStyle());
03152 style->setBorderBottomStyle(RenderStyle::initialBorderStyle());
03153 style->setBorderLeftStyle(RenderStyle::initialBorderStyle());
03154 style->setBorderRightStyle(RenderStyle::initialBorderStyle());
03155 }
03156 }
03157 if (id == CSS_PROP_BORDER || id == CSS_PROP_BORDER_WIDTH)
03158 {
03159 if (isInherit) {
03160 style->setBorderTopWidth(parentStyle->borderTopWidth());
03161 style->setBorderBottomWidth(parentStyle->borderBottomWidth());
03162 style->setBorderLeftWidth(parentStyle->borderLeftWidth());
03163 style->setBorderRightWidth(parentStyle->borderRightWidth());
03164 }
03165 else if (isInitial) {
03166 style->setBorderTopWidth(RenderStyle::initialBorderWidth());
03167 style->setBorderBottomWidth(RenderStyle::initialBorderWidth());
03168 style->setBorderLeftWidth(RenderStyle::initialBorderWidth());
03169 style->setBorderRightWidth(RenderStyle::initialBorderWidth());
03170 }
03171 }
03172 return;
03173 case CSS_PROP_BORDER_TOP:
03174 if ( isInherit ) {
03175 style->setBorderTopColor(parentStyle->borderTopColor());
03176 style->setBorderTopStyle(parentStyle->borderTopStyle());
03177 style->setBorderTopWidth(parentStyle->borderTopWidth());
03178 } else if (isInitial)
03179 style->resetBorderTop();
03180 return;
03181 case CSS_PROP_BORDER_RIGHT:
03182 if (isInherit) {
03183 style->setBorderRightColor(parentStyle->borderRightColor());
03184 style->setBorderRightStyle(parentStyle->borderRightStyle());
03185 style->setBorderRightWidth(parentStyle->borderRightWidth());
03186 }
03187 else if (isInitial)
03188 style->resetBorderRight();
03189 return;
03190 case CSS_PROP_BORDER_BOTTOM:
03191 if (isInherit) {
03192 style->setBorderBottomColor(parentStyle->borderBottomColor());
03193 style->setBorderBottomStyle(parentStyle->borderBottomStyle());
03194 style->setBorderBottomWidth(parentStyle->borderBottomWidth());
03195 }
03196 else if (isInitial)
03197 style->resetBorderBottom();
03198 return;
03199 case CSS_PROP_BORDER_LEFT:
03200 if (isInherit) {
03201 style->setBorderLeftColor(parentStyle->borderLeftColor());
03202 style->setBorderLeftStyle(parentStyle->borderLeftStyle());
03203 style->setBorderLeftWidth(parentStyle->borderLeftWidth());
03204 }
03205 else if (isInitial)
03206 style->resetBorderLeft();
03207 return;
03208 case CSS_PROP_MARGIN:
03209 if (isInherit) {
03210 style->setMarginTop(parentStyle->marginTop());
03211 style->setMarginBottom(parentStyle->marginBottom());
03212 style->setMarginLeft(parentStyle->marginLeft());
03213 style->setMarginRight(parentStyle->marginRight());
03214 }
03215 else if (isInitial)
03216 style->resetMargin();
03217 return;
03218 case CSS_PROP_PADDING:
03219 if (isInherit) {
03220 style->setPaddingTop(parentStyle->paddingTop());
03221 style->setPaddingBottom(parentStyle->paddingBottom());
03222 style->setPaddingLeft(parentStyle->paddingLeft());
03223 style->setPaddingRight(parentStyle->paddingRight());
03224 }
03225 else if (isInitial)
03226 style->resetPadding();
03227 return;
03228 case CSS_PROP_FONT:
03229 if ( isInherit ) {
03230 FontDef fontDef = parentStyle->htmlFont().fontDef;
03231 style->setLineHeight( parentStyle->lineHeight() );
03232 fontDirty |= style->setFontDef( fontDef );
03233 } else if (isInitial) {
03234 FontDef fontDef;
03235 style->setLineHeight(RenderStyle::initialLineHeight());
03236 if (style->setFontDef( fontDef ))
03237 fontDirty = true;
03238 } else if ( value->isFontValue() ) {
03239 FontValueImpl *font = static_cast<FontValueImpl *>(value);
03240 if ( !font->style || !font->variant || !font->weight ||
03241 !font->size || !font->lineHeight || !font->family )
03242 return;
03243 applyRule( CSS_PROP_FONT_STYLE, font->style );
03244 applyRule( CSS_PROP_FONT_VARIANT, font->variant );
03245 applyRule( CSS_PROP_FONT_WEIGHT, font->weight );
03246 applyRule( CSS_PROP_FONT_SIZE, font->size );
03247
03248
03249
03250
03251 if (fontDirty)
03252 CSSStyleSelector::style->htmlFont().update( paintDeviceMetrics );
03253
03254 applyRule( CSS_PROP_LINE_HEIGHT, font->lineHeight );
03255 applyRule( CSS_PROP_FONT_FAMILY, font->family );
03256 }
03257 return;
03258
03259 case CSS_PROP_LIST_STYLE:
03260 if (isInherit) {
03261 style->setListStyleType(parentStyle->listStyleType());
03262 style->setListStyleImage(parentStyle->listStyleImage());
03263 style->setListStylePosition(parentStyle->listStylePosition());
03264 }
03265 else if (isInitial) {
03266 style->setListStyleType(RenderStyle::initialListStyleType());
03267 style->setListStyleImage(RenderStyle::initialListStyleImage());
03268 style->setListStylePosition(RenderStyle::initialListStylePosition());
03269 }
03270 break;
03271 case CSS_PROP_OUTLINE:
03272 if (isInherit) {
03273 style->setOutlineWidth(parentStyle->outlineWidth());
03274 style->setOutlineColor(parentStyle->outlineColor());
03275 style->setOutlineStyle(parentStyle->outlineStyle());
03276 }
03277 else if (isInitial)
03278 style->resetOutline();
03279 break;
03280 case CSS_PROP_BOX_SIZING:
03281 HANDLE_INHERIT(boxSizing, BoxSizing)
03282 if (!primitiveValue) return;
03283 if (primitiveValue->getIdent() == CSS_VAL_CONTENT_BOX)
03284 style->setBoxSizing(CONTENT_BOX);
03285 else
03286 if (primitiveValue->getIdent() == CSS_VAL_BORDER_BOX)
03287 style->setBoxSizing(BORDER_BOX);
03288 break;
03289 case CSS_PROP__KHTML_MARQUEE:
03290 if (value->cssValueType() != CSSValue::CSS_INHERIT || !parentNode) return;
03291 style->setMarqueeDirection(parentStyle->marqueeDirection());
03292 style->setMarqueeIncrement(parentStyle->marqueeIncrement());
03293 style->setMarqueeSpeed(parentStyle->marqueeSpeed());
03294 style->setMarqueeLoopCount(parentStyle->marqueeLoopCount());
03295 style->setMarqueeBehavior(parentStyle->marqueeBehavior());
03296 break;
03297 case CSS_PROP__KHTML_MARQUEE_REPETITION: {
03298 HANDLE_INHERIT_AND_INITIAL(marqueeLoopCount, MarqueeLoopCount)
03299 if (!primitiveValue) return;
03300 if (primitiveValue->getIdent() == CSS_VAL_INFINITE)
03301 style->setMarqueeLoopCount(-1);
03302 else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER)
03303 style->setMarqueeLoopCount((int)(primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER)));
03304 break;
03305 }
03306 case CSS_PROP__KHTML_MARQUEE_SPEED: {
03307 HANDLE_INHERIT_AND_INITIAL(marqueeSpeed, MarqueeSpeed)
03308 if (!primitiveValue) return;
03309 if (primitiveValue->getIdent()) {
03310 switch (primitiveValue->getIdent())
03311 {
03312 case CSS_VAL_SLOW:
03313 style->setMarqueeSpeed(500);
03314 break;
03315 case CSS_VAL_NORMAL:
03316 style->setMarqueeSpeed(85);
03317 break;
03318 case CSS_VAL_FAST:
03319 style->setMarqueeSpeed(10);
03320 break;
03321 }
03322 }
03323 else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_S)
03324 style->setMarqueeSpeed(int(1000*primitiveValue->floatValue(CSSPrimitiveValue::CSS_S)));
03325 else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_MS)
03326 style->setMarqueeSpeed(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_MS)));
03327 else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER)
03328 style->setMarqueeSpeed(int(primitiveValue->floatValue(CSSPrimitiveValue::CSS_NUMBER)));
03329 break;
03330 }
03331 case CSS_PROP__KHTML_MARQUEE_INCREMENT: {
03332 HANDLE_INHERIT_AND_INITIAL(marqueeIncrement, MarqueeIncrement)
03333 if (!primitiveValue) return;
03334 if (primitiveValue->getIdent()) {
03335 switch (primitiveValue->getIdent())
03336 {
03337 case CSS_VAL_SMALL:
03338 style->setMarqueeIncrement(Length(1, Fixed));
03339 break;
03340 case CSS_VAL_NORMAL:
03341 style->setMarqueeIncrement(Length(6, Fixed));
03342 break;
03343 case CSS_VAL_LARGE:
03344 style->setMarqueeIncrement(Length(36, Fixed));
03345 break;
03346 }
03347 }
03348 else {
03349 bool ok = true;
03350 Length l = convertToLength(primitiveValue, style, paintDeviceMetrics, &ok);
03351 if (ok)
03352 style->setMarqueeIncrement(l);
03353 }
03354 break;
03355 }
03356 case CSS_PROP__KHTML_MARQUEE_STYLE: {
03357 HANDLE_INHERIT_AND_INITIAL(marqueeBehavior, MarqueeBehavior)
03358 if (!primitiveValue || !primitiveValue->getIdent()) return;
03359 switch (primitiveValue->getIdent())
03360 {
03361 case CSS_VAL_NONE:
03362 style->setMarqueeBehavior(MNONE);
03363 break;
03364 case CSS_VAL_SCROLL:
03365 style->setMarqueeBehavior(MSCROLL);
03366 break;
03367 case CSS_VAL_SLIDE:
03368 style->setMarqueeBehavior(MSLIDE);
03369 break;
03370 case CSS_VAL_ALTERNATE:
03371 style->setMarqueeBehavior(MALTERNATE);
03372 break;
03373 case CSS_VAL_UNFURL:
03374 style->setMarqueeBehavior(MUNFURL);
03375 break;
03376 }
03377 break;
03378 }
03379 case CSS_PROP__KHTML_MARQUEE_DIRECTION: {
03380 HANDLE_INHERIT_AND_INITIAL(marqueeDirection, MarqueeDirection)
03381 if (!primitiveValue || !primitiveValue->getIdent()) return;
03382 switch (primitiveValue->getIdent())
03383 {
03384 case CSS_VAL_FORWARDS:
03385 style->setMarqueeDirection(MFORWARD);
03386 break;
03387 case CSS_VAL_BACKWARDS:
03388 style->setMarqueeDirection(MBACKWARD);
03389 break;
03390 case CSS_VAL_AUTO:
03391 style->setMarqueeDirection(MAUTO);
03392 break;
03393 case CSS_VAL_AHEAD:
03394 case CSS_VAL_UP:
03395 style->setMarqueeDirection(MUP);
03396 break;
03397 case CSS_VAL_REVERSE:
03398 case CSS_VAL_DOWN:
03399 style->setMarqueeDirection(MDOWN);
03400 break;
03401 case CSS_VAL_LEFT:
03402 style->setMarqueeDirection(MLEFT);
03403 break;
03404 case CSS_VAL_RIGHT:
03405 style->setMarqueeDirection(MRIGHT);
03406 break;
03407 }
03408 break;
03409 }
03410 default:
03411 return;
03412 }
03413 }
03414
03415 #ifdef APPLE_CHANGES
03416 void CSSStyleSelector::checkForGenericFamilyChange(RenderStyle* aStyle, RenderStyle* aParentStyle)
03417 {
03418 const FontDef& childFont = aStyle->htmlFont().fontDef;
03419
03420 if (childFont.sizeSpecified || !aParentStyle)
03421 return;
03422
03423 const FontDef& parentFont = aParentStyle->htmlFont().fontDef;
03424
03425 if (childFont.genericFamily == parentFont.genericFamily)
03426 return;
03427
03428
03429 if (childFont.genericFamily != FontDef::eMonospace &&
03430 parentFont.genericFamily != FontDef::eMonospace)
03431 return;
03432
03433
03434
03435
03436 float size = 0;
03437 int minFontSize = settings->minFontSize();
03438 size = (childFont.genericFamily == FontDef::eMonospace) ? m_fixedFontSizes[3] : m_fontSizes[3];
03439 int isize = (int)size;
03440 if (isize < minFontSize)
03441 isize = minFontSize;
03442
03443 FontDef newFontDef(childFont);
03444 newFontDef.size = isize;
03445 aStyle->setFontDef(newFontDef);
03446 }
03447 #endif
03448
03449 }