void ScopedStyleResolver::matchHostRules(ElementRuleCollector& collector, bool includeEmptyRules) { if (m_atHostRules.isEmpty() || !m_scopingNode->isElementNode()) return; ElementShadow* shadow = toElement(m_scopingNode)->shadow(); if (!shadow) return; collector.clearMatchedRules(); collector.matchedResult().ranges.lastAuthorRule = collector.matchedResult().matchedProperties.size() - 1; // FIXME(99827): https://bugs.webkit.org/show_bug.cgi?id=99827 // add a new flag to ElementShadow and cache whether any @host @-rules are // applied to the element or not. So we can quickly exit this method // by using the flag. ShadowRoot* shadowRoot = shadow->youngestShadowRoot(); for (; shadowRoot; shadowRoot = shadowRoot->olderShadowRoot()) if (!ScopeContentDistribution::hasShadowElement(shadowRoot)) break; // All shadow roots have <shadow>. if (!shadowRoot) shadowRoot = shadow->oldestShadowRoot(); StyleResolver::RuleRange ruleRange = collector.matchedResult().ranges.authorRuleRange(); collector.setBehaviorAtBoundary(static_cast<SelectorChecker::BehaviorAtBoundary>(SelectorChecker::DoesNotCrossBoundary | SelectorChecker::ScopeContainsLastMatchedElement)); for (; shadowRoot; shadowRoot = shadowRoot->youngerShadowRoot()) { if (RuleSet* ruleSet = atHostRuleSetFor(shadowRoot)) collector.collectMatchingRules(MatchRequest(ruleSet, includeEmptyRules, m_scopingNode), ruleRange); } collector.sortAndTransferMatchedRules(); }
// FIXME: Move the following helper functions, authorShadowRootOf, firstWithinTraversingShadowTree, // nextTraversingShadowTree to the best place, e.g. NodeTraversal. static ShadowRoot* authorShadowRootOf(const ContainerNode& node) { if (!node.isElementNode() || !isShadowHost(&node)) return nullptr; ElementShadow* shadow = toElement(node).shadow(); ASSERT(shadow); for (ShadowRoot* shadowRoot = shadow->oldestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->youngerShadowRoot()) { if (shadowRoot->type() == ShadowRootType::OpenByDefault || shadowRoot->type() == ShadowRootType::Open) return shadowRoot; } return nullptr; }
// FIXME: Move the following helper functions, authorShadowRootOf, firstWithinTraversingShadowTree, // nextTraversingShadowTree to the best place, e.g. NodeTraversal. static ShadowRoot* authorShadowRootOf(const ContainerNode& node) { if (!node.isElementNode() || !isShadowHost(&node)) return 0; ElementShadow* shadow = toElement(node).shadow(); ASSERT(shadow); for (ShadowRoot* shadowRoot = shadow->oldestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->youngerShadowRoot()) { if (shadowRoot->type() == ShadowRoot::AuthorShadowRoot) return shadowRoot; } return 0; }
void InputType::destroyShadowSubtree() { ElementShadow* shadow = element()->shadow(); if (!shadow) return; ShadowRoot* root = shadow->oldestShadowRoot(); root->removeAllChildren(); // It's ok to clear contents of all other ShadowRoots because they must have // been created by TextFieldDecorationElement, and we don't allow adding // AuthorShadowRoot to HTMLInputElement. while ((root = root->youngerShadowRoot())) { root->removeAllChildren(); root->appendChild(HTMLShadowElement::create(shadowTag, element()->document())); } }