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

📄 visibleposition.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                    while (InlineBox* prevBox = box->prevLeafChild()) {                        if (prevBox->bidiLevel() < level)                            break;                        box = prevBox;                    }                    if (box->bidiLevel() == level)                        break;                    level = box->bidiLevel();                    while (InlineBox* nextBox = box->nextLeafChild()) {                        if (nextBox->bidiLevel() < level)                            break;                        box = nextBox;                    }                    if (box->bidiLevel() == level)                        break;                    level = box->bidiLevel();                }                renderer = box->renderer();                offset = primaryDirection == LTR ? box->caretMaxOffset() : box->caretMinOffset();            }            break;        }        p = Position(renderer->node(), offset);        if (p.isCandidate() && p.downstream() != downstreamStart || p.atStart() || p.atEnd())            return p;    }}VisiblePosition VisiblePosition::right(bool stayInEditableContent) const{    Position pos = rightVisuallyDistinctCandidate();    if (pos.atStart() || pos.atEnd())        return VisiblePosition();    VisiblePosition right = VisiblePosition(pos, DOWNSTREAM);    ASSERT(right != *this);    if (!stayInEditableContent)        return right;    // FIXME: This may need to do something different from "after".    return honorEditableBoundaryAtOrAfter(right);}VisiblePosition VisiblePosition::honorEditableBoundaryAtOrBefore(const VisiblePosition &pos) const{    if (pos.isNull())        return pos;        Node* highestRoot = highestEditableRoot(deepEquivalent());        // Return empty position if pos is not somewhere inside the editable region containing this position    if (highestRoot && !pos.deepEquivalent().node()->isDescendantOf(highestRoot))        return VisiblePosition();            // Return pos itself if the two are from the very same editable region, or both are non-editable    // FIXME: In the non-editable case, just because the new position is non-editable doesn't mean movement    // to it is allowed.  VisibleSelection::adjustForEditableContent has this problem too.    if (highestEditableRoot(pos.deepEquivalent()) == highestRoot)        return pos;      // Return empty position if this position is non-editable, but pos is editable    // FIXME: Move to the previous non-editable region.    if (!highestRoot)        return VisiblePosition();    // Return the last position before pos that is in the same editable region as this position    return lastEditablePositionBeforePositionInRoot(pos.deepEquivalent(), highestRoot);}VisiblePosition VisiblePosition::honorEditableBoundaryAtOrAfter(const VisiblePosition &pos) const{    if (pos.isNull())        return pos;        Node* highestRoot = highestEditableRoot(deepEquivalent());        // Return empty position if pos is not somewhere inside the editable region containing this position    if (highestRoot && !pos.deepEquivalent().node()->isDescendantOf(highestRoot))        return VisiblePosition();        // Return pos itself if the two are from the very same editable region, or both are non-editable    // FIXME: In the non-editable case, just because the new position is non-editable doesn't mean movement    // to it is allowed.  VisibleSelection::adjustForEditableContent has this problem too.    if (highestEditableRoot(pos.deepEquivalent()) == highestRoot)        return pos;    // Return empty position if this position is non-editable, but pos is editable    // FIXME: Move to the next non-editable region.    if (!highestRoot)        return VisiblePosition();    // Return the next position after pos that is in the same editable region as this position    return firstEditablePositionAfterPositionInRoot(pos.deepEquivalent(), highestRoot);}static Position canonicalizeCandidate(const Position& candidate){    if (candidate.isNull())        return Position();    ASSERT(candidate.isCandidate());    Position upstream = candidate.upstream();    if (upstream.isCandidate())        return upstream;    return candidate;}Position VisiblePosition::canonicalPosition(const Position& position){    // FIXME (9535):  Canonicalizing to the leftmost candidate means that if we're at a line wrap, we will     // ask renderers to paint downstream carets for other renderers.    // To fix this, we need to either a) add code to all paintCarets to pass the responsibility off to    // the appropriate renderer for VisiblePosition's like these, or b) canonicalize to the rightmost candidate    // unless the affinity is upstream.    Node* node = position.node();    if (!node)        return Position();    node->document()->updateLayoutIgnorePendingStylesheets();    Position candidate = position.upstream();    if (candidate.isCandidate())        return candidate;    candidate = position.downstream();    if (candidate.isCandidate())        return candidate;    // When neither upstream or downstream gets us to a candidate (upstream/downstream won't leave     // blocks or enter new ones), we search forward and backward until we find one.    Position next = canonicalizeCandidate(nextCandidate(position));    Position prev = canonicalizeCandidate(previousCandidate(position));    Node* nextNode = next.node();    Node* prevNode = prev.node();    // The new position must be in the same editable element. Enforce that first.    // Unless the descent is from a non-editable html element to an editable body.    if (node->hasTagName(htmlTag) && !node->isContentEditable() && node->document()->body() && node->document()->body()->isContentEditable())        return next.isNotNull() ? next : prev;    Node* editingRoot = editableRootForPosition(position);            // If the html element is editable, descending into its body will look like a descent     // from non-editable to editable content since rootEditableElement() always stops at the body.    if (editingRoot && editingRoot->hasTagName(htmlTag) || position.node()->isDocumentNode())        return next.isNotNull() ? next : prev;            bool prevIsInSameEditableElement = prevNode && editableRootForPosition(prev) == editingRoot;    bool nextIsInSameEditableElement = nextNode && editableRootForPosition(next) == editingRoot;    if (prevIsInSameEditableElement && !nextIsInSameEditableElement)        return prev;    if (nextIsInSameEditableElement && !prevIsInSameEditableElement)        return next;    if (!nextIsInSameEditableElement && !prevIsInSameEditableElement)        return Position();    // The new position should be in the same block flow element. Favor that.    Node *originalBlock = node->enclosingBlockFlowElement();    bool nextIsOutsideOriginalBlock = !nextNode->isDescendantOf(originalBlock) && nextNode != originalBlock;    bool prevIsOutsideOriginalBlock = !prevNode->isDescendantOf(originalBlock) && prevNode != originalBlock;    if (nextIsOutsideOriginalBlock && !prevIsOutsideOriginalBlock)        return prev;            return next;}UChar VisiblePosition::characterAfter() const{    // We canonicalize to the first of two equivalent candidates, but the second of the two candidates    // is the one that will be inside the text node containing the character after this visible position.    Position pos = m_deepPosition.downstream();    Node* node = pos.node();    if (!node || !node->isTextNode())        return 0;    Text* textNode = static_cast<Text*>(pos.node());    int offset = pos.offset();    if ((unsigned)offset >= textNode->length())        return 0;    return textNode->data()[offset];}IntRect VisiblePosition::localCaretRect(RenderObject*& renderer) const{    Node* node = m_deepPosition.node();    if (!node) {        renderer = 0;        return IntRect();    }        renderer = node->renderer();    if (!renderer)        return IntRect();    InlineBox* inlineBox;    int caretOffset;    getInlineBoxAndOffset(inlineBox, caretOffset);    if (inlineBox)        renderer = inlineBox->renderer();    return renderer->localCaretRect(inlineBox, caretOffset);}IntRect VisiblePosition::absoluteCaretBounds() const{    RenderObject* renderer;    IntRect localRect = localCaretRect(renderer);    if (localRect.isEmpty() || !renderer)        return IntRect();    return renderer->localToAbsoluteQuad(FloatRect(localRect)).enclosingBoundingBox();}int VisiblePosition::xOffsetForVerticalNavigation() const{    RenderObject* renderer;    IntRect localRect = localCaretRect(renderer);    if (localRect.isEmpty() || !renderer)        return 0;    // This ignores transforms on purpose, for now. Vertical navigation is done    // without consulting transforms, so that 'up' in transformed text is 'up'    // relative to the text, not absolute 'up'.    return renderer->localToAbsolute(localRect.location()).x();}void VisiblePosition::debugPosition(const char* msg) const{    if (isNull())        fprintf(stderr, "Position [%s]: null\n", msg);    else        fprintf(stderr, "Position [%s]: %s [%p] at %d\n", msg, m_deepPosition.node()->nodeName().utf8().data(), m_deepPosition.node(), m_deepPosition.offset());}#ifndef NDEBUGvoid VisiblePosition::formatForDebugger(char* buffer, unsigned length) const{    m_deepPosition.formatForDebugger(buffer, length);}void VisiblePosition::showTreeForThis() const{    m_deepPosition.showTreeForThis();}#endifPassRefPtr<Range> makeRange(const VisiblePosition &start, const VisiblePosition &end){    if (start.isNull() || end.isNull())        return 0;        Position s = rangeCompliantEquivalent(start);    Position e = rangeCompliantEquivalent(end);    return Range::create(s.node()->document(), s.node(), s.offset(), e.node(), e.offset());}VisiblePosition startVisiblePosition(const Range *r, EAffinity affinity){    int exception = 0;    return VisiblePosition(r->startContainer(exception), r->startOffset(exception), affinity);}VisiblePosition endVisiblePosition(const Range *r, EAffinity affinity){    int exception = 0;    return VisiblePosition(r->endContainer(exception), r->endOffset(exception), affinity);}bool setStart(Range *r, const VisiblePosition &visiblePosition){    if (!r)        return false;    Position p = rangeCompliantEquivalent(visiblePosition);    int code = 0;    r->setStart(p.node(), p.offset(), code);    return code == 0;}bool setEnd(Range *r, const VisiblePosition &visiblePosition){    if (!r)        return false;    Position p = rangeCompliantEquivalent(visiblePosition);    int code = 0;    r->setEnd(p.node(), p.offset(), code);    return code == 0;}Node *enclosingBlockFlowElement(const VisiblePosition &visiblePosition){    if (visiblePosition.isNull())        return NULL;    return visiblePosition.deepEquivalent().node()->enclosingBlockFlowElement();}bool isFirstVisiblePositionInNode(const VisiblePosition &visiblePosition, const Node *node){    if (visiblePosition.isNull())        return false;        if (!visiblePosition.deepEquivalent().node()->isDescendantOf(node))        return false;            VisiblePosition previous = visiblePosition.previous();    return previous.isNull() || !previous.deepEquivalent().node()->isDescendantOf(node);}bool isLastVisiblePositionInNode(const VisiblePosition &visiblePosition, const Node *node){    if (visiblePosition.isNull())        return false;        if (!visiblePosition.deepEquivalent().node()->isDescendantOf(node))        return false;                    VisiblePosition next = visiblePosition.next();    return next.isNull() || !next.deepEquivalent().node()->isDescendantOf(node);}}  // namespace WebCore#ifndef NDEBUGvoid showTree(const WebCore::VisiblePosition* vpos){    if (vpos)        vpos->showTreeForThis();}void showTree(const WebCore::VisiblePosition& vpos){    vpos.showTreeForThis();}#endif

⌨️ 快捷键说明

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