static void notifyDescendantInsertedIntoTree(ContainerNode& insertionPoint, ContainerNode& node, NodeVector& postInsertionNotificationTargets) { for (Node* child = node.firstChild(); child; child = child->nextSibling()) { if (is<ContainerNode>(*child)) notifyNodeInsertedIntoTree(insertionPoint, downcast<ContainerNode>(*child), postInsertionNotificationTargets); } if (ShadowRoot* root = node.shadowRoot()) notifyNodeInsertedIntoTree(insertionPoint, *root, postInsertionNotificationTargets); }
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)); }
EventPath::EventPath(Node& originalTarget, Event& event) : m_event(event) { bool isMouseOrFocusEvent = event.isMouseEvent() || event.isFocusEvent(); #if ENABLE(TOUCH_EVENTS) bool isTouchEvent = event.isTouchEvent(); #endif Node* node = nodeOrHostIfPseudoElement(&originalTarget); Node* target = node ? eventTargetRespectingTargetRules(*node) : nullptr; while (node) { while (node) { EventTarget* currentTarget = eventTargetRespectingTargetRules(*node); if (isMouseOrFocusEvent) m_path.append(std::make_unique<MouseOrFocusEventContext>(node, currentTarget, target)); #if ENABLE(TOUCH_EVENTS) else if (isTouchEvent) m_path.append(std::make_unique<TouchEventContext>(node, currentTarget, target)); #endif else m_path.append(std::make_unique<EventContext>(node, currentTarget, target)); if (is<ShadowRoot>(*node)) break; ContainerNode* parent = node->parentNode(); if (!parent) return; #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) if (ShadowRoot* shadowRootOfParent = parent->shadowRoot()) { if (auto* assignedSlot = shadowRootOfParent->findAssignedSlot(*node)) { // node is assigned to a slot. Continue dispatching the event at this slot. parent = assignedSlot; } } #endif node = parent; } bool exitingShadowTreeOfTarget = &target->treeScope() == &node->treeScope(); ShadowRoot& shadowRoot = downcast<ShadowRoot>(*node); if (!shouldEventCrossShadowBoundary(event, shadowRoot, originalTarget)) return; node = shadowRoot.host(); if (exitingShadowTreeOfTarget) target = eventTargetRespectingTargetRules(*node); } }
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)); }
EventPath::EventPath(Node& originalTarget, Event& event) : m_event(event) { #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) Vector<EventTarget*, 16> targetStack; #endif bool isMouseOrFocusEvent = event.isMouseEvent() || event.isFocusEvent(); #if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS) bool isTouchEvent = event.isTouchEvent(); #endif EventTarget* target = nullptr; Node* node = nodeOrHostIfPseudoElement(&originalTarget); while (node) { if (!target) target = eventTargetRespectingTargetRules(*node); ContainerNode* parent; for (; node; node = parent) { EventTarget* currentTarget = eventTargetRespectingTargetRules(*node); if (isMouseOrFocusEvent) m_path.append(std::make_unique<MouseOrFocusEventContext>(node, currentTarget, target)); #if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS) else if (isTouchEvent) m_path.append(std::make_unique<TouchEventContext>(node, currentTarget, target)); #endif else m_path.append(std::make_unique<EventContext>(node, currentTarget, target)); if (is<ShadowRoot>(*node)) break; parent = node->parentNode(); if (!parent) return; #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) if (ShadowRoot* shadowRootOfParent = parent->shadowRoot()) { if (auto* assignedSlot = shadowRootOfParent->findAssignedSlot(*node)) { // node is assigned to a slot. Continue dispatching the event at this slot. targetStack.append(target); parent = assignedSlot; target = assignedSlot; } } #endif node = parent; } ShadowRoot& shadowRoot = downcast<ShadowRoot>(*node); // At a shadow root. Continue dispatching the event at the shadow host. #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) if (!targetStack.isEmpty()) { // Move target back to a descendant of the shadow host if the event did not originate in this shadow tree or its inner shadow trees. target = targetStack.last(); targetStack.removeLast(); ASSERT(shadowRoot.host()->contains(target->toNode())); } else #endif target = nullptr; if (!shouldEventCrossShadowBoundary(event, shadowRoot, originalTarget)) return; node = shadowRoot.host(); } }
NodeRenderingContext::NodeRenderingContext(Node* node) : m_phase(AttachingNotInTree) , m_node(node) , m_parentNodeForRenderingAndStyle(0) , m_visualParentShadow(0) , m_insertionPoint(0) , m_style(0) , m_parentFlowRenderer(0) { ContainerNode* parent = m_node->parentOrHostNode(); if (!parent) return; if (parent->isShadowRoot() && toShadowRoot(parent)->isYoungest()) { m_phase = AttachingShadowChild; m_parentNodeForRenderingAndStyle = toShadowRoot(parent)->host(); return; } if (parent->isElementNode() || parent->isShadowRoot()) { if (parent->isElementNode()) m_visualParentShadow = toElement(parent)->shadow(); else if (parent->isShadowRoot()) m_visualParentShadow = toShadowRoot(parent)->owner(); if (m_visualParentShadow) { if ((m_insertionPoint = m_visualParentShadow->insertionPointFor(m_node))) { if (m_insertionPoint->shadowRoot()->isUsedForRendering()) { m_phase = AttachingDistributed; m_parentNodeForRenderingAndStyle = NodeRenderingContext(m_insertionPoint).parentNodeForRenderingAndStyle(); return; } } m_phase = AttachingNotDistributed; m_parentNodeForRenderingAndStyle = parent; return; } if (isShadowBoundary(parent)) { if (!parent->shadowRoot()->isUsedForRendering()) { m_phase = AttachingNotDistributed; m_parentNodeForRenderingAndStyle = parent; return; } if (toInsertionPoint(parent)->hasDistribution()) m_phase = AttachingNotFallbacked; else m_phase = AttachingFallbacked; if (toInsertionPoint(parent)->isActive()) m_parentNodeForRenderingAndStyle = NodeRenderingContext(parent).parentNodeForRenderingAndStyle(); else m_parentNodeForRenderingAndStyle = parent; return; } } m_phase = AttachingStraight; m_parentNodeForRenderingAndStyle = parent; }