📄 visible_units.cpp
字号:
static unsigned previousSentencePositionBoundary(const UChar* characters, unsigned length){ // FIXME: This is identical to startSentenceBoundary. I'm pretty sure that's not right. TextBreakIterator* iterator = sentenceBreakIterator(characters, length); // FIXME: The following function can return -1; we don't handle that. return textBreakPreceding(iterator, length);}VisiblePosition previousSentencePosition(const VisiblePosition &c){ VisiblePosition prev = previousBoundary(c, previousSentencePositionBoundary); return c.honorEditableBoundaryAtOrAfter(prev);}static unsigned nextSentencePositionBoundary(const UChar* characters, unsigned length){ // FIXME: This is identical to endSentenceBoundary. This isn't right, it needs to // move to the equivlant position in the following sentence. TextBreakIterator* iterator = sentenceBreakIterator(characters, length); return textBreakFollowing(iterator, 0);}VisiblePosition nextSentencePosition(const VisiblePosition &c){ VisiblePosition next = nextBoundary(c, nextSentencePositionBoundary); return c.honorEditableBoundaryAtOrBefore(next);}// FIXME: Broken for positions before/after images that aren't inline (5027702)VisiblePosition startOfParagraph(const VisiblePosition &c){ Position p = c.deepEquivalent(); Node *startNode = p.node(); if (!startNode) return VisiblePosition(); if (startNode->renderer() && ((startNode->renderer()->isTable() && !startNode->renderer()->isInline()) || startNode->renderer()->isHR()) && p.offset() == maxDeepOffset(startNode)) return VisiblePosition(Position(startNode, 0)); Node* startBlock = enclosingBlock(startNode); Node *node = startNode; int offset = p.offset(); Node *n = startNode; while (n) { if (n->isContentEditable() != startNode->isContentEditable()) break; RenderObject *r = n->renderer(); if (!r) { n = n->traversePreviousNodePostOrder(startBlock); continue; } RenderStyle *style = r->style(); if (style->visibility() != VISIBLE) { n = n->traversePreviousNodePostOrder(startBlock); continue; } if (r->isBR() || isBlock(n)) break; if (r->isText()) { if (style->preserveNewline()) { const UChar* chars = toRenderText(r)->characters(); int i = toRenderText(r)->textLength(); int o = offset; if (n == startNode && o < i) i = max(0, o); while (--i >= 0) if (chars[i] == '\n') return VisiblePosition(n, i + 1, DOWNSTREAM); } node = n; offset = 0; n = n->traversePreviousNodePostOrder(startBlock); } else if (editingIgnoresContent(n) || isTableElement(n)) { node = n; offset = 0; n = n->previousSibling() ? n->previousSibling() : n->traversePreviousNodePostOrder(startBlock); } else n = n->traversePreviousNodePostOrder(startBlock); } return VisiblePosition(node, offset, DOWNSTREAM);}// FIXME: Broken for positions before/after images that aren't inline (5027702)VisiblePosition endOfParagraph(const VisiblePosition &c){ if (c.isNull()) return VisiblePosition(); Position p = c.deepEquivalent(); Node* startNode = p.node(); if (startNode->renderer() && ((startNode->renderer()->isTable() && !startNode->renderer()->isInline()) || startNode->renderer()->isHR()) && p.offset() == 0) return VisiblePosition(Position(startNode, maxDeepOffset(startNode))); Node* startBlock = enclosingBlock(startNode); Node *stayInsideBlock = startBlock; Node *node = startNode; int offset = p.offset(); Node *n = startNode; while (n) { if (n->isContentEditable() != startNode->isContentEditable()) break; RenderObject *r = n->renderer(); if (!r) { n = n->traverseNextNode(stayInsideBlock); continue; } RenderStyle *style = r->style(); if (style->visibility() != VISIBLE) { n = n->traverseNextNode(stayInsideBlock); continue; } if (r->isBR() || isBlock(n)) break; // FIXME: We avoid returning a position where the renderer can't accept the caret. // We should probably do this in other cases such as startOfParagraph. if (r->isText() && r->caretMaxRenderedOffset() > 0) { int length = toRenderText(r)->textLength(); if (style->preserveNewline()) { const UChar* chars = toRenderText(r)->characters(); int o = n == startNode ? offset : 0; for (int i = o; i < length; ++i) if (chars[i] == '\n') return VisiblePosition(n, i, DOWNSTREAM); } node = n; offset = r->caretMaxOffset(); n = n->traverseNextNode(stayInsideBlock); } else if (editingIgnoresContent(n) || isTableElement(n)) { node = n; offset = maxDeepOffset(n); n = n->traverseNextSibling(stayInsideBlock); } else n = n->traverseNextNode(stayInsideBlock); } return VisiblePosition(node, offset, DOWNSTREAM);}VisiblePosition startOfNextParagraph(const VisiblePosition& visiblePosition){ VisiblePosition paragraphEnd(endOfParagraph(visiblePosition)); VisiblePosition afterParagraphEnd(paragraphEnd.next(true)); // The position after the last position in the last cell of a table // is not the start of the next paragraph. if (isFirstPositionAfterTable(afterParagraphEnd)) return afterParagraphEnd.next(true); return afterParagraphEnd;}bool inSameParagraph(const VisiblePosition &a, const VisiblePosition &b){ return a.isNotNull() && startOfParagraph(a) == startOfParagraph(b);}bool isStartOfParagraph(const VisiblePosition &pos){ return pos.isNotNull() && pos == startOfParagraph(pos);}bool isEndOfParagraph(const VisiblePosition &pos){ return pos.isNotNull() && pos == endOfParagraph(pos);}VisiblePosition previousParagraphPosition(const VisiblePosition &p, int x){ VisiblePosition pos = p; do { VisiblePosition n = previousLinePosition(pos, x); if (n.isNull() || n == pos) return p; pos = n; } while (inSameParagraph(p, pos)); return pos;}VisiblePosition nextParagraphPosition(const VisiblePosition &p, int x){ VisiblePosition pos = p; do { VisiblePosition n = nextLinePosition(pos, x); if (n.isNull() || n == pos) return p; pos = n; } while (inSameParagraph(p, pos)); return pos;}// ---------VisiblePosition startOfBlock(const VisiblePosition &c){ Position p = c.deepEquivalent(); Node *startNode = p.node(); if (!startNode) return VisiblePosition(); return VisiblePosition(Position(startNode->enclosingBlockFlowElement(), 0), DOWNSTREAM);}VisiblePosition endOfBlock(const VisiblePosition &c){ Position p = c.deepEquivalent(); Node *startNode = p.node(); if (!startNode) return VisiblePosition(); Node *startBlock = startNode->enclosingBlockFlowElement(); return VisiblePosition(startBlock, startBlock->childNodeCount(), VP_DEFAULT_AFFINITY); }bool inSameBlock(const VisiblePosition &a, const VisiblePosition &b){ return !a.isNull() && enclosingBlockFlowElement(a) == enclosingBlockFlowElement(b);}bool isStartOfBlock(const VisiblePosition &pos){ return pos.isNotNull() && pos == startOfBlock(pos);}bool isEndOfBlock(const VisiblePosition &pos){ return pos.isNotNull() && pos == endOfBlock(pos);}// ---------VisiblePosition startOfDocument(const Node* node){ if (!node) return VisiblePosition(); return VisiblePosition(node->document()->documentElement(), 0, DOWNSTREAM);}VisiblePosition startOfDocument(const VisiblePosition &c){ return startOfDocument(c.deepEquivalent().node());}VisiblePosition endOfDocument(const Node* node){ if (!node || !node->document()) return VisiblePosition(); Element* doc = node->document()->documentElement(); return VisiblePosition(doc, doc->childNodeCount(), DOWNSTREAM);}VisiblePosition endOfDocument(const VisiblePosition &c){ return endOfDocument(c.deepEquivalent().node());}bool inSameDocument(const VisiblePosition &a, const VisiblePosition &b){ Position ap = a.deepEquivalent(); Node *an = ap.node(); if (!an) return false; Position bp = b.deepEquivalent(); Node *bn = bp.node(); if (an == bn) return true; return an->document() == bn->document();}bool isStartOfDocument(const VisiblePosition &p){ return p.isNotNull() && p.previous().isNull();}bool isEndOfDocument(const VisiblePosition &p){ return p.isNotNull() && p.next().isNull();}// ---------VisiblePosition startOfEditableContent(const VisiblePosition& visiblePosition){ Node* highestRoot = highestEditableRoot(visiblePosition.deepEquivalent()); if (!highestRoot) return VisiblePosition(); return VisiblePosition(highestRoot, 0, DOWNSTREAM);}VisiblePosition endOfEditableContent(const VisiblePosition& visiblePosition){ Node* highestRoot = highestEditableRoot(visiblePosition.deepEquivalent()); if (!highestRoot) return VisiblePosition(); return VisiblePosition(highestRoot, maxDeepOffset(highestRoot), DOWNSTREAM);}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -