void ElementShadow::attach(const Node::AttachContext& context)
{
    ContentDistributor::ensureDistribution(shadowRoot());

    Node::AttachContext childrenContext(context);
    childrenContext.resolvedStyle = 0;

    if (ShadowRoot* root = shadowRoot()) {
        if (!root->attached())
            root->attach(childrenContext);
    }
}
示例#2
0
void SVGTRefElement::updateReferencedText()
{
    Element* target = SVGURIReference::targetElementFromIRIString(href(), document());
    ASSERT(target);
    String textContent;
    if (target->parentNode())
        textContent = target->textContent();
    ExceptionCode ignore = 0;
    if (!ensureShadowRoot()->firstChild())
        shadowRoot()->appendChild(SVGShadowText::create(document(), textContent), ignore);
    else
        shadowRoot()->firstChild()->setTextContent(textContent, ignore);
}
示例#3
0
void SVGTRefElement::updateReferencedText(Element* target)
{
    String textContent;
    if (target)
        textContent = target->textContent();

    ASSERT(shadowRoot());
    ShadowRoot* root = shadowRoot();
    if (!root->firstChild())
        root->appendChild(Text::create(document(), textContent), ASSERT_NO_EXCEPTION);
    else {
        ASSERT(root->firstChild()->isTextNode());
        root->firstChild()->setTextContent(textContent, ASSERT_NO_EXCEPTION);
    }
}
void ElementShadow::removeAllEventListeners()
{
    if (ShadowRoot* root = shadowRoot()) {
        for (Node* node = root; node; node = NodeTraversal::next(node))
            node->removeAllEventListeners();
    }
}
void ElementShadow::detach(const Node::AttachContext& context)
{
    Node::AttachContext childrenContext(context);
    childrenContext.resolvedStyle = 0;

    if (ShadowRoot* root = shadowRoot()) {
        if (root->attached())
            root->detach(childrenContext);
    }
}
示例#6
0
void SVGTRefElement::detachTarget()
{
    // Remove active listeners and clear the text content.
    m_targetListener->detach();

    String emptyContent;

    ASSERT(shadowRoot());
    Node* container = shadowRoot()->firstChild();
    if (container)
        container->setTextContent(emptyContent, IGNORE_EXCEPTION);

    if (!inDocument())
        return;

    // Mark the referenced ID as pending.
    String id;
    SVGURIReference::targetElementFromIRIString(href(), document(), &id);
    if (!id.isEmpty())
        document().accessSVGExtensions().addPendingResource(id, this);
}
示例#7
0
void HTMLTextAreaElement::updatePlaceholderText()
{
    ExceptionCode ec = 0;
    String placeholderText = strippedPlaceholder();
    if (placeholderText.isEmpty()) {
        if (m_placeholder) {
            shadowRoot()->removeChild(m_placeholder.get(), ec);
            ASSERT(!ec);
            m_placeholder.clear();
        }
        return;
    }
    if (!m_placeholder) {
        m_placeholder = HTMLDivElement::create(document());
        m_placeholder->setShadowPseudoId("-webkit-input-placeholder");
        shadowRoot()->insertBefore(m_placeholder, shadowRoot()->firstChild()->nextSibling(), ec);
        ASSERT(!ec);
    }
    m_placeholder->setInnerText(placeholderText, ec);
    ASSERT(!ec);
}
示例#8
0
void HTMLShadowElement::removedFrom(ContainerNode* insertionPoint)
{
    if (insertionPoint->inDocument() && m_registeredWithShadowRoot) {
        ShadowRoot* root = shadowRoot();
        if (!root)
            root = insertionPoint->shadowRoot();
        if (root)
            root->unregisterShadowElement();
        m_registeredWithShadowRoot = false;
    }
    InsertionPoint::removedFrom(insertionPoint);
}
示例#9
0
bool InsertionPoint::isActive() const
{
    if (!shadowRoot())
        return false;
    const Node* node = parentNode();
    while (node) {
        if (WebCore::isInsertionPoint(node))
            return false;

        node = node->parentNode();
    }
    return true;
}
示例#10
0
Node::InsertionNotificationRequest HTMLShadowElement::insertedInto(ContainerNode* insertionPoint)
{
    InsertionPoint::insertedInto(insertionPoint);

    if (insertionPoint->inDocument() && isActive()) {
        if (ShadowRoot* root = shadowRoot()) {
            root->registerShadowElement();
            m_registeredWithShadowRoot = true;
        }
    }

    return InsertionDone;
}
示例#11
0
void SVGUseElement::clearResourceReferences()
{
    // FIXME: We should try to optimize this, to at least allow partial reclones.
    if (ShadowRoot* shadowTreeRootElement = shadowRoot())
        shadowTreeRootElement->removeChildren();

    if (m_targetElementInstance) {
        m_targetElementInstance->detach();
        m_targetElementInstance = 0;
    }

    m_needsShadowTreeRecreation = false;

    document().accessSVGExtensions()->removeAllTargetReferencesForElement(this);
}
示例#12
0
void InsertionPoint::detach()
{
    ShadowRoot* root = shadowRoot();
    if (root && isActive()) {
        ElementShadow* shadow = root->owner();

        if (doesSelectFromHostChildren())
            clearDistribution(shadow);
        else if (ShadowRoot* assignedShadowRoot = assignedFrom())
            clearAssignment(assignedShadowRoot);

        // When shadow element is detached, shadow tree should be recreated to re-calculate selector for
        // other insertion points.
        shadow->setNeedsRedistributing();
    }

    ASSERT(m_distribution.isEmpty());
    HTMLElement::detach();
}
示例#13
0
void SVGUseElement::buildShadowTree(SVGElement* target, SVGElementInstance* targetInstance)
{
    ASSERT(target); // FIXME: Don't be a pointer!

    // For instance <use> on <foreignObject> (direct case).
    if (isDisallowedElement(*target))
        return;

    RefPtr<SVGElement> newChild = static_pointer_cast<SVGElement>(targetInstance->correspondingElement()->cloneElementWithChildren());

    // We don't walk the target tree element-by-element, and clone each element,
    // but instead use cloneElementWithChildren(). This is an optimization for the common
    // case where <use> doesn't contain disallowed elements (ie. <foreignObject>).
    // Though if there are disallowed elements in the subtree, we have to remove them.
    // For instance: <use> on <g> containing <foreignObject> (indirect case).
    if (subtreeContainsDisallowedElement(*newChild))
        removeDisallowedElementsFromSubtree(*newChild);

    shadowRoot()->appendChild(newChild.release());
}
示例#14
0
void HTMLProgressElement::createShadowSubtreeIfNeeded()
{
    if (shadowRoot())
        return;
    setShadowRoot(ProgressBarValueElement::create(this).get());
}
void ElementShadow::recalcStyle(Node::StyleChange change)
{
    if (ShadowRoot* root = shadowRoot())
        root->recalcStyle(change);
}
bool ElementShadow::needsStyleRecalc() const
{
    ASSERT(shadowRoot());
    return shadowRoot()->needsStyleRecalc();
}
示例#17
0
void SVGUseElement::buildShadowAndInstanceTree(SVGElement* target)
{
    ASSERT(!m_targetElementInstance);

    // Do not build the shadow/instance tree for <use> elements living in a shadow tree.
    // The will be expanded soon anyway - see expandUseElementsInShadowTree().
    if (isInShadowTree())
        return;

    // Do not allow self-referencing.
    // 'target' may be null, if it's a non SVG namespaced element.
    if (!target || target == this)
        return;

    // Why a seperated instance/shadow tree? SVG demands it:
    // The instance tree is accesable from JavaScript, and has to
    // expose a 1:1 copy of the referenced tree, whereas internally we need
    // to alter the tree for correct "use-on-symbol", "use-on-svg" support.

    // Build instance tree. Create root SVGElementInstance object for the first sub-tree node.
    //
    // Spec: If the 'use' element references a simple graphics element such as a 'rect', then there is only a
    // single SVGElementInstance object, and the correspondingElement attribute on this SVGElementInstance object
    // is the SVGRectElement that corresponds to the referenced 'rect' element.
    m_targetElementInstance = SVGElementInstance::create(this, this, target);

    // Eventually enter recursion to build SVGElementInstance objects for the sub-tree children
    bool foundProblem = false;
    buildInstanceTree(target, m_targetElementInstance.get(), foundProblem, false);

    if (instanceTreeIsLoading(m_targetElementInstance.get()))
        return;

    // SVG specification does not say a word about <use> & cycles. My view on this is: just ignore it!
    // Non-appearing <use> content is easier to debug, then half-appearing content.
    if (foundProblem) {
        clearResourceReferences();
        return;
    }

    // Assure instance tree building was successfull
    ASSERT(m_targetElementInstance);
    ASSERT(!m_targetElementInstance->shadowTreeElement());
    ASSERT(m_targetElementInstance->correspondingUseElement() == this);
    ASSERT(m_targetElementInstance->directUseElement() == this);
    ASSERT(m_targetElementInstance->correspondingElement() == target);

    ShadowRoot* shadowTreeRootElement = shadowRoot();
    ASSERT(shadowTreeRootElement);

    // Build shadow tree from instance tree
    // This also handles the special cases: <use> on <symbol>, <use> on <svg>.
    buildShadowTree(target, m_targetElementInstance.get());

    // Expand all <use> elements in the shadow tree.
    // Expand means: replace the actual <use> element by what it references.
    expandUseElementsInShadowTree(shadowTreeRootElement);

    // Expand all <symbol> elements in the shadow tree.
    // Expand means: replace the actual <symbol> element by the <svg> element.
    expandSymbolElementsInShadowTree(shadowTreeRootElement);

    // Now that the shadow tree is completly expanded, we can associate
    // shadow tree elements <-> instances in the instance tree.
    associateInstancesWithShadowTreeElements(shadowTreeRootElement->firstChild(), m_targetElementInstance.get());

    // If no shadow tree element is present, this means that the reference root
    // element was removed, as it is disallowed (ie. <use> on <foreignObject>)
    // Do NOT leave an inconsistent instance tree around, instead destruct it.
    if (!m_targetElementInstance->shadowTreeElement()) {
        clearResourceReferences();
        return;
    }

    ASSERT(m_targetElementInstance->shadowTreeElement()->parentNode() == shadowTreeRootElement);

    // Transfer event listeners assigned to the referenced element to our shadow tree elements.
    transferEventListenersToShadowTree(m_targetElementInstance.get());

    // Update relative length information.
    updateRelativeLengthsInformation();

    // Eventually dump instance tree
#ifdef DUMP_INSTANCE_TREE
    String text;
    unsigned int depth = 0;

    dumpInstanceTree(depth, text, m_targetElementInstance.get());
    fprintf(stderr, "\nDumping <use> instance tree:\n%s\n", text.latin1().data());
#endif

    // Eventually dump shadow tree
#ifdef DUMP_SHADOW_TREE
    RefPtr<XMLSerializer> serializer = XMLSerializer::create();
    String markup = serializer->serializeToString(shadowTreeRootElement, ASSERT_NO_EXCEPTION);
    fprintf(stderr, "Dumping <use> shadow tree markup:\n%s\n", markup.latin1().data());
#endif
}
示例#18
0
HTMLElement* HTMLTextAreaElement::innerTextElement() const
{
    Node* node = shadowRoot()->firstChild();
    ASSERT(!node || node->hasTagName(divTag));
    return static_cast<HTMLElement*>(node);
}
示例#19
0
ShadowBlockElement* HTMLProgressElement::valuePart()
{
    return static_cast<ShadowBlockElement*>(shadowRoot());
}