Exemplo n.º 1
0
static inline bool isKeyboardFocusableShadowHost(Node* node)
{
    ASSERT(node);
    if (!node->isElementNode())
        return false;
    Element* element = toElement(node);
    return element->isKeyboardFocusable() && isShadowHost(element);
}
ScopedStyleResolver* ScopedStyleTree::scopedStyleResolverFor(const ContainerNode& scopingNode)
{
    if (!scopingNode.hasScopedHTMLStyleChild()
        && !isShadowHost(&scopingNode)
        && !scopingNode.isDocumentNode()
        && !scopingNode.isShadowRoot())
        return 0;
    return lookupScopedStyleResolverFor(&scopingNode);
}
PassRefPtr<EventTarget> EventDispatcher::adjustToShadowBoundaries(PassRefPtr<Node> relatedTarget, const Vector<Node*> relatedTargetAncestors)
{
    Vector<EventContext>::const_iterator lowestCommonBoundary = m_ancestors.end();
    // Assume divergent boundary is the relatedTarget itself (in other words, related target ancestor chain does not cross any shadow DOM boundaries).
    Vector<Node*>::const_iterator firstDivergentBoundary = relatedTargetAncestors.begin();

    Vector<EventContext>::const_iterator targetAncestor = m_ancestors.end();
    // Walk down from the top, looking for lowest common ancestor, also monitoring shadow DOM boundaries.
    bool diverged = false;
    for (Vector<Node*>::const_iterator i = relatedTargetAncestors.end() - 1; i >= relatedTargetAncestors.begin(); --i) {
        if (diverged) {
            if (isShadowRootOrSVGShadowRoot(*i)) {
                firstDivergentBoundary = i + 1;
                break;
            }
            continue;
        }

        if (targetAncestor == m_ancestors.begin()) {
            diverged = true;
            continue;
        }

        targetAncestor--;

        if (isShadowRootOrSVGShadowRoot(*i))
            lowestCommonBoundary = targetAncestor;

        if ((*i) != (*targetAncestor).node())
            diverged = true;
    }

    if (!diverged) {
        // The relatedTarget is an ancestor or shadowHost of the target.
        // FIXME: Remove the first check once conversion to new shadow DOM is complete <http://webkit.org/b/48698>
        if (m_node->shadowHost() == relatedTarget.get() || isShadowHost(relatedTarget.get())) {
            Vector<EventContext>::const_iterator relatedTargetChild = targetAncestor - 1;
            if (relatedTargetChild >= m_ancestors.begin() && isShadowRootOrSVGShadowRoot(relatedTargetChild->node()))
                lowestCommonBoundary = relatedTargetChild;
        }
    } else if ((*firstDivergentBoundary) == m_node.get()) {
        // Since ancestors does not contain target itself, we must account
        // for the possibility that target is a shadowHost of relatedTarget
        // and thus serves as the lowestCommonBoundary.
        // Luckily, in this case the firstDivergentBoundary is target.
        lowestCommonBoundary = m_ancestors.begin();
        m_shouldPreventDispatch = true;
    }

    if (lowestCommonBoundary != m_ancestors.end()) {
        // Trim ancestors to lowestCommonBoundary to keep events inside of the common shadow DOM subtree.
        m_ancestors.shrink(lowestCommonBoundary - m_ancestors.begin());
    }
    // Set event's related target to the first encountered shadow DOM boundary in the divergent subtree.
    return firstDivergentBoundary != relatedTargetAncestors.begin() ? *firstDivergentBoundary : relatedTarget;
}
Exemplo n.º 4
0
Node* ComposedShadowTreeWalker::traverseChild(const Node* node, TraversalDirection direction) const
{
    ASSERT(node);
    if (canCrossUpperBoundary()) {
        return node->shadowRoot() ? traverseLightChildren(node->shadowRoot(), direction)
            : traverseLightChildren(node, direction);
    }
    if (isShadowHost(node))
        return 0;
    return traverseLightChildren(node, direction);
}
Node* ComposedShadowTreeWalker::traverseChild(const Node* node, TraversalDirection direction) const
{
    ASSERT(node);
    if (canCrossUpperBoundary()) {
        ElementShadow* shadow = shadowFor(node);
        return shadow ? traverseLightChildren(shadow->youngestShadowRoot(), direction)
            : traverseLightChildren(node, direction);
    }
    if (isShadowHost(node))
        return 0;
    return traverseLightChildren(node, direction);
}
static void invalidateStyleForLinkRecursively(Node& rootNode, LinkHash linkHash)
{
    for (Node& node : NodeTraversal::startsAt(rootNode)) {
        if (node.isLink() && linkHashForElement(toElement(node)) == linkHash) {
            toElement(node).pseudoStateChanged(CSSSelector::PseudoLink);
            toElement(node).pseudoStateChanged(CSSSelector::PseudoVisited);
            toElement(node).pseudoStateChanged(CSSSelector::PseudoAnyLink);
        }
        if (isShadowHost(&node))
            for (ShadowRoot* root = node.youngestShadowRoot(); root; root = root->olderShadowRoot())
                invalidateStyleForLinkRecursively(*root, linkHash);
    }
}
Exemplo n.º 7
0
// 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;
}
Exemplo n.º 8
0
// 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;
}
static void invalidateStyleForAllLinksRecursively(Node& rootNode, bool invalidateVisitedLinkHashes)
{
    for (Node& node : NodeTraversal::startsAt(rootNode)) {
        if (node.isLink()) {
            if (invalidateVisitedLinkHashes && isHTMLAnchorElement(node))
                toHTMLAnchorElement(node).invalidateCachedVisitedLinkHash();
            toElement(node).pseudoStateChanged(CSSSelector::PseudoLink);
            toElement(node).pseudoStateChanged(CSSSelector::PseudoVisited);
            toElement(node).pseudoStateChanged(CSSSelector::PseudoAnyLink);
        }
        if (isShadowHost(&node)) {
            for (ShadowRoot* root = node.youngestShadowRoot(); root; root = root->olderShadowRoot())
                invalidateStyleForAllLinksRecursively(*root, invalidateVisitedLinkHashes);
        }
    }
}
Exemplo n.º 10
0
FocusNavigationScope FocusNavigationScope::ownedByShadowHost(Node* node)
{
    ASSERT(isShadowHost(node));
    return FocusNavigationScope(toElement(node)->shadow()->shadowRoot());
}