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