ComposedTreeIterator::ComposedTreeIterator(ContainerNode& root, Node& current) : m_rootIsInShadowTree(root.isInShadowTree()) { ASSERT(!is<ShadowRoot>(root)); ASSERT(!is<ShadowRoot>(current)); bool mayNeedShadowStack = root.shadowRoot() || (¤t != &root && current.parentNode() != &root); if (mayNeedShadowStack) initializeContextStack(root, current); else m_contextStack.uncheckedAppend(Context(root, current)); }
void HTMLSlotElement::removedFrom(ContainerNode& insertionPoint) { // ContainerNode::removeBetween always sets the removed child's tree scope to Document's but InShadowRoot flag is unset in Node::removedFrom. // So if InShadowRoot flag is set but this element's tree scope is Document's, this element has just been removed from a shadow root. if (insertionPoint.isInShadowTree() && isInShadowTree() && &treeScope() == &document()) { auto* oldShadowRoot = insertionPoint.containingShadowRoot(); ASSERT(oldShadowRoot); oldShadowRoot->removeSlotElementByName(attributeWithoutSynchronization(nameAttr), *this); } HTMLElement::removedFrom(insertionPoint); }
HTMLSlotElement::InsertionNotificationRequest HTMLSlotElement::insertedInto(ContainerNode& insertionPoint) { auto insertionResult = HTMLElement::insertedInto(insertionPoint); ASSERT_UNUSED(insertionResult, insertionResult == InsertionDone); // This function could be called when this element's shadow root's host or its ancestor is inserted. // This element is new to the shadow tree (and its tree scope) only if the parent into which this element // or its ancestor is inserted belongs to the same tree scope as this element's. if (insertionPoint.isInShadowTree() && isInShadowTree() && &insertionPoint.treeScope() == &treeScope()) { if (auto shadowRoot = containingShadowRoot()) shadowRoot->addSlotElementByName(attributeWithoutSynchronization(nameAttr), *this); } return InsertionDone; }
static Node* determineScopingNodeForStyleScoped(HTMLStyleElement* ownerElement, StyleSheetContents* styleSheetContents) { ASSERT(ownerElement && ownerElement->isRegisteredAsScoped()); if (ownerElement->isInShadowTree()) { if (hasDistributedRule(styleSheetContents)) { ContainerNode* scope = ownerElement; do { scope = scope->containingShadowRoot()->shadowHost(); } while (scope->isInShadowTree()); return scope; } if (ownerElement->isRegisteredAsScoped()) return ownerElement->containingShadowRoot()->shadowHost(); } return ownerElement->isRegisteredInShadowRoot() ? ownerElement->containingShadowRoot()->shadowHost() : ownerElement->parentNode(); }
ComposedTreeIterator::ComposedTreeIterator(ContainerNode& root, FirstChildTag) : m_rootIsInShadowTree(root.isInShadowTree()) { ASSERT(!is<ShadowRoot>(root)); if (is<HTMLSlotElement>(root)) { auto& slot = downcast<HTMLSlotElement>(root); if (auto* assignedNodes = slot.assignedNodes()) { initializeContextStack(root, *assignedNodes->at(0)); return; } } if (auto* shadowRoot = root.shadowRoot()) { ElementAndTextDescendantIterator firstChild(*shadowRoot, ElementAndTextDescendantIterator::FirstChild); initializeContextStack(root, firstChild ? *firstChild : root); return; } m_contextStack.uncheckedAppend(Context(root, FirstChild)); }