void Text::reattachIfNeeded(const AttachContext& context) { bool layoutObjectIsNeeded = false; ContainerNode* layoutParent = LayoutTreeBuilderTraversal::parent(*this); if (layoutParent) { if (LayoutObject* parentLayoutObject = layoutParent->layoutObject()) { if (textLayoutObjectIsNeeded(*parentLayoutObject->style(), *parentLayoutObject)) layoutObjectIsNeeded = true; } } if (layoutObjectIsNeeded == !!layoutObject()) return; // The following is almost the same as Node::reattach() except that we create a layoutObject only if needed. // Not calling reattach() to avoid repeated calls to Text::textLayoutObjectIsNeeded(). AttachContext reattachContext(context); reattachContext.performingReattach = true; if (getStyleChangeType() < NeedsReattachStyleChange) detach(reattachContext); if (layoutObjectIsNeeded) LayoutTreeBuilderForText(*this, layoutParent->layoutObject()).createLayoutObject(); CharacterData::attach(reattachContext); }
bool HTMLFormElement::layoutObjectIsNeeded(const ComputedStyle& style) { if (!m_wasDemoted) return HTMLElement::layoutObjectIsNeeded(style); ContainerNode* node = parentNode(); if (!node || !node->layoutObject()) return HTMLElement::layoutObjectIsNeeded(style); LayoutObject* parentLayoutObject = node->layoutObject(); // FIXME: Shouldn't we also check for table caption (see |formIsTablePart| below). // FIXME: This check is not correct for Shadow DOM. bool parentIsTableElementPart = (parentLayoutObject->isTable() && isHTMLTableElement(*node)) || (parentLayoutObject->isTableRow() && isHTMLTableRowElement(*node)) || (parentLayoutObject->isTableSection() && node->hasTagName(tbodyTag)) || (parentLayoutObject->isLayoutTableCol() && node->hasTagName(colTag)) || (parentLayoutObject->isTableCell() && isHTMLTableRowElement(*node)); if (!parentIsTableElementPart) return true; EDisplay display = style.display(); bool formIsTablePart = display == TABLE || display == INLINE_TABLE || display == TABLE_ROW_GROUP || display == TABLE_HEADER_GROUP || display == TABLE_FOOTER_GROUP || display == TABLE_ROW || display == TABLE_COLUMN_GROUP || display == TABLE_COLUMN || display == TABLE_CELL || display == TABLE_CAPTION; return formIsTablePart; }
void SVGFELightElement::svgAttributeChanged(const QualifiedName& attrName) { if (attrName == SVGNames::azimuthAttr || attrName == SVGNames::elevationAttr || attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || attrName == SVGNames::zAttr || attrName == SVGNames::pointsAtXAttr || attrName == SVGNames::pointsAtYAttr || attrName == SVGNames::pointsAtZAttr || attrName == SVGNames::specularExponentAttr || attrName == SVGNames::limitingConeAngleAttr) { ContainerNode* parent = parentNode(); if (!parent) return; LayoutObject* layoutObject = parent->layoutObject(); if (!layoutObject || !layoutObject->isSVGResourceFilterPrimitive()) return; SVGElement::InvalidationGuard invalidationGuard(this); if (isSVGFEDiffuseLightingElement(*parent)) { toSVGFEDiffuseLightingElement(*parent).lightElementAttributeChanged(this, attrName); return; } if (isSVGFESpecularLightingElement(*parent)) { toSVGFESpecularLightingElement(*parent).lightElementAttributeChanged(this, attrName); return; } ASSERT_NOT_REACHED(); } SVGElement::svgAttributeChanged(attrName); }
void invalidateFilterPrimitiveParent(SVGElement* element) { if (!element) return; ContainerNode* parent = element->parentNode(); if (!parent) return; LayoutObject* layoutObject = parent->layoutObject(); if (!layoutObject || !layoutObject->isSVGResourceFilterPrimitive()) return; LayoutSVGResourceContainer::markForLayoutAndParentResourceInvalidation(layoutObject, false); }
Node* StyledMarkupTraverser<Strategy>::traverse(Node* startNode, Node* pastEnd) { HeapVector<Member<ContainerNode>> ancestorsToClose; Node* next; Node* lastClosed = nullptr; for (Node* n = startNode; n && n != pastEnd; n = next) { // If |n| is a selection boundary such as <input>, traverse the child // nodes in the DOM tree instead of the flat tree. if (handleSelectionBoundary<Strategy>(*n)) { lastClosed = StyledMarkupTraverser<EditingStrategy>(m_accumulator, m_lastClosed.get()).traverse(n, EditingStrategy::nextSkippingChildren(*n)); next = EditingInFlatTreeStrategy::nextSkippingChildren(*n); } else { next = Strategy::next(*n); if (isEnclosingBlock(n) && canHaveChildrenForEditing(n) && next == pastEnd) { // Don't write out empty block containers that aren't fully selected. continue; } if (!n->layoutObject() && !enclosingElementWithTag(firstPositionInOrBeforeNode(n), selectTag)) { next = Strategy::nextSkippingChildren(*n); // Don't skip over pastEnd. if (pastEnd && Strategy::isDescendantOf(*pastEnd, *n)) next = pastEnd; } else { // Add the node to the markup if we're not skipping the descendants appendStartMarkup(*n); // If node has no children, close the tag now. if (Strategy::hasChildren(*n)) { ancestorsToClose.append(toContainerNode(n)); continue; } appendEndMarkup(*n); lastClosed = n; } } // If we didn't insert open tag and there's no more siblings or we're at the end of the traversal, take care of ancestors. // FIXME: What happens if we just inserted open tag and reached the end? if (Strategy::nextSibling(*n) && next != pastEnd) continue; // Close up the ancestors. while (!ancestorsToClose.isEmpty()) { ContainerNode* ancestor = ancestorsToClose.last(); ASSERT(ancestor); if (next && next != pastEnd && Strategy::isDescendantOf(*next, *ancestor)) break; // Not at the end of the range, close ancestors up to sibling of next node. appendEndMarkup(*ancestor); lastClosed = ancestor; ancestorsToClose.removeLast(); } // Surround the currently accumulated markup with markup for ancestors we never opened as we leave the subtree(s) rooted at those ancestors. ContainerNode* nextParent = next ? Strategy::parent(*next) : nullptr; if (next == pastEnd || n == nextParent) continue; ASSERT(n); Node* lastAncestorClosedOrSelf = (lastClosed && Strategy::isDescendantOf(*n, *lastClosed)) ? lastClosed : n; for (ContainerNode* parent = Strategy::parent(*lastAncestorClosedOrSelf); parent && parent != nextParent; parent = Strategy::parent(*parent)) { // All ancestors that aren't in the ancestorsToClose list should either be a) unrendered: if (!parent->layoutObject()) continue; // or b) ancestors that we never encountered during a pre-order traversal starting at startNode: ASSERT(startNode); ASSERT(Strategy::isDescendantOf(*startNode, *parent)); RawPtr<EditingStyle> style = createInlineStyleIfNeeded(*parent); wrapWithNode(*parent, style); lastClosed = parent; } } return lastClosed; }