⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dom2_rangeimpl.cpp

📁 monqueror一个很具有参考价值的源玛
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    return;}DocumentFragment RangeImpl::extractContents(  ){    if( isDetached() )        throw DOMException( DOMException::INVALID_STATE_ERR );    return masterTraverse( true );}DocumentFragment RangeImpl::cloneContents(  ){    if( isDetached() )        throw DOMException( DOMException::INVALID_STATE_ERR );    return masterTraverse( false );}void RangeImpl::insertNode( const Node &newNode ){    if( isDetached() )        throw DOMException( DOMException::INVALID_STATE_ERR );    if( newNode.nodeType() == Node::ATTRIBUTE_NODE ||        newNode.nodeType() == Node::ENTITY_NODE ||        newNode.nodeType() == Node::NOTATION_NODE ||        newNode.nodeType() == Node::DOCUMENT_NODE ||        newNode.nodeType() == Node::DOCUMENT_FRAGMENT_NODE)        throw RangeException( RangeException::INVALID_NODE_TYPE_ERR);    if( newNode.ownerDocument() != startContainer.ownerDocument() )        throw DOMException( DOMException::WRONG_DOCUMENT_ERR );    if( startContainer.nodeType() == Node::TEXT_NODE )    {        Text newText;        Node newParent = newNode.parentNode();        Text textNode = static_cast<Text>(startContainer);        newText = textNode.splitText(startOffset);        newParent.insertBefore( newNode, newText );            }    else        startContainer.insertBefore( newNode, startContainer.childNodes().item( startOffset ) );}void RangeImpl::surroundContents( const Node &newParent ){    if( isDetached() )        throw DOMException( DOMException::INVALID_STATE_ERR );    if( newParent.isNull() )        return;    if( newParent.ownerDocument() != startContainer.ownerDocument() )        throw DOMException( DOMException::WRONG_DOCUMENT_ERR );        if( newParent.nodeType() == Node::ATTRIBUTE_NODE ||        newParent.nodeType() == Node::ENTITY_NODE ||        newParent.nodeType() == Node::NOTATION_NODE ||        newParent.nodeType() == Node::DOCUMENT_TYPE_NODE ||        newParent.nodeType() == Node::DOCUMENT_NODE ||        newParent.nodeType() == Node::DOCUMENT_FRAGMENT_NODE)        throw RangeException( RangeException::INVALID_NODE_TYPE_ERR );    // revisit: if you set a range without optimizing it (trimming) the following exception might be    // thrown incorrectly    Node realStart = (startContainer.nodeType() == Node::TEXT_NODE)? startContainer.parentNode() : startContainer;    Node realEnd = (endContainer.nodeType() == Node::TEXT_NODE)? endContainer.parentNode() : endContainer;    if( realStart != realEnd )        throw RangeException( RangeException::BAD_BOUNDARYPOINTS_ERR );    DocumentFragment fragment = extractContents();    insertNode( newParent );    // BIC: to avoid this const_cast newParent shouldn't be const    //(const_cast<Node>(newParent)).appendChild( fragment );    ((Node)(newParent)).appendChild( fragment );    selectNode( newParent );        }Range RangeImpl::cloneRange(  ){    if( isDetached() )        throw DOMException( DOMException::INVALID_STATE_ERR );    return Range( this );}DOMString RangeImpl::toString(  ){    if( isDetached() )        throw DOMException( DOMException::INVALID_STATE_ERR );    NodeIteratorImpl iterator( getStartContainer().childNodes().item( getStartOffset() ) );    DOMString _string;    Node _node = iterator.nextNode();    while( !_node.isNull() )    {        printf( "\nNodetype: %s\n", _node.nodeName().string().ascii() );        if( _node.nodeType() == Node::TEXT_NODE )        {            QString str = _node.nodeValue().string();            if( _node == getStartContainer() && _node == getEndContainer() )                _string = str.mid( getStartOffset(), getEndOffset() - getStartOffset() );            else if( _node == getStartContainer() )                _string = str.mid( getStartOffset() );            else if( _node == getEndContainer() )                _string += str.left( getStartOffset() );            else                _string += str;        }        else if( _node.nodeName() == "BR" )  _string += "\n";        else if( _node.nodeName() == "P" || _node.nodeName() == "TD" )  _string += "\n\n";        else  _string += " ";        _node = iterator.nextNode();    }    return _string;}DOMString RangeImpl::toHTML(  ){    if( isDetached() )        throw DOMException( DOMException::INVALID_STATE_ERR );    // this is just to avoid compiler warnings    DOMString d;    return d;}void RangeImpl::detach(  ){    if( isDetached() )        throw DOMException(DOMException::INVALID_STATE_ERR);    else        detached = true;}bool RangeImpl::isDetached() const{    return detached;}DocumentFragment RangeImpl::masterTraverse(bool contentExtract){    /* function description easy case, startContainer == endContainer     * If we have a text node simply clone/extract the contents between     * start & end and put them into the fragment     * If we don't have a text node, find the offset and copy/clone the content     * between the two offsets     * We end with returning the fragment of course     */    Node _clone;    DocumentFragment _endFragment( ownerDocument.createDocumentFragment() );    if(startContainer == endContainer)    {        if(startOffset == endOffset)            // we have a collapsed range            return DocumentFragment();        // TODO: we need to delete the text Node if a whole text is selected!!        if( startContainer.nodeType() == Node::TEXT_NODE )    // we have a text node.. special :)        {            _clone = startContainer.cloneNode(false);            _clone.nodeValue().remove(0, startOffset);  // we need to get the SUBSTRING            _clone.nodeValue().remove(endOffset, _clone.nodeValue().length() - endOffset);            if(contentExtract)            {                // full trim :)                startContainer.nodeValue().remove(startOffset, endOffset - startOffset);            }            _endFragment.appendChild(_clone);        }        else  // we have the same container class but we are not a text node        {            Node _tempCurrent = startContainer.firstChild();            unsigned int i;            for(i=0; i < startOffset; i++)    // get the node given by the offset                _tempCurrent = _tempCurrent.nextSibling();            /* now copy (or move) all the nodes in the range into the document fragment */            unsigned int range = endOffset - startOffset;            Node _nextCurrent = _tempCurrent;                  // to keep track of which node to take next            for(i=0; i<range && !_tempCurrent.isNull(); i++)   // check of isNull in case of strange errors            {                _nextCurrent = _tempCurrent.nextSibling();                if(contentExtract)                {                    _endFragment.appendChild(_tempCurrent);                }                else                {                    _clone = _tempCurrent.cloneNode(true);                    _endFragment.appendChild(_clone);                }                _tempCurrent = _nextCurrent;            }        }        return _endFragment;    }// END COMMON CONTAINER HERE!!!    /* Ok here we go for the harder part, first a general desription:     * First we copy all the border nodes (the have to be copied as long     * as they are partially selected) from the startContainer to the CmnAContainer. Then we do     * the same for the endContainer. After this we add all fully selected     * nodes that are between these two!     */    Node _cmnRoot = getCommonAncestorContainer();    Node _tempCurrent = startContainer;    Node _tempPartial;    // we still have Node _clone!!    // Special case text is first:    if( _tempCurrent.nodeType() == Node::TEXT_NODE )    {        _clone = _tempCurrent.cloneNode(false);        _clone.nodeValue().remove(0, startOffset);        if(contentExtract)        {            startContainer.nodeValue().split(startOffset);        }    }    else    {        _tempCurrent = _tempCurrent.firstChild();        unsigned int i;        for(i=0; i < startOffset; i++)            _tempCurrent = _tempCurrent.nextSibling();        if(contentExtract)            _clone = _tempCurrent.cloneNode(true);        else            _clone = _tempCurrent;     }    Node _tempParent;                       // we use this to traverse upwords trough the tree    Node _cloneParent;                      // this one is used to copy the current parent    Node _fragmentRoot;                     // this is eventually becomming the root of the DocumentFragment    while( _tempCurrent != _cmnRoot )    // traversing from the Container, all the way up to the commonAncestor    {                                    // all these node must be cloned as they are partially selected        _tempParent = _tempCurrent.parentNode();        if(_tempParent == _cmnRoot)        {            _cloneParent = _endFragment;            _fragmentRoot = _tempCurrent;        }        else        {            _cloneParent = _tempParent.cloneNode(false);            if( _tempPartial.isNull() && _tempParent != _cmnRoot )            {                _tempPartial = _tempParent;                // TODO: this means we should collapse after I think... :))            }        }        // we must not forget to grab with us the rest of this nodes siblings        Node _nextCurrent;        _tempCurrent = _tempCurrent.nextSibling();        _cloneParent.appendChild( _clone );        while( !_tempCurrent.isNull() )        {            _nextCurrent = _tempCurrent.nextSibling();            if( !_tempCurrent.isNull() && _tempParent != _cmnRoot) // the isNull() part should be unessesary            {                if(contentExtract)                {                    _cloneParent.appendChild(_tempCurrent);                }                else                {                    _clone = _tempCurrent.cloneNode(true);                    _cloneParent.appendChild(_clone);                }            }            _tempCurrent = _nextCurrent;        }        _tempCurrent = _tempParent;        _clone = _cloneParent;    }    //****** we should now be FINISHED with startContainer **********    _tempCurrent = endContainer;    Node _tempEnd;    // we still have Node _clone!!    // Special case text is first:    if( _tempCurrent.nodeType() == Node::TEXT_NODE )    {        _clone = _tempCurrent.cloneNode(false);        _clone.nodeValue().split(endOffset);         if(contentExtract)        {            endContainer.nodeValue().remove(endOffset, endContainer.nodeValue().length() - endOffset );        }    }    else    {        if(endOffset == 0)            _tempCurrent = endContainer;        else        {            _tempCurrent = _tempCurrent.firstChild();            unsigned int i;            for(i=0; i< endOffset; i++)                _tempCurrent = _tempCurrent.nextSibling();        }        if(contentExtract)            _clone = _tempCurrent;        else            _clone = _tempCurrent.cloneNode(true);    }    while( _tempCurrent != _cmnRoot )    // traversing from the Container, all the way up to the commonAncestor    {                                  //  all these node must be cloned as they are partially selected        _tempParent = _tempCurrent.parentNode();        if(_tempParent == _cmnRoot)        {            _cloneParent = _endFragment;            _fragmentRoot = _tempCurrent;        }        else        {            _cloneParent = _tempParent.cloneNode(false);            if( _tempPartial.isNull() && _tempParent != _cmnRoot )            {                _tempPartial = _tempParent;                // TODO: this means we should collapse before I think... :))            }        }        // we must not forget to grab with us the rest of this nodes siblings        Node _nextCurrent;        Node _stopNode = _tempCurrent;        _tempCurrent = _tempParent.firstChild();        _cloneParent.appendChild(_clone);        while( _tempCurrent != _stopNode && !_tempCurrent.isNull() )        {            _nextCurrent = _tempCurrent.nextSibling();            if( !_tempCurrent.isNull() && _tempParent != _cmnRoot) // the isNull() part should be unessesary            {                if(contentExtract)                {                    _cloneParent.appendChild(_tempCurrent);                }                else                {                    _clone = _tempCurrent.cloneNode(true);                    _cloneParent.appendChild(_clone);                }            }            _tempCurrent = _nextCurrent;        }        _tempCurrent = _tempParent;        _clone = _cloneParent;    }    // To end the balade we grab with us any nodes that are between the two topmost parents under    // the commonRoot    Node _clonePrevious = _endFragment.lastChild();    _tempCurrent = _tempEnd.previousSibling();    Node _nextCurrent;    while( (_nextCurrent != _fragmentRoot) && (!_tempCurrent.isNull()) )    {        _nextCurrent = _tempCurrent.previousSibling();        if(contentExtract)            _clone = _tempCurrent.cloneNode(true);        else            _clone = _tempCurrent;        _endFragment.insertBefore(_clone, _clonePrevious);        _tempCurrent = _nextCurrent;        _clonePrevious = _tempCurrent;    }    // WHAT ABOUT THE COLLAPSES??    return _endFragment;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -