void LayoutMultiColumnFlowThread::evacuateAndDestroy() { LayoutBlockFlow* multicolContainer = multiColumnBlockFlow(); m_isBeingEvacuated = true; // Remove all sets and spanners. while (LayoutBox* columnBox = firstMultiColumnBox()) { ASSERT(columnBox->isAnonymous()); columnBox->destroy(); } ASSERT(!previousSibling()); ASSERT(!nextSibling()); // Finally we can promote all flow thread's children. Before we move them to the flow thread's // container, we need to unregister the flow thread, so that they aren't just re-added again to // the flow thread that we're trying to empty. multicolContainer->resetMultiColumnFlowThread(); moveAllChildrenTo(multicolContainer, true); // We used to manually nuke the line box tree here, but that should happen automatically when // moving children around (the code above). ASSERT(!firstLineBox()); destroy(); }
void removeNode(Node *n) { Node *parent; Node *prev; Node *next; parent = parentNode(n); if (!parent) return; prev = previousSibling(n); next = nextSibling(n); if (prev) { set_nextSibling(prev, next); } else { if (parent) { set_firstChild(parent, next); } } if (next) { set_previousSibling(next, prev); } else { if (parent) { set_lastChild(parent, prev); } } /* Delete attributes */ Delattr(n,"parentNode"); Delattr(n,"nextSibling"); Delattr(n,"prevSibling"); }
bool RenderSVGInlineText::characterStartsNewTextChunk(int position) const { ASSERT(m_attributes.xValues().size() == textLength()); ASSERT(m_attributes.yValues().size() == textLength()); ASSERT(position >= 0); ASSERT(position < static_cast<int>(textLength())); // Each <textPath> element starts a new text chunk, regardless of any x/y values. if (!position && parent()->isSVGTextPath() && !previousSibling()) return true; int currentPosition = 0; unsigned size = m_attributes.textMetricsValues().size(); for (unsigned i = 0; i < size; ++i) { const SVGTextMetrics& metrics = m_attributes.textMetricsValues().at(i); // We found the desired character. if (currentPosition == position) { return m_attributes.xValues().at(position) != SVGTextLayoutAttributes::emptyValue() || m_attributes.yValues().at(position) != SVGTextLayoutAttributes::emptyValue(); } currentPosition += metrics.length(); if (currentPosition > position) break; } // The desired position is available in the x/y list, but not in the character data values list. // That means the previous character data described a single glyph, consisting of multiple unicode characters. // The consequence is that the desired character does not define a new absolute x/y position, even if present in the x/y test. // This code is tested by svg/W3C-SVG-1.1/text-text-06-t.svg (and described in detail, why this influences chunk detection). return false; }
int toProjectTemplateItem::order(bool asc) { if (asc) { toProjectTemplateItem *item = previousSibling(); if (item) { int attemptOrder = item->Order + 1; if (attemptOrder != Order) Order = item->order(asc) + 1; } else Order = 1; } else { toProjectTemplateItem *item = dynamic_cast<toProjectTemplateItem *>(nextSibling()); if (item) { int attemptOrder = item->Order + 1; if (attemptOrder != Order) Order = item->order(asc) + 1; } else Order = 1; } return Order; }
RenderMultiColumnSet* RenderMultiColumnSet::previousSiblingMultiColumnSet() const { for (RenderObject* sibling = previousSibling(); sibling; sibling = sibling->previousSibling()) { if (sibling->isRenderMultiColumnSet()) return toRenderMultiColumnSet(sibling); } return 0; }
unsigned FlatTreeTraversal::index(const Node& node) { assertPrecondition(node); unsigned count = 0; for (Node* runner = traversePreviousSibling(node); runner; runner = previousSibling(*runner)) ++count; return count; }
LayoutMultiColumnSet* LayoutMultiColumnSet::previousSiblingMultiColumnSet() const { for (LayoutObject* sibling = previousSibling(); sibling; sibling = sibling->previousSibling()) { if (sibling->isLayoutMultiColumnSet()) return toLayoutMultiColumnSet(sibling); } return nullptr; }
RenderObject* RenderTextTrackCue::overlappingObjectForRect(const IntRect& rect) const { for (RenderObject* box = previousSibling(); box; box = box->previousSibling()) { IntRect boxRect = box->absoluteBoundingBoxRect(); if (rect.intersects(boxRect)) return box; } return 0; }
bool RenderVTTCue::isOverlapping() const { for (RenderObject* box = previousSibling(); box; box = box->previousSibling()) { IntRect boxRect = box->absoluteBoundingBoxRect(); if (absoluteBoundingBoxRect().intersects(boxRect)) return true; } return false; }
Node* previous(const Node* node, const Node* stayWithin) { if (node == stayWithin) return 0; if (Node* previousNode = previousSibling(node)) { while (Node* previousLastChild = lastChild(previousNode)) previousNode = previousLastChild; return previousNode; } return parent(node); }
void PseudoElement::dispose() { InspectorInstrumentation::pseudoElementDestroyed(this); ASSERT(!nextSibling()); ASSERT(!previousSibling()); detach(); RefPtr<Element> parent = parentOrShadowHostElement(); setParentOrShadowHostNode(0); removedFrom(parent.get()); }
static Node* pseudoAwarePreviousSibling(const Node& node) { Node* previousNode = previousSibling(node); Node* parentNode = parent(node); if (parentNode && parentNode->isElementNode() && !previousNode) { if (node.isAfterPseudoElement()) { if (Node* child = lastChild(*parentNode)) return child; } if (!node.isBeforePseudoElement()) return toElement(parentNode)->pseudoElement(PseudoIdBefore); } return previousNode; }
void PseudoElement::dispose() { DCHECK(parentOrShadowHostElement()); InspectorInstrumentation::pseudoElementDestroyed(this); DCHECK(!nextSibling()); DCHECK(!previousSibling()); detachLayoutTree(); Element* parent = parentOrShadowHostElement(); document().adoptIfNeeded(*this); setParentOrShadowHostNode(0); removedFrom(parent); }
bool LayoutSVGInlineText::characterStartsNewTextChunk(int position) const { ASSERT(position >= 0); ASSERT(position < static_cast<int>(textLength())); // Each <textPath> element starts a new text chunk, regardless of any x/y values. if (!position && parent()->isSVGTextPath() && !previousSibling()) return true; const SVGCharacterDataMap::const_iterator it = m_layoutAttributes.characterDataMap().find(static_cast<unsigned>(position + 1)); if (it == m_layoutAttributes.characterDataMap().end()) return false; return it->value.x != SVGTextLayoutAttributes::emptyValue() || it->value.y != SVGTextLayoutAttributes::emptyValue(); }
Frame* FrameTree::traversePreviousWithWrap(bool wrap) const { // FIXME: besides the wrap feature, this is just the traversePreviousNode algorithm if (Frame* prevSibling = previousSibling()) return prevSibling->tree().deepLastChild(); if (Frame* parentFrame = parent()) return parentFrame; // no siblings, no parent, self==top if (wrap) return deepLastChild(); // top view is always the last one in this ordering, so prev is nil without wrap return nullptr; }
void QAnimationGroupJob::prependAnimation(QAbstractAnimationJob *animation) { if (QAnimationGroupJob *oldGroup = animation->m_group) oldGroup->removeAnimation(animation); Q_ASSERT(!previousSibling() && !nextSibling()); if (m_firstChild) m_firstChild->m_previousSibling = animation; else m_lastChild = animation; animation->m_nextSibling = m_firstChild; m_firstChild = animation; animation->m_group = this; animationInserted(animation); }
void HTMLElement::setOuterText(const String &text, ExceptionState& exceptionState) { if (ieForbidsInsertHTML()) { exceptionState.throwDOMException(NoModificationAllowedError, "The '" + localName() + "' element does not support text insertion."); return; } if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(framesetTag) || hasLocalName(headTag) || hasLocalName(htmlTag) || hasLocalName(tableTag) || hasLocalName(tbodyTag) || hasLocalName(tfootTag) || hasLocalName(theadTag) || hasLocalName(trTag)) { exceptionState.throwDOMException(NoModificationAllowedError, "The '" + localName() + "' element does not support text insertion."); return; } ContainerNode* parent = parentNode(); if (!parent) { exceptionState.throwDOMException(NoModificationAllowedError, "The element has no parent."); return; } RefPtr<Node> prev = previousSibling(); RefPtr<Node> next = nextSibling(); RefPtr<Node> newChild; // Convert text to fragment with <br> tags instead of linebreaks if needed. if (text.contains('\r') || text.contains('\n')) newChild = textToFragment(text, exceptionState); else newChild = Text::create(document(), text); // textToFragment might cause mutation events. if (!this || !parentNode()) exceptionState.throwDOMException(HierarchyRequestError, "The element has no parent."); if (exceptionState.hadException()) return; parent->replaceChild(newChild.release(), this, exceptionState); RefPtr<Node> node = next ? next->previousSibling() : 0; if (!exceptionState.hadException() && node && node->isTextNode()) mergeWithNextTextNode(node.release(), exceptionState); if (!exceptionState.hadException() && prev && prev->isTextNode()) mergeWithNextTextNode(prev.release(), exceptionState); }
void HTMLElement::setOuterText(const String &text, ExceptionCode& ec) { if (ieForbidsInsertHTML()) { ec = NO_MODIFICATION_ALLOWED_ERR; return; } if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(framesetTag) || hasLocalName(headTag) || hasLocalName(htmlTag) || hasLocalName(tableTag) || hasLocalName(tbodyTag) || hasLocalName(tfootTag) || hasLocalName(theadTag) || hasLocalName(trTag)) { ec = NO_MODIFICATION_ALLOWED_ERR; return; } ContainerNode* parent = parentNode(); if (!parent) { ec = NO_MODIFICATION_ALLOWED_ERR; return; } RefPtr<Node> prev = previousSibling(); RefPtr<Node> next = nextSibling(); RefPtr<Node> newChild; ec = 0; // Convert text to fragment with <br> tags instead of linebreaks if needed. if (text.contains('\r') || text.contains('\n')) newChild = textToFragment(text, ec); else newChild = Text::create(document(), text); if (!this || !parentNode()) ec = HIERARCHY_REQUEST_ERR; if (ec) return; parent->replaceChild(newChild.release(), this, ec); RefPtr<Node> node = next ? next->previousSibling() : 0; if (!ec && node && node->isTextNode()) mergeWithNextTextNode(node.release(), ec); if (!ec && prev && prev->isTextNode()) mergeWithNextTextNode(prev.release(), ec); }
void HTMLElement::setOuterText(const String& text, ExceptionState& exceptionState) { if (ieForbidsInsertHTML()) { exceptionState.throwDOMException(NoModificationAllowedError, "The '" + localName() + "' element does not support text insertion."); return; } if (shouldProhibitSetInnerOuterText(*this)) { exceptionState.throwDOMException(NoModificationAllowedError, "The '" + localName() + "' element does not support text insertion."); return; } ContainerNode* parent = parentNode(); if (!parent) { exceptionState.throwDOMException(NoModificationAllowedError, "The element has no parent."); return; } RefPtrWillBeRawPtr<Node> prev = previousSibling(); RefPtrWillBeRawPtr<Node> next = nextSibling(); RefPtrWillBeRawPtr<Node> newChild = nullptr; // Convert text to fragment with <br> tags instead of linebreaks if needed. if (text.contains('\r') || text.contains('\n')) newChild = textToFragment(text, exceptionState); else newChild = Text::create(document(), text); // textToFragment might cause mutation events. if (!parentNode()) exceptionState.throwDOMException(HierarchyRequestError, "The element has no parent."); if (exceptionState.hadException()) return; parent->replaceChild(newChild.release(), this, exceptionState); RefPtrWillBeRawPtr<Node> node = next ? next->previousSibling() : nullptr; if (!exceptionState.hadException() && node && node->isTextNode()) mergeWithNextTextNode(toText(node.get()), exceptionState); if (!exceptionState.hadException() && prev && prev->isTextNode()) mergeWithNextTextNode(toText(prev.get()), exceptionState); }
void CharacterData::didModifyData(const String& oldData, UpdateSource source) { if (OwnPtrWillBeRawPtr<MutationObserverInterestGroup> mutationRecipients = MutationObserverInterestGroup::createForCharacterDataMutation(*this)) mutationRecipients->enqueueMutationRecord(MutationRecord::createCharacterData(this, oldData)); if (parentNode()) { ContainerNode::ChildrenChange change = {ContainerNode::TextChanged, previousSibling(), nextSibling(), ContainerNode::ChildrenChangeSourceAPI}; parentNode()->childrenChanged(change); } // Skip DOM mutation events if the modification is from parser. // Note that mutation observer events will still fire. // Spec: https://html.spec.whatwg.org/multipage/syntax.html#insert-a-character if (source != UpdateFromParser && !isInShadowTree()) { if (document().hasListenerType(Document::DOMCHARACTERDATAMODIFIED_LISTENER)) dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMCharacterDataModified, true, nullptr, oldData, m_data)); dispatchSubtreeModifiedEvent(); } InspectorInstrumentation::characterDataModified(this); }
void HTMLElement::setOuterHTML(const String& html, ExceptionState& es) { Node* p = parentNode(); if (!p || !p->isHTMLElement()) { es.throwDOMException(NoModificationAllowedError); return; } RefPtr<HTMLElement> parent = toHTMLElement(p); RefPtr<Node> prev = previousSibling(); RefPtr<Node> next = nextSibling(); RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, parent.get(), AllowScriptingContent, es); if (es.hadException()) return; parent->replaceChild(fragment.release(), this, es); RefPtr<Node> node = next ? next->previousSibling() : 0; if (!es.hadException() && node && node->isTextNode()) mergeWithNextTextNode(node.release(), es); if (!es.hadException() && prev && prev->isTextNode()) mergeWithNextTextNode(prev.release(), es); }
void HTMLElement::setOuterHTML(const String& html, ExceptionCode& ec) { Node* p = parentNode(); if (!p || !p->isHTMLElement()) { ec = NO_MODIFICATION_ALLOWED_ERR; return; } RefPtr<HTMLElement> parent = toHTMLElement(p); RefPtr<Node> prev = previousSibling(); RefPtr<Node> next = nextSibling(); RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, parent.get(), AllowScriptingContent, ec); if (ec) return; parent->replaceChild(fragment.release(), this, ec); RefPtr<Node> node = next ? next->previousSibling() : 0; if (!ec && node && node->isTextNode()) mergeWithNextTextNode(node.release(), ec); if (!ec && prev && prev->isTextNode()) mergeWithNextTextNode(prev.release(), ec); }
void deleteNode(Node *n) { Node *parent; Node *prev; Node *next; parent = parentNode(n); prev = previousSibling(n); next = nextSibling(n); if (prev) { set_nextSibling(prev,next); } else { if (parent) { set_firstChild(parent,next); } } if (next) { set_previousSibling(next,prev); } else { if (parent) { set_lastChild(parent,prev); } } }