RenderObject* NodeRenderingContext::previousRenderer() const { ASSERT(m_node->renderer() || m_location != LocationUndetermined); if (RenderObject* renderer = m_node->renderer()) return renderer->previousSibling(); if (m_parentFlowRenderer) return m_parentFlowRenderer->previousRendererForNode(m_node); if (m_phase == AttachContentForwarded) { if (RenderObject* found = previousRendererOf(m_includer, m_node)) return found; return NodeRenderingContext(m_includer).previousRenderer(); } // FIXME: We should have the same O(N^2) avoidance as nextRenderer does // however, when I tried adding it, several tests failed. for (Node* node = m_node->previousSibling(); node; node = node->previousSibling()) { if (node->renderer()) { // Do not return elements that are attached to a different flow-thread. if (node->renderer()->style() && !node->renderer()->style()->flowThread().isEmpty()) continue; return node->renderer(); } if (node->isContentElement()) { if (RenderObject* last = lastRendererOf(toHTMLContentElement(node))) return last; } } if (m_phase == AttachContentFallback) return NodeRenderingContext(m_node->parentNode()).previousRenderer(); return 0; }
void DistributionPool::distributeTo(InsertionPoint* insertionPoint, ElementShadowV0* elementShadow) { DistributedNodes distributedNodes; for (size_t i = 0; i < m_nodes.size(); ++i) { if (m_distributed[i]) continue; if (isHTMLContentElement(*insertionPoint) && !toHTMLContentElement(insertionPoint)->canSelectNode(m_nodes, i)) continue; Node* node = m_nodes[i]; distributedNodes.append(node); elementShadow->didDistributeNode(node, insertionPoint); m_distributed[i] = true; } // Distributes fallback elements if (insertionPoint->isContentInsertionPoint() && distributedNodes.isEmpty()) { for (Node* fallbackNode = insertionPoint->firstChild(); fallbackNode; fallbackNode = fallbackNode->nextSibling()) { distributedNodes.append(fallbackNode); elementShadow->didDistributeNode(fallbackNode, insertionPoint); } } insertionPoint->setDistributedNodes(distributedNodes); }
Element* HTMLDetailsElement::findMainSummary() const { if (HTMLSummaryElement* summary = Traversal<HTMLSummaryElement>::firstChild(*this)) return summary; HTMLContentElement* content = toHTMLContentElement(closedShadowRoot()->firstChild()); ASSERT(content->firstChild() && isHTMLSummaryElement(*content->firstChild())); return toElement(content->firstChild()); }
bool Internals::isValidContentSelect(Element* contentElement, ExceptionCode& ec) { if (!contentElement || !contentElement->isContentElement()) { ec = INVALID_ACCESS_ERR; return false; } return toHTMLContentElement(contentElement)->isSelectValid(); }
Element* HTMLDetailsElement::findMainSummary() const { for (Element* child = ElementTraversal::firstWithin(*this); child; child = ElementTraversal::nextSibling(*child)) { if (child->hasTagName(summaryTag)) return child; } HTMLContentElement* content = toHTMLContentElement(userAgentShadowRoot()->firstChild()); ASSERT(content->firstChild() && content->firstChild()->hasTagName(summaryTag)); return toElement(content->firstChild()); }
NodeRenderingContext::NodeRenderingContext(Node* node) : m_location(LocationNotInTree) , m_phase(AttachStraight) , m_node(node) , m_parentNodeForRenderingAndStyle(0) , m_visualParentShadowRoot(0) , m_includer(0) , m_style(0) , m_parentFlowRenderer(0) { ContainerNode* parent = m_node->parentOrHostNode(); if (!parent) return; if (parent->isShadowRoot()) { m_location = LocationShadowChild; m_parentNodeForRenderingAndStyle = parent->shadowHost(); return; } m_location = LocationLightChild; if (parent->isElementNode()) { m_visualParentShadowRoot = toElement(parent)->shadowRoot(); if (m_visualParentShadowRoot) { if ((m_includer = m_visualParentShadowRoot->includerFor(m_node)) && m_visualParentShadowRoot->isInclusionSelectorActive()) { m_phase = AttachContentForwarded; m_parentNodeForRenderingAndStyle = NodeRenderingContext(m_includer).parentNodeForRenderingAndStyle(); return; } m_phase = AttachContentLight; m_parentNodeForRenderingAndStyle = parent; return; } if (parent->isContentElement()) { HTMLContentElement* shadowContentElement = toHTMLContentElement(parent); if (!shadowContentElement->hasInclusion()) { m_phase = AttachContentFallback; m_parentNodeForRenderingAndStyle = NodeRenderingContext(parent).parentNodeForRenderingAndStyle(); return; } } } m_parentNodeForRenderingAndStyle = parent; }
void ElementShadow::collectSelectFeatureSetFrom(ShadowRoot& root) { if (!root.containsShadowRoots() && !root.containsContentElements()) return; for (Element& element : ElementTraversal::descendantsOf(root)) { if (ElementShadow* shadow = element.shadow()) m_selectFeatures.add(shadow->ensureSelectFeatureSet()); if (!isHTMLContentElement(element)) continue; const CSSSelectorList& list = toHTMLContentElement(element).selectorList(); m_selectFeatures.collectFeaturesFromSelectorList(list); } }
void ElementShadow::collectSelectFeatureSetFrom(ShadowRoot& root) { if (!root.containsShadowRoots() && !root.containsContentElements()) return; for (Element* element = ElementTraversal::firstWithin(root); element; element = ElementTraversal::next(*element, &root)) { if (ElementShadow* shadow = element->shadow()) m_selectFeatures.add(shadow->ensureSelectFeatureSet()); if (!isHTMLContentElement(*element)) continue; const CSSSelectorList& list = toHTMLContentElement(*element).selectorList(); for (const CSSSelector* selector = list.first(); selector; selector = CSSSelectorList::next(*selector)) { for (const CSSSelector* component = selector; component; component = component->tagHistory()) m_selectFeatures.collectFeaturesFromSelector(*component); } } }
RenderObject* NodeRenderingContext::nextRenderer() const { ASSERT(m_node->renderer() || m_location != LocationUndetermined); if (RenderObject* renderer = m_node->renderer()) return renderer->nextSibling(); if (m_parentFlowRenderer) return m_parentFlowRenderer->nextRendererForNode(m_node); if (m_phase == AttachContentForwarded) { if (RenderObject* found = nextRendererOf(m_includer, m_node)) return found; return NodeRenderingContext(m_includer).nextRenderer(); } // Avoid an O(n^2) problem with this function by not checking for // nextRenderer() when the parent element hasn't attached yet. if (m_node->parentOrHostNode() && !m_node->parentOrHostNode()->attached() && m_phase != AttachContentFallback) return 0; for (Node* node = m_node->nextSibling(); node; node = node->nextSibling()) { if (node->renderer()) { // Do not return elements that are attached to a different flow-thread. if (node->renderer()->style() && !node->renderer()->style()->flowThread().isEmpty()) continue; return node->renderer(); } if (node->isContentElement()) { if (RenderObject* first = firstRendererOf(toHTMLContentElement(node))) return first; } } if (m_phase == AttachContentFallback) return NodeRenderingContext(m_node->parentNode()).nextRenderer(); return 0; }