| OLD | NEW |
| 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 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 return documentStyleSheetCollection().styleSheetsForStyleSheetList(); | 133 return documentStyleSheetCollection().styleSheetsForStyleSheetList(); |
| 134 | 134 |
| 135 return ensureStyleSheetCollectionFor(treeScope) | 135 return ensureStyleSheetCollectionFor(treeScope) |
| 136 ->styleSheetsForStyleSheetList(); | 136 ->styleSheetsForStyleSheetList(); |
| 137 } | 137 } |
| 138 | 138 |
| 139 void StyleEngine::injectAuthorSheet(StyleSheetContents* authorSheet) { | 139 void StyleEngine::injectAuthorSheet(StyleSheetContents* authorSheet) { |
| 140 m_injectedAuthorStyleSheets.append(TraceWrapperMember<CSSStyleSheet>( | 140 m_injectedAuthorStyleSheets.append(TraceWrapperMember<CSSStyleSheet>( |
| 141 this, CSSStyleSheet::create(authorSheet, *m_document))); | 141 this, CSSStyleSheet::create(authorSheet, *m_document))); |
| 142 markDocumentDirty(); | 142 markDocumentDirty(); |
| 143 resolverChanged(AnalyzedStyleUpdate); | |
| 144 } | 143 } |
| 145 | 144 |
| 146 CSSStyleSheet& StyleEngine::ensureInspectorStyleSheet() { | 145 CSSStyleSheet& StyleEngine::ensureInspectorStyleSheet() { |
| 147 if (m_inspectorStyleSheet) | 146 if (m_inspectorStyleSheet) |
| 148 return *m_inspectorStyleSheet; | 147 return *m_inspectorStyleSheet; |
| 149 | 148 |
| 150 StyleSheetContents* contents = | 149 StyleSheetContents* contents = |
| 151 StyleSheetContents::create(CSSParserContext(*m_document, nullptr)); | 150 StyleSheetContents::create(CSSParserContext(*m_document, nullptr)); |
| 152 m_inspectorStyleSheet = CSSStyleSheet::create(contents, *m_document); | 151 m_inspectorStyleSheet = CSSStyleSheet::create(contents, *m_document); |
| 153 markDocumentDirty(); | 152 markDocumentDirty(); |
| 154 resolverChanged(AnalyzedStyleUpdate); | 153 // TODO(rune@opera.com): Making the active stylesheets up-to-date here is |
| 154 // required by some inspector tests, at least. I theory this should not be |
| 155 // necessary. Need to investigate to figure out if/why. |
| 156 updateActiveStyle(); |
| 155 return *m_inspectorStyleSheet; | 157 return *m_inspectorStyleSheet; |
| 156 } | 158 } |
| 157 | 159 |
| 158 void StyleEngine::addPendingSheet(StyleEngineContext& context) { | 160 void StyleEngine::addPendingSheet(StyleEngineContext& context) { |
| 159 m_pendingScriptBlockingStylesheets++; | 161 m_pendingScriptBlockingStylesheets++; |
| 160 | 162 |
| 161 context.addingPendingSheet(document()); | 163 context.addingPendingSheet(document()); |
| 162 if (context.addedPendingSheetBeforeBody()) | 164 if (context.addedPendingSheetBeforeBody()) |
| 163 m_pendingRenderBlockingStylesheets++; | 165 m_pendingRenderBlockingStylesheets++; |
| 164 } | 166 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 178 // sync. | 180 // sync. |
| 179 DCHECK_GT(m_pendingScriptBlockingStylesheets, 0); | 181 DCHECK_GT(m_pendingScriptBlockingStylesheets, 0); |
| 180 | 182 |
| 181 m_pendingScriptBlockingStylesheets--; | 183 m_pendingScriptBlockingStylesheets--; |
| 182 if (m_pendingScriptBlockingStylesheets) | 184 if (m_pendingScriptBlockingStylesheets) |
| 183 return; | 185 return; |
| 184 | 186 |
| 185 document().didRemoveAllPendingStylesheet(); | 187 document().didRemoveAllPendingStylesheet(); |
| 186 } | 188 } |
| 187 | 189 |
| 188 void StyleEngine::setNeedsActiveStyleUpdate( | 190 void StyleEngine::setNeedsActiveStyleUpdate(TreeScope& treeScope) { |
| 189 StyleSheet* sheet, | |
| 190 StyleResolverUpdateMode updateMode) { | |
| 191 // resolverChanged() is called for inactive non-master documents because | |
| 192 // import documents are inactive documents. resolverChanged() for imports | |
| 193 // will call resolverChanged() for the master document and update the active | |
| 194 // stylesheets including the ones from the import. | |
| 195 if (!document().isActive() && isMaster()) | 191 if (!document().isActive() && isMaster()) |
| 196 return; | 192 return; |
| 197 | 193 markTreeScopeDirty(treeScope); |
| 198 if (sheet && document().isActive()) { | |
| 199 Node* node = sheet->ownerNode(); | |
| 200 if (node && node->isConnected()) | |
| 201 markTreeScopeDirty(node->treeScope()); | |
| 202 } | |
| 203 | |
| 204 resolverChanged(updateMode); | |
| 205 } | 194 } |
| 206 | 195 |
| 207 void StyleEngine::addStyleSheetCandidateNode(Node& node) { | 196 void StyleEngine::addStyleSheetCandidateNode(Node& node) { |
| 208 if (!node.isConnected() || document().isDetached()) | 197 if (!node.isConnected() || document().isDetached()) |
| 209 return; | 198 return; |
| 210 | 199 |
| 211 DCHECK(!isXSLStyleSheet(node)); | 200 DCHECK(!isXSLStyleSheet(node)); |
| 212 TreeScope& treeScope = node.treeScope(); | 201 TreeScope& treeScope = node.treeScope(); |
| 213 TreeScopeStyleSheetCollection* collection = | 202 TreeScopeStyleSheetCollection* collection = |
| 214 ensureStyleSheetCollectionFor(treeScope); | 203 ensureStyleSheetCollectionFor(treeScope); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 233 // After detaching document, collection could be null. In the case, | 222 // After detaching document, collection could be null. In the case, |
| 234 // we should not update anything. Instead, just return. | 223 // we should not update anything. Instead, just return. |
| 235 if (!collection) | 224 if (!collection) |
| 236 return; | 225 return; |
| 237 collection->removeStyleSheetCandidateNode(node); | 226 collection->removeStyleSheetCandidateNode(node); |
| 238 | 227 |
| 239 markTreeScopeDirty(treeScope); | 228 markTreeScopeDirty(treeScope); |
| 240 } | 229 } |
| 241 | 230 |
| 242 void StyleEngine::modifiedStyleSheetCandidateNode(Node& node) { | 231 void StyleEngine::modifiedStyleSheetCandidateNode(Node& node) { |
| 243 if (!node.isConnected()) | 232 if (node.isConnected()) |
| 244 return; | 233 markTreeScopeDirty(node.treeScope()); |
| 234 } |
| 245 | 235 |
| 246 markTreeScopeDirty(node.treeScope()); | 236 void StyleEngine::mediaQueriesChangedInScope(TreeScope& treeScope) { |
| 247 resolverChanged(AnalyzedStyleUpdate); | 237 if (ScopedStyleResolver* resolver = treeScope.scopedStyleResolver()) { |
| 238 resolver->setNeedsAppendAllSheets(); |
| 239 setNeedsActiveStyleUpdate(treeScope); |
| 240 } |
| 248 } | 241 } |
| 249 | 242 |
| 250 void StyleEngine::watchedSelectorsChanged() { | 243 void StyleEngine::watchedSelectorsChanged() { |
| 251 m_globalRuleSet.initWatchedSelectorsRuleSet(document()); | 244 m_globalRuleSet.initWatchedSelectorsRuleSet(document()); |
| 252 // TODO(rune@opera.com): Should be able to use RuleSetInvalidation here. | 245 // TODO(rune@opera.com): Should be able to use RuleSetInvalidation here. |
| 253 document().setNeedsStyleRecalc(SubtreeStyleChange, | 246 document().setNeedsStyleRecalc(SubtreeStyleChange, |
| 254 StyleChangeReasonForTracing::create( | 247 StyleChangeReasonForTracing::create( |
| 255 StyleChangeReason::DeclarativeContent)); | 248 StyleChangeReason::DeclarativeContent)); |
| 256 } | 249 } |
| 257 | 250 |
| 258 bool StyleEngine::shouldUpdateDocumentStyleSheetCollection() const { | 251 bool StyleEngine::shouldUpdateDocumentStyleSheetCollection() const { |
| 259 return m_allTreeScopesDirty || m_documentScopeDirty; | 252 return m_allTreeScopesDirty || m_documentScopeDirty; |
| 260 } | 253 } |
| 261 | 254 |
| 262 bool StyleEngine::shouldUpdateShadowTreeStyleSheetCollection() const { | 255 bool StyleEngine::shouldUpdateShadowTreeStyleSheetCollection() const { |
| 263 return m_allTreeScopesDirty || !m_dirtyTreeScopes.isEmpty(); | 256 return m_allTreeScopesDirty || !m_dirtyTreeScopes.isEmpty(); |
| 264 } | 257 } |
| 265 | 258 |
| 266 void StyleEngine::mediaQueryAffectingValueChanged( | 259 void StyleEngine::mediaQueryAffectingValueChanged( |
| 267 UnorderedTreeScopeSet& treeScopes) { | 260 UnorderedTreeScopeSet& treeScopes) { |
| 268 for (TreeScope* treeScope : treeScopes) { | 261 for (TreeScope* treeScope : treeScopes) { |
| 269 DCHECK(treeScope != m_document); | 262 DCHECK(treeScope != m_document); |
| 270 ShadowTreeStyleSheetCollection* collection = | 263 ShadowTreeStyleSheetCollection* collection = |
| 271 toShadowTreeStyleSheetCollection(styleSheetCollectionFor(*treeScope)); | 264 toShadowTreeStyleSheetCollection(styleSheetCollectionFor(*treeScope)); |
| 272 DCHECK(collection); | 265 DCHECK(collection); |
| 273 collection->clearMediaQueryRuleSetStyleSheets(); | 266 if (collection->mediaQueryAffectingValueChanged()) |
| 267 setNeedsActiveStyleUpdate(*treeScope); |
| 274 } | 268 } |
| 275 } | 269 } |
| 276 | 270 |
| 277 void StyleEngine::mediaQueryAffectingValueChanged() { | 271 void StyleEngine::mediaQueryAffectingValueChanged() { |
| 278 resolverChanged(FullStyleUpdate); | 272 if (documentStyleSheetCollection().mediaQueryAffectingValueChanged()) |
| 279 documentStyleSheetCollection().clearMediaQueryRuleSetStyleSheets(); | 273 setNeedsActiveStyleUpdate(document()); |
| 280 mediaQueryAffectingValueChanged(m_activeTreeScopes); | 274 mediaQueryAffectingValueChanged(m_activeTreeScopes); |
| 281 if (m_resolver) | 275 if (m_resolver) |
| 282 m_resolver->updateMediaType(); | 276 m_resolver->updateMediaType(); |
| 283 } | 277 } |
| 284 | 278 |
| 285 void StyleEngine::updateStyleSheetsInImport( | 279 void StyleEngine::updateStyleSheetsInImport( |
| 286 DocumentStyleSheetCollector& parentCollector) { | 280 DocumentStyleSheetCollector& parentCollector) { |
| 287 DCHECK(!isMaster()); | 281 DCHECK(!isMaster()); |
| 288 HeapVector<Member<StyleSheet>> sheetsForList; | 282 HeapVector<Member<StyleSheet>> sheetsForList; |
| 289 ImportedDocumentStyleSheetCollector subcollector(parentCollector, | 283 ImportedDocumentStyleSheetCollector subcollector(parentCollector, |
| 290 sheetsForList); | 284 sheetsForList); |
| 291 documentStyleSheetCollection().collectStyleSheets(*this, subcollector); | 285 documentStyleSheetCollection().collectStyleSheets(subcollector); |
| 292 documentStyleSheetCollection().swapSheetsForSheetList(sheetsForList); | 286 documentStyleSheetCollection().swapSheetsForSheetList(sheetsForList); |
| 293 } | 287 } |
| 294 | 288 |
| 295 void StyleEngine::updateActiveStyleSheetsInShadow( | 289 void StyleEngine::updateActiveStyleSheetsInShadow( |
| 296 StyleResolverUpdateMode updateMode, | |
| 297 TreeScope* treeScope, | 290 TreeScope* treeScope, |
| 298 UnorderedTreeScopeSet& treeScopesRemoved) { | 291 UnorderedTreeScopeSet& treeScopesRemoved) { |
| 299 DCHECK_NE(treeScope, m_document); | 292 DCHECK_NE(treeScope, m_document); |
| 300 ShadowTreeStyleSheetCollection* collection = | 293 ShadowTreeStyleSheetCollection* collection = |
| 301 toShadowTreeStyleSheetCollection(styleSheetCollectionFor(*treeScope)); | 294 toShadowTreeStyleSheetCollection(styleSheetCollectionFor(*treeScope)); |
| 302 DCHECK(collection); | 295 DCHECK(collection); |
| 303 collection->updateActiveStyleSheets(*this, updateMode); | 296 collection->updateActiveStyleSheets(); |
| 304 if (!collection->hasStyleSheetCandidateNodes()) { | 297 if (!collection->hasStyleSheetCandidateNodes()) { |
| 305 treeScopesRemoved.add(treeScope); | 298 treeScopesRemoved.add(treeScope); |
| 306 // When removing TreeScope from ActiveTreeScopes, | 299 // When removing TreeScope from ActiveTreeScopes, |
| 307 // its resolver should be destroyed by invoking resetAuthorStyle. | 300 // its resolver should be destroyed by invoking resetAuthorStyle. |
| 308 DCHECK(!treeScope->scopedStyleResolver()); | 301 DCHECK(!treeScope->scopedStyleResolver()); |
| 309 } | 302 } |
| 310 } | 303 } |
| 311 | 304 |
| 312 void StyleEngine::updateActiveStyleSheets(StyleResolverUpdateMode updateMode) { | 305 void StyleEngine::updateActiveStyleSheets() { |
| 306 if (!needsActiveStyleSheetUpdate()) |
| 307 return; |
| 308 |
| 313 DCHECK(isMaster()); | 309 DCHECK(isMaster()); |
| 314 DCHECK(!document().inStyleRecalc()); | 310 DCHECK(!document().inStyleRecalc()); |
| 315 | 311 DCHECK(document().isActive()); |
| 316 if (!document().isActive()) | |
| 317 return; | |
| 318 | 312 |
| 319 TRACE_EVENT0("blink,blink_style", "StyleEngine::updateActiveStyleSheets"); | 313 TRACE_EVENT0("blink,blink_style", "StyleEngine::updateActiveStyleSheets"); |
| 320 | 314 |
| 321 if (shouldUpdateDocumentStyleSheetCollection()) | 315 if (shouldUpdateDocumentStyleSheetCollection()) |
| 322 documentStyleSheetCollection().updateActiveStyleSheets(*this, updateMode); | 316 documentStyleSheetCollection().updateActiveStyleSheets(); |
| 323 | 317 |
| 324 if (shouldUpdateShadowTreeStyleSheetCollection()) { | 318 if (shouldUpdateShadowTreeStyleSheetCollection()) { |
| 325 UnorderedTreeScopeSet treeScopesRemoved; | 319 UnorderedTreeScopeSet treeScopesRemoved; |
| 326 | 320 |
| 327 if (m_allTreeScopesDirty) { | 321 if (m_allTreeScopesDirty) { |
| 328 for (TreeScope* treeScope : m_activeTreeScopes) | 322 for (TreeScope* treeScope : m_activeTreeScopes) |
| 329 updateActiveStyleSheetsInShadow(updateMode, treeScope, | 323 updateActiveStyleSheetsInShadow(treeScope, treeScopesRemoved); |
| 330 treeScopesRemoved); | |
| 331 } else { | 324 } else { |
| 332 for (TreeScope* treeScope : m_dirtyTreeScopes) | 325 for (TreeScope* treeScope : m_dirtyTreeScopes) |
| 333 updateActiveStyleSheetsInShadow(updateMode, treeScope, | 326 updateActiveStyleSheetsInShadow(treeScope, treeScopesRemoved); |
| 334 treeScopesRemoved); | |
| 335 } | 327 } |
| 336 for (TreeScope* treeScope : treeScopesRemoved) | 328 for (TreeScope* treeScope : treeScopesRemoved) |
| 337 m_activeTreeScopes.remove(treeScope); | 329 m_activeTreeScopes.remove(treeScope); |
| 338 } | 330 } |
| 339 | 331 |
| 340 InspectorInstrumentation::activeStyleSheetsUpdated(m_document); | 332 InspectorInstrumentation::activeStyleSheetsUpdated(m_document); |
| 341 | 333 |
| 342 m_dirtyTreeScopes.clear(); | 334 m_dirtyTreeScopes.clear(); |
| 343 m_documentScopeDirty = false; | 335 m_documentScopeDirty = false; |
| 344 m_allTreeScopesDirty = false; | 336 m_allTreeScopesDirty = false; |
| 345 } | 337 } |
| 346 | 338 |
| 347 void StyleEngine::updateActiveStyleSheets() { | |
| 348 // TODO(rune@opera.com): collect ActiveStyleSheets here. | |
| 349 } | |
| 350 | |
| 351 void StyleEngine::updateViewport() { | 339 void StyleEngine::updateViewport() { |
| 352 if (m_viewportResolver) | 340 if (m_viewportResolver) |
| 353 m_viewportResolver->updateViewport(documentStyleSheetCollection()); | 341 m_viewportResolver->updateViewport(documentStyleSheetCollection()); |
| 354 } | 342 } |
| 355 | 343 |
| 356 bool StyleEngine::needsActiveStyleUpdate() const { | 344 bool StyleEngine::needsActiveStyleUpdate() const { |
| 357 return m_viewportResolver && m_viewportResolver->needsUpdate(); | 345 return (m_viewportResolver && m_viewportResolver->needsUpdate()) || |
| 346 needsActiveStyleSheetUpdate() || m_globalRuleSet.isDirty(); |
| 358 } | 347 } |
| 359 | 348 |
| 360 void StyleEngine::updateActiveStyle() { | 349 void StyleEngine::updateActiveStyle() { |
| 350 DCHECK(document().isActive()); |
| 361 updateViewport(); | 351 updateViewport(); |
| 362 updateActiveStyleSheets(); | 352 updateActiveStyleSheets(); |
| 363 m_globalRuleSet.update(document()); | 353 m_globalRuleSet.update(document()); |
| 364 } | 354 } |
| 365 | 355 |
| 366 const HeapVector<Member<CSSStyleSheet>> | 356 const ActiveStyleSheetVector StyleEngine::activeStyleSheetsForInspector() { |
| 367 StyleEngine::activeStyleSheetsForInspector() const { | 357 if (document().isActive()) |
| 358 updateActiveStyle(); |
| 359 |
| 368 if (m_activeTreeScopes.isEmpty()) | 360 if (m_activeTreeScopes.isEmpty()) |
| 369 return documentStyleSheetCollection().activeAuthorStyleSheets(); | 361 return documentStyleSheetCollection().activeAuthorStyleSheets(); |
| 370 | 362 |
| 371 HeapVector<Member<CSSStyleSheet>> activeStyleSheets; | 363 ActiveStyleSheetVector activeStyleSheets; |
| 372 | 364 |
| 373 activeStyleSheets.appendVector( | 365 activeStyleSheets.appendVector( |
| 374 documentStyleSheetCollection().activeAuthorStyleSheets()); | 366 documentStyleSheetCollection().activeAuthorStyleSheets()); |
| 375 for (TreeScope* treeScope : m_activeTreeScopes) { | 367 for (TreeScope* treeScope : m_activeTreeScopes) { |
| 376 if (TreeScopeStyleSheetCollection* collection = | 368 if (TreeScopeStyleSheetCollection* collection = |
| 377 m_styleSheetCollectionMap.get(treeScope)) | 369 m_styleSheetCollectionMap.get(treeScope)) |
| 378 activeStyleSheets.appendVector(collection->activeAuthorStyleSheets()); | 370 activeStyleSheets.appendVector(collection->activeAuthorStyleSheets()); |
| 379 } | 371 } |
| 380 | 372 |
| 381 // FIXME: Inspector needs a vector which has all active stylesheets. | 373 // FIXME: Inspector needs a vector which has all active stylesheets. |
| 382 // However, creating such a large vector might cause performance regression. | 374 // However, creating such a large vector might cause performance regression. |
| 383 // Need to implement some smarter solution. | 375 // Need to implement some smarter solution. |
| 384 return activeStyleSheets; | 376 return activeStyleSheets; |
| 385 } | 377 } |
| 386 | 378 |
| 387 void StyleEngine::shadowRootRemovedFromDocument(ShadowRoot* shadowRoot) { | 379 void StyleEngine::shadowRootRemovedFromDocument(ShadowRoot* shadowRoot) { |
| 388 if (StyleResolver* styleResolver = resolver()) { | |
| 389 if (TreeScopeStyleSheetCollection* collection = | |
| 390 styleSheetCollectionFor(*shadowRoot)) | |
| 391 styleResolver->removePendingAuthorStyleSheets( | |
| 392 collection->activeAuthorStyleSheets()); | |
| 393 } | |
| 394 m_styleSheetCollectionMap.remove(shadowRoot); | 380 m_styleSheetCollectionMap.remove(shadowRoot); |
| 395 m_activeTreeScopes.remove(shadowRoot); | 381 m_activeTreeScopes.remove(shadowRoot); |
| 396 m_dirtyTreeScopes.remove(shadowRoot); | 382 m_dirtyTreeScopes.remove(shadowRoot); |
| 397 resetAuthorStyle(*shadowRoot); | 383 resetAuthorStyle(*shadowRoot); |
| 398 } | 384 } |
| 399 | 385 |
| 400 void StyleEngine::addTreeBoundaryCrossingScope(const TreeScope& treeScope) { | 386 void StyleEngine::addTreeBoundaryCrossingScope(const TreeScope& treeScope) { |
| 401 m_treeBoundaryCrossingScopes.add(&treeScope.rootNode()); | 387 m_treeBoundaryCrossingScopes.add(&treeScope.rootNode()); |
| 402 } | 388 } |
| 403 | 389 |
| 404 void StyleEngine::resetAuthorStyle(TreeScope& treeScope) { | 390 void StyleEngine::resetAuthorStyle(TreeScope& treeScope) { |
| 405 m_treeBoundaryCrossingScopes.remove(&treeScope.rootNode()); | 391 m_treeBoundaryCrossingScopes.remove(&treeScope.rootNode()); |
| 406 | 392 |
| 407 ScopedStyleResolver* scopedResolver = treeScope.scopedStyleResolver(); | 393 ScopedStyleResolver* scopedResolver = treeScope.scopedStyleResolver(); |
| 408 if (!scopedResolver) | 394 if (!scopedResolver) |
| 409 return; | 395 return; |
| 410 | 396 |
| 411 m_globalRuleSet.markDirty(); | 397 m_globalRuleSet.markDirty(); |
| 412 if (treeScope.rootNode().isDocumentNode()) { | 398 if (treeScope.rootNode().isDocumentNode()) { |
| 413 scopedResolver->resetAuthorStyle(); | 399 scopedResolver->resetAuthorStyle(); |
| 414 return; | 400 return; |
| 415 } | 401 } |
| 416 | 402 |
| 417 treeScope.clearScopedStyleResolver(); | 403 treeScope.clearScopedStyleResolver(); |
| 418 } | 404 } |
| 419 | 405 |
| 420 void StyleEngine::finishAppendAuthorStyleSheets() { | |
| 421 m_globalRuleSet.markDirty(); | |
| 422 m_globalRuleSet.update(document()); | |
| 423 | |
| 424 if (!document().layoutViewItem().isNull() && | |
| 425 document().layoutViewItem().style()) | |
| 426 document().layoutViewItem().style()->font().update(fontSelector()); | |
| 427 } | |
| 428 | |
| 429 void StyleEngine::appendActiveAuthorStyleSheets() { | |
| 430 DCHECK(isMaster()); | |
| 431 | |
| 432 m_resolver->appendAuthorStyleSheets( | |
| 433 documentStyleSheetCollection().activeAuthorStyleSheets()); | |
| 434 for (TreeScope* treeScope : m_activeTreeScopes) { | |
| 435 if (TreeScopeStyleSheetCollection* collection = | |
| 436 m_styleSheetCollectionMap.get(treeScope)) | |
| 437 m_resolver->appendAuthorStyleSheets( | |
| 438 collection->activeAuthorStyleSheets()); | |
| 439 } | |
| 440 } | |
| 441 | |
| 442 void StyleEngine::setRuleUsageTracker(StyleRuleUsageTracker* tracker) { | 406 void StyleEngine::setRuleUsageTracker(StyleRuleUsageTracker* tracker) { |
| 443 m_tracker = tracker; | 407 m_tracker = tracker; |
| 444 | 408 |
| 445 if (m_resolver) | 409 if (m_resolver) |
| 446 m_resolver->setRuleUsageTracker(m_tracker); | 410 m_resolver->setRuleUsageTracker(m_tracker); |
| 447 } | 411 } |
| 448 | 412 |
| 449 RuleSet* StyleEngine::ruleSetForSheet(CSSStyleSheet& sheet) { | 413 RuleSet* StyleEngine::ruleSetForSheet(CSSStyleSheet& sheet) { |
| 450 if (!sheet.matchesMediaQueries(ensureMediaQueryEvaluator())) | 414 if (!sheet.matchesMediaQueries(ensureMediaQueryEvaluator())) |
| 451 return nullptr; | 415 return nullptr; |
| 452 | 416 |
| 453 AddRuleFlags addRuleFlags = RuleHasNoSpecialState; | 417 AddRuleFlags addRuleFlags = RuleHasNoSpecialState; |
| 454 if (m_document->getSecurityOrigin()->canRequest(sheet.baseURL())) | 418 if (m_document->getSecurityOrigin()->canRequest(sheet.baseURL())) |
| 455 addRuleFlags = RuleHasDocumentSecurityOrigin; | 419 addRuleFlags = RuleHasDocumentSecurityOrigin; |
| 456 return &sheet.contents()->ensureRuleSet(*m_mediaQueryEvaluator, addRuleFlags); | 420 return &sheet.contents()->ensureRuleSet(*m_mediaQueryEvaluator, addRuleFlags); |
| 457 } | 421 } |
| 458 | 422 |
| 459 void StyleEngine::createResolver() { | 423 void StyleEngine::createResolver() { |
| 460 m_resolver = StyleResolver::create(*m_document); | 424 m_resolver = StyleResolver::create(*m_document); |
| 461 | |
| 462 m_resolver->setRuleUsageTracker(m_tracker); | 425 m_resolver->setRuleUsageTracker(m_tracker); |
| 463 | |
| 464 // A scoped style resolver for document will be created during | |
| 465 // appendActiveAuthorStyleSheets if needed. | |
| 466 appendActiveAuthorStyleSheets(); | |
| 467 finishAppendAuthorStyleSheets(); | |
| 468 } | 426 } |
| 469 | 427 |
| 470 void StyleEngine::clearResolver() { | 428 void StyleEngine::clearResolver() { |
| 471 DCHECK(!document().inStyleRecalc()); | 429 DCHECK(!document().inStyleRecalc()); |
| 472 DCHECK(isMaster() || !m_resolver); | 430 DCHECK(isMaster() || !m_resolver); |
| 473 | 431 |
| 474 document().clearScopedStyleResolver(); | 432 document().clearScopedStyleResolver(); |
| 475 // TODO(rune@opera.com): The clearing of all shadow tree scoped style | 433 // TODO(rune@opera.com): The clearing of all shadow tree scoped style |
| 476 // resolvers below should not be necessary. It was introduced to fix a crash | 434 // resolvers below should not be necessary. It was introduced to fix a crash |
| 477 // bug (https://crbug.com/447976) when clearResolver is called from didDetach | 435 // bug (https://crbug.com/447976) when clearResolver is called from didDetach |
| (...skipping 12 matching lines...) Expand all Loading... |
| 490 m_treeBoundaryCrossingScopes.clear(); | 448 m_treeBoundaryCrossingScopes.clear(); |
| 491 | 449 |
| 492 if (m_resolver) { | 450 if (m_resolver) { |
| 493 TRACE_EVENT1("blink", "StyleEngine::clearResolver", "frame", | 451 TRACE_EVENT1("blink", "StyleEngine::clearResolver", "frame", |
| 494 document().frame()); | 452 document().frame()); |
| 495 m_resolver->dispose(); | 453 m_resolver->dispose(); |
| 496 m_resolver.clear(); | 454 m_resolver.clear(); |
| 497 } | 455 } |
| 498 } | 456 } |
| 499 | 457 |
| 500 void StyleEngine::clearMasterResolver() { | |
| 501 if (Document* master = this->master()) | |
| 502 master->styleEngine().clearResolver(); | |
| 503 } | |
| 504 | |
| 505 void StyleEngine::didDetach() { | 458 void StyleEngine::didDetach() { |
| 506 clearResolver(); | 459 clearResolver(); |
| 507 m_viewportResolver = nullptr; | 460 m_viewportResolver = nullptr; |
| 508 m_mediaQueryEvaluator = nullptr; | 461 m_mediaQueryEvaluator = nullptr; |
| 509 } | 462 } |
| 510 | 463 |
| 511 bool StyleEngine::shouldClearResolver() const { | |
| 512 return !m_didCalculateResolver && !haveScriptBlockingStylesheetsLoaded(); | |
| 513 } | |
| 514 | |
| 515 void StyleEngine::resolverChanged(StyleResolverUpdateMode mode) { | |
| 516 if (!isMaster()) { | |
| 517 if (Document* master = this->master()) | |
| 518 master->styleEngine().resolverChanged(mode); | |
| 519 return; | |
| 520 } | |
| 521 | |
| 522 // Don't bother updating, since we haven't loaded all our style info yet | |
| 523 // and haven't calculated the style selector for the first time. | |
| 524 if (!document().isActive() || shouldClearResolver()) { | |
| 525 clearResolver(); | |
| 526 return; | |
| 527 } | |
| 528 | |
| 529 if (mode == FullStyleUpdate) | |
| 530 markAllTreeScopesDirty(); | |
| 531 m_didCalculateResolver = true; | |
| 532 updateActiveStyleSheets(mode); | |
| 533 } | |
| 534 | |
| 535 void StyleEngine::clearFontCache() { | 464 void StyleEngine::clearFontCache() { |
| 536 if (m_fontSelector) | 465 if (m_fontSelector) |
| 537 m_fontSelector->fontFaceCache()->clearCSSConnected(); | 466 m_fontSelector->fontFaceCache()->clearCSSConnected(); |
| 538 if (m_resolver) | 467 if (m_resolver) |
| 539 m_resolver->invalidateMatchedPropertiesCache(); | 468 m_resolver->invalidateMatchedPropertiesCache(); |
| 540 } | 469 } |
| 541 | 470 |
| 542 void StyleEngine::updateGenericFontFamilySettings() { | 471 void StyleEngine::updateGenericFontFamilySettings() { |
| 543 // FIXME: we should not update generic font family settings when | 472 // FIXME: we should not update generic font family settings when |
| 544 // document is inactive. | 473 // document is inactive. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 566 } | 495 } |
| 567 | 496 |
| 568 void StyleEngine::markTreeScopeDirty(TreeScope& scope) { | 497 void StyleEngine::markTreeScopeDirty(TreeScope& scope) { |
| 569 if (scope == m_document) { | 498 if (scope == m_document) { |
| 570 markDocumentDirty(); | 499 markDocumentDirty(); |
| 571 return; | 500 return; |
| 572 } | 501 } |
| 573 | 502 |
| 574 DCHECK(m_styleSheetCollectionMap.contains(&scope)); | 503 DCHECK(m_styleSheetCollectionMap.contains(&scope)); |
| 575 m_dirtyTreeScopes.add(&scope); | 504 m_dirtyTreeScopes.add(&scope); |
| 505 document().scheduleLayoutTreeUpdateIfNeeded(); |
| 576 } | 506 } |
| 577 | 507 |
| 578 void StyleEngine::markDocumentDirty() { | 508 void StyleEngine::markDocumentDirty() { |
| 579 m_documentScopeDirty = true; | 509 m_documentScopeDirty = true; |
| 580 if (RuntimeEnabledFeatures::cssViewportEnabled()) | 510 if (RuntimeEnabledFeatures::cssViewportEnabled()) |
| 581 viewportRulesChanged(); | 511 viewportRulesChanged(); |
| 582 if (document().importLoader()) | 512 if (document().importLoader()) |
| 583 document().importsController()->master()->styleEngine().markDocumentDirty(); | 513 document().importsController()->master()->styleEngine().markDocumentDirty(); |
| 514 else |
| 515 document().scheduleLayoutTreeUpdateIfNeeded(); |
| 584 } | 516 } |
| 585 | 517 |
| 586 CSSStyleSheet* StyleEngine::createSheet(Element& element, | 518 CSSStyleSheet* StyleEngine::createSheet(Element& element, |
| 587 const String& text, | 519 const String& text, |
| 588 TextPosition startPosition, | 520 TextPosition startPosition, |
| 589 StyleEngineContext& context) { | 521 StyleEngineContext& context) { |
| 590 DCHECK(element.document() == document()); | 522 DCHECK(element.document() == document()); |
| 591 CSSStyleSheet* styleSheet = nullptr; | 523 CSSStyleSheet* styleSheet = nullptr; |
| 592 | 524 |
| 593 addPendingSheet(context); | 525 addPendingSheet(context); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 608 DCHECK(contents); | 540 DCHECK(contents); |
| 609 DCHECK(contents->isCacheableForStyleElement()); | 541 DCHECK(contents->isCacheableForStyleElement()); |
| 610 DCHECK(contents->hasSingleOwnerDocument()); | 542 DCHECK(contents->hasSingleOwnerDocument()); |
| 611 contents->setIsUsedFromTextCache(); | 543 contents->setIsUsedFromTextCache(); |
| 612 styleSheet = CSSStyleSheet::createInline(contents, element, startPosition); | 544 styleSheet = CSSStyleSheet::createInline(contents, element, startPosition); |
| 613 } | 545 } |
| 614 | 546 |
| 615 DCHECK(styleSheet); | 547 DCHECK(styleSheet); |
| 616 if (!element.isInShadowTree()) { | 548 if (!element.isInShadowTree()) { |
| 617 styleSheet->setTitle(element.title()); | 549 styleSheet->setTitle(element.title()); |
| 618 setPreferredStylesheetSetNameIfNotSet(element.title(), | 550 setPreferredStylesheetSetNameIfNotSet(element.title()); |
| 619 DontUpdateActiveSheets); | |
| 620 } | 551 } |
| 621 return styleSheet; | 552 return styleSheet; |
| 622 } | 553 } |
| 623 | 554 |
| 624 CSSStyleSheet* StyleEngine::parseSheet(Element& element, | 555 CSSStyleSheet* StyleEngine::parseSheet(Element& element, |
| 625 const String& text, | 556 const String& text, |
| 626 TextPosition startPosition) { | 557 TextPosition startPosition) { |
| 627 CSSStyleSheet* styleSheet = nullptr; | 558 CSSStyleSheet* styleSheet = nullptr; |
| 628 styleSheet = CSSStyleSheet::createInline(element, KURL(), startPosition, | 559 styleSheet = CSSStyleSheet::createInline(element, KURL(), startPosition, |
| 629 document().characterSet()); | 560 document().characterSet()); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 return true; | 615 return true; |
| 685 return element.parentNode()->getStyleChangeType() >= SubtreeStyleChange; | 616 return element.parentNode()->getStyleChangeType() >= SubtreeStyleChange; |
| 686 } | 617 } |
| 687 | 618 |
| 688 void StyleEngine::classChangedForElement(const SpaceSplitString& changedClasses, | 619 void StyleEngine::classChangedForElement(const SpaceSplitString& changedClasses, |
| 689 Element& element) { | 620 Element& element) { |
| 690 if (shouldSkipInvalidationFor(element)) | 621 if (shouldSkipInvalidationFor(element)) |
| 691 return; | 622 return; |
| 692 InvalidationLists invalidationLists; | 623 InvalidationLists invalidationLists; |
| 693 unsigned changedSize = changedClasses.size(); | 624 unsigned changedSize = changedClasses.size(); |
| 694 // TODO(rune@opera.com): ensureResolver() can be removed once stylesheet | |
| 695 // updates are async. https://crbug.com/567021 | |
| 696 ensureResolver(); | |
| 697 const RuleFeatureSet& features = ruleFeatureSet(); | 625 const RuleFeatureSet& features = ruleFeatureSet(); |
| 698 for (unsigned i = 0; i < changedSize; ++i) { | 626 for (unsigned i = 0; i < changedSize; ++i) { |
| 699 features.collectInvalidationSetsForClass(invalidationLists, element, | 627 features.collectInvalidationSetsForClass(invalidationLists, element, |
| 700 changedClasses[i]); | 628 changedClasses[i]); |
| 701 } | 629 } |
| 702 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, | 630 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, |
| 703 element); | 631 element); |
| 704 } | 632 } |
| 705 | 633 |
| 706 void StyleEngine::classChangedForElement(const SpaceSplitString& oldClasses, | 634 void StyleEngine::classChangedForElement(const SpaceSplitString& oldClasses, |
| 707 const SpaceSplitString& newClasses, | 635 const SpaceSplitString& newClasses, |
| 708 Element& element) { | 636 Element& element) { |
| 709 if (shouldSkipInvalidationFor(element)) | 637 if (shouldSkipInvalidationFor(element)) |
| 710 return; | 638 return; |
| 711 | 639 |
| 712 if (!oldClasses.size()) { | 640 if (!oldClasses.size()) { |
| 713 classChangedForElement(newClasses, element); | 641 classChangedForElement(newClasses, element); |
| 714 return; | 642 return; |
| 715 } | 643 } |
| 716 | 644 |
| 717 // Class vectors tend to be very short. This is faster than using a hash | 645 // Class vectors tend to be very short. This is faster than using a hash |
| 718 // table. | 646 // table. |
| 719 BitVector remainingClassBits; | 647 BitVector remainingClassBits; |
| 720 remainingClassBits.ensureSize(oldClasses.size()); | 648 remainingClassBits.ensureSize(oldClasses.size()); |
| 721 | 649 |
| 722 InvalidationLists invalidationLists; | 650 InvalidationLists invalidationLists; |
| 723 // TODO(rune@opera.com): ensureResolver() can be removed once stylesheet | |
| 724 // updates are async. https://crbug.com/567021 | |
| 725 ensureResolver(); | |
| 726 const RuleFeatureSet& features = ruleFeatureSet(); | 651 const RuleFeatureSet& features = ruleFeatureSet(); |
| 727 | 652 |
| 728 for (unsigned i = 0; i < newClasses.size(); ++i) { | 653 for (unsigned i = 0; i < newClasses.size(); ++i) { |
| 729 bool found = false; | 654 bool found = false; |
| 730 for (unsigned j = 0; j < oldClasses.size(); ++j) { | 655 for (unsigned j = 0; j < oldClasses.size(); ++j) { |
| 731 if (newClasses[i] == oldClasses[j]) { | 656 if (newClasses[i] == oldClasses[j]) { |
| 732 // Mark each class that is still in the newClasses so we can skip doing | 657 // Mark each class that is still in the newClasses so we can skip doing |
| 733 // an n^2 search below when looking for removals. We can't break from | 658 // an n^2 search below when looking for removals. We can't break from |
| 734 // this loop early since a class can appear more than once. | 659 // this loop early since a class can appear more than once. |
| 735 remainingClassBits.quickSet(j); | 660 remainingClassBits.quickSet(j); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 754 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, | 679 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, |
| 755 element); | 680 element); |
| 756 } | 681 } |
| 757 | 682 |
| 758 void StyleEngine::attributeChangedForElement(const QualifiedName& attributeName, | 683 void StyleEngine::attributeChangedForElement(const QualifiedName& attributeName, |
| 759 Element& element) { | 684 Element& element) { |
| 760 if (shouldSkipInvalidationFor(element)) | 685 if (shouldSkipInvalidationFor(element)) |
| 761 return; | 686 return; |
| 762 | 687 |
| 763 InvalidationLists invalidationLists; | 688 InvalidationLists invalidationLists; |
| 764 // TODO(rune@opera.com): ensureResolver() can be removed once stylesheet | |
| 765 // updates are async. https://crbug.com/567021 | |
| 766 ensureResolver(); | |
| 767 ruleFeatureSet().collectInvalidationSetsForAttribute(invalidationLists, | 689 ruleFeatureSet().collectInvalidationSetsForAttribute(invalidationLists, |
| 768 element, attributeName); | 690 element, attributeName); |
| 769 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, | 691 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, |
| 770 element); | 692 element); |
| 771 } | 693 } |
| 772 | 694 |
| 773 void StyleEngine::idChangedForElement(const AtomicString& oldId, | 695 void StyleEngine::idChangedForElement(const AtomicString& oldId, |
| 774 const AtomicString& newId, | 696 const AtomicString& newId, |
| 775 Element& element) { | 697 Element& element) { |
| 776 if (shouldSkipInvalidationFor(element)) | 698 if (shouldSkipInvalidationFor(element)) |
| 777 return; | 699 return; |
| 778 | 700 |
| 779 InvalidationLists invalidationLists; | 701 InvalidationLists invalidationLists; |
| 780 // TODO(rune@opera.com): ensureResolver() can be removed once stylesheet | |
| 781 // updates are async. https://crbug.com/567021 | |
| 782 ensureResolver(); | |
| 783 const RuleFeatureSet& features = ruleFeatureSet(); | 702 const RuleFeatureSet& features = ruleFeatureSet(); |
| 784 if (!oldId.isEmpty()) | 703 if (!oldId.isEmpty()) |
| 785 features.collectInvalidationSetsForId(invalidationLists, element, oldId); | 704 features.collectInvalidationSetsForId(invalidationLists, element, oldId); |
| 786 if (!newId.isEmpty()) | 705 if (!newId.isEmpty()) |
| 787 features.collectInvalidationSetsForId(invalidationLists, element, newId); | 706 features.collectInvalidationSetsForId(invalidationLists, element, newId); |
| 788 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, | 707 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, |
| 789 element); | 708 element); |
| 790 } | 709 } |
| 791 | 710 |
| 792 void StyleEngine::pseudoStateChangedForElement( | 711 void StyleEngine::pseudoStateChangedForElement( |
| 793 CSSSelector::PseudoType pseudoType, | 712 CSSSelector::PseudoType pseudoType, |
| 794 Element& element) { | 713 Element& element) { |
| 795 if (shouldSkipInvalidationFor(element)) | 714 if (shouldSkipInvalidationFor(element)) |
| 796 return; | 715 return; |
| 797 | 716 |
| 798 InvalidationLists invalidationLists; | 717 InvalidationLists invalidationLists; |
| 799 // TODO(rune@opera.com): ensureResolver() can be removed once stylesheet | |
| 800 // updates are async. https://crbug.com/567021 | |
| 801 ensureResolver(); | |
| 802 ruleFeatureSet().collectInvalidationSetsForPseudoClass(invalidationLists, | 718 ruleFeatureSet().collectInvalidationSetsForPseudoClass(invalidationLists, |
| 803 element, pseudoType); | 719 element, pseudoType); |
| 804 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, | 720 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, |
| 805 element); | 721 element); |
| 806 } | 722 } |
| 807 | 723 |
| 808 void StyleEngine::scheduleSiblingInvalidationsForElement( | 724 void StyleEngine::scheduleSiblingInvalidationsForElement( |
| 809 Element& element, | 725 Element& element, |
| 810 ContainerNode& schedulingParent, | 726 ContainerNode& schedulingParent, |
| 811 unsigned minDirectAdjacent) { | 727 unsigned minDirectAdjacent) { |
| 812 DCHECK(minDirectAdjacent); | 728 DCHECK(minDirectAdjacent); |
| 813 | 729 |
| 814 InvalidationLists invalidationLists; | 730 InvalidationLists invalidationLists; |
| 815 | 731 |
| 816 // TODO(rune@opera.com): ensureResolver() can be removed once stylesheet | |
| 817 // updates are async. https://crbug.com/567021 | |
| 818 ensureResolver(); | |
| 819 const RuleFeatureSet& features = ruleFeatureSet(); | 732 const RuleFeatureSet& features = ruleFeatureSet(); |
| 820 | 733 |
| 821 if (element.hasID()) { | 734 if (element.hasID()) { |
| 822 features.collectSiblingInvalidationSetForId(invalidationLists, element, | 735 features.collectSiblingInvalidationSetForId(invalidationLists, element, |
| 823 element.idForStyleResolution(), | 736 element.idForStyleResolution(), |
| 824 minDirectAdjacent); | 737 minDirectAdjacent); |
| 825 } | 738 } |
| 826 | 739 |
| 827 if (element.hasClass()) { | 740 if (element.hasClass()) { |
| 828 const SpaceSplitString& classNames = element.classNames(); | 741 const SpaceSplitString& classNames = element.classNames(); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 878 scheduleSiblingInvalidationsForElement(removedElement, *schedulingParent, 1); | 791 scheduleSiblingInvalidationsForElement(removedElement, *schedulingParent, 1); |
| 879 | 792 |
| 880 for (unsigned i = 1; beforeElement && i <= affectedSiblings; | 793 for (unsigned i = 1; beforeElement && i <= affectedSiblings; |
| 881 i++, beforeElement = ElementTraversal::previousSibling(*beforeElement)) | 794 i++, beforeElement = ElementTraversal::previousSibling(*beforeElement)) |
| 882 scheduleSiblingInvalidationsForElement(*beforeElement, *schedulingParent, | 795 scheduleSiblingInvalidationsForElement(*beforeElement, *schedulingParent, |
| 883 i); | 796 i); |
| 884 } | 797 } |
| 885 | 798 |
| 886 void StyleEngine::scheduleNthPseudoInvalidations(ContainerNode& nthParent) { | 799 void StyleEngine::scheduleNthPseudoInvalidations(ContainerNode& nthParent) { |
| 887 InvalidationLists invalidationLists; | 800 InvalidationLists invalidationLists; |
| 888 // TODO(rune@opera.com): ensureResolver() can be removed once stylesheet | |
| 889 // updates are async. https://crbug.com/567021 | |
| 890 ensureResolver(); | |
| 891 ruleFeatureSet().collectNthInvalidationSet(invalidationLists); | 801 ruleFeatureSet().collectNthInvalidationSet(invalidationLists); |
| 892 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, | 802 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, |
| 893 nthParent); | 803 nthParent); |
| 894 } | 804 } |
| 895 | 805 |
| 896 void StyleEngine::scheduleRuleSetInvalidationsForElement( | 806 void StyleEngine::scheduleRuleSetInvalidationsForElement( |
| 897 Element& element, | 807 Element& element, |
| 898 const HeapVector<Member<RuleSet>>& ruleSets) { | 808 const HeapVector<Member<RuleSet>>& ruleSets) { |
| 899 AtomicString id; | 809 AtomicString id; |
| 900 const SpaceSplitString* classNames = nullptr; | 810 const SpaceSplitString* classNames = nullptr; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 978 if (!enabled) { | 888 if (!enabled) { |
| 979 m_styleResolverStats = nullptr; | 889 m_styleResolverStats = nullptr; |
| 980 return; | 890 return; |
| 981 } | 891 } |
| 982 if (!m_styleResolverStats) | 892 if (!m_styleResolverStats) |
| 983 m_styleResolverStats = StyleResolverStats::create(); | 893 m_styleResolverStats = StyleResolverStats::create(); |
| 984 else | 894 else |
| 985 m_styleResolverStats->reset(); | 895 m_styleResolverStats->reset(); |
| 986 } | 896 } |
| 987 | 897 |
| 988 void StyleEngine::setPreferredStylesheetSetNameIfNotSet( | 898 void StyleEngine::setPreferredStylesheetSetNameIfNotSet(const String& name) { |
| 989 const String& name, | |
| 990 ActiveSheetsUpdate activeSheetsUpdate) { | |
| 991 if (!m_preferredStylesheetSetName.isEmpty()) | 899 if (!m_preferredStylesheetSetName.isEmpty()) |
| 992 return; | 900 return; |
| 993 m_preferredStylesheetSetName = name; | 901 m_preferredStylesheetSetName = name; |
| 994 // TODO(rune@opera.com): Setting the selected set here is wrong if the set | 902 // TODO(rune@opera.com): Setting the selected set here is wrong if the set |
| 995 // has been previously set by through Document.selectedStylesheetSet. Our | 903 // has been previously set by through Document.selectedStylesheetSet. Our |
| 996 // current implementation ignores the effect of Document.selectedStylesheetSet | 904 // current implementation ignores the effect of Document.selectedStylesheetSet |
| 997 // and either only collects persistent style, or additionally preferred | 905 // and either only collects persistent style, or additionally preferred |
| 998 // style when present. | 906 // style when present. |
| 999 m_selectedStylesheetSetName = name; | 907 m_selectedStylesheetSetName = name; |
| 1000 | 908 markDocumentDirty(); |
| 1001 // TODO(rune@opera.com): For async stylesheet update, we should always mark | |
| 1002 // the TreeScope dirty here, and the synchronous active stylesheet update | |
| 1003 // (resolverChanged) should go away. | |
| 1004 if (activeSheetsUpdate == UpdateActiveSheets) { | |
| 1005 markDocumentDirty(); | |
| 1006 resolverChanged(AnalyzedStyleUpdate); | |
| 1007 } | |
| 1008 } | 909 } |
| 1009 | 910 |
| 1010 void StyleEngine::setSelectedStylesheetSetName(const String& name) { | 911 void StyleEngine::setSelectedStylesheetSetName(const String& name) { |
| 1011 m_selectedStylesheetSetName = name; | 912 m_selectedStylesheetSetName = name; |
| 1012 // TODO(rune@opera.com): Setting Document.selectedStylesheetSet currently | 913 // TODO(rune@opera.com): Setting Document.selectedStylesheetSet currently |
| 1013 // has no other effect than the ability to read back the set value using | 914 // has no other effect than the ability to read back the set value using |
| 1014 // the same api. If it did have an effect, we should have marked the | 915 // the same api. If it did have an effect, we should have marked the |
| 1015 // document scope dirty and triggered an update of the active stylesheets | 916 // document scope dirty and triggered an update of the active stylesheets |
| 1016 // from here. | 917 // from here. |
| 1017 } | 918 } |
| 1018 | 919 |
| 1019 void StyleEngine::setHttpDefaultStyle(const String& content) { | 920 void StyleEngine::setHttpDefaultStyle(const String& content) { |
| 1020 setPreferredStylesheetSetNameIfNotSet(content, UpdateActiveSheets); | 921 setPreferredStylesheetSetNameIfNotSet(content); |
| 1021 } | 922 } |
| 1022 | 923 |
| 1023 void StyleEngine::ensureUAStyleForFullscreen() { | 924 void StyleEngine::ensureUAStyleForFullscreen() { |
| 1024 if (m_globalRuleSet.hasFullscreenUAStyle()) | 925 if (m_globalRuleSet.hasFullscreenUAStyle()) |
| 1025 return; | 926 return; |
| 1026 CSSDefaultStyleSheets::instance().ensureDefaultStyleSheetForFullscreen(); | 927 CSSDefaultStyleSheets::instance().ensureDefaultStyleSheetForFullscreen(); |
| 1027 m_globalRuleSet.markDirty(); | 928 m_globalRuleSet.markDirty(); |
| 1028 m_globalRuleSet.update(document()); | 929 m_globalRuleSet.update(document()); |
| 1029 } | 930 } |
| 1030 | 931 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1043 void StyleEngine::initialViewportChanged() { | 944 void StyleEngine::initialViewportChanged() { |
| 1044 if (m_viewportResolver) | 945 if (m_viewportResolver) |
| 1045 m_viewportResolver->initialViewportChanged(); | 946 m_viewportResolver->initialViewportChanged(); |
| 1046 } | 947 } |
| 1047 | 948 |
| 1048 void StyleEngine::viewportRulesChanged() { | 949 void StyleEngine::viewportRulesChanged() { |
| 1049 if (m_viewportResolver) | 950 if (m_viewportResolver) |
| 1050 m_viewportResolver->setNeedsCollectRules(); | 951 m_viewportResolver->setNeedsCollectRules(); |
| 1051 } | 952 } |
| 1052 | 953 |
| 1053 void StyleEngine::importRemoved() { | 954 void StyleEngine::importAddedOrRemoved() { |
| 1054 if (document().importLoader()) { | 955 if (document().importLoader()) { |
| 1055 document().importsController()->master()->styleEngine().importRemoved(); | 956 document() |
| 957 .importsController() |
| 958 ->master() |
| 959 ->styleEngine() |
| 960 .importAddedOrRemoved(); |
| 1056 return; | 961 return; |
| 1057 } | 962 } |
| 1058 | 963 |
| 1059 // When we remove an import link and re-insert it into the document, the | 964 // When we remove an import link and re-insert it into the document, the |
| 1060 // import Document and CSSStyleSheet pointers are persisted. That means the | 965 // import Document and CSSStyleSheet pointers are persisted. That means the |
| 1061 // comparison of active stylesheets is not able to figure out that the order | 966 // comparison of active stylesheets is not able to figure out that the order |
| 1062 // of the stylesheets have changed after insertion. | 967 // of the stylesheets have changed after insertion. |
| 1063 // | 968 // |
| 1064 // Fall back to re-add all sheets to the scoped resolver and recalculate style | 969 // Fall back to re-add all sheets to the scoped resolver and recalculate style |
| 1065 // for the whole document if we remove an import in case it is re-inserted | 970 // for the whole document if we remove an import in case it is re-inserted |
| 1066 // into the document. The assumption is that removing html imports is very | 971 // into the document. The assumption is that removing html imports is very |
| 1067 // rare. | 972 // rare. |
| 1068 if (ScopedStyleResolver* resolver = document().scopedStyleResolver()) { | 973 if (ScopedStyleResolver* resolver = document().scopedStyleResolver()) { |
| 974 markDocumentDirty(); |
| 1069 resolver->setNeedsAppendAllSheets(); | 975 resolver->setNeedsAppendAllSheets(); |
| 1070 document().setNeedsStyleRecalc( | 976 document().setNeedsStyleRecalc( |
| 1071 SubtreeStyleChange, StyleChangeReasonForTracing::create( | 977 SubtreeStyleChange, StyleChangeReasonForTracing::create( |
| 1072 StyleChangeReason::ActiveStylesheetsUpdate)); | 978 StyleChangeReason::ActiveStylesheetsUpdate)); |
| 1073 } | 979 } |
| 1074 } | 980 } |
| 1075 | 981 |
| 1076 PassRefPtr<ComputedStyle> StyleEngine::findSharedStyle( | 982 PassRefPtr<ComputedStyle> StyleEngine::findSharedStyle( |
| 1077 const ElementResolveContext& elementResolveContext) { | 983 const ElementResolveContext& elementResolveContext) { |
| 1078 DCHECK(m_resolver); | 984 DCHECK(m_resolver); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1231 } | 1137 } |
| 1232 | 1138 |
| 1233 DEFINE_TRACE_WRAPPERS(StyleEngine) { | 1139 DEFINE_TRACE_WRAPPERS(StyleEngine) { |
| 1234 for (auto sheet : m_injectedAuthorStyleSheets) { | 1140 for (auto sheet : m_injectedAuthorStyleSheets) { |
| 1235 visitor->traceWrappers(sheet); | 1141 visitor->traceWrappers(sheet); |
| 1236 } | 1142 } |
| 1237 visitor->traceWrappers(m_documentStyleSheetCollection); | 1143 visitor->traceWrappers(m_documentStyleSheetCollection); |
| 1238 } | 1144 } |
| 1239 | 1145 |
| 1240 } // namespace blink | 1146 } // namespace blink |
| OLD | NEW |