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); } }
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); }
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); } }
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); }
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); }
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); }
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; }
Node::InsertionNotificationRequest HTMLShadowElement::insertedInto(ContainerNode* insertionPoint) { InsertionPoint::insertedInto(insertionPoint); if (insertionPoint->inDocument() && isActive()) { if (ShadowRoot* root = shadowRoot()) { root->registerShadowElement(); m_registeredWithShadowRoot = true; } } return InsertionDone; }
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); }
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(); }
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()); }
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(); }
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 }
HTMLElement* HTMLTextAreaElement::innerTextElement() const { Node* node = shadowRoot()->firstChild(); ASSERT(!node || node->hasTagName(divTag)); return static_cast<HTMLElement*>(node); }
ShadowBlockElement* HTMLProgressElement::valuePart() { return static_cast<ShadowBlockElement*>(shadowRoot()); }