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

📄 range.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        ec = NOT_FOUND_ERR;        return;    }    // NO_MODIFICATION_ALLOWED_ERR: Raised if an ancestor container of either boundary-point of    // the Range is read-only.    if (containedByReadOnly()) {        ec = 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 (newNode->document() != m_start.container()->document()) {        ec = 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 newNode or if newNode is an ancestor of the container.    // an extra one here - if a text node is going to split, it must have a parent to insert into    bool startIsText = m_start.container()->isTextNode();    if (startIsText && !m_start.container()->parentNode()) {        ec = HIERARCHY_REQUEST_ERR;        return;    }    // In the case where the container is a text node, we check against the container's parent, because    // text nodes get split up upon insertion.    Node* checkAgainst;    if (startIsText)        checkAgainst = m_start.container()->parentNode();    else        checkAgainst = m_start.container();    Node::NodeType newNodeType = newNode->nodeType();    int numNewChildren;    if (newNodeType == Node::DOCUMENT_FRAGMENT_NODE) {        // check each child node, not the DocumentFragment itself        numNewChildren = 0;        for (Node* c = newNode->firstChild(); c; c = c->nextSibling()) {            if (!checkAgainst->childTypeAllowed(c->nodeType())) {                ec = HIERARCHY_REQUEST_ERR;                return;            }            ++numNewChildren;        }    } else {        numNewChildren = 1;        if (!checkAgainst->childTypeAllowed(newNodeType)) {            ec = HIERARCHY_REQUEST_ERR;            return;        }    }    for (Node* n = m_start.container(); n; n = n->parentNode()) {        if (n == newNode) {            ec = HIERARCHY_REQUEST_ERR;            return;        }    }    // INVALID_NODE_TYPE_ERR: Raised if newNode is an Attr, Entity, Notation, or Document node.    if (newNodeType == Node::ATTRIBUTE_NODE || newNodeType == Node::ENTITY_NODE            || newNodeType == Node::NOTATION_NODE || newNodeType == Node::DOCUMENT_NODE) {        ec = RangeException::INVALID_NODE_TYPE_ERR;        return;    }    bool collapsed = m_start == m_end;    if (startIsText) {        RefPtr<Text> newText = static_cast<Text*>(m_start.container())->splitText(m_start.offset(), ec);        if (ec)            return;        m_start.container()->parentNode()->insertBefore(newNode.release(), newText.get(), ec);        if (ec)            return;        // This special case doesn't seem to match the DOM specification, but it's currently required        // to pass Acid3. We might later decide to remove this.        if (collapsed)            m_end.setToChild(newText.get());    } else {        RefPtr<Node> lastChild;        if (collapsed)            lastChild = (newNodeType == Node::DOCUMENT_FRAGMENT_NODE) ? newNode->lastChild() : newNode;        int startOffset = m_start.offset();        m_start.container()->insertBefore(newNode.release(), m_start.container()->childNode(startOffset), ec);        if (ec)            return;        // This special case doesn't seem to match the DOM specification, but it's currently required        // to pass Acid3. We might later decide to remove this.        if (collapsed)            m_end.set(m_start.container(), startOffset + numNewChildren, lastChild.get());    }}String Range::toString(ExceptionCode& ec) const{    if (!m_start.container()) {        ec = INVALID_STATE_ERR;        return String();    }    Vector<UChar> result;    Node* pastLast = pastLastNode();    for (Node* n = firstNode(); n != pastLast; n = n->traverseNextNode()) {        if (n->nodeType() == Node::TEXT_NODE || n->nodeType() == Node::CDATA_SECTION_NODE) {            String data = static_cast<CharacterData*>(n)->data();            int length = data.length();            int start = (n == m_start.container()) ? min(max(0, m_start.offset()), length) : 0;            int end = (n == m_end.container()) ? min(max(start, m_end.offset()), length) : length;            result.append(data.characters() + start, end - start);        }    }    return String::adopt(result);}String Range::toHTML() const{    return createMarkup(this);}String Range::text() const{    if (!m_start.container())        return String();    // We need to update layout, since plainText uses line boxes in the render tree.    // FIXME: As with innerText, we'd like this to work even if there are no render objects.    m_start.container()->document()->updateLayout();    return plainText(this);}PassRefPtr<DocumentFragment> Range::createContextualFragment(const String& markup, ExceptionCode& ec) const{    if (!m_start.container()) {        ec = INVALID_STATE_ERR;        return 0;    }    Node* element = m_start.container()->isElementNode() ? m_start.container() : m_start.container()->parentNode();    if (!element || !element->isHTMLElement()) {        ec = NOT_SUPPORTED_ERR;        return 0;    }    RefPtr<DocumentFragment> fragment = static_cast<HTMLElement*>(element)->createContextualFragment(markup);    if (!fragment) {        ec = NOT_SUPPORTED_ERR;        return 0;    }    return fragment.release();}void Range::detach(ExceptionCode& ec){    if (!m_start.container()) {        ec = INVALID_STATE_ERR;        return;    }    m_ownerDocument->detachRange(this);    m_start.clear();    m_end.clear();}Node* Range::checkNodeWOffset(Node* n, int offset, ExceptionCode& ec) const{    switch (n->nodeType()) {        case Node::DOCUMENT_TYPE_NODE:        case Node::ENTITY_NODE:        case Node::NOTATION_NODE:            ec = RangeException::INVALID_NODE_TYPE_ERR;            return 0;        case Node::CDATA_SECTION_NODE:        case Node::COMMENT_NODE:        case Node::TEXT_NODE:            if (static_cast<unsigned>(offset) > static_cast<CharacterData*>(n)->length())                ec = INDEX_SIZE_ERR;            return 0;        case Node::PROCESSING_INSTRUCTION_NODE:            if (static_cast<unsigned>(offset) > static_cast<ProcessingInstruction*>(n)->data().length())                ec = INDEX_SIZE_ERR;            return 0;        case Node::ATTRIBUTE_NODE:        case Node::DOCUMENT_FRAGMENT_NODE:        case Node::DOCUMENT_NODE:        case Node::ELEMENT_NODE:        case Node::ENTITY_REFERENCE_NODE:        case Node::XPATH_NAMESPACE_NODE: {            if (!offset)                return 0;            Node* childBefore = n->childNode(offset - 1);            if (!childBefore)                ec = INDEX_SIZE_ERR;            return childBefore;        }    }    ASSERT_NOT_REACHED();    return 0;}void Range::checkNodeBA(Node* n, ExceptionCode& ec) const{    // INVALID_NODE_TYPE_ERR: Raised if the root container of refNode is not an    // Attr, Document or DocumentFragment node or part of a shadow DOM tree    // or if refNode is a Document, DocumentFragment, Attr, Entity, or Notation node.    switch (n->nodeType()) {        case Node::ATTRIBUTE_NODE:        case Node::DOCUMENT_FRAGMENT_NODE:        case Node::DOCUMENT_NODE:        case Node::ENTITY_NODE:        case Node::NOTATION_NODE:            ec = RangeException::INVALID_NODE_TYPE_ERR;            return;        case Node::CDATA_SECTION_NODE:        case Node::COMMENT_NODE:        case Node::DOCUMENT_TYPE_NODE:        case Node::ELEMENT_NODE:        case Node::ENTITY_REFERENCE_NODE:        case Node::PROCESSING_INSTRUCTION_NODE:        case Node::TEXT_NODE:        case Node::XPATH_NAMESPACE_NODE:            break;    }    Node* root = n;    while (Node* parent = root->parentNode())        root = parent;    switch (root->nodeType()) {        case Node::ATTRIBUTE_NODE:        case Node::DOCUMENT_NODE:        case Node::DOCUMENT_FRAGMENT_NODE:            break;        case Node::CDATA_SECTION_NODE:        case Node::COMMENT_NODE:        case Node::DOCUMENT_TYPE_NODE:        case Node::ELEMENT_NODE:        case Node::ENTITY_NODE:        case Node::ENTITY_REFERENCE_NODE:        case Node::NOTATION_NODE:        case Node::PROCESSING_INSTRUCTION_NODE:        case Node::TEXT_NODE:        case Node::XPATH_NAMESPACE_NODE:            if (root->isShadowNode())                break;            ec = RangeException::INVALID_NODE_TYPE_ERR;            return;    }}PassRefPtr<Range> Range::cloneRange(ExceptionCode& ec) const{    if (!m_start.container()) {        ec = INVALID_STATE_ERR;        return 0;    }    return Range::create(m_ownerDocument, m_start.container(), m_start.offset(), m_end.container(), m_end.offset());}void Range::setStartAfter(Node* refNode, ExceptionCode& ec){    if (!m_start.container()) {        ec = INVALID_STATE_ERR;        return;    }    if (!refNode) {        ec = NOT_FOUND_ERR;        return;    }    if (refNode->document() != m_ownerDocument) {        ec = WRONG_DOCUMENT_ERR;        return;    }    ec = 0;    checkNodeBA(refNode, ec);    if (ec)        return;    setStart(refNode->parentNode(), refNode->nodeIndex() + 1, ec);}void Range::setEndBefore(Node* refNode, ExceptionCode& ec){    if (!m_start.container()) {        ec = INVALID_STATE_ERR;        return;    }    if (!refNode) {        ec = NOT_FOUND_ERR;        return;    }    if (refNode->document() != m_ownerDocument) {        ec = WRONG_DOCUMENT_ERR;        return;    }    ec = 0;    checkNodeBA(refNode, ec);    if (ec)        return;    setEnd(refNode->parentNode(), refNode->nodeIndex(), ec);}void Range::setEndAfter(Node* refNode, ExceptionCode& ec){    if (!m_start.container()) {        ec = INVALID_STATE_ERR;        return;    }    if (!refNode) {        ec = NOT_FOUND_ERR;        return;    }    if (refNode->document() != m_ownerDocument) {        ec = WRONG_DOCUMENT_ERR;        return;    }    ec = 0;    checkNodeBA(refNode, ec);    if (ec)        return;    setEnd(refNode->parentNode(), refNode->nodeIndex() + 1, ec);}void Range::selectNode(Node* refNode, ExceptionCode& ec){    if (!m_start.container()) {        ec = INVALID_STATE_ERR;        return;    }    if (!refNode) {        ec = 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.    for (Node* anc = refNode->parentNode(); anc; anc = anc->parentNode()) {        switch (anc->nodeType()) {            case Node::ATTRIBUTE_NODE:            case Node::CDATA_SECTION_NODE:            case Node::COMMENT_NODE:            case Node::DOCUMENT_FRAGMENT_NODE:            case Node::DOCUMENT_NODE:            case Node::ELEMENT_NODE:            case Node::ENTITY_REFERENCE_NODE:            case Node::PROCESSING_INSTRUCTION_NODE:            case Node::TEXT_NODE:            case Node::XPATH_NAMESPACE_NODE:                break;            case Node::DOCUMENT_TYPE_NODE:            case Node::ENTITY_NODE:            case Node::NOTATION_NODE:                ec = RangeException::INVALID_NODE_TYPE_ERR;                return;        }    }    switch (refNode->nodeType()) {        case Node::CDATA_SECTION_NODE:        case Node::COMMENT_NODE:        case Node::DOCUMENT_TYPE_NODE:        case Node::ELEMENT_NODE:        case Node::ENTITY_REFERENCE_NODE:        case Node::PROCESSING_INSTRUCTION_NODE:        case Node::TEXT_NODE:        case Node::XPATH_NAMESPACE_NODE:            break;        case Node::ATTRIBUTE_NODE:        case Node::DOCUMENT_FRAGMENT_NODE:        case Node::DOCUMENT_NODE:        case Node::ENTITY_NODE:        case Node::NOTATION_NODE:            ec = RangeException::INVALID_NODE_TYPE_ERR;            return;    }    ec = 0;    setStartBefore(refNode, ec);    if (ec)        return;    setEndAfter(refNode, ec);}void Range::selectNodeContents(Node* refNode, ExceptionCode& ec){    if (!m_start.container()) {        ec = INVALID_STATE_ERR;        return;    }    if (!refNode) {        ec = NOT_FOUND_ERR;        return;    }    // INVALID_NODE_TYPE_ERR: Raised if refNode or an ancestor of refNode is an Entity, Notation    // or DocumentType node.    for (Node* n = refNode; n; n = n->parentNode()) {        switch (n->nodeType()) {            case Node::ATTRIBUTE_NODE:            case Node::CDATA_SECTION_NODE:            case Node::COMMENT_NODE:            case Node::DOCUMENT_FRAGMENT_NODE:            case Node::DOCUMENT_NODE:            case Node::ELEMENT_NODE:            case Node::ENTITY_REFERENCE_NODE:            case Node::PROCESSING_INSTRUCTION_NODE:            case Node::TEXT_NODE:            case Node::XPATH_NAMESPACE_NODE:                break;            case Node::DOCUMENT_TYPE_NODE:            case Node::ENTITY_NODE:            case Node::NOTATION_NODE:                ec = RangeException::INVALID_NODE_TYPE_ERR;                return;        }    }    m_start.setToStart(refNode);    m_end.setToEnd(refNode);

⌨️ 快捷键说明

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