Exemplo n.º 1
0
EventPath::EventPath(Node& targetNode, Event& event)
{
    bool inDocument = targetNode.inDocument();
    bool isSVGElement = targetNode.isSVGElement();
    bool isMouseOrFocusEvent = event.isMouseEvent() || event.isFocusEvent();
#if ENABLE(TOUCH_EVENTS)
    bool isTouchEvent = event.isTouchEvent();
#endif
    EventTarget* target = 0;

    Node* node = nodeOrHostIfPseudoElement(&targetNode);
    while (node) {
        if (!target || !isSVGElement) // FIXME: This code doesn't make sense once we've climbed out of the SVG subtree in a HTML document.
            target = &eventTargetRespectingTargetRules(*node);
        for (; node; node = node->parentNode()) {
            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 (!inDocument)
                return;
            if (node->isShadowRoot())
                break;
        }
        if (!node || !shouldEventCrossShadowBoundary(event, *toShadowRoot(node), *target))
            return;
        node = toShadowRoot(node)->hostElement();
    }
}
Exemplo n.º 2
0
inline void TreeScopeAdopter::moveNodeToNewDocument(
    Node& node,
    Document& oldDocument,
    Document& newDocument) const {
  DCHECK_NE(oldDocument, newDocument);

  if (node.hasRareData()) {
    NodeRareData* rareData = node.rareData();
    if (rareData->nodeLists())
      rareData->nodeLists()->adoptDocument(oldDocument, newDocument);
  }

  oldDocument.moveNodeIteratorsToNewDocument(node, newDocument);

  if (node.getCustomElementState() == CustomElementState::Custom) {
    Element& element = toElement(node);
    CustomElement::enqueueAdoptedCallback(&element, &oldDocument, &newDocument);
  }

  if (node.isShadowRoot())
    toShadowRoot(node).setDocument(newDocument);

#if DCHECK_IS_ON()
  didMoveToNewDocumentWasCalled = false;
  oldDocumentDidMoveToNewDocumentWasCalledWith = &oldDocument;
#endif

  node.didMoveToNewDocument(oldDocument);
#if DCHECK_IS_ON()
  DCHECK(didMoveToNewDocumentWasCalled);
#endif
}
Exemplo n.º 3
0
void EventDispatcher::ensureEventAncestors(Event* event)
{
    if (m_ancestorsInitialized)
        return;
    m_ancestorsInitialized = true;
    bool inDocument = m_node->inDocument();
    bool isSVGElement = m_node->isSVGElement();
    Vector<EventTarget*, 32> targetStack;
    for (AncestorChainWalker walker(m_node.get()); walker.get(); walker.parent()) {
        Node* node = walker.get();
        if (targetStack.isEmpty())
            targetStack.append(eventTargetRespectingTargetRules(node));
        else if (walker.crossingInsertionPoint())
            targetStack.append(targetStack.last());
        m_ancestors.append(EventContext(node, eventTargetRespectingTargetRules(node), targetStack.last()));
        if (!inDocument)
            return;
        if (!node->isShadowRoot())
            continue;
        if (determineDispatchBehavior(event, toShadowRoot(node), targetStack.last()) == StayInsideShadowDOM)
            return;
        if (!isSVGElement) {
            ASSERT(!targetStack.isEmpty());
            targetStack.removeLast();
        }
    }
}
Exemplo n.º 4
0
void EventPathWalker::moveToParent()
{
    ASSERT(m_node);
    ASSERT(m_distributedNode);
    if (ElementShadow* shadow = shadowOfParent(m_node)) {
        ContentDistributor::ensureDistribution(shadow->youngestShadowRoot());
        if (InsertionPoint* insertionPoint = shadow->distributor().findInsertionPointFor(m_distributedNode)) {
            m_node = insertionPoint;
            m_isVisitingInsertionPointInReprojection = true;
            return;
        }
    }
    if (!m_node->isShadowRoot()) {
        m_node = m_node->parentNode();
        if (!(m_node && m_node->isShadowRoot() && ScopeContentDistribution::assignedTo(toShadowRoot(m_node))))
            m_distributedNode = m_node;
        m_isVisitingInsertionPointInReprojection = false;
        return;
    }

    const ShadowRoot* shadowRoot = toShadowRoot(m_node);
    if (InsertionPoint* insertionPoint = ScopeContentDistribution::assignedTo(shadowRoot)) {
        m_node = insertionPoint;
        m_isVisitingInsertionPointInReprojection = true;
        return;
    }
    m_node = shadowRoot->host();
    m_distributedNode = m_node;
    m_isVisitingInsertionPointInReprojection = false;
}
static ContainerNode* traverseParent(const Node* node, ShadowRootCrossing shadowRootCrossing)
{
    if (node->isPseudoElement())
        return toPseudoElement(node)->hostElement();

    if (shadowRootCrossing == DontCrossShadowRoot  && node->isShadowRoot())
        return 0;

    if (nodeCanBeDistributed(node)) {
        if (InsertionPoint* insertionPoint = findInsertionPointOf(node))
            return traverseParent(insertionPoint, shadowRootCrossing);
        return nullptr;
    }
    ContainerNode* parent = node->parentNode();
    if (!parent)
        return nullptr;

    if (parent->isShadowRoot())
        return shadowRootCrossing == CrossShadowRoot ? toShadowRoot(parent)->hostElement() : parent;

    if (parent->isInsertionPoint()) {
        const InsertionPoint* insertionPoint = toInsertionPoint(parent);
        if (insertionPoint->hasDistribution())
            return nullptr;
        if (insertionPoint->isActive())
            return traverseParent(parent, shadowRootCrossing);
    }
    return parent;
}
Exemplo n.º 6
0
void EventRetargeter::calculateEventPath(Node* targetNode, Event* event, EventPath& eventPath)
{
    bool inDocument = targetNode->inDocument();
    bool isSVGElement = targetNode->isSVGElement();
    bool isMouseOrFocusEvent = event->isMouseEvent() || event->isFocusEvent();
#if ENABLE(TOUCH_EVENTS)
    bool isTouchEvent = event->isTouchEvent();
#endif
    Vector<EventTarget*, 32> targetStack;

    for (Node* node = nodeOrHostIfPseudoElement(targetNode); node; node = node->parentOrShadowHostNode()) {
        if (targetStack.isEmpty())
            targetStack.append(eventTargetRespectingTargetRules(node));
        if (isMouseOrFocusEvent)
            eventPath.append(adoptPtr(new MouseOrFocusEventContext(node, eventTargetRespectingTargetRules(node), targetStack.last())));
#if ENABLE(TOUCH_EVENTS)
        else if (isTouchEvent)
            eventPath.append(adoptPtr(new TouchEventContext(node, eventTargetRespectingTargetRules(node), targetStack.last())));
#endif
        else
            eventPath.append(adoptPtr(new EventContext(node, eventTargetRespectingTargetRules(node), targetStack.last())));
        if (!inDocument)
            return;
        if (!node->isShadowRoot())
            continue;
        if (determineDispatchBehavior(event, toShadowRoot(node), targetStack.last()) == StayInsideShadowDOM)
            return;
        if (!isSVGElement) {
            ASSERT(!targetStack.isEmpty());
            targetStack.removeLast();
        }
    }
}
Exemplo n.º 7
0
void EventRetargeter::calculateEventPath(Node* node, Event* event)
{
    EventPath& eventPath = event->eventPath();
    eventPath.clear();
    bool inDocument = node->inDocument();
    bool isSVGElement = node->isSVGElement();
    bool isMouseOrFocusEvent = event->isMouseEvent() || event->isFocusEvent();
    bool isTouchEvent = event->isTouchEvent();
    Vector<EventTarget*, 32> targetStack;
    for (EventPathWalker walker(node); walker.node(); walker.moveToParent()) {
        Node* node = walker.node();
        if (targetStack.isEmpty())
            targetStack.append(eventTargetRespectingTargetRules(node));
        else if (walker.isVisitingInsertionPointInReprojection())
            targetStack.append(targetStack.last());
        if (isMouseOrFocusEvent)
            eventPath.append(adoptPtr(new MouseOrFocusEventContext(node, eventTargetRespectingTargetRules(node), targetStack.last())));
        else if (isTouchEvent)
            eventPath.append(adoptPtr(new TouchEventContext(node, eventTargetRespectingTargetRules(node), targetStack.last())));
        else
            eventPath.append(adoptPtr(new EventContext(node, eventTargetRespectingTargetRules(node), targetStack.last())));
        if (!inDocument)
            return;
        if (!node->isShadowRoot())
            continue;
        if (determineDispatchBehavior(event, toShadowRoot(node), targetStack.last()) == StayInsideShadowDOM)
            return;
        if (!isSVGElement) {
            ASSERT(!targetStack.isEmpty());
            targetStack.removeLast();
        }
    }
}
Exemplo n.º 8
0
inline EventTarget& eventTargetRespectingTargetRules(Node& referenceNode)
{
    if (referenceNode.isPseudoElement()) {
        EventTarget* hostElement = toPseudoElement(referenceNode).hostElement();
        ASSERT(hostElement);
        return *hostElement;
    }

#if ENABLE(SVG)
    if (!referenceNode.isSVGElement() || !referenceNode.isInShadowTree())
        return referenceNode;

    // Spec: The event handling for the non-exposed tree works as if the referenced element had been textually included
    // as a deeply cloned child of the 'use' element, except that events are dispatched to the SVGElementInstance objects
    Node* rootNode = referenceNode.treeScope().rootNode();
    Element* shadowHostElement = rootNode->isShadowRoot() ? toShadowRoot(rootNode)->hostElement() : 0;
    // At this time, SVG nodes are not supported in non-<use> shadow trees.
    if (!shadowHostElement || !shadowHostElement->hasTagName(SVGNames::useTag))
        return referenceNode;
    SVGUseElement* useElement = toSVGUseElement(shadowHostElement);
    if (SVGElementInstance* instance = useElement->instanceForShadowTreeElement(&referenceNode))
        return *instance;
#endif

    return referenceNode;
}
Exemplo n.º 9
0
void AncestorChainWalker::parent()
{
    ASSERT(m_node);
    ASSERT(m_distributedNode);
    if (ElementShadow* shadow = shadowOfParent(m_node)) {
        if (InsertionPoint* insertionPoint = shadow->insertionPointFor(m_distributedNode)) {
            m_node = insertionPoint;
            m_isCrossingInsertionPoint = true;
            return;
        }
    }
    if (!m_node->isShadowRoot()) {
        m_node = m_node->parentNode();
        m_distributedNode = m_node;
        m_isCrossingInsertionPoint = false;
        return;
    }

    const ShadowRoot* shadowRoot = toShadowRoot(m_node);
    if (InsertionPoint* insertionPoint = shadowRoot->assignedTo()) {
        m_node = insertionPoint;
        m_isCrossingInsertionPoint = true;
        return;
    }
    m_node = shadowRoot->host();
    m_distributedNode = m_node;
    m_isCrossingInsertionPoint = false;
}
Exemplo n.º 10
0
void EventDispatcher::ensureEventAncestors(Event* event)
{
    if (m_ancestorsInitialized)
        return;
    m_ancestorsInitialized = true;
    bool inDocument = m_node->inDocument();
    bool isSVGElement = m_node->isSVGElement();
    Vector<EventTarget*> targetStack;
    Node* last = 0;
    for (ComposedShadowTreeParentWalker walker(m_node.get()); walker.get(); walker.parentIncludingInsertionPointAndShadowRoot()) {
        Node* node = walker.get();
        if (targetStack.isEmpty())
            targetStack.append(eventTargetRespectingSVGTargetRules(node));
        else if (isInsertionPoint(node) && toInsertionPoint(node)->contains(last))
            targetStack.append(targetStack.last());
        m_ancestors.append(EventContext(node, eventTargetRespectingSVGTargetRules(node), targetStack.last()));
        if (!inDocument)
            return;
        last = node;
        if (!node->isShadowRoot())
            continue;
        if (determineDispatchBehavior(event, toShadowRoot(node), targetStack.last()) == StayInsideShadowDOM)
            return;
        if (!isSVGElement) {
            ASSERT(!targetStack.isEmpty());
            targetStack.removeLast();
        }
    }
}
Exemplo n.º 11
0
void SVGShadowText::willRecalcTextStyle(StyleChange change)
{
    if (change != NoChange && parentNode()->isShadowRoot()) {
        if (renderer())
            renderer()->setStyle(toShadowRoot(parentNode())->host()->renderer()->style());
    }
}
Exemplo n.º 12
0
// TODO(hayato): This may return a wrong result for a node which is not in a
// document flat tree.  See FlatTreeTraversalTest's redistribution test for details.
Node* FlatTreeTraversal::traverseSiblings(const Node& node, TraversalDirection direction)
{
    if (node.isChildOfV1ShadowHost())
        return traverseSiblingsForV1HostChild(node, direction);

    if (shadowWhereNodeCanBeDistributed(node))
        return traverseSiblingsForV0Distribution(node, direction);

    if (Node* found = resolveDistributionStartingAt(direction == TraversalDirectionForward ? node.nextSibling() : node.previousSibling(), direction))
        return found;

    if (!node.isInV0ShadowTree())
        return nullptr;

    // For v0 older shadow tree
    if (node.parentNode() && node.parentNode()->isShadowRoot()) {
        ShadowRoot* parentShadowRoot = toShadowRoot(node.parentNode());
        if (!parentShadowRoot->isYoungest()) {
            HTMLShadowElement* assignedInsertionPoint = parentShadowRoot->shadowInsertionPointOfYoungerShadowRoot();
            DCHECK(assignedInsertionPoint);
            return traverseSiblings(*assignedInsertionPoint, direction);
        }
    }
    return nullptr;
}
Exemplo n.º 13
0
String SVGElement::title() const
{
    // According to spec, we should not return titles when hovering over root <svg> elements (those
    // <title> elements are the title of the document, not a tooltip) so we instantly return.
    if (isOutermostSVGSVGElement())
        return String();

    // Walk up the tree, to find out whether we're inside a <use> shadow tree, to find the right title.
    if (isInShadowTree()) {
        Element* shadowHostElement = toShadowRoot(treeScope().rootNode()).host();
        // At this time, SVG nodes are not allowed in non-<use> shadow trees, so any shadow root we do
        // have should be a use. The assert and following test is here to catch future shadow DOM changes
        // that do enable SVG in a shadow tree.
        ASSERT(!shadowHostElement || isSVGUseElement(*shadowHostElement));
        if (isSVGUseElement(shadowHostElement)) {
            SVGUseElement& useElement = toSVGUseElement(*shadowHostElement);

            // If the <use> title is not empty we found the title to use.
            String useTitle(useElement.title());
            if (!useTitle.isEmpty())
                return useTitle;
        }
    }

    // If we aren't an instance in a <use> or the <use> title was not found, then find the first
    // <title> child of this element.
    // If a title child was found, return the text contents.
    if (Element* titleElement = Traversal<SVGTitleElement>::firstChild(*this))
        return titleElement->innerText();

    // Otherwise return a null/empty string.
    return String();
}
Exemplo n.º 14
0
Element* Internals::getElementByIdInShadowRoot(Node* shadowRoot, const String& id, ExceptionCode& ec)
{
    if (!shadowRoot || !shadowRoot->isShadowRoot()) {
        ec = INVALID_ACCESS_ERR;
        return 0;
    }
    return toShadowRoot(shadowRoot)->getElementById(id);
}
Exemplo n.º 15
0
TreeScope* TreeScope::olderShadowRootOrParentTreeScope() const
{
    if (rootNode().isShadowRoot()) {
        if (ShadowRoot* olderShadowRoot = toShadowRoot(rootNode()).olderShadowRoot())
            return olderShadowRoot;
    }
    return parentTreeScope();
}
Exemplo n.º 16
0
bool HTMLShadowElement::doesSelectFromHostChildren() const
{
    TreeScope* scope = treeScope();

    if (scope->isShadowRoot())
        return toShadowRoot(scope)->isOldest();
    return false;
}
Exemplo n.º 17
0
Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::olderShadowRoot(Node* shadow, ExceptionCode& ec)
{
    if (!shadow || !shadow->isShadowRoot()) {
        ec = INVALID_ACCESS_ERR;
        return 0;
    }

    return toShadowRoot(shadow)->olderShadowRoot();
}
Exemplo n.º 18
0
void EventPath::calculatePath()
{
    ASSERT(m_node);
    ASSERT(m_nodeEventContexts.isEmpty());
    m_node->updateDistribution();

    // For performance and memory usage reasons we want to store the
    // path using as few bytes as possible and with as few allocations
    // as possible which is why we gather the data on the stack before
    // storing it in a perfectly sized m_nodeEventContexts Vector.
    WillBeHeapVector<RawPtrWillBeMember<Node>, 64> nodesInPath;
    Node* current = m_node;
    nodesInPath.append(current);
    while (current) {
        if (m_event && current->keepEventInNode(m_event))
            break;
        WillBeHeapVector<RawPtrWillBeMember<InsertionPoint>, 8> insertionPoints;
        collectDestinationInsertionPoints(*current, insertionPoints);
        if (!insertionPoints.isEmpty()) {
            for (const auto& insertionPoint : insertionPoints) {
                if (insertionPoint->isShadowInsertionPoint()) {
                    ShadowRoot* containingShadowRoot = insertionPoint->containingShadowRoot();
                    ASSERT(containingShadowRoot);
                    if (!containingShadowRoot->isOldest())
                        nodesInPath.append(containingShadowRoot->olderShadowRoot());
                }
                nodesInPath.append(insertionPoint);
            }
            current = insertionPoints.last();
            continue;
        }
        if (current->isShadowRoot()) {
            if (m_event && shouldStopAtShadowRoot(*m_event, *toShadowRoot(current), *m_node))
                break;
            current = current->shadowHost();
#if !ENABLE(OILPAN)
            // TODO(kochi): crbug.com/507413 This check is necessary when some asynchronous event
            // is queued while its shadow host is removed and the shadow root gets the event
            // immediately after it.  When Oilpan is enabled, this situation does not happen.
            // Except this case, shadow root's host is assumed to be non-null.
            if (current)
                nodesInPath.append(current);
#else
            nodesInPath.append(current);
#endif
        } else {
            current = current->parentNode();
            if (current)
                nodesInPath.append(current);
        }
    }

    m_nodeEventContexts.reserveCapacity(nodesInPath.size());
    for (Node* nodeInPath : nodesInPath) {
        m_nodeEventContexts.append(NodeEventContext(nodeInPath, eventTargetRespectingTargetRules(*nodeInPath)));
    }
}
Exemplo n.º 19
0
Element* FocusNavigationScope::owner() const
{
    Node* root = rootNode();
    if (root->isShadowRoot()) {
        ShadowRoot* shadowRoot = toShadowRoot(root);
        return shadowRoot->host();
    }
    return 0;
}
Exemplo n.º 20
0
TreeScopeStyleSheetCollection* StyleEngine::ensureStyleSheetCollectionFor(TreeScope& treeScope)
{
    if (treeScope == m_document)
        return documentStyleSheetCollection();

    StyleSheetCollectionMap::AddResult result = m_styleSheetCollectionMap.add(&treeScope, nullptr);
    if (result.isNewEntry)
        result.storedValue->value = adoptPtr(new ShadowTreeStyleSheetCollection(toShadowRoot(treeScope)));
    return result.storedValue->value.get();
}
int TreeScopeEventContext::calculateTreeOrderAndSetNearestAncestorClosedTree(int orderNumber, TreeScopeEventContext* nearestAncestorClosedTreeScopeEventContext)
{
    m_preOrder = orderNumber;
    m_containingClosedShadowTree = (rootNode().isShadowRoot() && !toShadowRoot(rootNode()).isOpenOrV0()) ? this : nearestAncestorClosedTreeScopeEventContext;
    for (size_t i = 0; i < m_children.size(); ++i)
        orderNumber = m_children[i]->calculateTreeOrderAndSetNearestAncestorClosedTree(orderNumber + 1, containingClosedShadowTree());
    m_postOrder = orderNumber + 1;

    return orderNumber + 1;
}
Exemplo n.º 22
0
void EventRetargeter::calculateEventPath(Node* node, Event* event)
{
    EventPath& eventPath = event->eventPath();
    eventPath.clear();
    bool inDocument = node->inDocument();
    bool isSVGElement = node->isSVGElement();
    bool isMouseOrFocusEvent = event->isMouseEvent() || event->isFocusEvent();
    bool isTouchEvent = event->isTouchEvent();
    Vector<EventTarget*, 32> targetStack;
    for (EventPathWalker walker(node); walker.node(); walker.moveToParent()) {
        Node* node = walker.node();
        if (targetStack.isEmpty())
            targetStack.append(eventTargetRespectingTargetRules(node));
        else if (walker.isVisitingInsertionPointInReprojection())
            targetStack.append(targetStack.last());
        if (isMouseOrFocusEvent)
            eventPath.append(adoptPtr(new MouseOrFocusEventContext(node, eventTargetRespectingTargetRules(node), targetStack.last())));
        else if (isTouchEvent)
            eventPath.append(adoptPtr(new TouchEventContext(node, eventTargetRespectingTargetRules(node), targetStack.last())));
        else
            eventPath.append(adoptPtr(new EventContext(node, eventTargetRespectingTargetRules(node), targetStack.last())));
        if (!inDocument)
            return;
        if (!node->isShadowRoot())
            continue;
        if (determineDispatchBehavior(event, toShadowRoot(node), targetStack.last()) == StayInsideShadowDOM)
            return;
        if (!isSVGElement) {
            ASSERT(!targetStack.isEmpty());
            targetStack.removeLast();
        }
    }

    // Calculates eventPath for each node for Event.path() API.
    if (!RuntimeEnabledFeatures::experimentalShadowDOMEnabled())
        return;
    TreeScope* lastScope = 0;
    size_t eventPathSize = eventPath.size();
    for (size_t i = 0; i < eventPathSize; ++i) {
        TreeScope* currentScope = eventPath[i]->node()->treeScope();
        if (currentScope == lastScope) {
            // Fast path.
            eventPath[i]->setEventPath(eventPath[i - 1]->eventPath());
            continue;
        }
        lastScope = currentScope;
        Vector<RefPtr<Node> > nodes;
        for (size_t j = 0; j < eventPathSize; ++j) {
            Node* node = eventPath[j]->node();
            if (node->treeScope()->isInclusiveAncestorOf(currentScope))
                nodes.append(node);
        }
        eventPath[i]->adoptEventPath(nodes);
    }
}
Exemplo n.º 23
0
ShadowRoot* InsertionPoint::assignedFrom() const
{
    Node* treeScopeRoot = treeScope()->rootNode();
    if (!treeScopeRoot->isShadowRoot())
        return 0;

    ShadowRoot* olderShadowRoot = toShadowRoot(treeScopeRoot)->olderShadowRoot();
    if (olderShadowRoot && olderShadowRoot->assignedTo() == this)
        return olderShadowRoot;
    return 0;
}
Exemplo n.º 24
0
ShadowRoot* InsertionPoint::assignedFrom() const
{
    TreeScope* scope = treeScope();
    if (!scope->isShadowRoot())
        return 0;

    ShadowRoot* olderShadowRoot = toShadowRoot(scope)->olderShadowRoot();
    if (olderShadowRoot && olderShadowRoot->assignedTo() == this)
        return olderShadowRoot;
    return 0;
}
Exemplo n.º 25
0
void StyleScopeResolver::pop(const ContainerNode* scope)
{
    // Only bother to update the scoping element stack if it is consistent.
    if (stackIsConsistent(scope)) {
        if (!m_stack.isEmpty() && m_stack.last().m_scope == scope)
            m_stack.removeLast();
        if (scope->isShadowRoot() && !toShadowRoot(scope)->applyAuthorStyles())
            --m_stackParentBoundsIndex;
        m_stackParent = scope->parentOrHostNode();
    }
}
Exemplo n.º 26
0
Node* ComposedShadowTreeWalker::traverseParent(const Node* node) const
{
    if (!canCrossUpperBoundary() && node->isShadowRoot()) {
        ASSERT(toShadowRoot(node)->isYoungest());
        return 0;
    }
    if (ElementShadow* shadow = shadowOfParent(node)) {
        if (InsertionPoint* insertionPoint = shadow->insertionPointFor(node))
            return traverseParent(insertionPoint);
    }
    return traverseParentInCurrentTree(node);
}
Exemplo n.º 27
0
inline Node* ComposedTreeWalker::traverseParentOrHost(const Node* node) const
{
    Node* parent = node->parentNode();
    if (!parent)
        return 0;
    if (!parent->isShadowRoot())
        return parent;
    ShadowRoot* shadowRoot = toShadowRoot(parent);
    ASSERT(!shadowRoot->shadowInsertionPointOfYoungerShadowRoot());
    if (!shadowRoot->isYoungest())
        return 0;
    return shadowRoot->host();
}
Node* ComposedShadowTreeWalker::traverseBackToYoungerShadowRoot(const Node* node, TraversalDirection direction)
{
    ASSERT(node);
    if (node->parentNode() && node->parentNode()->isShadowRoot()) {
        ShadowRoot* parentShadowRoot = toShadowRoot(node->parentNode());
        if (!parentShadowRoot->isYoungest()) {
            InsertionPoint* assignedInsertionPoint = parentShadowRoot->insertionPoint();
            ASSERT(assignedInsertionPoint);
            return traverseSiblingInCurrentTree(assignedInsertionPoint, direction);
        }
    }
    return 0;
}
Exemplo n.º 29
0
ContainerNode* FlatTreeTraversal::traverseParentOrHost(const Node& node)
{
    ContainerNode* parent = node.parentNode();
    if (!parent)
        return nullptr;
    if (!parent->isShadowRoot())
        return parent;
    ShadowRoot* shadowRoot = toShadowRoot(parent);
    DCHECK(!shadowRoot->shadowInsertionPointOfYoungerShadowRoot());
    if (!shadowRoot->isYoungest())
        return nullptr;
    return &shadowRoot->host();
}
Exemplo n.º 30
0
inline void TreeScopeAdopter::moveNodeToNewDocument(Node& node, Document& oldDocument, Document& newDocument) const
{
    ASSERT(oldDocument != newDocument);

    if (node.isShadowRoot())
        toShadowRoot(node).setDocument(newDocument);

#if ENABLE(ASSERT)
    didMoveToNewDocumentWasCalled = false;
    oldDocumentDidMoveToNewDocumentWasCalledWith = &oldDocument;
#endif

    node.didMoveToNewDocument(oldDocument);
    ASSERT(didMoveToNewDocumentWasCalled);
}