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

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

Issue 2557533005: Collect active stylesheets and and apply asynchronously. (Closed)
Patch Set: Rebased. Created 4 years 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 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All
7 * rights reserved. 7 * rights reserved.
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
9 * (http://www.torchmobile.com/) 9 * (http://www.torchmobile.com/)
10 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved. 10 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved.
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 } 144 }
145 145
146 CSSStyleSheet& StyleEngine::ensureInspectorStyleSheet() { 146 CSSStyleSheet& StyleEngine::ensureInspectorStyleSheet() {
147 if (m_inspectorStyleSheet) 147 if (m_inspectorStyleSheet)
148 return *m_inspectorStyleSheet; 148 return *m_inspectorStyleSheet;
149 149
150 StyleSheetContents* contents = 150 StyleSheetContents* contents =
151 StyleSheetContents::create(CSSParserContext(*m_document, nullptr)); 151 StyleSheetContents::create(CSSParserContext(*m_document, nullptr));
152 m_inspectorStyleSheet = CSSStyleSheet::create(contents, *m_document); 152 m_inspectorStyleSheet = CSSStyleSheet::create(contents, *m_document);
153 markDocumentDirty(); 153 markDocumentDirty();
154 resolverChanged(AnalyzedStyleUpdate); 154 // TODO(rune@opera.com): Making the active stylesheets up-to-date here is
155 // required by some inspector tests, at least. I theory this should not be
156 // necessary. Need to investigate to figure out if/why.
157 updateActiveStyle();
155 return *m_inspectorStyleSheet; 158 return *m_inspectorStyleSheet;
156 } 159 }
157 160
158 void StyleEngine::addPendingSheet(StyleEngineContext& context) { 161 void StyleEngine::addPendingSheet(StyleEngineContext& context) {
159 m_pendingScriptBlockingStylesheets++; 162 m_pendingScriptBlockingStylesheets++;
160 163
161 context.addingPendingSheet(document()); 164 context.addingPendingSheet(document());
162 if (context.addedPendingSheetBeforeBody()) 165 if (context.addedPendingSheetBeforeBody())
163 m_pendingRenderBlockingStylesheets++; 166 m_pendingRenderBlockingStylesheets++;
164 } 167 }
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 return m_allTreeScopesDirty || !m_dirtyTreeScopes.isEmpty(); 263 return m_allTreeScopesDirty || !m_dirtyTreeScopes.isEmpty();
261 } 264 }
262 265
263 void StyleEngine::mediaQueryAffectingValueChanged( 266 void StyleEngine::mediaQueryAffectingValueChanged(
264 UnorderedTreeScopeSet& treeScopes) { 267 UnorderedTreeScopeSet& treeScopes) {
265 for (TreeScope* treeScope : treeScopes) { 268 for (TreeScope* treeScope : treeScopes) {
266 DCHECK(treeScope != m_document); 269 DCHECK(treeScope != m_document);
267 ShadowTreeStyleSheetCollection* collection = 270 ShadowTreeStyleSheetCollection* collection =
268 toShadowTreeStyleSheetCollection(styleSheetCollectionFor(*treeScope)); 271 toShadowTreeStyleSheetCollection(styleSheetCollectionFor(*treeScope));
269 DCHECK(collection); 272 DCHECK(collection);
270 collection->clearMediaQueryRuleSetStyleSheets(); 273 if (collection->mediaQueryAffectingValueChanged())
274 setNeedsActiveStyleUpdate(*treeScope);
271 } 275 }
272 } 276 }
273 277
274 void StyleEngine::mediaQueryAffectingValueChanged() { 278 void StyleEngine::mediaQueryAffectingValueChanged() {
275 resolverChanged(FullStyleUpdate); 279 if (documentStyleSheetCollection().mediaQueryAffectingValueChanged())
276 documentStyleSheetCollection().clearMediaQueryRuleSetStyleSheets(); 280 setNeedsActiveStyleUpdate(document());
277 mediaQueryAffectingValueChanged(m_activeTreeScopes); 281 mediaQueryAffectingValueChanged(m_activeTreeScopes);
278 if (m_resolver) 282 if (m_resolver)
279 m_resolver->updateMediaType(); 283 m_resolver->updateMediaType();
280 } 284 }
281 285
282 void StyleEngine::updateStyleSheetsInImport( 286 void StyleEngine::updateStyleSheetsInImport(
283 DocumentStyleSheetCollector& parentCollector) { 287 DocumentStyleSheetCollector& parentCollector) {
284 DCHECK(!isMaster()); 288 DCHECK(!isMaster());
285 HeapVector<Member<StyleSheet>> sheetsForList; 289 HeapVector<Member<StyleSheet>> sheetsForList;
286 ImportedDocumentStyleSheetCollector subcollector(parentCollector, 290 ImportedDocumentStyleSheetCollector subcollector(parentCollector,
287 sheetsForList); 291 sheetsForList);
288 documentStyleSheetCollection().collectStyleSheets(*this, subcollector); 292 documentStyleSheetCollection().collectStyleSheets(subcollector);
289 documentStyleSheetCollection().swapSheetsForSheetList(sheetsForList); 293 documentStyleSheetCollection().swapSheetsForSheetList(sheetsForList);
290 } 294 }
291 295
292 void StyleEngine::updateActiveStyleSheetsInShadow( 296 void StyleEngine::updateActiveStyleSheetsInShadow(
293 StyleResolverUpdateMode updateMode,
294 TreeScope* treeScope, 297 TreeScope* treeScope,
295 UnorderedTreeScopeSet& treeScopesRemoved) { 298 UnorderedTreeScopeSet& treeScopesRemoved) {
296 DCHECK_NE(treeScope, m_document); 299 DCHECK_NE(treeScope, m_document);
297 ShadowTreeStyleSheetCollection* collection = 300 ShadowTreeStyleSheetCollection* collection =
298 toShadowTreeStyleSheetCollection(styleSheetCollectionFor(*treeScope)); 301 toShadowTreeStyleSheetCollection(styleSheetCollectionFor(*treeScope));
299 DCHECK(collection); 302 DCHECK(collection);
300 collection->updateActiveStyleSheets(*this, updateMode); 303 collection->updateActiveStyleSheets();
301 if (!collection->hasStyleSheetCandidateNodes()) { 304 if (!collection->hasStyleSheetCandidateNodes()) {
302 treeScopesRemoved.add(treeScope); 305 treeScopesRemoved.add(treeScope);
303 // When removing TreeScope from ActiveTreeScopes, 306 // When removing TreeScope from ActiveTreeScopes,
304 // its resolver should be destroyed by invoking resetAuthorStyle. 307 // its resolver should be destroyed by invoking resetAuthorStyle.
305 DCHECK(!treeScope->scopedStyleResolver()); 308 DCHECK(!treeScope->scopedStyleResolver());
306 } 309 }
307 } 310 }
308 311
309 void StyleEngine::updateActiveStyleSheets(StyleResolverUpdateMode updateMode) { 312 void StyleEngine::updateActiveStyleSheets() {
313 if (!needsActiveStyleSheetUpdate())
314 return;
315
310 DCHECK(isMaster()); 316 DCHECK(isMaster());
311 DCHECK(!document().inStyleRecalc()); 317 DCHECK(!document().inStyleRecalc());
312 318 DCHECK(document().isActive());
313 if (!document().isActive())
314 return;
315 319
316 TRACE_EVENT0("blink,blink_style", "StyleEngine::updateActiveStyleSheets"); 320 TRACE_EVENT0("blink,blink_style", "StyleEngine::updateActiveStyleSheets");
317 321
318 if (shouldUpdateDocumentStyleSheetCollection()) 322 if (shouldUpdateDocumentStyleSheetCollection())
319 documentStyleSheetCollection().updateActiveStyleSheets(*this, updateMode); 323 documentStyleSheetCollection().updateActiveStyleSheets();
320 324
321 if (shouldUpdateShadowTreeStyleSheetCollection()) { 325 if (shouldUpdateShadowTreeStyleSheetCollection()) {
322 UnorderedTreeScopeSet treeScopesRemoved; 326 UnorderedTreeScopeSet treeScopesRemoved;
323 327
324 if (m_allTreeScopesDirty) { 328 if (m_allTreeScopesDirty) {
325 for (TreeScope* treeScope : m_activeTreeScopes) 329 for (TreeScope* treeScope : m_activeTreeScopes)
326 updateActiveStyleSheetsInShadow(updateMode, treeScope, 330 updateActiveStyleSheetsInShadow(treeScope, treeScopesRemoved);
327 treeScopesRemoved);
328 } else { 331 } else {
329 for (TreeScope* treeScope : m_dirtyTreeScopes) 332 for (TreeScope* treeScope : m_dirtyTreeScopes)
330 updateActiveStyleSheetsInShadow(updateMode, treeScope, 333 updateActiveStyleSheetsInShadow(treeScope, treeScopesRemoved);
331 treeScopesRemoved);
332 } 334 }
333 for (TreeScope* treeScope : treeScopesRemoved) 335 for (TreeScope* treeScope : treeScopesRemoved)
334 m_activeTreeScopes.remove(treeScope); 336 m_activeTreeScopes.remove(treeScope);
335 } 337 }
336 338
337 InspectorInstrumentation::activeStyleSheetsUpdated(m_document); 339 InspectorInstrumentation::activeStyleSheetsUpdated(m_document);
338 340
339 m_dirtyTreeScopes.clear(); 341 m_dirtyTreeScopes.clear();
340 m_documentScopeDirty = false; 342 m_documentScopeDirty = false;
341 m_allTreeScopesDirty = false; 343 m_allTreeScopesDirty = false;
342 } 344 }
343 345
344 void StyleEngine::updateActiveStyleSheets() {
345 // TODO(rune@opera.com): collect ActiveStyleSheets here.
346 }
347
348 void StyleEngine::updateViewport() { 346 void StyleEngine::updateViewport() {
349 if (m_viewportResolver) 347 if (m_viewportResolver)
350 m_viewportResolver->updateViewport(documentStyleSheetCollection()); 348 m_viewportResolver->updateViewport(documentStyleSheetCollection());
351 } 349 }
352 350
353 bool StyleEngine::needsActiveStyleUpdate() const { 351 bool StyleEngine::needsActiveStyleUpdate() const {
354 return m_viewportResolver && m_viewportResolver->needsUpdate(); 352 return (m_viewportResolver && m_viewportResolver->needsUpdate()) ||
353 needsActiveStyleSheetUpdate() || m_globalRuleSet.isDirty();
355 } 354 }
356 355
357 void StyleEngine::updateActiveStyle() { 356 void StyleEngine::updateActiveStyle() {
357 DCHECK(document().isActive());
358 updateViewport(); 358 updateViewport();
359 updateActiveStyleSheets(); 359 updateActiveStyleSheets();
360 m_globalRuleSet.update(document()); 360 m_globalRuleSet.update(document());
361 } 361 }
362 362
363 const HeapVector<Member<CSSStyleSheet>> 363 const ActiveStyleSheetVector StyleEngine::activeStyleSheetsForInspector() {
364 StyleEngine::activeStyleSheetsForInspector() const { 364 if (document().isActive())
365 updateActiveStyle();
366
365 if (m_activeTreeScopes.isEmpty()) 367 if (m_activeTreeScopes.isEmpty())
366 return documentStyleSheetCollection().activeAuthorStyleSheets(); 368 return documentStyleSheetCollection().activeAuthorStyleSheets();
367 369
368 HeapVector<Member<CSSStyleSheet>> activeStyleSheets; 370 ActiveStyleSheetVector activeStyleSheets;
369 371
370 activeStyleSheets.appendVector( 372 activeStyleSheets.appendVector(
371 documentStyleSheetCollection().activeAuthorStyleSheets()); 373 documentStyleSheetCollection().activeAuthorStyleSheets());
372 for (TreeScope* treeScope : m_activeTreeScopes) { 374 for (TreeScope* treeScope : m_activeTreeScopes) {
373 if (TreeScopeStyleSheetCollection* collection = 375 if (TreeScopeStyleSheetCollection* collection =
374 m_styleSheetCollectionMap.get(treeScope)) 376 m_styleSheetCollectionMap.get(treeScope))
375 activeStyleSheets.appendVector(collection->activeAuthorStyleSheets()); 377 activeStyleSheets.appendVector(collection->activeAuthorStyleSheets());
376 } 378 }
377 379
378 // FIXME: Inspector needs a vector which has all active stylesheets. 380 // FIXME: Inspector needs a vector which has all active stylesheets.
379 // However, creating such a large vector might cause performance regression. 381 // However, creating such a large vector might cause performance regression.
380 // Need to implement some smarter solution. 382 // Need to implement some smarter solution.
381 return activeStyleSheets; 383 return activeStyleSheets;
382 } 384 }
383 385
384 void StyleEngine::shadowRootRemovedFromDocument(ShadowRoot* shadowRoot) { 386 void StyleEngine::shadowRootRemovedFromDocument(ShadowRoot* shadowRoot) {
385 if (StyleResolver* styleResolver = resolver()) {
386 if (TreeScopeStyleSheetCollection* collection =
387 styleSheetCollectionFor(*shadowRoot))
388 styleResolver->removePendingAuthorStyleSheets(
389 collection->activeAuthorStyleSheets());
390 }
391 m_styleSheetCollectionMap.remove(shadowRoot); 387 m_styleSheetCollectionMap.remove(shadowRoot);
392 m_activeTreeScopes.remove(shadowRoot); 388 m_activeTreeScopes.remove(shadowRoot);
393 m_dirtyTreeScopes.remove(shadowRoot); 389 m_dirtyTreeScopes.remove(shadowRoot);
394 resetAuthorStyle(*shadowRoot); 390 resetAuthorStyle(*shadowRoot);
395 } 391 }
396 392
397 void StyleEngine::addTreeBoundaryCrossingScope(const TreeScope& treeScope) { 393 void StyleEngine::addTreeBoundaryCrossingScope(const TreeScope& treeScope) {
398 m_treeBoundaryCrossingScopes.add(&treeScope.rootNode()); 394 m_treeBoundaryCrossingScopes.add(&treeScope.rootNode());
399 } 395 }
400 396
401 void StyleEngine::resetAuthorStyle(TreeScope& treeScope) { 397 void StyleEngine::resetAuthorStyle(TreeScope& treeScope) {
402 m_treeBoundaryCrossingScopes.remove(&treeScope.rootNode()); 398 m_treeBoundaryCrossingScopes.remove(&treeScope.rootNode());
403 399
404 ScopedStyleResolver* scopedResolver = treeScope.scopedStyleResolver(); 400 ScopedStyleResolver* scopedResolver = treeScope.scopedStyleResolver();
405 if (!scopedResolver) 401 if (!scopedResolver)
406 return; 402 return;
407 403
408 m_globalRuleSet.markDirty(); 404 m_globalRuleSet.markDirty();
409 if (treeScope.rootNode().isDocumentNode()) { 405 if (treeScope.rootNode().isDocumentNode()) {
410 scopedResolver->resetAuthorStyle(); 406 scopedResolver->resetAuthorStyle();
411 return; 407 return;
412 } 408 }
413 409
414 treeScope.clearScopedStyleResolver(); 410 treeScope.clearScopedStyleResolver();
415 } 411 }
416 412
417 void StyleEngine::finishAppendAuthorStyleSheets() {
418 m_globalRuleSet.markDirty();
419 m_globalRuleSet.update(document());
420
421 if (!document().layoutViewItem().isNull() &&
422 document().layoutViewItem().style())
423 document().layoutViewItem().style()->font().update(fontSelector());
424 }
425
426 void StyleEngine::appendActiveAuthorStyleSheets() {
427 DCHECK(isMaster());
428
429 m_resolver->appendAuthorStyleSheets(
430 documentStyleSheetCollection().activeAuthorStyleSheets());
431 for (TreeScope* treeScope : m_activeTreeScopes) {
432 if (TreeScopeStyleSheetCollection* collection =
433 m_styleSheetCollectionMap.get(treeScope))
434 m_resolver->appendAuthorStyleSheets(
435 collection->activeAuthorStyleSheets());
436 }
437 }
438
439 void StyleEngine::setRuleUsageTracker(StyleRuleUsageTracker* tracker) { 413 void StyleEngine::setRuleUsageTracker(StyleRuleUsageTracker* tracker) {
440 m_tracker = tracker; 414 m_tracker = tracker;
441 415
442 if (m_resolver) 416 if (m_resolver)
443 m_resolver->setRuleUsageTracker(m_tracker); 417 m_resolver->setRuleUsageTracker(m_tracker);
444 } 418 }
445 419
446 RuleSet* StyleEngine::ruleSetForSheet(CSSStyleSheet& sheet) { 420 RuleSet* StyleEngine::ruleSetForSheet(CSSStyleSheet& sheet) {
447 if (!sheet.matchesMediaQueries(ensureMediaQueryEvaluator())) 421 if (!sheet.matchesMediaQueries(ensureMediaQueryEvaluator()))
448 return nullptr; 422 return nullptr;
449 423
450 AddRuleFlags addRuleFlags = RuleHasNoSpecialState; 424 AddRuleFlags addRuleFlags = RuleHasNoSpecialState;
451 if (m_document->getSecurityOrigin()->canRequest(sheet.baseURL())) 425 if (m_document->getSecurityOrigin()->canRequest(sheet.baseURL()))
452 addRuleFlags = RuleHasDocumentSecurityOrigin; 426 addRuleFlags = RuleHasDocumentSecurityOrigin;
453 return &sheet.contents()->ensureRuleSet(*m_mediaQueryEvaluator, addRuleFlags); 427 return &sheet.contents()->ensureRuleSet(*m_mediaQueryEvaluator, addRuleFlags);
454 } 428 }
455 429
456 void StyleEngine::createResolver() { 430 void StyleEngine::createResolver() {
457 m_resolver = StyleResolver::create(*m_document); 431 m_resolver = StyleResolver::create(*m_document);
458
459 m_resolver->setRuleUsageTracker(m_tracker); 432 m_resolver->setRuleUsageTracker(m_tracker);
460
461 // A scoped style resolver for document will be created during
462 // appendActiveAuthorStyleSheets if needed.
463 appendActiveAuthorStyleSheets();
464 finishAppendAuthorStyleSheets();
465 } 433 }
466 434
467 void StyleEngine::clearResolver() { 435 void StyleEngine::clearResolver() {
468 DCHECK(!document().inStyleRecalc()); 436 DCHECK(!document().inStyleRecalc());
469 DCHECK(isMaster() || !m_resolver); 437 DCHECK(isMaster() || !m_resolver);
470 438
471 document().clearScopedStyleResolver(); 439 document().clearScopedStyleResolver();
472 // TODO(rune@opera.com): The clearing of all shadow tree scoped style 440 // TODO(rune@opera.com): The clearing of all shadow tree scoped style
473 // resolvers below should not be necessary. It was introduced to fix a crash 441 // resolvers below should not be necessary. It was introduced to fix a crash
474 // bug (https://crbug.com/447976) when clearResolver is called from didDetach 442 // bug (https://crbug.com/447976) when clearResolver is called from didDetach
(...skipping 12 matching lines...) Expand all
487 m_treeBoundaryCrossingScopes.clear(); 455 m_treeBoundaryCrossingScopes.clear();
488 456
489 if (m_resolver) { 457 if (m_resolver) {
490 TRACE_EVENT1("blink", "StyleEngine::clearResolver", "frame", 458 TRACE_EVENT1("blink", "StyleEngine::clearResolver", "frame",
491 document().frame()); 459 document().frame());
492 m_resolver->dispose(); 460 m_resolver->dispose();
493 m_resolver.clear(); 461 m_resolver.clear();
494 } 462 }
495 } 463 }
496 464
497 void StyleEngine::clearMasterResolver() {
498 if (Document* master = this->master())
499 master->styleEngine().clearResolver();
500 }
501
502 void StyleEngine::didDetach() { 465 void StyleEngine::didDetach() {
503 clearResolver(); 466 clearResolver();
504 m_viewportResolver = nullptr; 467 m_viewportResolver = nullptr;
505 m_mediaQueryEvaluator = nullptr; 468 m_mediaQueryEvaluator = nullptr;
506 } 469 }
507 470
508 bool StyleEngine::shouldClearResolver() const {
509 return !m_didCalculateResolver && !haveScriptBlockingStylesheetsLoaded();
510 }
511
512 void StyleEngine::resolverChanged(StyleResolverUpdateMode mode) {
513 if (!isMaster()) {
514 if (Document* master = this->master())
515 master->styleEngine().resolverChanged(mode);
516 return;
517 }
518
519 // Don't bother updating, since we haven't loaded all our style info yet
520 // and haven't calculated the style selector for the first time.
521 if (!document().isActive() || shouldClearResolver()) {
522 clearResolver();
523 return;
524 }
525
526 if (mode == FullStyleUpdate)
527 markAllTreeScopesDirty();
528 m_didCalculateResolver = true;
529 updateActiveStyleSheets(mode);
530 }
531
532 void StyleEngine::clearFontCache() { 471 void StyleEngine::clearFontCache() {
533 if (m_fontSelector) 472 if (m_fontSelector)
534 m_fontSelector->fontFaceCache()->clearCSSConnected(); 473 m_fontSelector->fontFaceCache()->clearCSSConnected();
535 if (m_resolver) 474 if (m_resolver)
536 m_resolver->invalidateMatchedPropertiesCache(); 475 m_resolver->invalidateMatchedPropertiesCache();
537 } 476 }
538 477
539 void StyleEngine::updateGenericFontFamilySettings() { 478 void StyleEngine::updateGenericFontFamilySettings() {
540 // FIXME: we should not update generic font family settings when 479 // FIXME: we should not update generic font family settings when
541 // document is inactive. 480 // document is inactive.
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after
1238 } 1177 }
1239 1178
1240 DEFINE_TRACE_WRAPPERS(StyleEngine) { 1179 DEFINE_TRACE_WRAPPERS(StyleEngine) {
1241 for (auto sheet : m_injectedAuthorStyleSheets) { 1180 for (auto sheet : m_injectedAuthorStyleSheets) {
1242 visitor->traceWrappers(sheet); 1181 visitor->traceWrappers(sheet);
1243 } 1182 }
1244 visitor->traceWrappers(m_documentStyleSheetCollection); 1183 visitor->traceWrappers(m_documentStyleSheetCollection);
1245 } 1184 }
1246 1185
1247 } // namespace blink 1186 } // 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