Changeset 104060 in webkit
- Timestamp:
- Jan 4, 2012 12:03:35 PM (12 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r104047 r104060 1 2012-01-03 Antti Koivisto <antti@apple.com> 2 3 Reviewed by Dave Hyatt. 4 5 Analyze stylesheet scope to minimize style recalcs 6 https://bugs.webkit.org/show_bug.cgi?id=75508 7 8 It is a relatively common pattern to use inline stylesheets in document body where all rules are scoped using descendant selector 9 10 <style> 11 #foo {...} 12 #foo div {...} 13 #foo .bar {...} 14 </style> 15 16 When this pattern is used it is also common that the rules only apply to elements that come after the style element. 17 18 When the set of active stylesheets changes we invalidate and recompute the entire document style. This is very expensive. We can 19 detect the case above and avoid the style recalc. 20 21 On engadget.com, this patch cuts the time spent in style recalcs to roughly half. There are further savings from reduced 22 relayouts. In total the engine CPU time used over the page load is reduced by ~10%. 23 24 * css/CSSStyleSelector.cpp: 25 (WebCore::CSSStyleSelector::CSSStyleSelector): 26 (WebCore::CSSStyleSelector::collectFeatures): 27 28 Refactor feature collection from constructor to a separate function. 29 30 (WebCore::CSSStyleSelector::appendAuthorStylesheets): 31 32 New function for non-destructively updating the style selector. 33 34 (WebCore::CSSStyleSelector::Features::clear): 35 36 Clear the features for another collection. 37 38 (WebCore::CSSStyleSelector::determineStylesheetSelectorScopes): 39 40 Find if all rules on a stylesheetare scoped to some set of ids and classes. 41 42 (WebCore::CSSStyleSelector::styleForDocument): 43 44 Add optional font selector argument. We updated the correct base style font on style selector construction but that is no longer sufficient 45 as font selector may be updated without reconstructing the style selector. 46 47 (WebCore::RuleSet::addRulesFromSheet): 48 49 Invalidate the matched declaration cache in case of new font-face rules. 50 51 * css/CSSStyleSelector.h: 52 * css/SelectorChecker.cpp: 53 (WebCore::SelectorChecker::determineSelectorScopes): 54 55 Find if all rules on a selector list are scoped to some set of ids and classes. 56 57 * css/SelectorChecker.h: 58 * dom/Document.cpp: 59 (WebCore::Document::Document): 60 (WebCore::Document::recalcStyle): 61 62 Pass the font selector, if exists, to styleForDocument so we always have the base font up to date. 63 64 (WebCore::Document::combineCSSFeatureFlags): 65 (WebCore::Document::resetCSSFeatureFlags): 66 (WebCore::Document::createStyleSelector): 67 68 Refactor css feature flag resetting to functions. 69 70 (WebCore::Document::removePendingSheet): 71 72 Use new PendingStylesheetCompleted flag when new stylesheets arrive. 73 74 (WebCore::Document::styleSelectorChanged): 75 76 Skip style recalc if it is not needed. 77 78 (WebCore::Document::collectActiveStylesheets): 79 80 Refactor collecting stylesheets to a separate function. 81 82 (WebCore::Document::testAddedStylesheetRequiresStyleRecalc): 83 84 Determine the scopes and use hasElementWithId/getElementsByClassName to figure out if any scoped elements currently exist in the tree. 85 86 (WebCore::Document::analyzeStylesheetChange): 87 88 Figure out if we can update the style selector incrementally and if we can skip the style recalc. 89 90 (WebCore::Document::updateActiveStylesheets): 91 92 Renamed from recalcStyleSelector. 93 Invoke the new analysis functions. 94 95 * dom/Document.h: 96 1 97 2012-01-04 Igor Oliveira <igor.oliveira@openbossa.org> 2 98 -
trunk/Source/WebCore/css/CSSStyleSelector.cpp
r104036 r104060 419 419 m_authorStyle->addRulesFromSheet(static_cast<CSSStyleSheet*>(sheet), *m_medium, this); 420 420 } 421 m_authorStyle->shrinkToFit(); 422 423 collectFeatures(); 424 425 if (document->renderer() && document->renderer()->style()) 426 document->renderer()->style()->font().update(fontSelector()); 427 } 428 429 void CSSStyleSelector::collectFeatures() 430 { 421 431 // Collect all ids and rules using sibling selectors (:first-child and similar) 422 432 // in the current set of stylesheets. Style sharing code uses this information to reject … … 430 440 if (m_userStyle) 431 441 m_userStyle->collectFeatures(m_features); 432 433 m_authorStyle->shrinkToFit();434 442 if (m_features.siblingRules) 435 443 m_features.siblingRules->shrinkToFit(); 436 444 if (m_features.uncommonAttributeRules) 437 445 m_features.uncommonAttributeRules->shrinkToFit(); 438 439 if (document->renderer() && document->renderer()->style()) 440 document->renderer()->style()->font().update(fontSelector()); 446 } 447 448 void CSSStyleSelector::appendAuthorStylesheets(unsigned firstNew, const Vector<RefPtr<StyleSheet> >& stylesheets) 449 { 450 // This handles sheets added to the end of the stylesheet list only. In other cases the style resolver 451 // needs to be reconstructed. To handle insertions too the rule order numbers would need to be updated. 452 unsigned size = stylesheets.size(); 453 for (unsigned i = firstNew; i < size; ++i) { 454 if (!stylesheets[i]->isCSSStyleSheet() || stylesheets[i]->disabled()) 455 continue; 456 m_authorStyle->addRulesFromSheet(static_cast<CSSStyleSheet*>(stylesheets[i].get()), *m_medium, this); 457 } 458 m_authorStyle->shrinkToFit(); 459 // FIXME: This really only needs to collect the features from the newly added sheets. 460 m_features.clear(); 461 collectFeatures(); 462 463 if (document()->renderer() && document()->renderer()->style()) 464 document()->renderer()->style()->font().update(fontSelector()); 441 465 } 442 466 … … 468 492 CSSStyleSelector::Features::~Features() 469 493 { 494 } 495 496 void CSSStyleSelector::Features::clear() 497 { 498 idsInRules.clear(); 499 attrsInRules.clear(); 500 siblingRules.clear(); 501 uncommonAttributeRules.clear(); 502 usesFirstLineRules = false; 503 usesBeforeAfterRules = false; 504 usesLinkRules = false; 470 505 } 471 506 … … 1149 1184 } 1150 1185 1151 PassRefPtr<RenderStyle> CSSStyleSelector::styleForDocument(Document* document )1186 PassRefPtr<RenderStyle> CSSStyleSelector::styleForDocument(Document* document, CSSFontSelector* fontSelector) 1152 1187 { 1153 1188 Frame* frame = document->frame(); … … 1205 1240 1206 1241 documentStyle->setFontDescription(fontDescription); 1207 documentStyle->font().update( 0);1242 documentStyle->font().update(fontSelector); 1208 1243 1209 1244 return documentStyle.release(); … … 1800 1835 return true; 1801 1836 } 1837 1838 bool CSSStyleSelector::determineStylesheetSelectorScopes(CSSStyleSheet* stylesheet, HashSet<AtomicStringImpl*>& idScopes, HashSet<AtomicStringImpl*>& classScopes) 1839 { 1840 ASSERT(!stylesheet->isLoading()); 1841 1842 size_t size = stylesheet->length(); 1843 for (size_t i = 0; i < size; i++) { 1844 CSSRule* rule = stylesheet->item(i); 1845 if (rule->isStyleRule()) { 1846 CSSStyleRule* styleRule = static_cast<CSSStyleRule*>(rule); 1847 if (!SelectorChecker::determineSelectorScopes(styleRule->selectorList(), idScopes, classScopes)) 1848 return false; 1849 continue; 1850 } 1851 if (rule->isImportRule()) { 1852 CSSImportRule* importRule = static_cast<CSSImportRule*>(rule); 1853 if (importRule->styleSheet()) { 1854 if (!determineStylesheetSelectorScopes(importRule->styleSheet(), idScopes, classScopes)) 1855 return false; 1856 } 1857 continue; 1858 } 1859 // FIXME: Media rules and maybe some others could be allowed. 1860 return false; 1861 } 1862 return true; 1863 } 1802 1864 1803 1865 // ----------------------------------------------------------------- … … 1969 2031 const CSSFontFaceRule* fontFaceRule = static_cast<CSSFontFaceRule*>(childItem); 1970 2032 styleSelector->fontSelector()->addFontFaceRule(fontFaceRule); 2033 styleSelector->invalidateMatchedDeclarationCache(); 1971 2034 } else if (childItem->isKeyframesRule() && styleSelector) { 1972 2035 // Add this keyframe rule to our set. … … 1979 2042 const CSSFontFaceRule* fontFaceRule = static_cast<CSSFontFaceRule*>(rule); 1980 2043 styleSelector->fontSelector()->addFontFaceRule(fontFaceRule); 2044 styleSelector->invalidateMatchedDeclarationCache(); 1981 2045 } else if (rule->isKeyframesRule()) 1982 2046 styleSelector->addKeyframeStyle(static_cast<WebKitCSSKeyframesRule*>(rule)); -
trunk/Source/WebCore/css/CSSStyleSelector.h
r104036 r104060 113 113 PassRefPtr<RenderStyle> styleForPage(int pageIndex); 114 114 115 static PassRefPtr<RenderStyle> styleForDocument(Document* );115 static PassRefPtr<RenderStyle> styleForDocument(Document*, CSSFontSelector* = 0); 116 116 117 117 RenderStyle* style() const { return m_style.get(); } … … 127 127 void setTextSizeAdjust(bool b) { m_fontDirty |= style()->setTextSizeAdjust(b); } 128 128 bool hasParentNode() const { return m_parentNode; } 129 130 void appendAuthorStylesheets(unsigned firstNew, const Vector<RefPtr<StyleSheet> >&); 131 132 // Find the ids or classes the selectors on a stylesheet are scoped to. The selectors only apply to elements in subtrees where the root element matches the scope. 133 static bool determineStylesheetSelectorScopes(CSSStyleSheet*, HashSet<AtomicStringImpl*>& idScopes, HashSet<AtomicStringImpl*>& classScopes); 129 134 130 135 private: 131 136 void initForStyleResolve(Element*, RenderStyle* parentStyle = 0, PseudoId = NOPSEUDO); 132 137 void initElement(Element*); 138 void collectFeatures(); 133 139 RenderStyle* locateSharedStyle(); 134 140 bool matchesRuleSet(RuleSet*); … … 219 225 Features(); 220 226 ~Features(); 227 void clear(); 221 228 HashSet<AtomicStringImpl*> idsInRules; 222 229 HashSet<AtomicStringImpl*> attrsInRules; -
trunk/Source/WebCore/css/SelectorChecker.cpp
r102770 r104060 1399 1399 } 1400 1400 1401 } 1401 bool SelectorChecker::determineSelectorScopes(const CSSSelectorList& selectorList, HashSet<AtomicStringImpl*>& idScopes, HashSet<AtomicStringImpl*>& classScopes) 1402 { 1403 for (CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector)) { 1404 CSSSelector* rightmostSelector = selector; 1405 CSSSelector::Relation relation = CSSSelector::Descendant; 1406 for (;rightmostSelector->tagHistory(); rightmostSelector = rightmostSelector->tagHistory()) { 1407 if (rightmostSelector->relation() != CSSSelector::SubSelector) 1408 relation = rightmostSelector->relation(); 1409 } 1410 if (relation != CSSSelector::Descendant && relation != CSSSelector::Child) 1411 return false; 1412 if (rightmostSelector->m_match == CSSSelector::Id) { 1413 idScopes.add(rightmostSelector->value().impl()); 1414 continue; 1415 } 1416 if (rightmostSelector->m_match == CSSSelector::Class) { 1417 classScopes.add(rightmostSelector->value().impl()); 1418 continue; 1419 } 1420 return false; 1421 } 1422 return true; 1423 } 1424 1425 } -
trunk/Source/WebCore/css/SelectorChecker.h
r102770 r104060 91 91 static unsigned determineLinkMatchType(const CSSSelector*); 92 92 93 // Find the ids or classes selectors are scoped to. The selectors only apply to elements in subtrees where the root element matches the scope. 94 static bool determineSelectorScopes(const CSSSelectorList&, HashSet<AtomicStringImpl*>& idScopes, HashSet<AtomicStringImpl*>& classScopes); 95 93 96 private: 94 97 bool checkOneSelector(CSSSelector*, Element*, PseudoId& dynamicPseudo, bool isSubSelector, VisitedMatchType, RenderStyle*, RenderStyle* elementParentStyle) const; -
trunk/Source/WebCore/dom/Document.cpp
r103883 r104060 383 383 #endif 384 384 , m_styleSheets(StyleSheetList::create(this)) 385 , m_hadActiveLoadingStylesheet(false) 385 386 , m_readyState(Complete) 386 387 , m_styleRecalcTimer(this, &Document::styleRecalcTimerFired) … … 1529 1530 1530 1531 if (m_hasDirtyStyleSelector) 1531 recalcStyleSelector();1532 updateActiveStylesheets(RecalcStyleImmediately); 1532 1533 1533 1534 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRecalculateStyle(this); … … 1554 1555 m_hasNodesWithPlaceholderStyle = false; 1555 1556 1556 RefPtr<RenderStyle> documentStyle = CSSStyleSelector::styleForDocument(this );1557 RefPtr<RenderStyle> documentStyle = CSSStyleSelector::styleForDocument(this, m_styleSelector ? m_styleSelector->fontSelector() : 0); 1557 1558 StyleChange ch = diff(documentStyle.get(), renderer()->style()); 1558 1559 if (ch != NoChange) … … 1585 1586 1586 1587 // Pseudo element removal and similar may only work with these flags still set. Reset them after the style recalc. 1587 if (m_styleSelector) { 1588 m_usesSiblingRules = m_styleSelector->usesSiblingRules(); 1589 m_usesFirstLineRules = m_styleSelector->usesFirstLineRules(); 1590 m_usesBeforeAfterRules = m_styleSelector->usesBeforeAfterRules(); 1591 m_usesLinkRules = m_styleSelector->usesLinkRules(); 1592 } 1588 if (m_styleSelector) 1589 resetCSSFeatureFlags(); 1593 1590 1594 1591 if (frameView) { … … 1779 1776 } 1780 1777 1778 void Document::combineCSSFeatureFlags() 1779 { 1780 // Delay resetting the flags until after next style recalc since unapplying the style may not work without these set (this is true at least with before/after). 1781 m_usesSiblingRules = m_usesSiblingRules || m_styleSelector->usesSiblingRules(); 1782 m_usesFirstLineRules = m_usesFirstLineRules || m_styleSelector->usesFirstLineRules(); 1783 m_usesBeforeAfterRules = m_usesBeforeAfterRules || m_styleSelector->usesBeforeAfterRules(); 1784 m_usesLinkRules = m_usesLinkRules || m_styleSelector->usesLinkRules(); 1785 } 1786 1787 void Document::resetCSSFeatureFlags() 1788 { 1789 m_usesSiblingRules = m_styleSelector->usesSiblingRules(); 1790 m_usesFirstLineRules = m_styleSelector->usesFirstLineRules(); 1791 m_usesBeforeAfterRules = m_styleSelector->usesBeforeAfterRules(); 1792 m_usesLinkRules = m_styleSelector->usesLinkRules(); 1793 } 1794 1781 1795 void Document::createStyleSelector() 1782 1796 { … … 1786 1800 m_styleSelector = adoptPtr(new CSSStyleSelector(this, m_styleSheets.get(), m_mappedElementSheet.get(), pageUserSheet(), pageGroupUserSheets(), m_userSheets.get(), 1787 1801 !inQuirksMode(), matchAuthorAndUserStyles)); 1788 // Delay resetting the flags until after next style recalc since unapplying the style may not work without these set (this is true at least with before/after). 1789 m_usesSiblingRules = m_usesSiblingRules || m_styleSelector->usesSiblingRules(); 1790 m_usesFirstLineRules = m_usesFirstLineRules || m_styleSelector->usesFirstLineRules(); 1791 m_usesBeforeAfterRules = m_usesBeforeAfterRules || m_styleSelector->usesBeforeAfterRules(); 1792 m_usesLinkRules = m_usesLinkRules || m_styleSelector->usesLinkRules(); 1802 combineCSSFeatureFlags(); 1793 1803 } 1794 1804 … … 2951 2961 return; 2952 2962 2953 styleSelectorChanged(RecalcStyleI mmediately);2963 styleSelectorChanged(RecalcStyleIfNeeded); 2954 2964 2955 2965 if (ScriptableDocumentParser* parser = scriptableDocumentParser()) … … 2972 2982 #endif 2973 2983 2974 recalcStyleSelector(); 2975 2984 bool stylesheetChangeRequiresStyleRecalc = updateActiveStylesheets(updateFlag); 2985 if (!stylesheetChangeRequiresStyleRecalc) 2986 return; 2987 2976 2988 if (updateFlag == DeferRecalcStyle) { 2977 2989 scheduleForcedStyleRecalc(); … … 3045 3057 m_styleSheetCandidateNodes.remove(node); 3046 3058 } 3047 3048 void Document::recalcStyleSelector() 3049 { 3050 if (m_inStyleRecalc) { 3051 // SVG <use> element may manage to invalidate style selector in the middle of a style recalc. 3052 // https://bugs.webkit.org/show_bug.cgi?id=54344 3053 // FIXME: This should be fixed in SVG and this code replaced with ASSERT(!m_inStyleRecalc). 3054 m_hasDirtyStyleSelector = true; 3055 scheduleForcedStyleRecalc(); 3056 return; 3057 } 3058 if (!renderer() || !attached()) 3059 return; 3060 3061 StyleSheetVector sheets; 3062 3059 3060 void Document::collectActiveStylesheets(Vector<RefPtr<StyleSheet> >& sheets) 3061 { 3063 3062 bool matchAuthorAndUserStyles = true; 3064 3063 if (Settings* settings = this->settings()) … … 3071 3070 for (StyleSheetCandidateListHashSet::iterator it = begin; it != end; ++it) { 3072 3071 Node* n = *it; 3073 3074 3072 StyleSheet* sheet = 0; 3075 3076 3073 if (n->nodeType() == PROCESSING_INSTRUCTION_NODE) { 3077 3074 // Processing instruction (XML documents only). … … 3090 3087 } else if ((n->isHTMLElement() && (n->hasTagName(linkTag) || n->hasTagName(styleTag))) 3091 3088 #if ENABLE(SVG) 3092 || (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))3093 #endif 3094 ) {3089 || (n->isSVGElement() && n->hasTagName(SVGNames::styleTag)) 3090 #endif 3091 ) { 3095 3092 Element* e = static_cast<Element*>(n); 3096 3093 AtomicString title = e->getAttribute(titleAttr); … … 3116 3113 title = nullAtom; 3117 3114 } 3118 3119 3115 // Get the current preferred styleset. This is the 3120 3116 // set of sheets that will be enabled. … … 3129 3125 // <STYLE> element 3130 3126 sheet = static_cast<HTMLStyleElement*>(n)->sheet(); 3131 3132 3127 // Check to see if this sheet belongs to a styleset 3133 3128 // (thus making it PREFERRED or ALTERNATE rather than … … 3144 3139 m_preferredStylesheetSet = m_selectedStylesheetSet = title; 3145 3140 } 3146 3147 3141 if (title != m_preferredStylesheetSet) 3148 3142 sheet = 0; 3149 3143 } 3150 3144 } 3151 3152 3145 if (sheet) 3153 3146 sheets.append(sheet); 3154 3147 } 3155 3156 m_styleSheets->swap(sheets); 3157 3158 m_styleSelector.clear(); 3148 } 3149 3150 bool Document::testAddedStylesheetRequiresStyleRecalc(CSSStyleSheet* stylesheet) 3151 { 3152 if (stylesheet->disabled()) 3153 return false; 3154 // See if all rules on the sheet are scoped to some specific ids or classes. 3155 // Then test if we actually have any of those in the tree at the moment. 3156 // FIXME: Even we if we find some, we could just invalidate those subtrees instead of invalidating the entire style. 3157 HashSet<AtomicStringImpl*> idScopes; 3158 HashSet<AtomicStringImpl*> classScopes; 3159 if (!CSSStyleSelector::determineStylesheetSelectorScopes(stylesheet, idScopes, classScopes)) 3160 return true; 3161 // Testing for classes is not particularly fast so bail out if there are more than a few. 3162 static const int maximumClassScopesToTest = 4; 3163 if (classScopes.size() > maximumClassScopesToTest) 3164 return true; 3165 HashSet<AtomicStringImpl*>::iterator end = idScopes.end(); 3166 for (HashSet<AtomicStringImpl*>::iterator it = idScopes.begin(); it != end; ++it) { 3167 if (hasElementWithId(*it)) 3168 return true; 3169 } 3170 end = classScopes.end(); 3171 for (HashSet<AtomicStringImpl*>::iterator it = classScopes.begin(); it != end; ++it) { 3172 // FIXME: getElementsByClassName is not optimal for this. We should handle all classes in a single pass. 3173 if (getElementsByClassName(*it)->length()) 3174 return true; 3175 } 3176 return false; 3177 } 3178 3179 void Document::analyzeStylesheetChange(StyleSelectorUpdateFlag updateFlag, const Vector<RefPtr<StyleSheet> >& newStylesheets, bool& requiresStyleSelectorReset, bool& requiresStyleRecalc) 3180 { 3181 requiresStyleSelectorReset = true; 3182 requiresStyleRecalc = true; 3183 3184 // Stylesheets of <style> elements that @import stylesheets are active but loading. We need to trigger a full recalc when such loads are done. 3185 bool hasActiveLoadingStylesheet = false; 3186 unsigned newStylesheetCount = newStylesheets.size(); 3187 for (unsigned i = 0; i < newStylesheetCount; ++i) { 3188 if (newStylesheets[i]->isLoading()) 3189 hasActiveLoadingStylesheet = true; 3190 } 3191 if (m_hadActiveLoadingStylesheet && !hasActiveLoadingStylesheet) { 3192 m_hadActiveLoadingStylesheet = false; 3193 return; 3194 } 3195 m_hadActiveLoadingStylesheet = hasActiveLoadingStylesheet; 3196 3197 if (updateFlag != RecalcStyleIfNeeded) 3198 return; 3199 if (!m_styleSelector) 3200 return; 3201 3202 // See if we are just adding stylesheets. 3203 unsigned oldStylesheetCount = m_styleSheets->length(); 3204 if (newStylesheetCount < oldStylesheetCount) 3205 return; 3206 for (unsigned i = 0; i < oldStylesheetCount; ++i) { 3207 if (m_styleSheets->item(i) != newStylesheets[i]) 3208 return; 3209 } 3210 requiresStyleSelectorReset = false; 3211 3212 // If we are already parsing the body and so may have significant amount of elements, put some effort into trying to avoid style recalcs. 3213 if (!body() || m_hasNodesWithPlaceholderStyle) 3214 return; 3215 for (unsigned i = oldStylesheetCount; i < newStylesheetCount; ++i) { 3216 if (!newStylesheets[i]->isCSSStyleSheet()) 3217 return; 3218 if (testAddedStylesheetRequiresStyleRecalc(static_cast<CSSStyleSheet*>(newStylesheets[i].get()))) 3219 return; 3220 } 3221 requiresStyleRecalc = false; 3222 } 3223 3224 bool Document::updateActiveStylesheets(StyleSelectorUpdateFlag updateFlag) 3225 { 3226 if (m_inStyleRecalc) { 3227 // SVG <use> element may manage to invalidate style selector in the middle of a style recalc. 3228 // https://bugs.webkit.org/show_bug.cgi?id=54344 3229 // FIXME: This should be fixed in SVG and this code replaced with ASSERT(!m_inStyleRecalc). 3230 m_hasDirtyStyleSelector = true; 3231 scheduleForcedStyleRecalc(); 3232 return false; 3233 } 3234 if (!renderer() || !attached()) 3235 return false; 3236 3237 StyleSheetVector newStylesheets; 3238 collectActiveStylesheets(newStylesheets); 3239 3240 bool requiresStyleSelectorReset; 3241 bool requiresStyleRecalc; 3242 analyzeStylesheetChange(updateFlag, newStylesheets, requiresStyleSelectorReset, requiresStyleRecalc); 3243 3244 if (requiresStyleSelectorReset) 3245 m_styleSelector.clear(); 3246 else { 3247 m_styleSelector->appendAuthorStylesheets(m_styleSheets->length(), newStylesheets); 3248 resetCSSFeatureFlags(); 3249 } 3250 m_styleSheets->swap(newStylesheets); 3251 3159 3252 m_didCalculateStyleSelector = true; 3160 3253 m_hasDirtyStyleSelector = false; 3254 3255 return requiresStyleRecalc; 3161 3256 } 3162 3257 -
trunk/Source/WebCore/dom/Document.h
r103865 r104060 212 212 }; 213 213 214 enum StyleSelectorUpdateFlag { RecalcStyleImmediately, DeferRecalcStyle };214 enum StyleSelectorUpdateFlag { RecalcStyleImmediately, DeferRecalcStyle, RecalcStyleIfNeeded }; 215 215 216 216 class Document : public TreeScope, public ScriptExecutionContext { … … 457 457 458 458 /** 459 * Updates the pending sheet count and then calls update StyleSelector.459 * Updates the pending sheet count and then calls updateActiveStylesheets. 460 460 */ 461 461 void removePendingSheet(); … … 492 492 */ 493 493 void styleSelectorChanged(StyleSelectorUpdateFlag); 494 void recalcStyleSelector();495 494 496 495 bool usesSiblingRules() const { return m_usesSiblingRules || m_usesSiblingRulesOverride; } … … 1162 1161 1163 1162 void createStyleSelector(); 1163 void combineCSSFeatureFlags(); 1164 void resetCSSFeatureFlags(); 1165 1166 bool updateActiveStylesheets(StyleSelectorUpdateFlag); 1167 void collectActiveStylesheets(Vector<RefPtr<StyleSheet> >&); 1168 bool testAddedStylesheetRequiresStyleRecalc(CSSStyleSheet*); 1169 void analyzeStylesheetChange(StyleSelectorUpdateFlag, const Vector<RefPtr<StyleSheet> >& newStylesheets, bool& requiresStyleSelectorReset, bool& requiresStyleRecalc); 1164 1170 1165 1171 void deleteCustomFonts(); … … 1265 1271 1266 1272 RefPtr<StyleSheetList> m_styleSheets; // All of the stylesheets that are currently in effect for our media type and stylesheet set. 1273 bool m_hadActiveLoadingStylesheet; 1267 1274 1268 1275 typedef ListHashSet<Node*, 32> StyleSheetCandidateListHashSet;
Note: See TracChangeset
for help on using the changeset viewer.