void RenderObjectChildList::insertChildNode(RenderObject* owner, RenderObject* newChild, RenderObject* beforeChild, bool notifyRenderer) { ASSERT(!newChild->parent()); ASSERT(!owner->isBlockFlow() || (!newChild->isTableSection() && !newChild->isTableRow() && !newChild->isTableCell())); while (beforeChild && beforeChild->parent() && beforeChild->parent() != owner) beforeChild = beforeChild->parent(); // This should never happen, but if it does prevent render tree corruption // where child->parent() ends up being owner but child->nextSibling()->parent() // is not owner. if (beforeChild && beforeChild->parent() != owner) { ASSERT_NOT_REACHED(); return; } newChild->setParent(owner); if (firstChild() == beforeChild) setFirstChild(newChild); if (beforeChild) { RenderObject* previousSibling = beforeChild->previousSibling(); if (previousSibling) previousSibling->setNextSibling(newChild); newChild->setPreviousSibling(previousSibling); newChild->setNextSibling(beforeChild); beforeChild->setPreviousSibling(newChild); } else { if (lastChild()) lastChild()->setNextSibling(newChild); newChild->setPreviousSibling(lastChild()); setLastChild(newChild); } if (!owner->documentBeingDestroyed() && notifyRenderer) newChild->insertedIntoTree(); if (!owner->documentBeingDestroyed()) { RenderCounter::rendererSubtreeAttached(newChild); } newChild->setNeedsLayoutAndPrefWidthsRecalc(); if (!owner->normalChildNeedsLayout()) owner->setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child. if (AXObjectCache* cache = owner->document()->axObjectCache()) cache->childrenChanged(owner); }
static Node* pseudoAwareLastChild(const Node& node) { if (node.isElementNode()) { const Element& currentElement = toElement(node); Node* last = currentElement.pseudoElement(PseudoIdAfter); if (last) return last; last = lastChild(currentElement); if (!last) last = currentElement.pseudoElement(PseudoIdBefore); return last; } return lastChild(node); }
void ShadowRoot::recalcStyle(StyleRecalcChange change) { // ShadowRoot doesn't support custom callbacks. ASSERT(!hasCustomStyleCallbacks()); StyleResolverParentScope parentScope(*this); if (styleChangeType() >= SubtreeStyleChange) change = Force; if (change < Force && hasRareData() && childNeedsStyleRecalc()) checkForChildrenAdjacentRuleChanges(); // There's no style to update so just calling recalcStyle means we're updated. clearNeedsStyleRecalc(); // FIXME: This doesn't handle :hover + div properly like Element::recalcStyle does. Text* lastTextNode = 0; for (Node* child = lastChild(); child; child = child->previousSibling()) { if (child->isTextNode()) { toText(child)->recalcTextStyle(change, lastTextNode); lastTextNode = toText(child); } else if (child->isElementNode()) { if (child->shouldCallRecalcStyle(change)) toElement(child)->recalcStyle(change, lastTextNode); if (child->renderer()) lastTextNode = 0; } } clearChildNeedsStyleRecalc(); }
bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction) { IntPoint pointInContainer(_x, _y); IntSize containerToParentOffset(_tx, _ty); IntPoint pointInParent = pointInContainer - containerToParentOffset; IntPoint pointInBorderBox = pointInParent - parentOriginToBorderBox(); // Note: For now, we're ignoring hits to border and padding for <svg> IntPoint pointInContentBox = pointInBorderBox - borderOriginToContentBox(); if (!contentBoxRect().contains(pointInContentBox)) return false; IntPoint localPoint = localToParentTransform().inverse().mapPoint(pointInParent); for (RenderObject* child = lastChild(); child; child = child->previousSibling()) { if (child->nodeAtFloatPoint(request, result, localPoint, hitTestAction)) { // FIXME: CSS/HTML assumes the local point is relative to the border box, right? updateHitTestResult(result, pointInBorderBox); return true; } } // Spec: Only graphical elements can be targeted by the mouse, so we don't check self here. // 16.4: "If there are no graphics elements whose relevant graphics content is under the pointer (i.e., there is no target element), the event is not dispatched." return false; }
bool RenderSVGContainer::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction) { // Give RenderSVGViewportContainer a chance to apply its viewport clip if (!pointIsInsideViewportClip(pointInParent)) return false; FloatPoint localPoint = localToParentTransform().inverse().mapPoint(pointInParent); if (!SVGRenderSupport::pointInClippingArea(this, localPoint)) return false; for (RenderObject* child = lastChild(); child; child = child->previousSibling()) { if (child->nodeAtFloatPoint(request, result, localPoint, hitTestAction)) { updateHitTestResult(result, roundedLayoutPoint(localPoint)); return true; } } // Accessibility wants to return SVG containers, if appropriate. if (request.type() & HitTestRequest::AccessibilityHitTest && m_objectBoundingBox.contains(localPoint)) { updateHitTestResult(result, roundedLayoutPoint(localPoint)); return true; } // Spec: Only graphical elements can be targeted by the mouse, period. // 16.4: "If there are no graphics elements whose relevant graphics content is under the pointer (i.e., there is no target element), the event is not dispatched." return false; }
void Element::recalcChildStyle(StyleRecalcChange change) { ASSERT(document().inStyleRecalc()); ASSERT(change >= Inherit || childNeedsStyleRecalc()); ASSERT(!needsStyleRecalc()); if (change > Inherit || childNeedsStyleRecalc()) { // This loop is deliberately backwards because we use insertBefore in the rendering tree, and want to avoid // a potentially n^2 loop to find the insertion point while resolving style. Having us start from the last // child and work our way back means in the common case, we'll find the insertion point in O(1) time. // See crbug.com/288225 StyleResolver& styleResolver = document().styleResolver(); for (Node* child = lastChild(); child; child = child->previousSibling()) { if (child->isTextNode()) { toText(child)->recalcTextStyle(change); } else if (child->isElementNode()) { Element* element = toElement(child); if (element->shouldCallRecalcStyle(change)) element->recalcStyle(change); else if (element->supportsStyleSharing()) styleResolver.addToStyleSharingList(*element); } } } }
bool RenderSVGContainer::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction) { // Give RenderSVGViewportContainer a chance to apply its viewport clip if (!pointIsInsideViewportClip(pointInParent)) return false; FloatPoint localPoint; if (!SVGRenderSupport::transformToUserSpaceAndCheckClipping(this, localToParentTransform(), pointInParent, localPoint)) return false; for (RenderObject* child = lastChild(); child; child = child->previousSibling()) { if (child->nodeAtFloatPoint(request, result, localPoint, hitTestAction)) { updateHitTestResult(result, roundedLayoutPoint(localPoint)); return true; } } // pointer-events=boundingBox makes it possible for containers to be direct targets if (style()->pointerEvents() == PE_BOUNDINGBOX) { ASSERT(isObjectBoundingBoxValid()); if (objectBoundingBox().contains(localPoint)) { updateHitTestResult(result, roundedLayoutPoint(localPoint)); return true; } } // 16.4: "If there are no graphics elements whose relevant graphics content is under the pointer (i.e., there is no target element), the event is not dispatched." return false; }
void RenderObjectChildList::appendChildNode(RenderObject* owner, RenderObject* newChild, bool notifyRenderer) { ASSERT(newChild->parent() == 0); ASSERT(!owner->isBlockFlow() || (!newChild->isTableSection() && !newChild->isTableRow() && !newChild->isTableCell())); newChild->setParent(owner); RenderObject* lChild = lastChild(); if (lChild) { newChild->setPreviousSibling(lChild); lChild->setNextSibling(newChild); } else setFirstChild(newChild); setLastChild(newChild); if (!owner->documentBeingDestroyed() && notifyRenderer) newChild->insertedIntoTree(); if (!owner->documentBeingDestroyed()) { RenderCounter::rendererSubtreeAttached(newChild); } newChild->setNeedsLayoutAndPrefWidthsRecalc(); // Goes up the containing block hierarchy. if (!owner->normalChildNeedsLayout()) owner->setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child. if (AXObjectCache::accessibilityEnabled()) owner->document()->axObjectCache()->childrenChanged(owner); }
bool RenderSVGContainer::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction) { if (!viewport().isEmpty() && style()->overflowX() == OHIDDEN && style()->overflowY() == OHIDDEN) { int tx = _tx + m_x; int ty = _ty + m_y; // Check if we need to do anything at all. IntRect overflowBox = overflowRect(false); overflowBox.move(tx, ty); AffineTransform ctm = RenderContainer::absoluteTransform(); ctm.translate(viewport().x(), viewport().y()); double localX, localY; ctm.inverse().map(_x + _tx, _y + _ty, &localX, &localY); if (!overflowBox.contains((int)localX, (int)localY)) return false; } for (RenderObject* child = lastChild(); child; child = child->previousSibling()) { if (child->nodeAtPoint(request, result, _x, _y, _tx, _ty, hitTestAction)) { updateHitTestResult(result, IntPoint(_x - _tx, _y - _ty)); return true; } } // Spec: Only graphical elements can be targeted by the mouse, period. // 16.4: "If there are no graphics elements whose relevant graphics content is under the pointer (i.e., there is no target element), the event is not dispatched." return false; }
bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const IntPoint& pointInContainer, const IntPoint& accumulatedOffset, HitTestAction hitTestAction) { IntPoint pointInParent = pointInContainer - toSize(accumulatedOffset); IntPoint pointInBorderBox = pointInParent - parentOriginToBorderBox(); // Note: For now, we're ignoring hits to border and padding for <svg> IntPoint pointInContentBox = pointInBorderBox - borderOriginToContentBox(); if (!contentBoxRect().contains(pointInContentBox)) return false; IntPoint localPoint = localToParentTransform().inverse().mapPoint(pointInParent); for (RenderObject* child = lastChild(); child; child = child->previousSibling()) { if (child->nodeAtFloatPoint(request, result, localPoint, hitTestAction)) { // FIXME: CSS/HTML assumes the local point is relative to the border box, right? updateHitTestResult(result, pointInBorderBox); // FIXME: nodeAtFloatPoint() doesn't handle rect-based hit tests yet. result.addNodeToRectBasedTestResult(child->node(), pointInContainer); return true; } } // If we didn't early exit above, we've just hit the container <svg> element. Unlike SVG 1.1, 2nd Edition allows container elements to be hit. if (hitTestAction == HitTestBlockBackground && style()->pointerEvents() != PE_NONE) { // Only return true here, if the last hit testing phase 'BlockBackground' is executed. If we'd return true in the 'Foreground' phase, // hit testing would stop immediately. For SVG only trees this doesn't matter. Though when we have a <foreignObject> subtree we need // to be able to detect hits on the background of a <div> element. If we'd return true here in the 'Foreground' phase, we are not able // to detect these hits anymore. updateHitTestResult(result, roundedIntPoint(localPoint)); return true; } return false; }
Node *Node::lastChildNE() { Node *n = lastChild(); while(n && n->tag->type == Tag::Empty) n = n->prev; return n; }
RenderObject* RenderObjectChildList::removeChildNode(RenderObject* owner, RenderObject* oldChild, bool notifyRenderer) { ASSERT(oldChild->parent() == owner); if (oldChild->isFloatingOrOutOfFlowPositioned()) toRenderBox(oldChild)->removeFloatingOrPositionedChildFromBlockLists(); // So that we'll get the appropriate dirty bit set (either that a normal flow child got yanked or // that a positioned child got yanked). if (!owner->documentBeingDestroyed() && notifyRenderer && oldChild->everHadLayout()) { oldChild->setNeedsLayoutAndPrefWidthsRecalc(); // We only repaint |oldChild| if we have a RenderLayer as its visual overflow may not be tracked by its parent. if (oldChild->hasLayer()) oldChild->repaint(); } // If we have a line box wrapper, delete it. if (oldChild->isBox()) toRenderBox(oldChild)->deleteLineBoxWrapper(); // If oldChild is the start or end of the selection, then clear the selection to // avoid problems of invalid pointers. // FIXME: The FrameSelection should be responsible for this when it // is notified of DOM mutations. if (!owner->documentBeingDestroyed() && oldChild->isSelectionBorder()) owner->view()->clearSelection(); if (!owner->documentBeingDestroyed() && notifyRenderer) oldChild->willBeRemovedFromTree(); // WARNING: There should be no code running between willBeRemovedFromTree and the actual removal below. // This is needed to avoid race conditions where willBeRemovedFromTree would dirty the tree's structure // and the code running here would force an untimely rebuilding, leaving |oldChild| dangling. if (oldChild->previousSibling()) oldChild->previousSibling()->setNextSibling(oldChild->nextSibling()); if (oldChild->nextSibling()) oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling()); if (firstChild() == oldChild) setFirstChild(oldChild->nextSibling()); if (lastChild() == oldChild) setLastChild(oldChild->previousSibling()); oldChild->setPreviousSibling(0); oldChild->setNextSibling(0); oldChild->setParent(0); // rendererRemovedFromTree walks the whole subtree. We can improve performance // by skipping this step when destroying the entire tree. if (!owner->documentBeingDestroyed()) { RenderCounter::rendererRemovedFromTree(oldChild); } if (AXObjectCache::accessibilityEnabled()) owner->document()->axObjectCache()->childrenChanged(owner); return oldChild; }
Frame* FrameTree::deepLastChild() const { Frame* result = &m_thisFrame; for (Frame* last = lastChild(); last; last = last->tree().lastChild()) result = last; return result; }
RenderObject* RenderObjectChildList::removeChildNode(RenderObject* owner, RenderObject* oldChild, bool notifyRenderer) { ASSERT(oldChild->parent() == owner); if (oldChild->isFloatingOrOutOfFlowPositioned()) toRenderBox(oldChild)->removeFloatingOrPositionedChildFromBlockLists(); // So that we'll get the appropriate dirty bit set (either that a normal flow child got yanked or // that a positioned child got yanked). We also repaint, so that the area exposed when the child // disappears gets repainted properly. if (!owner->documentBeingDestroyed() && notifyRenderer && oldChild->everHadLayout()) { oldChild->setNeedsLayoutAndPrefWidthsRecalc(); if (oldChild->isBody()) owner->view()->repaint(); else oldChild->repaint(); } // If we have a line box wrapper, delete it. if (oldChild->isBox()) toRenderBox(oldChild)->deleteLineBoxWrapper(); if (!owner->documentBeingDestroyed() && notifyRenderer) oldChild->willBeRemovedFromTree(); // If oldChild is the start or end of the selection, then clear the selection to // avoid problems of invalid pointers. // FIXME: The FrameSelection should be responsible for this when it // is notified of DOM mutations. if (!owner->documentBeingDestroyed() && oldChild->isSelectionBorder()) owner->view()->clearSelection(); // remove the child if (oldChild->previousSibling()) oldChild->previousSibling()->setNextSibling(oldChild->nextSibling()); if (oldChild->nextSibling()) oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling()); if (firstChild() == oldChild) setFirstChild(oldChild->nextSibling()); if (lastChild() == oldChild) setLastChild(oldChild->previousSibling()); oldChild->setPreviousSibling(0); oldChild->setNextSibling(0); oldChild->setParent(0); // rendererRemovedFromTree walks the whole subtree. We can improve performance // by skipping this step when destroying the entire tree. if (!owner->documentBeingDestroyed()) { RenderCounter::rendererRemovedFromTree(oldChild); } if (AXObjectCache::accessibilityEnabled()) owner->document()->axObjectCache()->childrenChanged(owner); return oldChild; }
void CounterNode::remove () { if (m_parent) m_parent->removeChild(this); else { Q_ASSERT(isReset()); Q_ASSERT(!firstChild()); Q_ASSERT(!lastChild()); } }
Node* FlatTreeTraversal::lastWithin(const Node& node) { assertPrecondition(node); Node* descendant = traverseLastChild(node); for (Node* child = descendant; child; child = lastChild(*child)) descendant = child; assertPostcondition(descendant); return descendant; }
void QSequentialAnimationGroupJob::restart() { // restarting the group by making the first/last animation the current one if (m_direction == Forward) { m_previousLoop = 0; if (m_currentAnimation == firstChild()) activateCurrentAnimation(); else setCurrentAnimation(firstChild()); } else { // direction == Backward m_previousLoop = m_loopCount - 1; if (m_currentAnimation == lastChild()) activateCurrentAnimation(); else setCurrentAnimation(lastChild()); } }
void RenderObjectChildList::appendChildNode(RenderObject* owner, RenderObject* newChild, bool fullAppend) { ASSERT(newChild->parent() == 0); ASSERT(!owner->isBlockFlow() || (!newChild->isTableSection() && !newChild->isTableRow() && !newChild->isTableCell())); newChild->setParent(owner); RenderObject* lChild = lastChild(); if (lChild) { newChild->setPreviousSibling(lChild); lChild->setNextSibling(newChild); } else setFirstChild(newChild); setLastChild(newChild); if (fullAppend) { // Keep our layer hierarchy updated. Optimize for the common case where we don't have any children // and don't have a layer attached to ourselves. RenderLayer* layer = 0; if (newChild->firstChild() || newChild->hasLayer()) { layer = owner->enclosingLayer(); newChild->addLayers(layer); } // if the new child is visible but this object was not, tell the layer it has some visible content // that needs to be drawn and layer visibility optimization can't be used if (owner->style()->visibility() != VISIBLE && newChild->style()->visibility() == VISIBLE && !newChild->hasLayer()) { if (!layer) layer = owner->enclosingLayer(); if (layer) layer->setHasVisibleContent(true); } if (newChild->isListItem()) toRenderListItem(newChild)->updateListMarkerNumbers(); if (!newChild->isFloating() && owner->childrenInline()) owner->dirtyLinesFromChangedChild(newChild); if (newChild->isRenderRegion()) toRenderRegion(newChild)->attachRegion(); if (RenderNamedFlowThread* containerFlowThread = renderNamedFlowThreadContainer(owner)) containerFlowThread->addFlowChild(newChild); } RenderCounter::rendererSubtreeAttached(newChild); RenderQuote::rendererSubtreeAttached(newChild); newChild->setNeedsLayoutAndPrefWidthsRecalc(); // Goes up the containing block hierarchy. if (!owner->normalChildNeedsLayout()) owner->setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child. if (AXObjectCache::accessibilityEnabled()) owner->document()->axObjectCache()->childrenChanged(owner); }
LayoutTextFragment* LayoutQuote::findFragmentChild() const { // We walk from the end of the child list because, if we've had a first-letter // LayoutObject inserted then the remaining text will be at the end. while (LayoutObject* child = lastChild()) { if (child->isText() && toLayoutText(child)->isTextFragment()) return toLayoutTextFragment(child); } return nullptr; }
RenderObject* RenderObjectChildList::removeChildNode(RenderObject* owner, RenderObject* oldChild, bool notifyRenderer) { ASSERT(oldChild->parent() == owner); if (oldChild->isFloatingOrOutOfFlowPositioned()) toRenderBox(oldChild)->removeFloatingOrPositionedChildFromBlockLists(); { // FIXME: We should not be allowing paint invalidation during layout. crbug.com/336250 AllowPaintInvalidationScope scoper(owner->frameView()); // So that we'll get the appropriate dirty bit set (either that a normal flow child got yanked or // that a positioned child got yanked). We also issue paint invalidations, so that the area exposed when the child // disappears gets paint invalidated properly. if (!owner->documentBeingDestroyed() && notifyRenderer && oldChild->everHadLayout()) { oldChild->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(); oldChild->invalidatePaintForWholeRenderer(); } } // If we have a line box wrapper, delete it. if (oldChild->isBox()) toRenderBox(oldChild)->deleteLineBoxWrapper(); // If oldChild is the start or end of the selection, then clear the selection to // avoid problems of invalid pointers. // FIXME: The FrameSelection should be responsible for this when it // is notified of DOM mutations. if (!owner->documentBeingDestroyed() && oldChild->isSelectionBorder()) owner->view()->clearSelection(); if (!owner->documentBeingDestroyed() && notifyRenderer) oldChild->willBeRemovedFromTree(); // WARNING: There should be no code running between willBeRemovedFromTree and the actual removal below. // This is needed to avoid race conditions where willBeRemovedFromTree would dirty the tree's structure // and the code running here would force an untimely rebuilding, leaving |oldChild| dangling. if (oldChild->previousSibling()) oldChild->previousSibling()->setNextSibling(oldChild->nextSibling()); if (oldChild->nextSibling()) oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling()); if (firstChild() == oldChild) setFirstChild(oldChild->nextSibling()); if (lastChild() == oldChild) setLastChild(oldChild->previousSibling()); oldChild->setPreviousSibling(0); oldChild->setNextSibling(0); oldChild->setParent(0); return oldChild; }
void Node::append(Node* node) { assert(!node->parent()); assert(!node->previousSibling()); assert(!node->nextSibling()); node->setParent(this); if (!firstChild()) { assert(!lastChild()); setFirstChild(node); setLastChild(node); } else { assert(lastChild()); Node* lastChild = this->lastChild(); assert(!lastChild->nextSibling()); lastChild->setNextSibling(node); node->setPreviousSibling(lastChild); setLastChild(node); } }
FbTextElement FbTextElement::operator[](const QString &name) { FbTextElement child = firstChild(); while (!child.isNull()) { if (child.tagName().toLower() == name) return child; child = child.nextSibling(); } QString html = QString("<%1></%1>").arg(name); appendInside(html); return lastChild(); }
void RenderObjectChildList::insertChildNode(RenderObject* owner, RenderObject* newChild, RenderObject* beforeChild, bool notifyRenderer) { ASSERT(!newChild->parent()); while (beforeChild && beforeChild->parent() && beforeChild->parent() != owner) beforeChild = beforeChild->parent(); // This should never happen, but if it does prevent render tree corruption // where child->parent() ends up being owner but child->nextSibling()->parent() // is not owner. if (beforeChild && beforeChild->parent() != owner) { ASSERT_NOT_REACHED(); return; } newChild->setParent(owner); if (firstChild() == beforeChild) setFirstChild(newChild); if (beforeChild) { RenderObject* previousSibling = beforeChild->previousSibling(); if (previousSibling) previousSibling->setNextSibling(newChild); newChild->setPreviousSibling(previousSibling); newChild->setNextSibling(beforeChild); beforeChild->setPreviousSibling(newChild); } else { if (lastChild()) lastChild()->setNextSibling(newChild); newChild->setPreviousSibling(lastChild()); setLastChild(newChild); } if (!owner->documentBeingDestroyed() && notifyRenderer) newChild->insertedIntoTree(); newChild->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(); if (!owner->normalChildNeedsLayout()) owner->setChildNeedsLayout(); // We may supply the static position for an absolute positioned child. }
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); }
bool RenderSVGContainer::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction) { for (RenderObject* child = lastChild(); child; child = child->previousSibling()) { if (child->nodeAtPoint(request, result, _x, _y, _tx, _ty, hitTestAction)) { updateHitTestResult(result, IntPoint(_x - _tx, _y - _ty)); return true; } } // Spec: Only graphical elements can be targeted by the mouse, period. // 16.4: "If there are no graphics elements whose relevant graphics content is under the pointer (i.e., there is no target element), the event is not dispatched." return false; }
void RenderInline::addChildToFlow(RenderObject* newChild, RenderObject* beforeChild) { // Make sure we don't append things after :after-generated content if we have it. if (!beforeChild && isAfterContent(lastChild())) beforeChild = lastChild(); if (!newChild->isInline() && !newChild->isFloatingOrPositioned()) { // We are placing a block inside an inline. We have to perform a split of this // inline into continuations. This involves creating an anonymous block box to hold // |newChild|. We then make that block box a continuation of this inline. We take all of // the children after |beforeChild| and put them in a clone of this object. RefPtr<RenderStyle> newStyle = RenderStyle::create(); newStyle->inheritFrom(style()); newStyle->setDisplay(BLOCK); RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */); newBox->setStyle(newStyle.release()); RenderFlow* oldContinuation = continuation(); setContinuation(newBox); // Someone may have put a <p> inside a <q>, causing a split. When this happens, the :after content // has to move into the inline continuation. Call updateBeforeAfterContent to ensure that our :after // content gets properly destroyed. bool isLastChild = (beforeChild == lastChild()); if (document()->usesBeforeAfterRules()) updateBeforeAfterContent(RenderStyle::AFTER); if (isLastChild && beforeChild != lastChild()) beforeChild = 0; // We destroyed the last child, so now we need to update our insertion // point to be 0. It's just a straight append now. splitFlow(beforeChild, newBox, newChild, oldContinuation); return; } RenderContainer::addChild(newChild, beforeChild); newChild->setNeedsLayoutAndPrefWidthsRecalc(); }
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 Playlist::appendTracks( const QList<Track*> tracks ) { // a week attempt to speed up the setItemWidget time issue setUpdatesEnabled(false); bool doSort = isSortingEnabled(); setSortingEnabled(false); hide(); appendTracks( tracks,(PlaylistItem*)lastChild()); setSortingEnabled(doSort); setUpdatesEnabled(true); show(); }
void RenderQuote::updateText() { String text = computeText(); if (m_text == text) return; m_text = text; // Start from the end of the child list because, if we've had a first-letter // renderer inserted then the remaining text will be at the end. if (auto* fragment = fragmentChild(lastChild())) { fragment->setContentString(m_text); return; } addChild(new RenderTextFragment(document(), m_text)); }
void QSequentialAnimationGroupJob::rewindForwards(const AnimationIndex &newAnimationIndex) { if (m_previousLoop > m_currentLoop) { // we need to fast rewind to the beginning for (QAbstractAnimationJob *anim = m_currentAnimation; anim; anim = anim->previousSibling()) { RETURN_IF_DELETED(setCurrentAnimation(anim, true)); RETURN_IF_DELETED(anim->setCurrentTime(0)); } // this will make sure the current animation is reset to the end if (lastChild() && !lastChild()->previousSibling()) { //count == 1 // we need to force activation because setCurrentAnimation will have no effect RETURN_IF_DELETED(activateCurrentAnimation()); } else { RETURN_IF_DELETED(setCurrentAnimation(lastChild(), true)); } } // and now we need to fast rewind from the current position to for (QAbstractAnimationJob *anim = m_currentAnimation; anim && anim != newAnimationIndex.animation; anim = anim->previousSibling()) { RETURN_IF_DELETED(setCurrentAnimation(anim, true)); RETURN_IF_DELETED(anim->setCurrentTime(0)); } // setting the new current animation will happen later }