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

📄 dom2_rangeimpl.cpp

📁 手机浏览器源码程序,功能强大
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        return;
    }

    if (refNode->getDocument() != m_ownerDocument->document()) {
        exceptioncode = DOMException::WRONG_DOCUMENT_ERR;
        return;
    }

    checkNodeBA( refNode, exceptioncode );
    if (exceptioncode)
        return;

    setEnd( refNode->parentNode(), refNode->nodeIndex()+1, exceptioncode );

}

void RangeImpl::selectNode( NodeImpl *refNode, int &exceptioncode )
{
    if (m_detached) {
        exceptioncode = DOMException::INVALID_STATE_ERR;
        return;
    }

    if (!refNode) {
        exceptioncode = DOMException::NOT_FOUND_ERR;
        return;
    }

    // INVALID_NODE_TYPE_ERR: Raised if an ancestor of refNode is an Entity, Notation or
    // DocumentType node or if refNode is a Document, DocumentFragment, Attr, Entity, or Notation
    // node.
    NodeImpl *anc;
    for (anc = refNode->parentNode(); anc; anc = anc->parentNode()) {
        if (anc->nodeType() == Node::ENTITY_NODE ||
            anc->nodeType() == Node::NOTATION_NODE ||
            anc->nodeType() == Node::DOCUMENT_TYPE_NODE) {

            exceptioncode = RangeException::INVALID_NODE_TYPE_ERR + RangeException::_EXCEPTION_OFFSET;
            return;
        }
    }

    if (refNode->nodeType() == Node::DOCUMENT_NODE ||
        refNode->nodeType() == Node::DOCUMENT_FRAGMENT_NODE ||
        refNode->nodeType() == Node::ATTRIBUTE_NODE ||
        refNode->nodeType() == Node::ENTITY_NODE ||
        refNode->nodeType() == Node::NOTATION_NODE) {

        exceptioncode = RangeException::INVALID_NODE_TYPE_ERR + RangeException::_EXCEPTION_OFFSET;
        return;
    }

    setStartBefore( refNode, exceptioncode );
    if (exceptioncode)
        return;
    setEndAfter( refNode, exceptioncode );
}

void RangeImpl::selectNodeContents( NodeImpl *refNode, int &exceptioncode )
{
    if (m_detached) {
        exceptioncode = DOMException::INVALID_STATE_ERR;
        return;
    }

    if (!refNode) {
        exceptioncode = DOMException::NOT_FOUND_ERR;
        return;
    }

    // INVALID_NODE_TYPE_ERR: Raised if refNode or an ancestor of refNode is an Entity, Notation
    // or DocumentType node.
    NodeImpl *n;
    for (n = refNode; n; n = n->parentNode()) {
        if (n->nodeType() == Node::ENTITY_NODE ||
            n->nodeType() == Node::NOTATION_NODE ||
            n->nodeType() == Node::DOCUMENT_TYPE_NODE) {

            exceptioncode = RangeException::INVALID_NODE_TYPE_ERR + RangeException::_EXCEPTION_OFFSET;
            return;
        }
    }

    setStartContainer(refNode);
    m_startOffset = 0;
    setEndContainer(refNode);
    m_endOffset = refNode->childNodeCount();
}

void RangeImpl::surroundContents( NodeImpl *newParent, int &exceptioncode )
{
    if (m_detached) {
        exceptioncode = DOMException::INVALID_STATE_ERR;
        return;
    }

    if( !newParent ) {
        exceptioncode = DOMException::NOT_FOUND_ERR;
        return;
    }

    // INVALID_NODE_TYPE_ERR: Raised if node is an Attr, Entity, DocumentType, Notation,
    // Document, or DocumentFragment node.
    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) {
        exceptioncode = RangeException::INVALID_NODE_TYPE_ERR + RangeException::_EXCEPTION_OFFSET;
        return;
    }

    // NO_MODIFICATION_ALLOWED_ERR: Raised if an ancestor container of either boundary-point of
    // the Range is read-only.
    if (containedByReadOnly()) {
        exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
        return;
    }

    // WRONG_DOCUMENT_ERR: Raised if newParent and the container of the start of the Range were
    // not created from the same document.
    if (newParent->getDocument() != m_startContainer->getDocument()) {
        exceptioncode = DOMException::WRONG_DOCUMENT_ERR;
        return;
    }

    // HIERARCHY_REQUEST_ERR: Raised if the container of the start of the Range is of a type that
    // does not allow children of the type of newParent or if newParent is an ancestor of the container
    // or if node would end up with a child node of a type not allowed by the type of node.
    if (!m_startContainer->childTypeAllowed(newParent->nodeType())) {
        exceptioncode = DOMException::HIERARCHY_REQUEST_ERR;
        return;
    }

    for (NodeImpl *n = m_startContainer; n; n = n->parentNode()) {
        if (n == newParent) {
            exceptioncode = DOMException::HIERARCHY_REQUEST_ERR;
            return;
        }
    }

    // ### check if node would end up with a child node of a type not allowed by the type of node

    // BAD_BOUNDARYPOINTS_ERR: Raised if the Range partially selects a non-text node.
    if (!offsetInCharacters(m_startContainer->nodeType())) {
        if (m_startOffset > 0 && m_startOffset < m_startContainer->childNodeCount()) {
            exceptioncode = RangeException::BAD_BOUNDARYPOINTS_ERR + RangeException::_EXCEPTION_OFFSET;
            return;
        }
    }
    if (!offsetInCharacters(m_endContainer->nodeType())) {
        if (m_endOffset > 0 && m_endOffset < m_endContainer->childNodeCount()) {
            exceptioncode = RangeException::BAD_BOUNDARYPOINTS_ERR + RangeException::_EXCEPTION_OFFSET;
            return;
        }
    }

    while (newParent->firstChild()) {
    	newParent->removeChild(newParent->firstChild(),exceptioncode);
	if (exceptioncode)
	    return;
    }
    DocumentFragmentImpl *fragment = extractContents(exceptioncode);
    if (exceptioncode)
        return;
    insertNode( newParent, exceptioncode );
    if (exceptioncode)
        return;
    newParent->appendChild( fragment, exceptioncode );
    if (exceptioncode)
        return;
    selectNode( newParent, exceptioncode );
}

