OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) | 3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) |
4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) | 4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) |
5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc.
All rights reserved. | 5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc.
All rights reserved. |
6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> | 6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> |
7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> | 7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> |
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
orchmobile.com/) | 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
orchmobile.com/) |
9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. | 9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. |
10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. | 10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 #include "core/css/resolver/AnimatedStyleBuilder.h" | 62 #include "core/css/resolver/AnimatedStyleBuilder.h" |
63 #include "core/css/resolver/CSSVariableResolver.h" | 63 #include "core/css/resolver/CSSVariableResolver.h" |
64 #include "core/css/resolver/MatchResult.h" | 64 #include "core/css/resolver/MatchResult.h" |
65 #include "core/css/resolver/MediaQueryResult.h" | 65 #include "core/css/resolver/MediaQueryResult.h" |
66 #include "core/css/resolver/ScopedStyleResolver.h" | 66 #include "core/css/resolver/ScopedStyleResolver.h" |
67 #include "core/css/resolver/SelectorFilterParentScope.h" | 67 #include "core/css/resolver/SelectorFilterParentScope.h" |
68 #include "core/css/resolver/SharedStyleFinder.h" | 68 #include "core/css/resolver/SharedStyleFinder.h" |
69 #include "core/css/resolver/StyleAdjuster.h" | 69 #include "core/css/resolver/StyleAdjuster.h" |
70 #include "core/css/resolver/StyleResolverState.h" | 70 #include "core/css/resolver/StyleResolverState.h" |
71 #include "core/css/resolver/StyleResolverStats.h" | 71 #include "core/css/resolver/StyleResolverStats.h" |
72 #include "core/css/resolver/ViewportStyleResolver.h" | |
73 #include "core/dom/CSSSelectorWatch.h" | 72 #include "core/dom/CSSSelectorWatch.h" |
74 #include "core/dom/FirstLetterPseudoElement.h" | 73 #include "core/dom/FirstLetterPseudoElement.h" |
75 #include "core/dom/NodeComputedStyle.h" | 74 #include "core/dom/NodeComputedStyle.h" |
76 #include "core/dom/StyleEngine.h" | 75 #include "core/dom/StyleEngine.h" |
77 #include "core/dom/Text.h" | 76 #include "core/dom/Text.h" |
78 #include "core/dom/shadow/ElementShadow.h" | 77 #include "core/dom/shadow/ElementShadow.h" |
79 #include "core/dom/shadow/ShadowRoot.h" | 78 #include "core/dom/shadow/ShadowRoot.h" |
80 #include "core/frame/FrameView.h" | 79 #include "core/frame/FrameView.h" |
81 #include "core/frame/LocalFrame.h" | 80 #include "core/frame/LocalFrame.h" |
82 #include "core/frame/Settings.h" | 81 #include "core/frame/Settings.h" |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 for (ShadowRoot* shadowRoot = &shadow->youngestShadowRoot(); shadowRoot; sha
dowRoot = shadowRoot->olderShadowRoot()) { | 164 for (ShadowRoot* shadowRoot = &shadow->youngestShadowRoot(); shadowRoot; sha
dowRoot = shadowRoot->olderShadowRoot()) { |
166 if (shadowRoot->numberOfStyles() > 0) { | 165 if (shadowRoot->numberOfStyles() > 0) { |
167 if (ScopedStyleResolver* resolver = shadowRoot->scopedStyleResolver(
)) | 166 if (ScopedStyleResolver* resolver = shadowRoot->scopedStyleResolver(
)) |
168 resolvers.append(resolver); | 167 resolvers.append(resolver); |
169 } | 168 } |
170 } | 169 } |
171 } | 170 } |
172 | 171 |
173 StyleResolver::StyleResolver(Document& document) | 172 StyleResolver::StyleResolver(Document& document) |
174 : m_document(document) | 173 : m_document(document) |
175 , m_viewportStyleResolver(ViewportStyleResolver::create(&document)) | |
176 , m_needCollectFeatures(false) | |
177 , m_printMediaType(false) | |
178 , m_styleSharingDepth(0) | |
179 { | 174 { |
180 FrameView* view = document.view(); | 175 if (FrameView* view = document.view()) |
181 if (view) { | |
182 m_medium = new MediaQueryEvaluator(&view->frame()); | |
183 m_printMediaType = equalIgnoringCase(view->mediaType(), MediaTypeNames::
print); | 176 m_printMediaType = equalIgnoringCase(view->mediaType(), MediaTypeNames::
print); |
184 } else { | |
185 m_medium = new MediaQueryEvaluator("all"); | |
186 } | |
187 | |
188 initWatchedSelectorRules(); | |
189 } | 177 } |
190 | 178 |
191 StyleResolver::~StyleResolver() | 179 StyleResolver::~StyleResolver() |
192 { | 180 { |
193 } | 181 } |
194 | 182 |
195 void StyleResolver::dispose() | 183 void StyleResolver::dispose() |
196 { | 184 { |
197 m_matchedPropertiesCache.clear(); | 185 m_matchedPropertiesCache.clear(); |
198 } | 186 } |
199 | 187 |
200 void StyleResolver::initWatchedSelectorRules() | |
201 { | |
202 m_watchedSelectorsRules = nullptr; | |
203 CSSSelectorWatch* watch = CSSSelectorWatch::fromIfExists(*m_document); | |
204 if (!watch) | |
205 return; | |
206 const HeapVector<Member<StyleRule>>& watchedSelectors = watch->watchedCallba
ckSelectors(); | |
207 if (!watchedSelectors.size()) | |
208 return; | |
209 m_watchedSelectorsRules = RuleSet::create(); | |
210 for (unsigned i = 0; i < watchedSelectors.size(); ++i) | |
211 m_watchedSelectorsRules->addStyleRule(watchedSelectors[i].get(), RuleHas
NoSpecialState); | |
212 } | |
213 | |
214 void StyleResolver::lazyAppendAuthorStyleSheets(unsigned firstNew, const HeapVec
tor<Member<CSSStyleSheet>>& styleSheets) | |
215 { | |
216 unsigned size = styleSheets.size(); | |
217 for (unsigned i = firstNew; i < size; ++i) | |
218 m_pendingStyleSheets.add(styleSheets[i].get()); | |
219 } | |
220 | |
221 void StyleResolver::removePendingAuthorStyleSheets(const HeapVector<Member<CSSSt
yleSheet>>& styleSheets) | |
222 { | |
223 for (unsigned i = 0; i < styleSheets.size(); ++i) | |
224 m_pendingStyleSheets.remove(styleSheets[i].get()); | |
225 } | |
226 | |
227 void StyleResolver::appendCSSStyleSheet(CSSStyleSheet& cssSheet) | |
228 { | |
229 ASSERT(!cssSheet.disabled()); | |
230 ASSERT(cssSheet.ownerDocument()); | |
231 ASSERT(cssSheet.ownerNode()); | |
232 ASSERT(isHTMLStyleElement(cssSheet.ownerNode()) || isSVGStyleElement(cssShee
t.ownerNode()) || cssSheet.ownerNode()->treeScope() == cssSheet.ownerDocument())
; | |
233 | |
234 if (cssSheet.mediaQueries() && !m_medium->eval(cssSheet.mediaQueries(), &m_v
iewportDependentMediaQueryResults, &m_deviceDependentMediaQueryResults)) | |
235 return; | |
236 | |
237 TreeScope* treeScope = &cssSheet.ownerNode()->treeScope(); | |
238 // TODO(rune@opera.com): This is a workaround for crbug.com/559292 | |
239 // when we're in the middle of removing a subtree with a style element | |
240 // and the treescope has been changed but inDocument and isInShadowTree | |
241 // are not. | |
242 // | |
243 // This check can be removed when crbug.com/567021 is fixed. | |
244 if (cssSheet.ownerNode()->isInShadowTree() && treeScope->rootNode().isDocume
ntNode()) | |
245 return; | |
246 | |
247 // Sheets in the document scope of HTML imports apply to the main document | |
248 // (m_document), so we override it for all document scoped sheets. | |
249 if (treeScope->rootNode().isDocumentNode()) | |
250 treeScope = m_document; | |
251 treeScope->ensureScopedStyleResolver().appendCSSStyleSheet(cssSheet, *m_medi
um); | |
252 } | |
253 | |
254 void StyleResolver::appendPendingAuthorStyleSheets() | |
255 { | |
256 for (const auto& styleSheet : m_pendingStyleSheets) | |
257 appendCSSStyleSheet(*styleSheet); | |
258 | |
259 m_pendingStyleSheets.clear(); | |
260 finishAppendAuthorStyleSheets(); | |
261 } | |
262 | |
263 void StyleResolver::appendAuthorStyleSheets(const HeapVector<Member<CSSStyleShee
t>>& styleSheets) | |
264 { | |
265 // This handles sheets added to the end of the stylesheet list only. In othe
r cases the style resolver | |
266 // needs to be reconstructed. To handle insertions too the rule order number
s would need to be updated. | |
267 for (const auto& styleSheet : styleSheets) | |
268 appendCSSStyleSheet(*styleSheet); | |
269 } | |
270 | |
271 void StyleResolver::finishAppendAuthorStyleSheets() | |
272 { | |
273 collectFeatures(); | |
274 | |
275 if (document().layoutView() && document().layoutView()->style()) | |
276 document().layoutView()->style()->font().update(document().styleEngine()
.fontSelector()); | |
277 | |
278 m_viewportStyleResolver->collectViewportRules(); | |
279 | |
280 document().styleEngine().resetCSSFeatureFlags(m_features); | |
281 } | |
282 | |
283 void StyleResolver::resetRuleFeatures() | |
284 { | |
285 // Need to recreate RuleFeatureSet. | |
286 m_features.clear(); | |
287 m_siblingRuleSet.clear(); | |
288 m_uncommonAttributeRuleSet.clear(); | |
289 m_needCollectFeatures = true; | |
290 } | |
291 | |
292 void StyleResolver::addTreeBoundaryCrossingScope(ContainerNode& scope) | |
293 { | |
294 m_treeBoundaryCrossingScopes.add(&scope); | |
295 } | |
296 | |
297 void StyleResolver::resetAuthorStyle(TreeScope& treeScope) | |
298 { | |
299 m_treeBoundaryCrossingScopes.remove(&treeScope.rootNode()); | |
300 | |
301 ScopedStyleResolver* resolver = treeScope.scopedStyleResolver(); | |
302 if (!resolver) | |
303 return; | |
304 | |
305 resetRuleFeatures(); | |
306 | |
307 if (treeScope.rootNode().isDocumentNode()) { | |
308 resolver->resetAuthorStyle(); | |
309 return; | |
310 } | |
311 | |
312 // resolver is going to be freed below. | |
313 treeScope.clearScopedStyleResolver(); | |
314 } | |
315 | |
316 static RuleSet* makeRuleSet(const HeapVector<RuleFeature>& rules) | |
317 { | |
318 size_t size = rules.size(); | |
319 if (!size) | |
320 return nullptr; | |
321 RuleSet* ruleSet = RuleSet::create(); | |
322 for (size_t i = 0; i < size; ++i) | |
323 ruleSet->addRule(rules[i].rule, rules[i].selectorIndex, rules[i].hasDocu
mentSecurityOrigin ? RuleHasDocumentSecurityOrigin : RuleHasNoSpecialState); | |
324 return ruleSet; | |
325 } | |
326 | |
327 void StyleResolver::collectFeatures() | |
328 { | |
329 m_features.clear(); | |
330 // Collect all ids and rules using sibling selectors (:first-child and simil
ar) | |
331 // in the current set of stylesheets. Style sharing code uses this informati
on to reject | |
332 // sharing candidates. | |
333 CSSDefaultStyleSheets& defaultStyleSheets = CSSDefaultStyleSheets::instance(
); | |
334 if (defaultStyleSheets.defaultStyle()) { | |
335 m_features.add(defaultStyleSheets.defaultStyle()->features()); | |
336 m_hasFullscreenUAStyle = defaultStyleSheets.fullscreenStyleSheet(); | |
337 } | |
338 | |
339 if (document().isViewSource()) | |
340 m_features.add(defaultStyleSheets.defaultViewSourceStyle()->features()); | |
341 | |
342 if (m_watchedSelectorsRules) | |
343 m_features.add(m_watchedSelectorsRules->features()); | |
344 | |
345 document().styleEngine().collectScopedStyleFeaturesTo(m_features); | |
346 | |
347 m_siblingRuleSet = makeRuleSet(m_features.siblingRules); | |
348 m_uncommonAttributeRuleSet = makeRuleSet(m_features.uncommonAttributeRules); | |
349 m_needCollectFeatures = false; | |
350 } | |
351 | |
352 bool StyleResolver::hasRulesForId(const AtomicString& id) const | |
353 { | |
354 return m_features.hasSelectorForId(id); | |
355 } | |
356 | |
357 void StyleResolver::addToStyleSharingList(Element& element) | 188 void StyleResolver::addToStyleSharingList(Element& element) |
358 { | 189 { |
359 ASSERT(RuntimeEnabledFeatures::styleSharingEnabled()); | 190 ASSERT(RuntimeEnabledFeatures::styleSharingEnabled()); |
360 // Never add elements to the style sharing list if we're not in a recalcStyl
e, | 191 // Never add elements to the style sharing list if we're not in a recalcStyl
e, |
361 // otherwise we could leave stale pointers in there. | 192 // otherwise we could leave stale pointers in there. |
362 if (!document().inStyleRecalc()) | 193 if (!document().inStyleRecalc()) |
363 return; | 194 return; |
364 INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), sharedStyleCandidate
s, 1); | 195 INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), sharedStyleCandidate
s, 1); |
365 StyleSharingList& list = styleSharingList(); | 196 StyleSharingList& list = styleSharingList(); |
366 if (list.size() >= styleSharingListSize) | 197 if (list.size() >= styleSharingListSize) |
(...skipping 16 matching lines...) Expand all Loading... |
383 | 214 |
384 void StyleResolver::clearStyleSharingList() | 215 void StyleResolver::clearStyleSharingList() |
385 { | 216 { |
386 m_styleSharingLists.resize(0); | 217 m_styleSharingLists.resize(0); |
387 } | 218 } |
388 | 219 |
389 static inline ScopedStyleResolver* scopedResolverFor(const Element& element) | 220 static inline ScopedStyleResolver* scopedResolverFor(const Element& element) |
390 { | 221 { |
391 // Ideally, returning element->treeScope().scopedStyleResolver() should be | 222 // Ideally, returning element->treeScope().scopedStyleResolver() should be |
392 // enough, but ::cue and custom pseudo elements like ::-webkit-meter-bar pie
rce | 223 // enough, but ::cue and custom pseudo elements like ::-webkit-meter-bar pie
rce |
393 // through a shadow dom boundary, yet they are not part of m_treeBoundaryCro
ssingScopes. | 224 // through a shadow dom boundary, yet they are not part of treeBoundaryCross
ingScopes. |
394 // The assumption here is that these rules only pierce through one boundary
and | 225 // The assumption here is that these rules only pierce through one boundary
and |
395 // that the scope of these elements do not have a style resolver due to the
fact | 226 // that the scope of these elements do not have a style resolver due to the
fact |
396 // that VTT scopes and UA shadow trees don't have <style> elements. This is | 227 // that VTT scopes and UA shadow trees don't have <style> elements. This is |
397 // backed up by the ASSERTs below. | 228 // backed up by the ASSERTs below. |
398 // | 229 // |
399 // FIXME: Make ::cue and custom pseudo elements part of boundary crossing ru
les | 230 // FIXME: Make ::cue and custom pseudo elements part of boundary crossing ru
les |
400 // when moving those rules to ScopedStyleResolver as part of issue 401359. | 231 // when moving those rules to ScopedStyleResolver as part of issue 401359. |
401 | 232 |
402 TreeScope* treeScope = &element.treeScope(); | 233 TreeScope* treeScope = &element.treeScope(); |
403 if (ScopedStyleResolver* resolver = treeScope->scopedStyleResolver()) { | 234 if (ScopedStyleResolver* resolver = treeScope->scopedStyleResolver()) { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 ScopedStyleResolver* elementScopeResolver = scopedResolverFor(element); | 335 ScopedStyleResolver* elementScopeResolver = scopedResolverFor(element); |
505 | 336 |
506 if (!document().mayContainV0Shadow()) { | 337 if (!document().mayContainV0Shadow()) { |
507 matchSlottedRules(element, collector); | 338 matchSlottedRules(element, collector); |
508 matchElementScopeRules(element, elementScopeResolver, collector); | 339 matchElementScopeRules(element, elementScopeResolver, collector); |
509 return; | 340 return; |
510 } | 341 } |
511 | 342 |
512 bool matchElementScopeDone = !elementScopeResolver && !element.inlineStyle()
; | 343 bool matchElementScopeDone = !elementScopeResolver && !element.inlineStyle()
; |
513 | 344 |
514 for (auto it = m_treeBoundaryCrossingScopes.rbegin(); it != m_treeBoundaryCr
ossingScopes.rend(); ++it) { | 345 const auto& treeBoundaryCrossingScopes = document().styleEngine().treeBounda
ryCrossingScopes(); |
| 346 for (auto it = treeBoundaryCrossingScopes.rbegin(); it != treeBoundaryCrossi
ngScopes.rend(); ++it) { |
515 const TreeScope& scope = (*it)->treeScope(); | 347 const TreeScope& scope = (*it)->treeScope(); |
516 ScopedStyleResolver* resolver = scope.scopedStyleResolver(); | 348 ScopedStyleResolver* resolver = scope.scopedStyleResolver(); |
517 ASSERT(resolver); | 349 ASSERT(resolver); |
518 | 350 |
519 bool isInnerTreeScope = element.treeScope().isInclusiveAncestorOf(scope)
; | 351 bool isInnerTreeScope = element.treeScope().isInclusiveAncestorOf(scope)
; |
520 if (!shouldCheckScope(element, **it, isInnerTreeScope)) | 352 if (!shouldCheckScope(element, **it, isInnerTreeScope)) |
521 continue; | 353 continue; |
522 | 354 |
523 if (!matchElementScopeDone && scope.isInclusiveAncestorOf(element.treeSc
ope())) { | 355 if (!matchElementScopeDone && scope.isInclusiveAncestorOf(element.treeSc
ope())) { |
524 | 356 |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
642 // Now check SMIL animation override style. | 474 // Now check SMIL animation override style. |
643 if (includeSMILProperties && state.element()->isSVGElement()) | 475 if (includeSMILProperties && state.element()->isSVGElement()) |
644 collector.addElementStyleProperties(toSVGElement(state.element())->a
nimatedSMILStyleProperties(), false /* isCacheable */); | 476 collector.addElementStyleProperties(toSVGElement(state.element())->a
nimatedSMILStyleProperties(), false /* isCacheable */); |
645 } | 477 } |
646 | 478 |
647 collector.finishAddingAuthorRulesForTreeScope(); | 479 collector.finishAddingAuthorRulesForTreeScope(); |
648 } | 480 } |
649 | 481 |
650 void StyleResolver::collectTreeBoundaryCrossingRules(const Element& element, Ele
mentRuleCollector& collector) | 482 void StyleResolver::collectTreeBoundaryCrossingRules(const Element& element, Ele
mentRuleCollector& collector) |
651 { | 483 { |
652 if (m_treeBoundaryCrossingScopes.isEmpty()) | 484 const auto& treeBoundaryCrossingScopes = document().styleEngine().treeBounda
ryCrossingScopes(); |
| 485 if (treeBoundaryCrossingScopes.isEmpty()) |
653 return; | 486 return; |
654 | 487 |
655 // When comparing rules declared in outer treescopes, outer's rules win. | 488 // When comparing rules declared in outer treescopes, outer's rules win. |
656 CascadeOrder outerCascadeOrder = m_treeBoundaryCrossingScopes.size() * 2; | 489 CascadeOrder outerCascadeOrder = treeBoundaryCrossingScopes.size() * 2; |
657 // When comparing rules declared in inner treescopes, inner's rules win. | 490 // When comparing rules declared in inner treescopes, inner's rules win. |
658 CascadeOrder innerCascadeOrder = m_treeBoundaryCrossingScopes.size(); | 491 CascadeOrder innerCascadeOrder = treeBoundaryCrossingScopes.size(); |
659 | 492 |
660 for (const auto& scopingNode : m_treeBoundaryCrossingScopes) { | 493 for (const auto& scopingNode : treeBoundaryCrossingScopes) { |
661 // Skip rule collection for element when tree boundary crossing rules of
scopingNode's | 494 // Skip rule collection for element when tree boundary crossing rules of
scopingNode's |
662 // scope can never apply to it. | 495 // scope can never apply to it. |
663 bool isInnerTreeScope = element.treeScope().isInclusiveAncestorOf(scopin
gNode->treeScope()); | 496 bool isInnerTreeScope = element.treeScope().isInclusiveAncestorOf(scopin
gNode->treeScope()); |
664 if (!shouldCheckScope(element, *scopingNode, isInnerTreeScope)) | 497 if (!shouldCheckScope(element, *scopingNode, isInnerTreeScope)) |
665 continue; | 498 continue; |
666 | 499 |
667 CascadeOrder cascadeOrder = isInnerTreeScope ? innerCascadeOrder : outer
CascadeOrder; | 500 CascadeOrder cascadeOrder = isInnerTreeScope ? innerCascadeOrder : outer
CascadeOrder; |
668 scopingNode->treeScope().scopedStyleResolver()->collectMatchingTreeBound
aryCrossingRules(collector, cascadeOrder); | 501 scopingNode->treeScope().scopedStyleResolver()->collectMatchingTreeBound
aryCrossingRules(collector, cascadeOrder); |
669 | 502 |
670 ++innerCascadeOrder; | 503 ++innerCascadeOrder; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 void StyleResolver::loadPendingResources(StyleResolverState& state) | 538 void StyleResolver::loadPendingResources(StyleResolverState& state) |
706 { | 539 { |
707 state.elementStyleResources().loadPendingResources(state.style()); | 540 state.elementStyleResources().loadPendingResources(state.style()); |
708 } | 541 } |
709 | 542 |
710 PassRefPtr<ComputedStyle> StyleResolver::styleForElement(Element* element, const
ComputedStyle* defaultParent, StyleSharingBehavior sharingBehavior, | 543 PassRefPtr<ComputedStyle> StyleResolver::styleForElement(Element* element, const
ComputedStyle* defaultParent, StyleSharingBehavior sharingBehavior, |
711 RuleMatchingBehavior matchingBehavior) | 544 RuleMatchingBehavior matchingBehavior) |
712 { | 545 { |
713 ASSERT(document().frame()); | 546 ASSERT(document().frame()); |
714 ASSERT(document().settings()); | 547 ASSERT(document().settings()); |
715 ASSERT(!hasPendingAuthorStyleSheets()); | |
716 ASSERT(!m_needCollectFeatures); | |
717 | 548 |
718 // Once an element has a layoutObject, we don't try to destroy it, since oth
erwise the layoutObject | 549 // Once an element has a layoutObject, we don't try to destroy it, since oth
erwise the layoutObject |
719 // will vanish if a style recalc happens during loading. | 550 // will vanish if a style recalc happens during loading. |
720 if (sharingBehavior == AllowStyleSharing && !document().isRenderingReady() &
& !element->layoutObject()) { | 551 if (sharingBehavior == AllowStyleSharing && !document().isRenderingReady() &
& !element->layoutObject()) { |
721 if (!s_styleNotYetAvailable) { | 552 if (!s_styleNotYetAvailable) { |
722 s_styleNotYetAvailable = ComputedStyle::create().leakRef(); | 553 s_styleNotYetAvailable = ComputedStyle::create().leakRef(); |
723 s_styleNotYetAvailable->setDisplay(NONE); | 554 s_styleNotYetAvailable->setDisplay(NONE); |
724 s_styleNotYetAvailable->font().update(document().styleEngine().fontS
elector()); | 555 s_styleNotYetAvailable->font().update(document().styleEngine().fontS
elector()); |
725 } | 556 } |
726 | 557 |
727 document().setHasNodesWithPlaceholderStyle(); | 558 document().setHasNodesWithPlaceholderStyle(); |
728 return s_styleNotYetAvailable; | 559 return s_styleNotYetAvailable; |
729 } | 560 } |
730 | 561 |
731 document().styleEngine().incStyleForElementCount(); | 562 document().styleEngine().incStyleForElementCount(); |
732 INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), elementsStyled, 1); | 563 INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), elementsStyled, 1); |
733 | 564 |
734 SelectorFilterParentScope::ensureParentStackIsPushed(); | 565 SelectorFilterParentScope::ensureParentStackIsPushed(); |
735 | 566 |
736 ElementResolveContext elementContext(*element); | 567 ElementResolveContext elementContext(*element); |
737 | 568 |
738 if (RuntimeEnabledFeatures::styleSharingEnabled() && sharingBehavior == Allo
wStyleSharing && (defaultParent || elementContext.parentStyle())) { | 569 if (RuntimeEnabledFeatures::styleSharingEnabled() && sharingBehavior == Allo
wStyleSharing && (defaultParent || elementContext.parentStyle())) { |
739 SharedStyleFinder styleFinder(elementContext, m_features, m_siblingRuleS
et.get(), m_uncommonAttributeRuleSet.get(), *this); | 570 if (RefPtr<ComputedStyle> sharedStyle = document().styleEngine().findSha
redStyle(elementContext)) |
740 if (RefPtr<ComputedStyle> sharedStyle = styleFinder.findSharedStyle()) | |
741 return sharedStyle.release(); | 571 return sharedStyle.release(); |
742 } | 572 } |
743 | 573 |
744 StyleResolverState state(document(), elementContext, defaultParent); | 574 StyleResolverState state(document(), elementContext, defaultParent); |
745 | 575 |
746 ElementAnimations* elementAnimations = element->elementAnimations(); | 576 ElementAnimations* elementAnimations = element->elementAnimations(); |
747 const ComputedStyle* baseComputedStyle = elementAnimations ? elementAnimatio
ns->baseComputedStyle() : nullptr; | 577 const ComputedStyle* baseComputedStyle = elementAnimations ? elementAnimatio
ns->baseComputedStyle() : nullptr; |
748 | 578 |
749 if (baseComputedStyle) { | 579 if (baseComputedStyle) { |
750 state.setStyle(ComputedStyle::clone(*baseComputedStyle)); | 580 state.setStyle(ComputedStyle::clone(*baseComputedStyle)); |
(...skipping 25 matching lines...) Expand all Loading... |
776 if (linkState != NotInsideLink) { | 606 if (linkState != NotInsideLink) { |
777 bool forceVisited = InspectorInstrumentation::forcePseudoState(eleme
nt, CSSSelector::PseudoVisited); | 607 bool forceVisited = InspectorInstrumentation::forcePseudoState(eleme
nt, CSSSelector::PseudoVisited); |
778 if (forceVisited) | 608 if (forceVisited) |
779 linkState = InsideVisitedLink; | 609 linkState = InsideVisitedLink; |
780 } | 610 } |
781 state.style()->setInsideLink(linkState); | 611 state.style()->setInsideLink(linkState); |
782 } | 612 } |
783 | 613 |
784 if (!baseComputedStyle) { | 614 if (!baseComputedStyle) { |
785 | 615 |
786 bool needsCollection = false; | 616 document().styleEngine().ensureUAStyleForElement(*element); |
787 CSSDefaultStyleSheets::instance().ensureDefaultStyleSheetsForElement(*el
ement, needsCollection); | |
788 if (needsCollection) | |
789 collectFeatures(); | |
790 | 617 |
791 ElementRuleCollector collector(state.elementContext(), m_selectorFilter,
state.style()); | 618 ElementRuleCollector collector(state.elementContext(), m_selectorFilter,
state.style()); |
792 | 619 |
793 matchAllRules(state, collector, matchingBehavior != MatchAllRulesExcludi
ngSMIL); | 620 matchAllRules(state, collector, matchingBehavior != MatchAllRulesExcludi
ngSMIL); |
794 | 621 |
795 if (element->computedStyle() && element->computedStyle()->textAutosizing
Multiplier() != state.style()->textAutosizingMultiplier()) { | 622 if (element->computedStyle() && element->computedStyle()->textAutosizing
Multiplier() != state.style()->textAutosizingMultiplier()) { |
796 // Preserve the text autosizing multiplier on style recalc. Autosize
r will update it during layout if needed. | 623 // Preserve the text autosizing multiplier on style recalc. Autosize
r will update it during layout if needed. |
797 // NOTE: this must occur before applyMatchedProperties for correct c
omputation of font-relative lengths. | 624 // NOTE: this must occur before applyMatchedProperties for correct c
omputation of font-relative lengths. |
798 state.style()->setTextAutosizingMultiplier(element->computedStyle()-
>textAutosizingMultiplier()); | 625 state.style()->setTextAutosizingMultiplier(element->computedStyle()-
>textAutosizingMultiplier()); |
799 state.style()->setUnique(); | 626 state.style()->setUnique(); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
995 | 822 |
996 if (PseudoElement* pseudoElement = element->pseudoElement(pseudoStyleRequest
.pseudoId)) | 823 if (PseudoElement* pseudoElement = element->pseudoElement(pseudoStyleRequest
.pseudoId)) |
997 setAnimationUpdateIfNeeded(state, *pseudoElement); | 824 setAnimationUpdateIfNeeded(state, *pseudoElement); |
998 | 825 |
999 // Now return the style. | 826 // Now return the style. |
1000 return state.takeStyle(); | 827 return state.takeStyle(); |
1001 } | 828 } |
1002 | 829 |
1003 PassRefPtr<ComputedStyle> StyleResolver::styleForPage(int pageIndex) | 830 PassRefPtr<ComputedStyle> StyleResolver::styleForPage(int pageIndex) |
1004 { | 831 { |
1005 ASSERT(!hasPendingAuthorStyleSheets()); | |
1006 StyleResolverState state(document(), document().documentElement()); // m_roo
tElementStyle will be set to the document style. | 832 StyleResolverState state(document(), document().documentElement()); // m_roo
tElementStyle will be set to the document style. |
1007 | 833 |
1008 RefPtr<ComputedStyle> style = ComputedStyle::create(); | 834 RefPtr<ComputedStyle> style = ComputedStyle::create(); |
1009 const ComputedStyle* rootElementStyle = state.rootElementStyle() ? state.roo
tElementStyle() : document().computedStyle(); | 835 const ComputedStyle* rootElementStyle = state.rootElementStyle() ? state.roo
tElementStyle() : document().computedStyle(); |
1010 ASSERT(rootElementStyle); | 836 ASSERT(rootElementStyle); |
1011 style->inheritFrom(*rootElementStyle); | 837 style->inheritFrom(*rootElementStyle); |
1012 state.setStyle(style.release()); | 838 state.setStyle(style.release()); |
1013 | 839 |
1014 PageRuleCollector collector(rootElementStyle, pageIndex); | 840 PageRuleCollector collector(rootElementStyle, pageIndex); |
1015 | 841 |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1500 return StringHasher::hashMemory(properties, sizeof(MatchedProperties) * size
); | 1326 return StringHasher::hashMemory(properties, sizeof(MatchedProperties) * size
); |
1501 } | 1327 } |
1502 | 1328 |
1503 void StyleResolver::invalidateMatchedPropertiesCache() | 1329 void StyleResolver::invalidateMatchedPropertiesCache() |
1504 { | 1330 { |
1505 m_matchedPropertiesCache.clear(); | 1331 m_matchedPropertiesCache.clear(); |
1506 } | 1332 } |
1507 | 1333 |
1508 void StyleResolver::notifyResizeForViewportUnits() | 1334 void StyleResolver::notifyResizeForViewportUnits() |
1509 { | 1335 { |
1510 m_viewportStyleResolver->collectViewportRules(); | 1336 document().styleEngine().updateActiveStyle(); |
1511 m_matchedPropertiesCache.clearViewportDependent(); | 1337 m_matchedPropertiesCache.clearViewportDependent(); |
1512 } | 1338 } |
1513 | 1339 |
1514 void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc
hResult& matchResult) | 1340 void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc
hResult& matchResult) |
1515 { | 1341 { |
1516 const Element* element = state.element(); | 1342 const Element* element = state.element(); |
1517 ASSERT(element); | 1343 ASSERT(element); |
1518 | 1344 |
1519 INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), matchedPropertyApply
, 1); | 1345 INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), matchedPropertyApply
, 1); |
1520 | 1346 |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1645 } | 1471 } |
1646 | 1472 |
1647 bool StyleResolver::hasAuthorBorder(const StyleResolverState& state) | 1473 bool StyleResolver::hasAuthorBorder(const StyleResolverState& state) |
1648 { | 1474 { |
1649 const CachedUAStyle* cachedUAStyle = state.cachedUAStyle(); | 1475 const CachedUAStyle* cachedUAStyle = state.cachedUAStyle(); |
1650 return cachedUAStyle && (cachedUAStyle->border != state.style()->border()); | 1476 return cachedUAStyle && (cachedUAStyle->border != state.style()->border()); |
1651 } | 1477 } |
1652 | 1478 |
1653 void StyleResolver::applyCallbackSelectors(StyleResolverState& state) | 1479 void StyleResolver::applyCallbackSelectors(StyleResolverState& state) |
1654 { | 1480 { |
1655 if (!m_watchedSelectorsRules) | 1481 RuleSet* watchedSelectorsRuleSet = document().styleEngine().watchedSelectors
RuleSet(); |
| 1482 if (!watchedSelectorsRuleSet) |
1656 return; | 1483 return; |
1657 | 1484 |
1658 ElementRuleCollector collector(state.elementContext(), m_selectorFilter, sta
te.style()); | 1485 ElementRuleCollector collector(state.elementContext(), m_selectorFilter, sta
te.style()); |
1659 collector.setMode(SelectorChecker::CollectingStyleRules); | 1486 collector.setMode(SelectorChecker::CollectingStyleRules); |
1660 collector.setIncludeEmptyRules(true); | 1487 collector.setIncludeEmptyRules(true); |
1661 | 1488 |
1662 MatchRequest matchRequest(m_watchedSelectorsRules.get()); | 1489 MatchRequest matchRequest(watchedSelectorsRuleSet); |
1663 collector.collectMatchingRules(matchRequest); | 1490 collector.collectMatchingRules(matchRequest); |
1664 collector.sortAndTransferMatchedRules(); | 1491 collector.sortAndTransferMatchedRules(); |
1665 | 1492 |
1666 StyleRuleList* rules = collector.matchedStyleRuleList(); | 1493 StyleRuleList* rules = collector.matchedStyleRuleList(); |
1667 if (!rules) | 1494 if (!rules) |
1668 return; | 1495 return; |
1669 for (size_t i = 0; i < rules->size(); i++) | 1496 for (size_t i = 0; i < rules->size(); i++) |
1670 state.style()->addCallbackSelector(rules->at(i)->selectorList().selector
sText()); | 1497 state.style()->addCallbackSelector(rules->at(i)->selectorList().selector
sText()); |
1671 } | 1498 } |
1672 | 1499 |
(...skipping 13 matching lines...) Expand all Loading... |
1686 StyleResolverState state(document(), nullptr, style); | 1513 StyleResolverState state(document(), nullptr, style); |
1687 state.setStyle(style); | 1514 state.setStyle(style); |
1688 | 1515 |
1689 for (CSSPropertyID property : properties) { | 1516 for (CSSPropertyID property : properties) { |
1690 if (property == CSSPropertyLineHeight) | 1517 if (property == CSSPropertyLineHeight) |
1691 updateFont(state); | 1518 updateFont(state); |
1692 StyleBuilder::applyProperty(property, state, propertySet.getPropertyCSSV
alue(property)); | 1519 StyleBuilder::applyProperty(property, state, propertySet.getPropertyCSSV
alue(property)); |
1693 } | 1520 } |
1694 } | 1521 } |
1695 | 1522 |
1696 void StyleResolver::addViewportDependentMediaQueries(const MediaQueryResultList&
list) | |
1697 { | |
1698 for (size_t i = 0; i < list.size(); ++i) | |
1699 m_viewportDependentMediaQueryResults.append(list[i]); | |
1700 } | |
1701 | |
1702 void StyleResolver::addDeviceDependentMediaQueries(const MediaQueryResultList& l
ist) | |
1703 { | |
1704 for (size_t i = 0; i < list.size(); ++i) | |
1705 m_deviceDependentMediaQueryResults.append(list[i]); | |
1706 } | |
1707 | |
1708 bool StyleResolver::mediaQueryAffectedByViewportChange() const | |
1709 { | |
1710 for (unsigned i = 0; i < m_viewportDependentMediaQueryResults.size(); ++i) { | |
1711 if (m_medium->eval(m_viewportDependentMediaQueryResults[i]->expression()
) != m_viewportDependentMediaQueryResults[i]->result()) | |
1712 return true; | |
1713 } | |
1714 return false; | |
1715 } | |
1716 | |
1717 bool StyleResolver::mediaQueryAffectedByDeviceChange() const | |
1718 { | |
1719 for (unsigned i = 0; i < m_deviceDependentMediaQueryResults.size(); ++i) { | |
1720 if (m_medium->eval(m_deviceDependentMediaQueryResults[i]->expression())
!= m_deviceDependentMediaQueryResults[i]->result()) | |
1721 return true; | |
1722 } | |
1723 return false; | |
1724 } | |
1725 | |
1726 DEFINE_TRACE(StyleResolver) | 1523 DEFINE_TRACE(StyleResolver) |
1727 { | 1524 { |
1728 visitor->trace(m_matchedPropertiesCache); | 1525 visitor->trace(m_matchedPropertiesCache); |
1729 visitor->trace(m_medium); | |
1730 visitor->trace(m_viewportDependentMediaQueryResults); | |
1731 visitor->trace(m_deviceDependentMediaQueryResults); | |
1732 visitor->trace(m_selectorFilter); | 1526 visitor->trace(m_selectorFilter); |
1733 visitor->trace(m_viewportStyleResolver); | |
1734 visitor->trace(m_features); | |
1735 visitor->trace(m_siblingRuleSet); | |
1736 visitor->trace(m_uncommonAttributeRuleSet); | |
1737 visitor->trace(m_watchedSelectorsRules); | |
1738 visitor->trace(m_treeBoundaryCrossingScopes); | |
1739 visitor->trace(m_styleSharingLists); | 1527 visitor->trace(m_styleSharingLists); |
1740 visitor->trace(m_pendingStyleSheets); | |
1741 visitor->trace(m_document); | 1528 visitor->trace(m_document); |
1742 } | 1529 } |
1743 | 1530 |
1744 } // namespace blink | 1531 } // namespace blink |
OLD | NEW |