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; }
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 CharacterData::updateRenderer(unsigned offsetOfReplacedData, unsigned lengthOfReplacedData) { if ((!renderer() || !rendererIsNeeded(NodeRenderingContext(this, renderer()->style()))) && attached()) reattach(); else if (renderer()) toRenderText(renderer())->setTextWithOffset(m_data.impl(), offsetOfReplacedData, lengthOfReplacedData); }
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()) 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(toShadowContentElement(node))) return first; } } return 0; }
Element* Internals::includerFor(Node* node, ExceptionCode& ec) { if (!node) { ec = INVALID_ACCESS_ERR; return 0; } return NodeRenderingContext(node).insertionPoint(); }
void Text::updateTextRenderer(unsigned offsetOfReplacedData, unsigned lengthOfReplacedData) { if (!attached()) return; RenderText* textRenderer = toRenderText(renderer()); if (!textRenderer || !textRendererIsNeeded(NodeRenderingContext(this, textRenderer->style()))) { reattach(); return; } textRenderer->setTextWithOffset(dataImpl(), offsetOfReplacedData, lengthOfReplacedData); }
void Text::updateTextRenderer(unsigned offsetOfReplacedData, unsigned lengthOfReplacedData, RecalcStyleBehavior recalcStyleBehavior) { if (!inActiveDocument()) return; RenderText* textRenderer = toRenderText(renderer()); if (!textRenderer || !textRendererIsNeeded(NodeRenderingContext(this, textRenderer->style()))) { lazyReattachIfAttached(); // FIXME: Editing should be updated so this is not neccesary. if (recalcStyleBehavior == DeprecatedRecalcStyleImmediatlelyForEditing) document().updateStyleIfNeeded(); return; } textRenderer->setTextWithOffset(dataImpl(), offsetOfReplacedData, lengthOfReplacedData); }
bool RenderNamedFlowThread::isChildAllowed(RenderObject* child, RenderStyle* style) const { ASSERT(child); ASSERT(style); if (!child->node()) return true; ASSERT(child->node()->isElementNode()); RenderObject* parentRenderer = NodeRenderingContext(child->node()).parentRenderer(); if (!parentRenderer) return true; return parentRenderer->isChildAllowed(child, style); }
static void createRendererIfNeeded(Element* element, const AttachContext& context) { NodeRenderingContext(element, context).createRendererForElementIfNeeded(); }
void Text::createTextRendererIfNeeded() { NodeRenderingContext(this).createRendererForTextIfNeeded(); }
void Text::attach(const AttachContext& context) { NodeRenderingContext(this, context.resolvedStyle).createRendererForTextIfNeeded(); CharacterData::attach(context); }