bool NodeRenderingContext::shouldCreateRenderer() const { ASSERT(m_location != LocationUndetermined); ASSERT(parentNodeForRenderingAndStyle()); if (m_location == LocationNotInTree || m_phase == AttachContentLight) return false; RenderObject* parentRenderer = this->parentRenderer(); if (!parentRenderer) return false; if (m_location == LocationLightChild && m_phase == AttachStraight) { // FIXME: Ignoring canHaveChildren() in a case of shadow children might be wrong. // See https://bugs.webkit.org/show_bug.cgi?id=52423 if (!parentRenderer->canHaveChildren()) return false; if (m_visualParentShadowRoot) return false; } if (!m_parentNodeForRenderingAndStyle->childShouldCreateRenderer(m_node)) return false; return true; }
RenderBlock* RenderTextFragment::blockForAccompanyingFirstLetter() const { if (!m_firstLetter) return 0; for (RenderObject* block = m_firstLetter->parent(); block; block = block->parent()) { if (block->style()->hasPseudoStyle(FIRST_LETTER) && block->canHaveChildren() && block->isRenderBlock()) return toRenderBlock(block); } return 0; }
bool NodeRenderingContext::shouldCreateRenderer() const { if (!m_renderingParent) return false; RenderObject* parentRenderer = this->parentRenderer(); if (!parentRenderer) return false; if (!parentRenderer->canHaveChildren()) return false; if (!m_renderingParent->childShouldCreateRenderer(*this)) return false; return true; }
bool Text::textRendererIsNeeded(const RenderStyle& style, const RenderObject& parent) { if (!parent.canHaveChildren()) return false; if (isEditingText()) return true; if (!length()) return false; if (style.display() == NONE) return false; if (!containsOnlyWhitespace()) return true; if (!canHaveWhitespaceChildren(parent)) return false; if (style.preserveNewline()) // pre/pre-wrap/pre-line always make renderers. return true; const RenderObject* prev = NodeRenderingTraversal::previousSiblingRenderer(*this); if (prev && prev->isBR()) // <span><br/> <br/></span> return false; if (parent.isRenderInline()) { // <span><div/> <div/></span> if (prev && !prev->isInline()) return false; } else { if (parent.isRenderBlock() && !parent.childrenInline() && (!prev || !prev->isInline())) return false; // Avoiding creation of a Renderer for the text node is a non-essential memory optimization. // So to avoid blowing up on very wide DOMs, we limit the number of siblings to visit. unsigned maxSiblingsToVisit = 50; RenderObject* first = parent.slowFirstChild(); while (first && first->isFloatingOrOutOfFlowPositioned() && maxSiblingsToVisit--) first = first->nextSibling(); if (!first || first == renderer() || NodeRenderingTraversal::nextSiblingRenderer(*this) == first) // Whitespace at the start of a block just goes away. Don't even // make a render object for this text. return false; } return true; }
bool NodeRenderingContext::shouldCreateRenderer() const { if (!m_node->document()->shouldCreateRenderers()) return false; if (!m_renderingParent) return false; RenderObject* parentRenderer = this->parentRenderer(); if (!parentRenderer) return false; if (!parentRenderer->canHaveChildren() && !(m_node->isPseudoElement() && parentRenderer->canHaveGeneratedChildren())) return false; if (!m_renderingParent->childShouldCreateRenderer(*this)) return false; return true; }
static bool shouldCreateRenderer(const Element& element, const ContainerNode* renderingParent) { if (!element.document().shouldCreateRenderers()) return false; if (!renderingParent) return false; RenderObject* parentRenderer = renderingParent->renderer(); if (!parentRenderer) return false; if (!parentRenderer->canHaveChildren() && !(element.isPseudoElement() && parentRenderer->canHaveGeneratedChildren())) return false; if (!renderingParent->childShouldCreateRenderer(&element)) return false; return true; }
bool NodeRenderingContext::shouldCreateRenderer() const { if (!m_node->document()->shouldCreateRenderers()) return false; if (!m_parentDetails.node()) return false; RenderObject* parentRenderer = this->parentRenderer(); if (!parentRenderer) return false; if (!parentRenderer->canHaveChildren()) return false; if (!m_parentDetails.node()->childShouldCreateRenderer(*this)) return false; return true; }
bool NodeRenderingContext::shouldCreateRenderer() const { ASSERT(m_phase != Calculating); ASSERT(parentNodeForRenderingAndStyle()); if (m_phase == AttachingNotInTree || m_phase == AttachingNotDistributed || m_phase == AttachingNotFallbacked) return false; RenderObject* parentRenderer = this->parentRenderer(); if (!parentRenderer) return false; if (!parentRenderer->canHaveChildren()) return false; if (!m_parentNodeForRenderingAndStyle->childShouldCreateRenderer(*this)) return false; return true; }
static void createTextRendererIfNeeded(Text& textNode) { ASSERT(!textNode.renderer()); ContainerNode* renderingParentNode = NodeRenderingTraversal::parent(&textNode); if (!renderingParentNode) return; RenderObject* parentRenderer = renderingParentNode->renderer(); if (!parentRenderer || !parentRenderer->canHaveChildren()) return; if (!renderingParentNode->childShouldCreateRenderer(&textNode)) return; Document& document = textNode.document(); RefPtr<RenderStyle> style; bool resetStyleInheritance = textNode.parentNode()->isShadowRoot() && toShadowRoot(textNode.parentNode())->resetStyleInheritance(); if (resetStyleInheritance) style = document.ensureStyleResolver().defaultStyleForElement(); else style = parentRenderer->style(); if (!textRendererIsNeeded(textNode, *parentRenderer, *style)) return; RenderText* newRenderer = textNode.createTextRenderer(document.renderArena(), style.get()); if (!newRenderer) return; if (!parentRenderer->isChildAllowed(newRenderer, style.get())) { newRenderer->destroy(); return; } // Make sure the RenderObject already knows it is going to be added to a RenderFlowThread before we set the style // for the first time. Otherwise code using inRenderFlowThread() in the styleWillChange and styleDidChange will fail. newRenderer->setFlowThreadState(parentRenderer->flowThreadState()); RenderObject* nextRenderer = nextSiblingRenderer(textNode); textNode.setRenderer(newRenderer); // Parent takes care of the animations, no need to call setAnimatableStyle. newRenderer->setStyle(style.release()); parentRenderer->addChild(newRenderer, nextRenderer); Node* sibling = textNode.nextSibling(); if (sibling && !sibling->renderer() && sibling->attached()) createTextRenderersForSiblingsAfterAttachIfNeeded(sibling); }
bool RenderTreeBuilder::shouldCreateRenderer() const { if (!m_renderingParent) return false; if (m_node->isSVGElement()) { // SVG elements only render when inside <svg>, or if the element is an <svg> itself. if (!isSVGSVGElement(*m_node) && !m_renderingParent->isSVGElement()) return false; if (!toSVGElement(m_node)->isValid()) return false; } RenderObject* parentRenderer = this->parentRenderer(); if (!parentRenderer) return false; if (!parentRenderer->canHaveChildren()) return false; return true; }
// Check the specific case of elements that are children of regions but are flowed into a flow thread themselves. bool NodeRenderingContext::elementInsideRegionNeedsRenderer() { Element* element = toElement(m_node); bool elementInsideRegionNeedsRenderer = false; RenderObject* parentRenderer = this->parentRenderer(); if ((parentRenderer && !parentRenderer->canHaveChildren() && parentRenderer->isRenderRegion()) || (!parentRenderer && element->parentElement() && element->parentElement()->isInsideRegion())) { if (!m_style) m_style = element->styleForRenderer(); elementInsideRegionNeedsRenderer = element->shouldMoveToFlowThread(m_style.get()); // Children of this element will only be allowed to be flowed into other flow-threads if display is NOT none. if (element->rendererIsNeeded(*this)) element->setIsInsideRegion(true); } return elementInsideRegionNeedsRenderer; }
bool NodeRenderingContext::shouldCreateRenderer() { if (!m_node->document()->shouldCreateRenderers()) return false; if (!m_renderingParent) return false; RenderObject* parentRenderer = this->parentRenderer(); if (!parentRenderer) return false; if (!parentRenderer->canHaveChildren()) { if (parentRenderer->canDOMChildrenHaveRenderParent()) { // In a region, only the children that need to be in a flow thread should have a renderer. bool shouldBeInNamedFlow = m_node->isElementNode() && toElement(m_node)->moveToFlowThreadIsNeeded(m_style); if (!shouldBeInNamedFlow) return false; } else return false; } if (!m_renderingParent->childShouldCreateRenderer(*this)) return false; return true; }