Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(242)

Side by Side Diff: third_party/WebKit/Source/core/dom/StyleEngine.cpp

Issue 1913833002: Current work-in-progress crbug.com/567021 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: More assert fixes Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) 5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org)
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All r ights reserved. 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All r ights reserved.
7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/) 7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/)
8 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved. 8 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved.
9 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) 9 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
10 * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved. 10 * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved.
(...skipping 17 matching lines...) Expand all
28 #include "core/dom/StyleEngine.h" 28 #include "core/dom/StyleEngine.h"
29 29
30 #include "core/HTMLNames.h" 30 #include "core/HTMLNames.h"
31 #include "core/css/CSSDefaultStyleSheets.h" 31 #include "core/css/CSSDefaultStyleSheets.h"
32 #include "core/css/CSSFontSelector.h" 32 #include "core/css/CSSFontSelector.h"
33 #include "core/css/CSSStyleSheet.h" 33 #include "core/css/CSSStyleSheet.h"
34 #include "core/css/FontFaceCache.h" 34 #include "core/css/FontFaceCache.h"
35 #include "core/css/StyleSheetContents.h" 35 #include "core/css/StyleSheetContents.h"
36 #include "core/css/invalidation/InvalidationSet.h" 36 #include "core/css/invalidation/InvalidationSet.h"
37 #include "core/css/resolver/ScopedStyleResolver.h" 37 #include "core/css/resolver/ScopedStyleResolver.h"
38 #include "core/css/resolver/SharedStyleFinder.h"
39 #include "core/css/resolver/ViewportStyleResolver.h"
38 #include "core/dom/DocumentStyleSheetCollector.h" 40 #include "core/dom/DocumentStyleSheetCollector.h"
39 #include "core/dom/Element.h" 41 #include "core/dom/Element.h"
42 #include "core/dom/ElementTraversal.h"
40 #include "core/dom/ProcessingInstruction.h" 43 #include "core/dom/ProcessingInstruction.h"
41 #include "core/dom/ShadowTreeStyleSheetCollection.h" 44 #include "core/dom/ShadowTreeStyleSheetCollection.h"
42 #include "core/dom/StyleChangeReason.h" 45 #include "core/dom/StyleChangeReason.h"
43 #include "core/dom/shadow/ShadowRoot.h" 46 #include "core/dom/shadow/ShadowRoot.h"
44 #include "core/frame/Settings.h" 47 #include "core/frame/Settings.h"
45 #include "core/html/HTMLIFrameElement.h" 48 #include "core/html/HTMLIFrameElement.h"
46 #include "core/html/HTMLLinkElement.h" 49 #include "core/html/HTMLLinkElement.h"
50 #include "core/html/HTMLSlotElement.h"
47 #include "core/html/imports/HTMLImportsController.h" 51 #include "core/html/imports/HTMLImportsController.h"
48 #include "core/inspector/InspectorInstrumentation.h" 52 #include "core/inspector/InspectorInstrumentation.h"
49 #include "core/page/Page.h" 53 #include "core/page/Page.h"
50 #include "core/svg/SVGStyleElement.h" 54 #include "core/svg/SVGStyleElement.h"
51 #include "platform/TraceEvent.h" 55 #include "platform/TraceEvent.h"
52 #include "platform/fonts/FontCache.h" 56 #include "platform/fonts/FontCache.h"
53 57
54 namespace blink { 58 namespace blink {
55 59
56 using namespace HTMLNames; 60 using namespace HTMLNames;
57 61
58 StyleEngine::StyleEngine(Document& document) 62 StyleEngine::StyleEngine(Document& document)
59 : m_document(&document) 63 : m_document(&document)
60 , m_isMaster(!document.importsController() || document.importsController()-> master() == &document) 64 , m_isMaster(!document.importsController() || document.importsController()-> master() == &document)
61 , m_documentStyleSheetCollection(DocumentStyleSheetCollection::create(docume nt)) 65 , m_documentStyleSheetCollection(DocumentStyleSheetCollection::create(docume nt))
62 // We don't need to create CSSFontSelector for imported document or
63 // HTMLTemplateElement's document, because those documents have no frame.
64 , m_fontSelector(document.frame() ? CSSFontSelector::create(&document) : nul lptr)
65 { 66 {
66 if (m_fontSelector) 67 if (document.frame()) {
68 // We don't need to create CSSFontSelector for imported document or
69 // HTMLTemplateElement's document, because those documents have no frame .
70 m_fontSelector = CSSFontSelector::create(&document);
67 m_fontSelector->registerForInvalidationCallbacks(this); 71 m_fontSelector->registerForInvalidationCallbacks(this);
72 }
68 } 73 }
69 74
70 StyleEngine::~StyleEngine() 75 StyleEngine::~StyleEngine()
71 { 76 {
72 } 77 }
73 78
74 static bool isStyleElement(Node& node) 79 static bool isStyleElement(Node& node)
75 { 80 {
76 return isHTMLStyleElement(node) || isSVGStyleElement(node); 81 return isHTMLStyleElement(node) || isSVGStyleElement(node);
77 } 82 }
(...skipping 25 matching lines...) Expand all
103 return documentStyleSheetCollection(); 108 return documentStyleSheetCollection();
104 109
105 StyleSheetCollectionMap::iterator it = m_styleSheetCollectionMap.find(&treeS cope); 110 StyleSheetCollectionMap::iterator it = m_styleSheetCollectionMap.find(&treeS cope);
106 if (it == m_styleSheetCollectionMap.end()) 111 if (it == m_styleSheetCollectionMap.end())
107 return 0; 112 return 0;
108 return it->value.get(); 113 return it->value.get();
109 } 114 }
110 115
111 const HeapVector<Member<StyleSheet>>& StyleEngine::styleSheetsForStyleSheetList( TreeScope& treeScope) 116 const HeapVector<Member<StyleSheet>>& StyleEngine::styleSheetsForStyleSheetList( TreeScope& treeScope)
112 { 117 {
118 // TODO(rune@opera.com): we could split styleSheets and active stylesheet
119 // update to have a lighter update while accessing the styleSheets list.
120 DCHECK(master());
121 if (master()->isActive()) {
122 if (isMaster())
123 updateActiveStyle();
124 else
125 master()->styleEngine().updateActiveStyle();
126 }
127
113 if (treeScope == m_document) 128 if (treeScope == m_document)
114 return documentStyleSheetCollection()->styleSheetsForStyleSheetList(); 129 return documentStyleSheetCollection()->styleSheetsForStyleSheetList();
115 130
116 return ensureStyleSheetCollectionFor(treeScope)->styleSheetsForStyleSheetLis t(); 131 return ensureStyleSheetCollectionFor(treeScope)->styleSheetsForStyleSheetLis t();
117 } 132 }
118 133
119 void StyleEngine::resetCSSFeatureFlags(const RuleFeatureSet& features)
120 {
121 m_usesSiblingRules = features.usesSiblingRules();
122 m_usesFirstLineRules = features.usesFirstLineRules();
123 m_usesWindowInactiveSelector = features.usesWindowInactiveSelector();
124 m_maxDirectAdjacentSelectors = features.maxDirectAdjacentSelectors();
125 }
126
127 void StyleEngine::injectAuthorSheet(StyleSheetContents* authorSheet) 134 void StyleEngine::injectAuthorSheet(StyleSheetContents* authorSheet)
128 { 135 {
129 m_injectedAuthorStyleSheets.append(CSSStyleSheet::create(authorSheet, m_docu ment)); 136 m_injectedAuthorStyleSheets.append(CSSStyleSheet::create(authorSheet, m_docu ment));
130 markDocumentDirty(); 137 markDocumentDirty();
131 resolverChanged(AnalyzedStyleUpdate);
132 } 138 }
133 139
134 void StyleEngine::addPendingSheet(StyleEngineContext &context) 140 void StyleEngine::addPendingSheet(StyleEngineContext &context)
135 { 141 {
136 m_pendingScriptBlockingStylesheets++; 142 m_pendingScriptBlockingStylesheets++;
137 143
138 context.addingPendingSheet(document()); 144 context.addingPendingSheet(document());
139 if (context.addedPendingSheetBeforeBody()) 145 if (context.addedPendingSheetBeforeBody())
140 m_pendingRenderBlockingStylesheets++; 146 m_pendingRenderBlockingStylesheets++;
141 } 147 }
142 148
143 // This method is called whenever a top-level stylesheet has finished loading. 149 // This method is called whenever a top-level stylesheet has finished loading.
144 void StyleEngine::removePendingSheet(Node* styleSheetCandidateNode, const StyleE ngineContext &context) 150 void StyleEngine::removePendingSheet(Node* styleSheetCandidateNode, const StyleE ngineContext &context)
145 { 151 {
146 DCHECK(styleSheetCandidateNode); 152 DCHECK(styleSheetCandidateNode);
147 TreeScope* treeScope = isStyleElement(*styleSheetCandidateNode) ? &styleShee tCandidateNode->treeScope() : m_document.get(); 153 TreeScope* treeScope = isStyleElement(*styleSheetCandidateNode) ? &styleShee tCandidateNode->treeScope() : m_document.get();
148 if (styleSheetCandidateNode->inShadowIncludingDocument()) 154 if (styleSheetCandidateNode->inShadowIncludingDocument())
149 markTreeScopeDirty(*treeScope); 155 markTreeScopeDirty(*treeScope);
150 156
151 if (context.addedPendingSheetBeforeBody()) { 157 if (context.addedPendingSheetBeforeBody()) {
152 DCHECK_GT(m_pendingRenderBlockingStylesheets, 0); 158 DCHECK(m_pendingRenderBlockingStylesheets);
153 m_pendingRenderBlockingStylesheets--; 159 m_pendingRenderBlockingStylesheets--;
154 } 160 }
155 161
156 // Make sure we knew this sheet was pending, and that our count isn't out of sync. 162 // Make sure we knew this sheet was pending, and that our count isn't out of sync.
157 DCHECK_GT(m_pendingScriptBlockingStylesheets, 0); 163 DCHECK(m_pendingScriptBlockingStylesheets);
158 164
159 m_pendingScriptBlockingStylesheets--; 165 m_pendingScriptBlockingStylesheets--;
160 if (m_pendingScriptBlockingStylesheets) 166 if (m_pendingScriptBlockingStylesheets)
161 return; 167 return;
162 168
163 document().didRemoveAllPendingStylesheet(); 169 document().didRemoveAllPendingStylesheet();
164 } 170 }
165 171
166 void StyleEngine::setNeedsActiveStyleUpdate(StyleSheet* sheet, StyleResolverUpda teMode updateMode) 172 void StyleEngine::setNeedsActiveStyleUpdate(TreeScope& treeScope)
167 { 173 {
168 // resolverChanged() is called for inactive non-master documents because
169 // import documents are inactive documents. resolverChanged() for imports
170 // will call resolverChanged() for the master document and update the active
171 // stylesheets including the ones from the import.
172 if (!document().isActive() && isMaster()) 174 if (!document().isActive() && isMaster())
173 return; 175 return;
176 markTreeScopeDirty(treeScope);
177 }
174 178
175 if (sheet && document().isActive()) { 179 void StyleEngine::updateActiveStyle()
176 Node* node = sheet->ownerNode(); 180 {
177 if (node && node->inShadowIncludingDocument()) { 181 DCHECK(document().isActive());
178 TreeScope& treeScope = isStyleElement(*node) ? node->treeScope() : * m_document;
179 DCHECK(isStyleElement(*node) || node->treeScope() == m_document);
180 markTreeScopeDirty(treeScope);
181 }
182 }
183 182
184 resolverChanged(updateMode); 183 if (!needsActiveStyleUpdate())
184 return;
185
186 updateActiveStyleSheets();
187 updateGlobalRuleSet();
188
189 DCHECK(!needsActiveStyleUpdate());
185 } 190 }
186 191
187 void StyleEngine::addStyleSheetCandidateNode(Node* node) 192 void StyleEngine::addStyleSheetCandidateNode(Node* node)
188 { 193 {
189 if (!node->inShadowIncludingDocument() || document().isDetached()) 194 if (!node->inShadowIncludingDocument() || document().isDetached())
190 return; 195 return;
191 196
192 TreeScope& treeScope = isStyleElement(*node) ? node->treeScope() : *m_docume nt; 197 TreeScope& treeScope = isStyleElement(*node) ? node->treeScope() : *m_docume nt;
193 DCHECK(isStyleElement(*node) || treeScope == m_document); 198 DCHECK(isStyleElement(*node) || treeScope == m_document);
194 DCHECK(!isXSLStyleSheet(*node)); 199 DCHECK(!isXSLStyleSheet(*node));
(...skipping 27 matching lines...) Expand all
222 } 227 }
223 228
224 void StyleEngine::modifiedStyleSheetCandidateNode(Node* node) 229 void StyleEngine::modifiedStyleSheetCandidateNode(Node* node)
225 { 230 {
226 if (!node->inShadowIncludingDocument()) 231 if (!node->inShadowIncludingDocument())
227 return; 232 return;
228 233
229 TreeScope& treeScope = isStyleElement(*node) ? node->treeScope() : *m_docume nt; 234 TreeScope& treeScope = isStyleElement(*node) ? node->treeScope() : *m_docume nt;
230 DCHECK(isStyleElement(*node) || treeScope == m_document); 235 DCHECK(isStyleElement(*node) || treeScope == m_document);
231 markTreeScopeDirty(treeScope); 236 markTreeScopeDirty(treeScope);
232 resolverChanged(FullStyleUpdate);
233 } 237 }
234 238
235 void StyleEngine::watchedSelectorsChanged() 239 void StyleEngine::watchedSelectorsChanged()
236 { 240 {
237 if (m_resolver) { 241 m_globalRuleSet.initWatchedSelectorsRuleSet(document());
238 m_resolver->initWatchedSelectorRules(); 242 m_needsGlobalRuleSetUpdate = true;
239 m_resolver->resetRuleFeatures();
240 }
241 document().setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTraci ng::create(StyleChangeReason::DeclarativeContent)); 243 document().setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTraci ng::create(StyleChangeReason::DeclarativeContent));
242 } 244 }
243 245
244 bool StyleEngine::shouldUpdateDocumentStyleSheetCollection(StyleResolverUpdateMo de updateMode) const 246 bool StyleEngine::shouldUpdateDocumentStyleSheetCollection() const
245 { 247 {
246 return m_documentScopeDirty || updateMode == FullStyleUpdate; 248 return m_allTreeScopesDirty || m_documentScopeDirty;
247 } 249 }
248 250
249 bool StyleEngine::shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdate Mode updateMode) const 251 bool StyleEngine::shouldUpdateShadowTreeStyleSheetCollection() const
250 { 252 {
251 return !m_dirtyTreeScopes.isEmpty() || updateMode == FullStyleUpdate; 253 return m_allTreeScopesDirty || !m_dirtyTreeScopes.isEmpty();
252 } 254 }
253 255
254 void StyleEngine::clearMediaQueryRuleSetOnTreeScopeStyleSheets(UnorderedTreeScop eSet& treeScopes) 256 void StyleEngine::mediaQueryAffectingValueChanged(UnorderedTreeScopeSet& treeSco pes)
255 { 257 {
256 for (TreeScope* treeScope : treeScopes) { 258 for (TreeScope* treeScope : treeScopes) {
257 DCHECK(treeScope != m_document); 259 DCHECK(treeScope != m_document);
258 ShadowTreeStyleSheetCollection* collection = toShadowTreeStyleSheetColle ction(styleSheetCollectionFor(*treeScope)); 260 ShadowTreeStyleSheetCollection* collection = toShadowTreeStyleSheetColle ction(styleSheetCollectionFor(*treeScope));
259 DCHECK(collection); 261 DCHECK(collection);
260 collection->clearMediaQueryRuleSetStyleSheets(); 262 if (collection->mediaQueryAffectingValueChanged())
263 setNeedsActiveStyleUpdate(*treeScope);
261 } 264 }
262 } 265 }
263 266
264 void StyleEngine::clearMediaQueryRuleSetStyleSheets() 267 void StyleEngine::mediaQueryAffectingValueChanged()
265 { 268 {
266 resolverChanged(FullStyleUpdate); 269 if (documentStyleSheetCollection()->mediaQueryAffectingValueChanged())
267 documentStyleSheetCollection()->clearMediaQueryRuleSetStyleSheets(); 270 setNeedsActiveStyleUpdate(document());
268 clearMediaQueryRuleSetOnTreeScopeStyleSheets(m_activeTreeScopes); 271 mediaQueryAffectingValueChanged(m_activeTreeScopes);
272
273 if (!document().frame())
274 return;
275
276 if (document().wasPrinting() != document().printing() && document().frame()- >pageZoomFactor() != 1)
277 document().setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForT racing::create(StyleChangeReason::StyleSheetChange));
269 } 278 }
270 279
271 void StyleEngine::updateStyleSheetsInImport(DocumentStyleSheetCollector& parentC ollector) 280 void StyleEngine::updateStyleSheetsInImport(DocumentStyleSheetCollector& parentC ollector)
272 { 281 {
273 DCHECK(!isMaster()); 282 DCHECK(!isMaster());
274 HeapVector<Member<StyleSheet>> sheetsForList; 283 HeapVector<Member<StyleSheet>> sheetsForList;
275 ImportedDocumentStyleSheetCollector subcollector(parentCollector, sheetsForL ist); 284 ImportedDocumentStyleSheetCollector subcollector(parentCollector, sheetsForL ist);
276 documentStyleSheetCollection()->collectStyleSheets(*this, subcollector); 285 documentStyleSheetCollection()->collectStyleSheets(subcollector);
277 documentStyleSheetCollection()->swapSheetsForSheetList(sheetsForList); 286 documentStyleSheetCollection()->swapSheetsForSheetList(sheetsForList);
278 } 287 }
279 288
280 void StyleEngine::updateActiveStyleSheetsInShadow(StyleResolverUpdateMode update Mode, TreeScope* treeScope, UnorderedTreeScopeSet& treeScopesRemoved) 289 void StyleEngine::updateActiveStyleSheetsInShadow(TreeScope* treeScope, Unordere dTreeScopeSet& treeScopesRemoved)
281 { 290 {
282 DCHECK_NE(treeScope, m_document); 291 DCHECK_NE(treeScope, m_document);
283 ShadowTreeStyleSheetCollection* collection = toShadowTreeStyleSheetCollectio n(styleSheetCollectionFor(*treeScope)); 292 ShadowTreeStyleSheetCollection* collection = toShadowTreeStyleSheetCollectio n(styleSheetCollectionFor(*treeScope));
284 DCHECK(collection); 293 DCHECK(collection);
285 collection->updateActiveStyleSheets(*this, updateMode); 294 collection->updateActiveStyleSheets();
286 if (!collection->hasStyleSheetCandidateNodes()) { 295 if (!collection->hasStyleSheetCandidateNodes()) {
287 treeScopesRemoved.add(treeScope); 296 treeScopesRemoved.add(treeScope);
288 // When removing TreeScope from ActiveTreeScopes, 297 // When removing TreeScope from ActiveTreeScopes,
289 // its resolver should be destroyed by invoking resetAuthorStyle. 298 // its resolver should be destroyed by invoking resetAuthorStyle.
290 DCHECK(!treeScope->scopedStyleResolver()); 299 DCHECK(!treeScope->scopedStyleResolver());
291 } 300 }
292 } 301 }
293 302
294 void StyleEngine::updateActiveStyleSheets(StyleResolverUpdateMode updateMode) 303 void StyleEngine::updateActiveStyleSheets()
295 { 304 {
305 if (!needsActiveStyleSheetUpdate())
306 return;
307
296 DCHECK(isMaster()); 308 DCHECK(isMaster());
297 DCHECK(!document().inStyleRecalc()); 309 DCHECK(!document().inStyleRecalc());
298 310 DCHECK(document().isActive());
299 if (!document().isActive())
300 return;
301 311
302 TRACE_EVENT0("blink,blink_style", "StyleEngine::updateActiveStyleSheets"); 312 TRACE_EVENT0("blink,blink_style", "StyleEngine::updateActiveStyleSheets");
303 313
304 if (shouldUpdateDocumentStyleSheetCollection(updateMode)) 314 if (shouldUpdateDocumentStyleSheetCollection()) {
305 documentStyleSheetCollection()->updateActiveStyleSheets(*this, updateMod e); 315 documentStyleSheetCollection()->updateViewport();
316 documentStyleSheetCollection()->updateActiveStyleSheets();
317 }
306 318
307 if (shouldUpdateShadowTreeStyleSheetCollection(updateMode)) { 319 if (shouldUpdateShadowTreeStyleSheetCollection()) {
308 UnorderedTreeScopeSet treeScopesRemoved; 320 UnorderedTreeScopeSet treeScopesRemoved;
309 321
310 if (updateMode == FullStyleUpdate) { 322 for (TreeScope* treeScope : m_dirtyTreeScopes)
311 for (TreeScope* treeScope : m_activeTreeScopes) 323 updateActiveStyleSheetsInShadow(treeScope, treeScopesRemoved);
312 updateActiveStyleSheetsInShadow(updateMode, treeScope, treeScope sRemoved);
313 } else {
314 for (TreeScope* treeScope : m_dirtyTreeScopes)
315 updateActiveStyleSheetsInShadow(updateMode, treeScope, treeScope sRemoved);
316 }
317 for (TreeScope* treeScope : treeScopesRemoved) 324 for (TreeScope* treeScope : treeScopesRemoved)
318 m_activeTreeScopes.remove(treeScope); 325 m_activeTreeScopes.remove(treeScope);
319 } 326 }
320 327
321 InspectorInstrumentation::activeStyleSheetsUpdated(m_document); 328 InspectorInstrumentation::activeStyleSheetsUpdated(m_document);
322 329
323 m_dirtyTreeScopes.clear(); 330 m_dirtyTreeScopes.clear();
324 m_documentScopeDirty = false; 331 m_documentScopeDirty = false;
332 m_allTreeScopesDirty = false;
325 } 333 }
326 334
327 const HeapVector<Member<CSSStyleSheet>> StyleEngine::activeStyleSheetsForInspect or() const 335 const ActiveStyleSheetVector StyleEngine::activeStyleSheetsForInspector()
328 { 336 {
337 if (document().isActive())
338 updateActiveStyle();
339
329 if (m_activeTreeScopes.isEmpty()) 340 if (m_activeTreeScopes.isEmpty())
330 return documentStyleSheetCollection()->activeAuthorStyleSheets(); 341 return documentStyleSheetCollection()->activeAuthorStyleSheets();
331 342
332 HeapVector<Member<CSSStyleSheet>> activeStyleSheets; 343 ActiveStyleSheetVector activeStyleSheets;
333 344
334 activeStyleSheets.appendVector(documentStyleSheetCollection()->activeAuthorS tyleSheets()); 345 activeStyleSheets.appendVector(documentStyleSheetCollection()->activeAuthorS tyleSheets());
335 for (TreeScope* treeScope : m_activeTreeScopes) { 346 for (TreeScope* treeScope : m_activeTreeScopes) {
336 if (TreeScopeStyleSheetCollection* collection = m_styleSheetCollectionMa p.get(treeScope)) 347 if (TreeScopeStyleSheetCollection* collection = m_styleSheetCollectionMa p.get(treeScope))
337 activeStyleSheets.appendVector(collection->activeAuthorStyleSheets() ); 348 activeStyleSheets.appendVector(collection->activeAuthorStyleSheets() );
338 } 349 }
339 350
340 // FIXME: Inspector needs a vector which has all active stylesheets. 351 // FIXME: Inspector needs a vector which has all active stylesheets.
341 // However, creating such a large vector might cause performance regression. 352 // However, creating such a large vector might cause performance regression.
342 // Need to implement some smarter solution. 353 // Need to implement some smarter solution.
343 return activeStyleSheets; 354 return activeStyleSheets;
344 } 355 }
345 356
346 void StyleEngine::didRemoveShadowRoot(ShadowRoot* shadowRoot) 357 void StyleEngine::didRemoveShadowRoot(ShadowRoot* shadowRoot)
347 { 358 {
348 m_styleSheetCollectionMap.remove(shadowRoot); 359 m_styleSheetCollectionMap.remove(shadowRoot);
349 m_activeTreeScopes.remove(shadowRoot); 360 m_activeTreeScopes.remove(shadowRoot);
350 m_dirtyTreeScopes.remove(shadowRoot); 361 m_dirtyTreeScopes.remove(shadowRoot);
351 } 362 }
352 363
353 void StyleEngine::shadowRootRemovedFromDocument(ShadowRoot* shadowRoot) 364 void StyleEngine::shadowRootRemovedFromDocument(ShadowRoot* shadowRoot)
354 { 365 {
355 if (StyleResolver* styleResolver = resolver()) { 366 m_needsGlobalRuleSetUpdate = true;
356 styleResolver->resetAuthorStyle(*shadowRoot); 367 shadowRoot->clearScopedStyleResolver();
357
358 if (TreeScopeStyleSheetCollection* collection = styleSheetCollectionFor( *shadowRoot))
359 styleResolver->removePendingAuthorStyleSheets(collection->activeAuth orStyleSheets());
360 }
361 m_styleSheetCollectionMap.remove(shadowRoot); 368 m_styleSheetCollectionMap.remove(shadowRoot);
362 m_activeTreeScopes.remove(shadowRoot); 369 m_activeTreeScopes.remove(shadowRoot);
363 m_dirtyTreeScopes.remove(shadowRoot); 370 m_dirtyTreeScopes.remove(shadowRoot);
371 m_treeBoundaryCrossingScopes.remove(&shadowRoot->rootNode());
364 } 372 }
365 373
366 void StyleEngine::appendActiveAuthorStyleSheets() 374 void StyleEngine::addTreeBoundaryCrossingScope(ContainerNode& scope)
367 { 375 {
368 DCHECK(isMaster()); 376 m_treeBoundaryCrossingScopes.add(&scope);
377 }
369 378
370 m_resolver->appendAuthorStyleSheets(documentStyleSheetCollection()->activeAu thorStyleSheets()); 379 RuleSet& StyleEngine::ensureRuleSetForSheet(CSSStyleSheet& sheet)
371 for (TreeScope* treeScope : m_activeTreeScopes) { 380 {
372 if (TreeScopeStyleSheetCollection* collection = m_styleSheetCollectionMa p.get(treeScope)) 381 if (!sheet.matchesMediaQueries(ensureMediaQueryEvaluator()))
373 m_resolver->appendAuthorStyleSheets(collection->activeAuthorStyleShe ets()); 382 return *RuleSet::emptyRuleSet();
374 } 383
375 m_resolver->finishAppendAuthorStyleSheets(); 384 AddRuleFlags addRuleFlags = RuleHasNoSpecialState;
385 if (m_document->getSecurityOrigin()->canRequest(sheet.baseURL()))
386 addRuleFlags = RuleHasDocumentSecurityOrigin;
387 return sheet.contents()->ensureRuleSet(*m_medium, addRuleFlags);
376 } 388 }
377 389
378 void StyleEngine::createResolver() 390 void StyleEngine::createResolver()
379 { 391 {
380 TRACE_EVENT1("blink", "StyleEngine::createResolver", "frame", document().fra me()); 392 TRACE_EVENT1("blink", "StyleEngine::createResolver", "frame", document().fra me());
381 // It is a programming error to attempt to resolve style on a Document 393 // It is a programming error to attempt to resolve style on a Document
382 // which is not in a frame. Code which hits this should have checked 394 // which is not in a frame. Code which hits this should have checked
383 // Document::isActive() before calling into code which could get here. 395 // Document::isActive() before calling into code which could get here.
384 396
385 DCHECK(document().frame()); 397 DCHECK(document().frame());
386 398
387 m_resolver = StyleResolver::create(*m_document); 399 m_resolver = StyleResolver::create(*m_document);
388
389 // A scoped style resolver for document will be created during
390 // appendActiveAuthorStyleSheets if needed.
391 appendActiveAuthorStyleSheets();
392 } 400 }
393 401
394 void StyleEngine::clearResolver() 402 void StyleEngine::clearResolver()
395 { 403 {
396 DCHECK(!document().inStyleRecalc()); 404 DCHECK(!document().inStyleRecalc());
397 DCHECK(isMaster() || !m_resolver); 405 DCHECK(isMaster() || !m_resolver);
398 406
399 document().clearScopedStyleResolver(); 407 document().clearScopedStyleResolver();
400 // StyleEngine::shadowRootRemovedFromDocument removes not-in-document 408 // StyleEngine::shadowRootRemovedFromDocument removes not-in-document
401 // treescopes from activeTreeScopes. StyleEngine::didRemoveShadowRoot 409 // treescopes from activeTreeScopes. StyleEngine::didRemoveShadowRoot
402 // removes treescopes which are being destroyed from activeTreeScopes. 410 // removes treescopes which are being destroyed from activeTreeScopes.
403 // So we need to clearScopedStyleResolver for treescopes which have been 411 // So we need to clearScopedStyleResolver for treescopes which have been
404 // just removed from document. If document is destroyed before invoking 412 // just removed from document. If document is destroyed before invoking
405 // updateActiveStyleSheets, the treescope has a scopedStyleResolver which 413 // updateActiveStyleSheets, the treescope has a scopedStyleResolver which
406 // has destroyed StyleSheetContents. 414 // has destroyed StyleSheetContents.
407 for (TreeScope* treeScope : m_activeTreeScopes) 415 for (TreeScope* treeScope : m_activeTreeScopes)
408 treeScope->clearScopedStyleResolver(); 416 treeScope->clearScopedStyleResolver();
409 417
410 if (m_resolver) { 418 if (m_resolver) {
411 TRACE_EVENT1("blink", "StyleEngine::clearResolver", "frame", document(). frame()); 419 TRACE_EVENT1("blink", "StyleEngine::clearResolver", "frame", document(). frame());
412 m_resolver->dispose(); 420 m_resolver->dispose();
413 m_resolver.clear(); 421 m_resolver.clear();
414 } 422 }
415 } 423 }
416 424
417 void StyleEngine::clearMasterResolver()
418 {
419 if (Document* master = this->master())
420 master->styleEngine().clearResolver();
421 }
422
423 void StyleEngine::didDetach() 425 void StyleEngine::didDetach()
424 { 426 {
425 clearResolver(); 427 clearResolver();
428 m_viewportResolver.clear();
429 m_medium = nullptr;
426 } 430 }
427 431
428 bool StyleEngine::shouldClearResolver() const 432 bool StyleEngine::shouldClearResolver() const
429 { 433 {
430 return !m_didCalculateResolver && !haveScriptBlockingStylesheetsLoaded(); 434 return !m_didCalculateResolver && !haveScriptBlockingStylesheetsLoaded();
431 } 435 }
432 436
433 void StyleEngine::resolverChanged(StyleResolverUpdateMode mode)
434 {
435 if (!isMaster()) {
436 if (Document* master = this->master())
437 master->styleEngine().resolverChanged(mode);
438 return;
439 }
440
441 // Don't bother updating, since we haven't loaded all our style info yet
442 // and haven't calculated the style selector for the first time.
443 if (!document().isActive() || shouldClearResolver()) {
444 clearResolver();
445 return;
446 }
447
448 m_didCalculateResolver = true;
449 updateActiveStyleSheets(mode);
450 }
451
452 void StyleEngine::clearFontCache() 437 void StyleEngine::clearFontCache()
453 { 438 {
454 if (m_fontSelector) 439 if (m_fontSelector)
455 m_fontSelector->fontFaceCache()->clearCSSConnected(); 440 m_fontSelector->fontFaceCache()->clearCSSConnected();
456 if (m_resolver) 441 if (m_resolver)
457 m_resolver->invalidateMatchedPropertiesCache(); 442 m_resolver->invalidateMatchedPropertiesCache();
458 } 443 }
459 444
460 void StyleEngine::updateGenericFontFamilySettings() 445 void StyleEngine::updateGenericFontFamilySettings()
461 { 446 {
(...skipping 15 matching lines...) Expand all
477 if (!m_fontSelector) 462 if (!m_fontSelector)
478 return; 463 return;
479 464
480 FontFaceCache* cache = m_fontSelector->fontFaceCache(); 465 FontFaceCache* cache = m_fontSelector->fontFaceCache();
481 for (unsigned i = 0; i < fontFaceRules.size(); ++i) 466 for (unsigned i = 0; i < fontFaceRules.size(); ++i)
482 cache->remove(fontFaceRules[i]); 467 cache->remove(fontFaceRules[i]);
483 if (m_resolver) 468 if (m_resolver)
484 m_resolver->invalidateMatchedPropertiesCache(); 469 m_resolver->invalidateMatchedPropertiesCache();
485 } 470 }
486 471
472 void StyleEngine::removeFontFaceRules(const HeapVector<Member<StyleRuleFontFace> >& fontFaceRules)
473 {
474 if (!m_fontSelector)
475 return;
476
477 FontFaceCache* cache = m_fontSelector->fontFaceCache();
478 for (unsigned i = 0; i < fontFaceRules.size(); ++i)
479 cache->remove(fontFaceRules[i]);
480 if (m_resolver)
481 m_resolver->invalidateMatchedPropertiesCache();
482 }
483
484 ViewportStyleResolver& StyleEngine::ensureViewportStyleResolver()
485 {
486 if (!m_viewportResolver)
487 m_viewportResolver = ViewportStyleResolver::create(m_document);
488 return *m_viewportResolver.get();
489 }
490
487 void StyleEngine::markTreeScopeDirty(TreeScope& scope) 491 void StyleEngine::markTreeScopeDirty(TreeScope& scope)
488 { 492 {
489 if (scope == m_document) { 493 if (scope == m_document) {
490 markDocumentDirty(); 494 markDocumentDirty();
491 return; 495 return;
492 } 496 }
493 497
494 DCHECK(m_styleSheetCollectionMap.contains(&scope)); 498 DCHECK(m_styleSheetCollectionMap.contains(&scope));
495 m_dirtyTreeScopes.add(&scope); 499 m_dirtyTreeScopes.add(&scope);
500 document().scheduleLayoutTreeUpdateIfNeeded();
496 } 501 }
497 502
498 void StyleEngine::markDocumentDirty() 503 void StyleEngine::markDocumentDirty()
499 { 504 {
500 m_documentScopeDirty = true; 505 m_documentScopeDirty = true;
501 if (document().importLoader()) 506 if (document().importLoader())
502 document().importsController()->master()->styleEngine().markDocumentDirt y(); 507 document().importsController()->master()->styleEngine().markDocumentDirt y();
508 else
509 document().scheduleLayoutTreeUpdateIfNeeded();
503 } 510 }
504 511
505 CSSStyleSheet* StyleEngine::createSheet(Element* e, const String& text, TextPosi tion startPosition, StyleEngineContext &context) 512 CSSStyleSheet* StyleEngine::createSheet(Element* e, const String& text, TextPosi tion startPosition, StyleEngineContext &context)
506 { 513 {
507 CSSStyleSheet* styleSheet = nullptr; 514 CSSStyleSheet* styleSheet = nullptr;
508 515
509 e->document().styleEngine().addPendingSheet(context); 516 addPendingSheet(context);
510 517
511 AtomicString textContent(text); 518 AtomicString textContent(text);
512 519
513 HeapHashMap<AtomicString, Member<StyleSheetContents>>::AddResult result = m_ textToSheetCache.add(textContent, nullptr); 520 HeapHashMap<AtomicString, Member<StyleSheetContents>>::AddResult result = m_ textToSheetCache.add(textContent, nullptr);
514 if (result.isNewEntry || !result.storedValue->value) { 521 if (result.isNewEntry || !result.storedValue->value) {
515 styleSheet = StyleEngine::parseSheet(e, text, startPosition); 522 styleSheet = parseSheet(e, text, startPosition);
516 if (result.isNewEntry && styleSheet->contents()->isCacheableForStyleElem ent()) { 523 if (result.isNewEntry && styleSheet->contents()->isCacheableForStyleElem ent()) {
517 result.storedValue->value = styleSheet->contents(); 524 result.storedValue->value = styleSheet->contents();
518 m_sheetToTextCache.add(styleSheet->contents(), textContent); 525 m_sheetToTextCache.add(styleSheet->contents(), textContent);
519 } 526 }
520 } else { 527 } else {
521 StyleSheetContents* contents = result.storedValue->value; 528 StyleSheetContents* contents = result.storedValue->value;
522 DCHECK(contents); 529 DCHECK(contents);
523 DCHECK(contents->isCacheableForStyleElement()); 530 DCHECK(contents->isCacheableForStyleElement());
524 DCHECK_EQ(contents->singleOwnerDocument(), e->document()); 531 DCHECK_EQ(contents->singleOwnerDocument(), document());
525 styleSheet = CSSStyleSheet::createInline(contents, e, startPosition); 532 styleSheet = CSSStyleSheet::createInline(contents, e, startPosition);
526 } 533 }
527 534
528 DCHECK(styleSheet); 535 DCHECK(styleSheet);
529 styleSheet->setTitle(e->title()); 536 styleSheet->setTitle(e->title());
537 if (!e->isInShadowTree())
538 setPreferredStylesheetSetNameIfNotSet(e->title());
530 return styleSheet; 539 return styleSheet;
531 } 540 }
532 541
533 CSSStyleSheet* StyleEngine::parseSheet(Element* e, const String& text, TextPosit ion startPosition) 542 CSSStyleSheet* StyleEngine::parseSheet(Element* e, const String& text, TextPosit ion startPosition)
534 { 543 {
535 CSSStyleSheet* styleSheet = nullptr; 544 CSSStyleSheet* styleSheet = nullptr;
536 styleSheet = CSSStyleSheet::createInline(e, KURL(), startPosition, e->docume nt().characterSet()); 545 styleSheet = CSSStyleSheet::createInline(e, KURL(), startPosition, document( ).characterSet());
537 styleSheet->contents()->parseStringAtPosition(text, startPosition); 546 styleSheet->contents()->parseStringAtPosition(text, startPosition);
538 return styleSheet; 547 return styleSheet;
539 } 548 }
540 549
541 void StyleEngine::removeSheet(StyleSheetContents* contents) 550 void StyleEngine::removeSheet(StyleSheetContents* contents)
542 { 551 {
543 HeapHashMap<Member<StyleSheetContents>, AtomicString>::iterator it = m_sheet ToTextCache.find(contents); 552 HeapHashMap<Member<StyleSheetContents>, AtomicString>::iterator it = m_sheet ToTextCache.find(contents);
544 if (it == m_sheetToTextCache.end()) 553 if (it == m_sheetToTextCache.end())
545 return; 554 return;
546 555
547 m_textToSheetCache.remove(it->value); 556 m_textToSheetCache.remove(it->value);
548 m_sheetToTextCache.remove(contents); 557 m_sheetToTextCache.remove(contents);
549 } 558 }
550 559
560 bool StyleEngine::hasRulesForId(const AtomicString& id) const
561 {
562 return m_globalRuleSet.m_features.hasSelectorForId(id);
563 }
564
565 void StyleEngine::updateGlobalRuleSet()
566 {
567 if (!m_needsGlobalRuleSetUpdate)
568 return;
569
570 m_globalRuleSet.update(document());
571 m_needsGlobalRuleSetUpdate = false;
572 }
573
551 void StyleEngine::collectScopedStyleFeaturesTo(RuleFeatureSet& features) const 574 void StyleEngine::collectScopedStyleFeaturesTo(RuleFeatureSet& features) const
552 { 575 {
553 HeapHashSet<Member<const StyleSheetContents>> visitedSharedStyleSheetContent s; 576 HeapHashSet<Member<const StyleSheetContents>> visitedSharedStyleSheetContent s;
554 if (document().scopedStyleResolver()) 577 if (document().scopedStyleResolver())
555 document().scopedStyleResolver()->collectFeaturesTo(features, visitedSha redStyleSheetContents); 578 document().scopedStyleResolver()->collectFeaturesTo(features, visitedSha redStyleSheetContents);
556 for (TreeScope* treeScope : m_activeTreeScopes) { 579 for (TreeScope* treeScope : m_activeTreeScopes) {
557 // When creating StyleResolver, dirty treescopes might not be processed. 580 // When creating StyleResolver, dirty treescopes might not be processed.
558 // So some active treescopes might not have a scoped style resolver. 581 // So some active treescopes might not have a scoped style resolver.
559 // In this case, we should skip collectFeatures for the treescopes witho ut 582 // In this case, we should skip collectFeatures for the treescopes witho ut
560 // scoped style resolvers. When invoking updateActiveStyleSheets, 583 // scoped style resolvers. When invoking updateActiveStyleSheets,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 return true; 623 return true;
601 return element.parentNode()->getStyleChangeType() >= SubtreeStyleChange; 624 return element.parentNode()->getStyleChangeType() >= SubtreeStyleChange;
602 } 625 }
603 626
604 void StyleEngine::classChangedForElement(const SpaceSplitString& changedClasses, Element& element) 627 void StyleEngine::classChangedForElement(const SpaceSplitString& changedClasses, Element& element)
605 { 628 {
606 if (shouldSkipInvalidationFor(element)) 629 if (shouldSkipInvalidationFor(element))
607 return; 630 return;
608 InvalidationLists invalidationLists; 631 InvalidationLists invalidationLists;
609 unsigned changedSize = changedClasses.size(); 632 unsigned changedSize = changedClasses.size();
610 RuleFeatureSet& ruleFeatureSet = ensureResolver().ensureUpdatedRuleFeatureSe t(); 633 const RuleFeatureSet& ruleFeatures = ruleFeatureSet();
611 for (unsigned i = 0; i < changedSize; ++i) 634 for (unsigned i = 0; i < changedSize; ++i)
612 ruleFeatureSet.collectInvalidationSetsForClass(invalidationLists, elemen t, changedClasses[i]); 635 ruleFeatures.collectInvalidationSetsForClass(invalidationLists, element, changedClasses[i]);
613 m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, ele ment); 636 m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, ele ment);
614 } 637 }
615 638
616 void StyleEngine::classChangedForElement(const SpaceSplitString& oldClasses, con st SpaceSplitString& newClasses, Element& element) 639 void StyleEngine::classChangedForElement(const SpaceSplitString& oldClasses, con st SpaceSplitString& newClasses, Element& element)
617 { 640 {
618 if (shouldSkipInvalidationFor(element)) 641 if (shouldSkipInvalidationFor(element))
619 return; 642 return;
620 643
621 if (!oldClasses.size()) { 644 if (!oldClasses.size()) {
622 classChangedForElement(newClasses, element); 645 classChangedForElement(newClasses, element);
623 return; 646 return;
624 } 647 }
625 648
626 // Class vectors tend to be very short. This is faster than using a hash tab le. 649 // Class vectors tend to be very short. This is faster than using a hash tab le.
627 BitVector remainingClassBits; 650 BitVector remainingClassBits;
628 remainingClassBits.ensureSize(oldClasses.size()); 651 remainingClassBits.ensureSize(oldClasses.size());
629 652
630 InvalidationLists invalidationLists; 653 InvalidationLists invalidationLists;
631 RuleFeatureSet& ruleFeatureSet = ensureResolver().ensureUpdatedRuleFeatureSe t(); 654 const RuleFeatureSet& ruleFeatures = ruleFeatureSet();
632 655
633 for (unsigned i = 0; i < newClasses.size(); ++i) { 656 for (unsigned i = 0; i < newClasses.size(); ++i) {
634 bool found = false; 657 bool found = false;
635 for (unsigned j = 0; j < oldClasses.size(); ++j) { 658 for (unsigned j = 0; j < oldClasses.size(); ++j) {
636 if (newClasses[i] == oldClasses[j]) { 659 if (newClasses[i] == oldClasses[j]) {
637 // Mark each class that is still in the newClasses so we can ski p doing 660 // Mark each class that is still in the newClasses so we can ski p doing
638 // an n^2 search below when looking for removals. We can't break from 661 // an n^2 search below when looking for removals. We can't break from
639 // this loop early since a class can appear more than once. 662 // this loop early since a class can appear more than once.
640 remainingClassBits.quickSet(j); 663 remainingClassBits.quickSet(j);
641 found = true; 664 found = true;
642 } 665 }
643 } 666 }
644 // Class was added. 667 // Class was added.
645 if (!found) 668 if (!found)
646 ruleFeatureSet.collectInvalidationSetsForClass(invalidationLists, el ement, newClasses[i]); 669 ruleFeatures.collectInvalidationSetsForClass(invalidationLists, elem ent, newClasses[i]);
647 } 670 }
648 671
649 for (unsigned i = 0; i < oldClasses.size(); ++i) { 672 for (unsigned i = 0; i < oldClasses.size(); ++i) {
650 if (remainingClassBits.quickGet(i)) 673 if (remainingClassBits.quickGet(i))
651 continue; 674 continue;
652 // Class was removed. 675 // Class was removed.
653 ruleFeatureSet.collectInvalidationSetsForClass(invalidationLists, elemen t, oldClasses[i]); 676 ruleFeatures.collectInvalidationSetsForClass(invalidationLists, element, oldClasses[i]);
654 } 677 }
655 678
656 m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, ele ment); 679 m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, ele ment);
657 } 680 }
658 681
659 void StyleEngine::attributeChangedForElement(const QualifiedName& attributeName, Element& element) 682 void StyleEngine::attributeChangedForElement(const QualifiedName& attributeName, Element& element)
660 { 683 {
661 if (shouldSkipInvalidationFor(element)) 684 if (shouldSkipInvalidationFor(element))
662 return; 685 return;
663 686
664 InvalidationLists invalidationLists; 687 InvalidationLists invalidationLists;
665 ensureResolver().ensureUpdatedRuleFeatureSet().collectInvalidationSetsForAtt ribute(invalidationLists, element, attributeName); 688 ruleFeatureSet().collectInvalidationSetsForAttribute(invalidationLists, elem ent, attributeName);
666 m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, ele ment); 689 m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, ele ment);
667 } 690 }
668 691
669 void StyleEngine::idChangedForElement(const AtomicString& oldId, const AtomicStr ing& newId, Element& element) 692 void StyleEngine::idChangedForElement(const AtomicString& oldId, const AtomicStr ing& newId, Element& element)
670 { 693 {
671 if (shouldSkipInvalidationFor(element)) 694 if (shouldSkipInvalidationFor(element))
672 return; 695 return;
673 696
674 InvalidationLists invalidationLists; 697 InvalidationLists invalidationLists;
675 RuleFeatureSet& ruleFeatureSet = ensureResolver().ensureUpdatedRuleFeatureSe t(); 698 const RuleFeatureSet& ruleFeatures = ruleFeatureSet();
676 if (!oldId.isEmpty()) 699 if (!oldId.isEmpty())
677 ruleFeatureSet.collectInvalidationSetsForId(invalidationLists, element, oldId); 700 ruleFeatures.collectInvalidationSetsForId(invalidationLists, element, ol dId);
678 if (!newId.isEmpty()) 701 if (!newId.isEmpty())
679 ruleFeatureSet.collectInvalidationSetsForId(invalidationLists, element, newId); 702 ruleFeatures.collectInvalidationSetsForId(invalidationLists, element, ne wId);
680 m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, ele ment); 703 m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, ele ment);
681 } 704 }
682 705
683 void StyleEngine::pseudoStateChangedForElement(CSSSelector::PseudoType pseudoTyp e, Element& element) 706 void StyleEngine::pseudoStateChangedForElement(CSSSelector::PseudoType pseudoTyp e, Element& element)
684 { 707 {
685 if (shouldSkipInvalidationFor(element)) 708 if (shouldSkipInvalidationFor(element))
686 return; 709 return;
687 710
688 InvalidationLists invalidationLists; 711 InvalidationLists invalidationLists;
689 ensureResolver().ensureUpdatedRuleFeatureSet().collectInvalidationSetsForPse udoClass(invalidationLists, element, pseudoType); 712 ruleFeatureSet().collectInvalidationSetsForPseudoClass(invalidationLists, el ement, pseudoType);
690 m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, ele ment); 713 m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, ele ment);
691 } 714 }
692 715
693 void StyleEngine::setStatsEnabled(bool enabled) 716 void StyleEngine::setStatsEnabled(bool enabled)
694 { 717 {
695 if (!enabled) { 718 if (!enabled) {
696 m_styleResolverStats = nullptr; 719 m_styleResolverStats = nullptr;
697 return; 720 return;
698 } 721 }
699 if (!m_styleResolverStats) 722 if (!m_styleResolverStats)
700 m_styleResolverStats = StyleResolverStats::create(); 723 m_styleResolverStats = StyleResolverStats::create();
701 else 724 else
702 m_styleResolverStats->reset(); 725 m_styleResolverStats->reset();
703 } 726 }
704 727
728 void StyleEngine::scheduleRuleSetInvalidationsForElement(Element& element, const HeapVector<Member<RuleSet>>& ruleSets)
729 {
730 AtomicString id;
731 const SpaceSplitString* classNames = nullptr;
732 bool typeSelectorMatch = false;
733 const AtomicString& shadowPseudoId = element.shadowPseudoId();
734 bool customPseudoMatch = shadowPseudoId.isEmpty();
735
736 if (element.hasID())
737 id = element.idForStyleResolution();
738 if (element.hasClass())
739 classNames = &element.classNames();
740
741 InvalidationLists invalidationLists;
742 for (const auto& ruleSet : ruleSets) {
743
744 if (!id.isNull())
745 ruleSet->features().collectInvalidationSetsForId(invalidationLists, element, id);
746
747 if (classNames) {
748 unsigned classNameCount = classNames->size();
749 for (size_t i = 0; i < classNameCount; i++)
750 ruleSet->features().collectInvalidationSetsForClass(invalidation Lists, element, (*classNames)[i]);
751 }
752
753 for (const Attribute& attribute : element.attributes())
754 ruleSet->features().collectInvalidationSetsForAttribute(invalidation Lists, element, attribute.name());
755
756 if (element.needsStyleRecalc())
757 continue;
758
759 if (!typeSelectorMatch && ruleSet->tagRules(element.localNameForSelector Matching())) {
760 typeSelectorMatch = true;
761 element.setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTr acing::create(StyleChangeReason::StyleSheetChange));
762 }
763
764 if (!customPseudoMatch && ruleSet->shadowPseudoElementRules(shadowPseudo Id)) {
765 customPseudoMatch = true;
766 element.setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTr acing::create(StyleChangeReason::StyleSheetChange));
767 }
768 }
769 m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, ele ment);
770 }
771
772 void StyleEngine::scheduleInvalidationsForRuleSets(TreeScope& treeScope, const H eapVector<Member<RuleSet>>& ruleSets)
773 {
774 if (treeScope.rootNode().isShadowRoot()) {
775 Element& host = toShadowRoot(treeScope.rootNode()).host();
776 scheduleRuleSetInvalidationsForElement(host, ruleSets);
777 if (host.getStyleChangeType() >= SubtreeStyleChange)
778 return;
779 }
780
781 Node* stayWithin = &treeScope.rootNode();
782 Element* element = ElementTraversal::firstChild(*stayWithin);
783 while (element) {
784 scheduleRuleSetInvalidationsForElement(*element, ruleSets);
785 if (isHTMLSlotElement(element)) {
786 for (auto& node : toHTMLSlotElement(element)->getDistributedNodes()) {
787 if (node->isElementNode())
788 scheduleRuleSetInvalidationsForElement(*toElement(node), rul eSets);
789 }
790 }
791 if (element->getStyleChangeType() < SubtreeStyleChange)
792 element = ElementTraversal::next(*element, stayWithin);
793 else
794 element = ElementTraversal::nextSkippingChildren(*element, stayWithi n);
795 }
796 }
797
705 void StyleEngine::setPreferredStylesheetSetNameIfNotSet(const String& name) 798 void StyleEngine::setPreferredStylesheetSetNameIfNotSet(const String& name)
706 { 799 {
707 if (!m_preferredStylesheetSetName.isEmpty()) 800 if (!m_preferredStylesheetSetName.isEmpty())
708 return; 801 return;
709 m_preferredStylesheetSetName = name; 802 m_preferredStylesheetSetName = name;
710 // TODO(rune@opera.com): Setting the selected set here is wrong if the set 803 // TODO(rune@opera.com): Setting the selected set here is wrong if the set
711 // has been previously set by through Document.selectedStylesheetSet. Our 804 // has been previously set by through Document.selectedStylesheetSet. Our
712 // current implementation ignores the effect of Document.selectedStylesheetS et 805 // current implementation ignores the effect of Document.selectedStylesheetS et
713 // and either only collects persistent style, or additionally preferred 806 // and either only collects persistent style, or additionally preferred
714 // style when present. We are currently not marking the document scope dirty 807 // style when present. We are currently not marking the document scope dirty
715 // because preferred style is updated during active stylesheet update which 808 // because preferred style is updated during active stylesheet update which
716 // would make this method re-entrant. Will need to change for async update. 809 // would make this method re-entrant. Will need to change for async update.
717 m_selectedStylesheetSetName = name; 810 m_selectedStylesheetSetName = name;
718 } 811 }
719 812
720 void StyleEngine::setSelectedStylesheetSetName(const String& name) 813 void StyleEngine::setSelectedStylesheetSetName(const String& name)
721 { 814 {
722 m_selectedStylesheetSetName = name; 815 m_selectedStylesheetSetName = name;
723 // TODO(rune@opera.com): Setting Document.selectedStylesheetSet currently 816 // TODO(rune@opera.com): Setting Document.selectedStylesheetSet currently
724 // has no other effect than the ability to read back the set value using 817 // has no other effect than the ability to read back the set value using
725 // the same api. If it did have an effect, we should have marked the 818 // the same api. If it did have an effect, we should have marked the
726 // document scope dirty and triggered an update of the active stylesheets 819 // document scope dirty and triggered an update of the active stylesheets
727 // from here. 820 // from here.
728 } 821 }
729 822
730 void StyleEngine::setHttpDefaultStyle(const String& content) 823 void StyleEngine::setHttpDefaultStyle(const String& content)
731 { 824 {
732 setPreferredStylesheetSetNameIfNotSet(content); 825 setPreferredStylesheetSetNameIfNotSet(content);
733 markDocumentDirty(); 826 markDocumentDirty();
734 resolverChanged(FullStyleUpdate);
735 } 827 }
736 828
737 void StyleEngine::ensureFullscreenUAStyle() 829 void StyleEngine::ensureUAStyleForFullscreen()
738 { 830 {
739 CSSDefaultStyleSheets::instance().ensureDefaultStyleSheetForFullscreen(); 831 if (CSSDefaultStyleSheets::instance().ensureDefaultStyleSheetForFullscreen() ) {
740 if (!m_resolver) 832 m_needsGlobalRuleSetUpdate = true;
741 return; 833 updateGlobalRuleSet();
742 if (!m_resolver->hasFullscreenUAStyle()) 834 }
743 m_resolver->resetRuleFeatures(); 835 }
836
837 void StyleEngine::ensureUAStyleForElement(const Element& element)
838 {
839 if (CSSDefaultStyleSheets::instance().ensureDefaultStyleSheetsForElement(ele ment)) {
840 m_needsGlobalRuleSetUpdate = true;
841 updateGlobalRuleSet();
842 }
843 }
844
845 PassRefPtr<ComputedStyle> StyleEngine::findSharedStyle(const ElementResolveConte xt& elementResolveContext)
846 {
847 return SharedStyleFinder(elementResolveContext,
848 m_globalRuleSet.m_features,
849 m_globalRuleSet.m_siblingRuleSet.get(),
850 m_globalRuleSet.m_uncommonAttributeRuleSet.get(),
851 *m_resolver).findSharedStyle();
852 }
853
854 MediaQueryEvaluator& StyleEngine::ensureMediaQueryEvaluator()
855 {
856 if (!m_medium) {
857 if (document().frame())
858 m_medium = new MediaQueryEvaluator(document().frame());
859 else
860 m_medium = new MediaQueryEvaluator("all");
861 }
862 return *m_medium;
863 }
864
865 bool StyleEngine::mediaQueryAffectedByViewportChange()
866 {
867 const MediaQueryEvaluator& evaluator = ensureMediaQueryEvaluator();
868 const auto& results = m_globalRuleSet.m_features.viewportDependentMediaQuery Results;
869 for (unsigned i = 0; i < results.size(); ++i) {
870 if (evaluator.eval(results[i]->expression()) != results[i]->result())
871 return true;
872 }
873 return false;
874 }
875
876 bool StyleEngine::mediaQueryAffectedByDeviceChange()
877 {
878 const MediaQueryEvaluator& evaluator = ensureMediaQueryEvaluator();
879 const auto& results = m_globalRuleSet.m_features.deviceDependentMediaQueryRe sults;
880 for (unsigned i = 0; i < results.size(); ++i) {
881 if (evaluator.eval(results[i]->expression()) != results[i]->result())
882 return true;
883 }
884 return false;
744 } 885 }
745 886
746 DEFINE_TRACE(StyleEngine) 887 DEFINE_TRACE(StyleEngine)
747 { 888 {
748 visitor->trace(m_document); 889 visitor->trace(m_document);
749 visitor->trace(m_injectedAuthorStyleSheets); 890 visitor->trace(m_injectedAuthorStyleSheets);
750 visitor->trace(m_documentStyleSheetCollection); 891 visitor->trace(m_documentStyleSheetCollection);
751 visitor->trace(m_styleSheetCollectionMap); 892 visitor->trace(m_styleSheetCollectionMap);
752 visitor->trace(m_resolver); 893 visitor->trace(m_resolver);
894 visitor->trace(m_viewportResolver);
895 visitor->trace(m_medium);
753 visitor->trace(m_styleInvalidator); 896 visitor->trace(m_styleInvalidator);
754 visitor->trace(m_dirtyTreeScopes); 897 visitor->trace(m_dirtyTreeScopes);
755 visitor->trace(m_activeTreeScopes); 898 visitor->trace(m_activeTreeScopes);
899 visitor->trace(m_treeBoundaryCrossingScopes);
900 visitor->trace(m_globalRuleSet);
756 visitor->trace(m_fontSelector); 901 visitor->trace(m_fontSelector);
757 visitor->trace(m_textToSheetCache); 902 visitor->trace(m_textToSheetCache);
758 visitor->trace(m_sheetToTextCache); 903 visitor->trace(m_sheetToTextCache);
759 CSSFontSelectorClient::trace(visitor); 904 CSSFontSelectorClient::trace(visitor);
760 } 905 }
761 906
762 DEFINE_TRACE_WRAPPERS(StyleEngine) 907 DEFINE_TRACE_WRAPPERS(StyleEngine)
763 { 908 {
764 for (auto sheet : m_injectedAuthorStyleSheets) { 909 for (auto sheet : m_injectedAuthorStyleSheets) {
765 visitor->traceWrappers(sheet); 910 visitor->traceWrappers(sheet);
766 } 911 }
767 visitor->traceWrappers(m_documentStyleSheetCollection); 912 visitor->traceWrappers(m_documentStyleSheetCollection);
768 } 913 }
769 914
770 } // namespace blink 915 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/dom/StyleEngine.h ('k') | third_party/WebKit/Source/core/dom/StyleEngineTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698