void RangeImpl::setStartBefore( NodeImpl *refNode, int &exceptioncode )
{
    if (m_detached) {
        exceptioncode = DOMException::INVALID_STATE_ERR;
        return;
    }

    if (!refNode) {
        exceptioncode = DOMException::NOT_FOUND_ERR;
        return;
    }

    if (refNode->getDocument() != m_ownerDocument->document()) {
        exceptioncode = DOMException::WRONG_DOCUMENT_ERR;
        return;
    }

    checkNodeBA( refNode, exceptioncode );
    if (exceptioncode)
        return;

    setStart( refNode->parentNode(), refNode->nodeIndex(), exceptioncode );
}

void RangeImpl::setStartContainer(NodeImpl *_startContainer)
{
    if (m_startContainer == _startContainer)
        return;

    if (m_startContainer)
        m_startContainer->deref();
    m_startContainer = _startContainer;
    if (m_startContainer)
        m_startContainer->ref();
}

void RangeImpl::setEndContainer(NodeImpl *_endContainer)
{
    if (m_endContainer == _endContainer)
        return;

    if (m_endContainer)
        m_endContainer->deref();
    m_endContainer = _endContainer;
    if (m_endContainer)
        m_endContainer->ref();
}

void RangeImpl::checkDeleteExtract(int &exceptioncode)
{
    NodeImpl *pastEnd = pastEndNode();
    for (NodeImpl *n = startNode(); n != pastEnd; n = n->traverseNextNode()) {
	if (n->isReadOnly()) {
	    exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
	    return;
	}
	if (n->nodeType() == Node::DOCUMENT_TYPE_NODE) { // ### is this for only directly under the DF, or anywhere?
	    exceptioncode = DOMException::HIERARCHY_REQUEST_ERR;
	    return;
	}
    }

    if (containedByReadOnly()) {
	exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
	return;
    }
}

bool RangeImpl::containedByReadOnly() const
{
    NodeImpl *n;
    for (n = m_startContainer; n; n = n->parentNode()) {
	if (n->isReadOnly())
	    return true;
    }
    for (n = m_endContainer; n; n = n->parentNode()) {
	if (n->isReadOnly())
	    return true;
    }
    return false;
}

Position RangeImpl::startPosition() const
{
    return Position(m_startContainer, m_startOffset);
}

Position RangeImpl::endPosition() const
{
    return Position(m_endContainer, m_endOffset);
}

NodeImpl *RangeImpl::startNode() const
{
    if (!m_startContainer)
        return 0;
    if (offsetInCharacters(m_startContainer->nodeType()))
        return m_startContainer;
    NodeImpl *child = m_startContainer->childNode(m_startOffset);
    if (child)
        return child;
    return m_startContainer->traverseNextSibling();
}

Position RangeImpl::editingStartPosition() const
{
    // This function is used to avoid bugs like:
    // <rdar://problem/4017641> REGRESSION (Mail): you can only bold/unbold a selection starting from end of line once
    // The issue here is that calculating the selection using the start of a range sometimes considers nodes that
    // should not be considered. In the case of this bug, we need to move past the offset after the last character
    // in a text node in order to make the right style calculation, so we do not wind up with a false "mixed"
    // style.
    
    Position pos(m_startContainer, m_startOffset);    
    if (pos.isNull())
        return Position();
    
    int exceptionCode = 0;
    return collapsed(exceptionCode) ? VisiblePosition(pos, UPSTREAM).deepEquivalent() : pos.downstream(DoNotStayInBlock);
}

NodeImpl *RangeImpl::pastEndNode() const
{
    if (!m_endContainer)
        return 0;
    if (offsetInCharacters(m_endContainer->nodeType()))
        return m_endContainer->traverseNextSibling();
    NodeImpl *child = m_endContainer->childNode(m_endOffset);
    if (child)
        return child;
    return m_endContainer->traverseNextSibling();
}

#ifndef NDEBUG
#define FormatBufferSize 1024
void RangeImpl::formatForDebugger(char *buffer, unsigned length) const
{
    DOMString result;
    DOMString s;
    
    if (!m_startContainer || !m_endContainer) {
        result = "<empty>";
    }
    else {
        char s[FormatBufferSize];
        result += "from offset ";
        result += QString::number(m_startOffset);
        result += " of ";
        m_startContainer->formatForDebugger(s, FormatBufferSize);
        result += s;
        result += " to offset ";
        result += QString::number(m_endOffset);
        result += " of ";
        m_endContainer->formatForDebugger(s, FormatBufferSize);
        result += s;
    }
          
    strncpy(buffer, result.string().latin1(), length - 1);
}
#undef FormatBufferSize
#endif

}

⌨️ 快捷键说明

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