Esempio n. 1
0
void RangeImpl::setEndAfter(const DOM_Node& refNode)
{
    if( fDetached) {
        throw DOM_DOMException(
            DOM_DOMException::INVALID_STATE_ERR, null);
    }
    if ( !hasLegalRootContainer(refNode) || !isLegalContainedNode(refNode)) {
        throw DOM_RangeException(
            DOM_RangeException::INVALID_NODE_TYPE_ERR, null);
    }

    fEndContainer = refNode.getParentNode();
    unsigned int i = 0;
    for (DOM_Node n = refNode; n!=null; n = n.getPreviousSibling(), i++) ;

    if (i ==0)
        fEndOffset = 0;
    else
        fEndOffset = i;

    if ((fDocument != refNode.getOwnerDocument() )
            && (refNode.getOwnerDocument().fImpl != 0) )
    {
        fDocument = refNode.getOwnerDocument();
        collapse(true);
    }

    //compare the start and end boundary point
    //collapse if start point is after the end point
    if(compareBoundaryPoints(DOM_Range::END_TO_START, this) == 1)
        collapse(false); //collapse the range positions to end
    else
        fCollapsed = false;
}
Esempio n. 2
0
const DOM_Node RangeImpl::commonAncestorOf(const DOM_Node& pointA, const DOM_Node& pointB) const
{
    if (fDetached)
        throw DOM_DOMException(DOM_DOMException::INVALID_STATE_ERR, null);

    if (pointA.getOwnerDocument() != pointB.getOwnerDocument())
        throw DOM_DOMException( DOM_DOMException::WRONG_DOCUMENT_ERR, null );

    //if the containers are same then it itself is its common ancestor.
    if (pointA == pointB)
        return pointA;

    typedef RefVectorOf<NodeImpl> VectorNodes;
    VectorNodes* startV= new (((DocumentImpl*)fDocument.fImpl)->getMemoryManager()) VectorNodes(1, false, ((DocumentImpl*)fDocument.fImpl)->getMemoryManager());
    DOM_Node node;

    for (node=fStartContainer; node != null; node=node.getParentNode())
    {
        startV->addElement(node.fImpl);
    }
    VectorNodes* endV = new (((DocumentImpl*)fDocument.fImpl)->getMemoryManager()) VectorNodes(1, false, ((DocumentImpl*)fDocument.fImpl)->getMemoryManager());
    for (node=fEndContainer; node != null; node=node.getParentNode())
    {
        endV->addElement(node.fImpl);
    }

    int s = startV->size()-1;
    int e = endV->size()-1;

    NodeImpl* commonAncestor = 0;

    while (s>=0 && e>=0) {
        if (startV->elementAt(s) == endV->elementAt(e)) {
            commonAncestor = startV->elementAt(s);
        }
        else  break;
        --s;
        --e;
    }

    delete startV;
    delete endV;

    return DOM_Node(commonAncestor);
}
Esempio n. 3
0
void RangeImpl::setEnd(const DOM_Node& refNode, unsigned int offset)
{
    validateNode(refNode);
    checkIndex(refNode, offset);

    fEndContainer   = refNode;
    fEndOffset      = offset;

    if ((fDocument != refNode.getOwnerDocument() )
            && (refNode.getOwnerDocument().fImpl != 0) )
    {
        fDocument = refNode.getOwnerDocument();
        collapse(false);
    }

    //compare the start and end boundary point
    //collapse if start point is after the end point
    if(compareBoundaryPoints(DOM_Range::END_TO_START, this) == 1)
        collapse(false); //collapse the range positions to end
    else
        fCollapsed = false;
}
Esempio n. 4
0
void RangeImpl::surroundContents(DOM_Node& newParent)
{
    if (newParent==null) return;

    //check for elimination criteria
    if( fDetached) {
        throw DOM_DOMException(
            DOM_DOMException::INVALID_STATE_ERR, null);
    }

    if (newParent.getOwnerDocument() !=fDocument) {
        throw DOM_DOMException(
            DOM_DOMException::WRONG_DOCUMENT_ERR, null);
    }

    int type = newParent.getNodeType();
    if ( !isLegalContainedNode(newParent)
            || type == DOM_Node::DOCUMENT_TYPE_NODE)
    {
        throw DOM_RangeException(
            DOM_RangeException::INVALID_NODE_TYPE_ERR, null);
    }

    DOM_Node root = getCommonAncestorContainer();

    DOM_Node realStart = fStartContainer;
    DOM_Node realEnd = fEndContainer;

    if (fStartContainer.getNodeType() == DOM_Node::TEXT_NODE) {
        realStart = fStartContainer.getParentNode();
    }
    if (fEndContainer.getNodeType() == DOM_Node::TEXT_NODE) {
        realEnd = fEndContainer.getParentNode();
    }

    if (realStart != realEnd) {
        throw DOM_RangeException(
            DOM_RangeException::BAD_BOUNDARYPOINTS_ERR, null);
    }

    DOM_DocumentFragment frag = extractContents();
    insertNode(newParent);
    newParent.appendChild(frag);
    selectNode(newParent);
}
Esempio n. 5
0
void RangeImpl::insertNode(DOM_Node& newNode)
{
    if (newNode == null) return; //don't have to do anything

    for (DOM_Node aNode = fStartContainer; aNode!=null; aNode = aNode.getParentNode()) {
        if (aNode.fImpl->isReadOnly()) {
            throw DOM_DOMException(
                DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR, null);
        }
    }

    if (fDocument != newNode.getOwnerDocument()) {
        throw DOM_DOMException(
            DOM_DOMException::WRONG_DOCUMENT_ERR, null);
    }

    // Prevent cycles in the tree.
    //isKidOK() is not checked here as its taken care by insertBefore() function
    if (isAncestorOf( newNode, fStartContainer)) {
        throw DOM_DOMException(
            DOM_DOMException::HIERARCHY_REQUEST_ERR, null);
    }

    if( fDetached) {
        throw DOM_DOMException(
            DOM_DOMException::INVALID_STATE_ERR, null);
    }

    int type = newNode.getNodeType();
    if (type == DOM_Node::ATTRIBUTE_NODE
            || type == DOM_Node::ENTITY_NODE
            || type == DOM_Node::NOTATION_NODE
            || type == DOM_Node::DOCUMENT_NODE)
    {
        throw DOM_RangeException(
            DOM_RangeException::INVALID_NODE_TYPE_ERR, null);
    }


    DOM_Node parent;
    DOM_Node next;

    if (fStartContainer.getNodeType() == DOM_Node::TEXT_NODE) {

        //set 'parent' and 'next' here
        parent = fStartContainer.getParentNode();

        //split the text nodes
        if (fStartOffset > 0)
            ((DOM_Text &)fStartContainer).splitText(fStartOffset);

        //update the new start information later. After inserting the first newNode
        if (fStartOffset == 0)
            next = fStartContainer;
        else
            next = fStartContainer.getNextSibling();

    } // end of text handling
    else {
        parent = fStartContainer;

        next = fStartContainer.getFirstChild();
        for(unsigned int i = 0; (i < fStartOffset) && (next != null); i++) {
            next=next.getNextSibling();
        }
    }

    if (parent != null) {
        if (next != null)
            parent.insertBefore(newNode, next);
        else
            parent.appendChild(newNode);
    }
}