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();
}
Exemplo n.º 2
0
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");
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
0
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);
}
Exemplo n.º 11
0
void PseudoElement::dispose()
{
    InspectorInstrumentation::pseudoElementDestroyed(this);

    ASSERT(!nextSibling());
    ASSERT(!previousSibling());

    detach();
    RefPtr<Element> parent = parentOrShadowHostElement();
    setParentOrShadowHostNode(0);
    removedFrom(parent.get());
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
void PseudoElement::dispose() {
  DCHECK(parentOrShadowHostElement());

  InspectorInstrumentation::pseudoElementDestroyed(this);

  DCHECK(!nextSibling());
  DCHECK(!previousSibling());

  detachLayoutTree();
  Element* parent = parentOrShadowHostElement();
  document().adoptIfNeeded(*this);
  setParentOrShadowHostNode(0);
  removedFrom(parent);
}
Exemplo n.º 14
0
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();
}
Exemplo n.º 15
0
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;
}
Exemplo n.º 16
0
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);
}
Exemplo n.º 17
0
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);
}
Exemplo n.º 18
0
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);
}
Exemplo n.º 19
0
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);
}
Exemplo n.º 20
0
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);
}
Exemplo n.º 21
0
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);
}
Exemplo n.º 22
0
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);
}
Exemplo n.º 23
0
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);
    }
  }
}