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

📄 visible_units.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    VisiblePosition visPos = VisiblePosition(startNode, startOffset, DOWNSTREAM);    return positionAvoidingFirstPositionInTable(visPos);}VisiblePosition startOfLine(const VisiblePosition& c){    VisiblePosition visPos = startPositionForLine(c);        if (visPos.isNotNull()) {        // Make sure the start of line is not greater than the given input position.  Else use the previous position to         // obtain start of line.  This condition happens when the input position is before the space character at the end         // of a soft-wrapped non-editable line. In this scenario, startPositionForLine would incorrectly hand back a position        // greater than the input position.  This fix is to account for the discrepancy between lines with webkit-line-break:after-white-space         // style versus lines without that style, which would break before a space by default.         Position p = visPos.deepEquivalent();        if (p.offset() > c.deepEquivalent().offset() && p.node()->isSameNode(c.deepEquivalent().node())) {            visPos = c.previous();            if (visPos.isNull())                return VisiblePosition();            visPos = startPositionForLine(visPos);        }    }    return c.honorEditableBoundaryAtOrAfter(visPos);}static VisiblePosition endPositionForLine(const VisiblePosition& c){    if (c.isNull())        return VisiblePosition();    RootInlineBox *rootBox = rootBoxForLine(c);    if (!rootBox) {        // There are VisiblePositions at offset 0 in blocks without        // RootInlineBoxes, like empty editable blocks and bordered blocks.        Position p = c.deepEquivalent();        if (p.node()->renderer() && p.node()->renderer()->isRenderBlock() && p.offset() == 0)            return c;        return VisiblePosition();    }        // Generated content (e.g. list markers and CSS :before and :after    // pseudoelements) have no corresponding DOM element, and so cannot be    // represented by a VisiblePosition.  Use whatever precedes instead.    Node *endNode;    InlineBox *endBox = rootBox->lastLeafChild();    while (1) {        if (!endBox)            return VisiblePosition();        RenderObject *endRenderer = endBox->renderer();        if (!endRenderer)            return VisiblePosition();        endNode = endRenderer->node();        if (endNode)            break;                endBox = endBox->prevLeafChild();    }        int endOffset = 1;    if (endNode->hasTagName(brTag)) {        endOffset = 0;    } else if (endBox->isInlineTextBox()) {        InlineTextBox *endTextBox = static_cast<InlineTextBox *>(endBox);        endOffset = endTextBox->start();        if (!endTextBox->isLineBreak())            endOffset += endTextBox->len();    }        return VisiblePosition(endNode, endOffset, VP_UPSTREAM_IF_POSSIBLE);}VisiblePosition endOfLine(const VisiblePosition& c){    VisiblePosition visPos = endPositionForLine(c);        // Make sure the end of line is at the same line as the given input position.  Else use the previous position to     // obtain end of line.  This condition happens when the input position is before the space character at the end     // of a soft-wrapped non-editable line. In this scenario, endPositionForLine would incorrectly hand back a position    // in the next line instead. This fix is to account for the discrepancy between lines with webkit-line-break:after-white-space style    // versus lines without that style, which would break before a space by default.     if (!inSameLine(c, visPos)) {        visPos = c.previous();        if (visPos.isNull())            return VisiblePosition();        visPos = endPositionForLine(visPos);    }        return c.honorEditableBoundaryAtOrBefore(visPos);}bool inSameLine(const VisiblePosition &a, const VisiblePosition &b){    return a.isNotNull() && startOfLine(a) == startOfLine(b);}bool isStartOfLine(const VisiblePosition &p){    return p.isNotNull() && p == startOfLine(p);}bool isEndOfLine(const VisiblePosition &p){    return p.isNotNull() && p == endOfLine(p);}// The first leaf before node that has the same editability as node.static Node* previousLeafWithSameEditability(Node* node){    bool editable = node->isContentEditable();    Node* n = node->previousLeafNode();    while (n) {        if (editable == n->isContentEditable())            return n;        n = n->previousLeafNode();    }    return 0;}VisiblePosition previousLinePosition(const VisiblePosition &visiblePosition, int x){    Position p = visiblePosition.deepEquivalent();    Node *node = p.node();    Node* highestRoot = highestEditableRoot(p);    if (!node)        return VisiblePosition();        node->document()->updateLayoutIgnorePendingStylesheets();        RenderObject *renderer = node->renderer();    if (!renderer)        return VisiblePosition();    RenderBlock *containingBlock = 0;    RootInlineBox *root = 0;    InlineBox* box;    int ignoredCaretOffset;    visiblePosition.getInlineBoxAndOffset(box, ignoredCaretOffset);    if (box) {        root = box->root()->prevRootBox();        if (root)            containingBlock = renderer->containingBlock();    }    if (!root) {        // This containing editable block does not have a previous line.        // Need to move back to previous containing editable block in this root editable        // block and find the last root line box in that block.        Node* startBlock = enclosingBlock(node);        Node* n = previousLeafWithSameEditability(node);        while (n && startBlock == enclosingBlock(n))            n = previousLeafWithSameEditability(n);        while (n) {            if (highestEditableRoot(Position(n, 0)) != highestRoot)                break;            Position pos(n, caretMinOffset(n));            if (pos.isCandidate()) {                ASSERT(n->renderer());                Position maxPos(n, caretMaxOffset(n));                maxPos.getInlineBoxAndOffset(DOWNSTREAM, box, ignoredCaretOffset);                if (box) {                    // previous root line box found                    root = box->root();                    containingBlock = n->renderer()->containingBlock();                    break;                }                return VisiblePosition(pos, DOWNSTREAM);            }            n = previousLeafWithSameEditability(n);        }    }        if (root) {        // FIXME: Can be wrong for multi-column layout and with transforms.        FloatPoint absPos = containingBlock->localToAbsolute(FloatPoint());        if (containingBlock->hasOverflowClip())            absPos -= containingBlock->layer()->scrolledContentOffset();        RenderObject* renderer = root->closestLeafChildForXPos(x - absPos.x(), isEditablePosition(p))->renderer();        Node* node = renderer->node();        if (editingIgnoresContent(node))            return Position(node->parent(), node->nodeIndex());        return renderer->positionForCoordinates(x - absPos.x(), root->topOverflow());    }        // Could not find a previous line. This means we must already be on the first line.    // Move to the start of the content in this block, which effectively moves us    // to the start of the line we're on.    Node* rootElement = node->isContentEditable() ? node->rootEditableElement() : node->document()->documentElement();    return VisiblePosition(rootElement, 0, DOWNSTREAM);}static Node* nextLeafWithSameEditability(Node* node, int offset){    bool editable = node->isContentEditable();    ASSERT(offset >= 0);    Node* child = node->childNode(offset);    Node* n = child ? child->nextLeafNode() : node->nextLeafNode();    while (n) {        if (editable == n->isContentEditable())            return n;        n = n->nextLeafNode();    }    return 0;}static Node* nextLeafWithSameEditability(Node* node){    if (!node)        return 0;        bool editable = node->isContentEditable();    Node* n = node->nextLeafNode();    while (n) {        if (editable == n->isContentEditable())            return n;        n = n->nextLeafNode();    }    return 0;}VisiblePosition nextLinePosition(const VisiblePosition &visiblePosition, int x){    Position p = visiblePosition.deepEquivalent();    Node *node = p.node();    Node* highestRoot = highestEditableRoot(p);    if (!node)        return VisiblePosition();        node->document()->updateLayoutIgnorePendingStylesheets();    RenderObject *renderer = node->renderer();    if (!renderer)        return VisiblePosition();    RenderBlock *containingBlock = 0;    RootInlineBox *root = 0;    InlineBox* box;    int ignoredCaretOffset;    visiblePosition.getInlineBoxAndOffset(box, ignoredCaretOffset);    if (box) {        root = box->root()->nextRootBox();        if (root)            containingBlock = renderer->containingBlock();    }    if (!root) {        // This containing editable block does not have a next line.        // Need to move forward to next containing editable block in this root editable        // block and find the first root line box in that block.        Node* startBlock = enclosingBlock(node);        Node* n = nextLeafWithSameEditability(node, p.offset());        while (n && startBlock == enclosingBlock(n))            n = nextLeafWithSameEditability(n);        while (n) {            if (highestEditableRoot(Position(n, 0)) != highestRoot)                break;            Position pos(n, caretMinOffset(n));            if (pos.isCandidate()) {                ASSERT(n->renderer());                pos.getInlineBoxAndOffset(DOWNSTREAM, box, ignoredCaretOffset);                if (box) {                    // next root line box found                    root = box->root();                    containingBlock = n->renderer()->containingBlock();                    break;                }                return VisiblePosition(pos, DOWNSTREAM);            }            n = nextLeafWithSameEditability(n);        }    }        if (root) {        // FIXME: Can be wrong for multi-column layout and with transforms.        FloatPoint absPos = containingBlock->localToAbsolute(FloatPoint());        if (containingBlock->hasOverflowClip())            absPos -= containingBlock->layer()->scrolledContentOffset();        RenderObject* renderer = root->closestLeafChildForXPos(x - absPos.x(), isEditablePosition(p))->renderer();        Node* node = renderer->node();        if (editingIgnoresContent(node))            return Position(node->parent(), node->nodeIndex());        return renderer->positionForCoordinates(x - absPos.x(), root->topOverflow());    }        // Could not find a next line. This means we must already be on the last line.    // Move to the end of the content in this block, which effectively moves us    // to the end of the line we're on.    Element* rootElement = node->isContentEditable() ? node->rootEditableElement() : node->document()->documentElement();    return VisiblePosition(rootElement, rootElement ? rootElement->childNodeCount() : 0, DOWNSTREAM);}// ---------static unsigned startSentenceBoundary(const UChar* characters, unsigned length){    TextBreakIterator* iterator = sentenceBreakIterator(characters, length);    // FIXME: The following function can return -1; we don't handle that.    return textBreakPreceding(iterator, length);}VisiblePosition startOfSentence(const VisiblePosition &c){    return previousBoundary(c, startSentenceBoundary);}static unsigned endSentenceBoundary(const UChar* characters, unsigned length){    TextBreakIterator* iterator = sentenceBreakIterator(characters, length);    return textBreakNext(iterator);}// FIXME: This includes the space after the punctuation that marks the end of the sentence.VisiblePosition endOfSentence(const VisiblePosition &c){    return nextBoundary(c, endSentenceBoundary);}

⌨️ 快捷键说明

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