📄 dom_position.cpp
字号:
return it.next(); RenderObject *renderer = it.current().node()->renderer(); if (!renderer) continue; if (renderer->style()->visibility() != khtml::VISIBLE) continue; if (renderer->isBlockFlow() || renderer->isReplaced() || renderer->isBR()) { if (it.current().offset() >= renderer->caretMaxOffset()) return Position(it.current().node(), renderer->caretMaxOffset()); else continue; } if (renderer->isText() && static_cast<RenderText *>(renderer)->firstTextBox()) { if (it.current().node() != node()) return Position(it.current().node(), renderer->caretMaxOffset()); if (it.current().offset() < 0) continue; uint textOffset = it.current().offset(); RenderText *textRenderer = static_cast<RenderText *>(renderer); for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) { if (textOffset > box->start() && textOffset <= box->start() + box->len()) return it.current(); } } } return it.current();}Position Position::equivalentDownstreamPosition() const{ if (!node()) return Position(); NodeImpl *block = node()->enclosingBlockFlowElement(); PositionIterator it(*this); for (; !it.atEnd(); it.next()) { NodeImpl *currentBlock = it.current().node()->enclosingBlockFlowElement(); if (block != currentBlock) return it.previous(); RenderObject *renderer = it.current().node()->renderer(); if (!renderer) continue; if (renderer->style()->visibility() != khtml::VISIBLE) continue; if (renderer->isBlockFlow() || renderer->isReplaced() || renderer->isBR()) { if (it.current().offset() <= renderer->caretMinOffset()) return Position(it.current().node(), renderer->caretMinOffset()); else continue; } if (renderer->isText() && static_cast<RenderText *>(renderer)->firstTextBox()) { if (it.current().node() != node()) return Position(it.current().node(), renderer->caretMinOffset()); if (it.current().offset() < 0) continue; uint textOffset = it.current().offset(); RenderText *textRenderer = static_cast<RenderText *>(renderer); for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) { if (textOffset >= box->start() && textOffset <= box->end()) return it.current(); } } } return it.current();}Position Position::equivalentRangeCompliantPosition() const{ if (isEmpty()) return *this; if (!node()->parentNode()) return *this; RenderObject *renderer = node()->renderer(); if (!renderer) return *this; if (!renderer->isReplaced() && !renderer->isBR()) return *this; int o = 0; const NodeImpl *n = node(); while ((n = n->previousSibling())) o++; return Position(node()->parentNode(), o + offset());}Position Position::equivalentShallowPosition() const{ if (isEmpty()) return *this; Position pos(*this); while (pos.offset() == pos.node()->caretMinOffset() && pos.node()->parentNode() && pos.node() == pos.node()->parentNode()->firstChild()) pos = Position(pos.node()->parentNode(), 0); return pos;}bool Position::atStartOfContainingEditableBlock() const{ return renderedOffset() == 0 && inFirstEditableInContainingEditableBlock();}bool Position::atStartOfRootEditableElement() const{ return renderedOffset() == 0 && inFirstEditableInRootEditableElement();}bool Position::inRenderedContent() const{ if (isEmpty()) return false; RenderObject *renderer = node()->renderer(); if (!renderer || !renderer->isEditable()) return false; if (renderer->style()->visibility() != khtml::VISIBLE) return false; if (renderer->isBR() && static_cast<RenderText *>(renderer)->firstTextBox()) { return offset() == 0; } else if (renderer->isText()) { RenderText *textRenderer = static_cast<RenderText *>(renderer); for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) { if (offset() >= box->m_start && offset() <= box->m_start + box->m_len) { return true; } else if (offset() < box->m_start) { // The offset we're looking for is before this node // this means the offset must be in content that is // not rendered. Return false. return false; } } } else if (offset() >= renderer->caretMinOffset() && offset() <= renderer->caretMaxOffset()) { // don't return containing editable blocks unless they are empty if (node()->enclosingBlockFlowElement() == node() && node()->firstChild()) return false; return true; } return false;}bool Position::inRenderedText() const{ if (!node()->isTextNode()) return false; RenderObject *renderer = node()->renderer(); if (!renderer) return false; RenderText *textRenderer = static_cast<RenderText *>(renderer); for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) { if (offset() < box->m_start) { // The offset we're looking for is before this node // this means the offset must be in content that is // not rendered. Return false. return false; } if (offset() >= box->m_start && offset() <= box->m_start + box->m_len) return true; } return false;}bool Position::rendersOnSameLine(const Position &pos) const{ if (isEmpty() || pos.isEmpty()) return false; if (node() == pos.node() && offset() == pos.offset()) return true; if (node()->enclosingBlockFlowElement() != pos.node()->enclosingBlockFlowElement()) return false; RenderObject *renderer = node()->renderer(); if (!renderer) return false; RenderObject *posRenderer = pos.node()->renderer(); if (!posRenderer) return false; if (renderer->style()->visibility() != khtml::VISIBLE || posRenderer->style()->visibility() != khtml::VISIBLE) return false; return renderersOnDifferentLine(renderer, offset(), posRenderer, pos.offset());}bool Position::rendersInDifferentPosition(const Position &pos) const{ if (isEmpty() || pos.isEmpty()) return false; RenderObject *renderer = node()->renderer(); if (!renderer) return false; RenderObject *posRenderer = pos.node()->renderer(); if (!posRenderer) return false; if (renderer->style()->visibility() != khtml::VISIBLE || posRenderer->style()->visibility() != khtml::VISIBLE) return false; if (node() == pos.node()) { if (node()->id() == ID_BR) return false; if (offset() == pos.offset()) return false; if (!node()->isTextNode() && !pos.node()->isTextNode()) { if (offset() != pos.offset()) return true; } } if (node()->id() == ID_BR && pos.inRenderedContent()) return true; if (pos.node()->id() == ID_BR && inRenderedContent()) return true; if (node()->enclosingBlockFlowElement() != pos.node()->enclosingBlockFlowElement()) return true; if (node()->isTextNode() && !inRenderedText()) return false; if (pos.node()->isTextNode() && !pos.inRenderedText()) return false; long thisRenderedOffset = renderedOffset(); long posRenderedOffset = pos.renderedOffset(); if (renderer == posRenderer && thisRenderedOffset == posRenderedOffset) return false; LOG(Editing, "onDifferentLine: %s\n", renderersOnDifferentLine(renderer, offset(), posRenderer, pos.offset()) ? "YES" : "NO"); LOG(Editing, "renderer: %p [%p]\n", renderer, renderer ? renderer->inlineBox(offset()) : 0); LOG(Editing, "thisRenderedOffset: %d\n", thisRenderedOffset); LOG(Editing, "posRenderer: %p [%p]\n", posRenderer, posRenderer ? posRenderer->inlineBox(offset()) : 0); LOG(Editing, "posRenderedOffset: %d\n", posRenderedOffset); LOG(Editing, "node min/max: %d:%d\n", node()->caretMinOffset(), node()->caretMaxRenderedOffset()); LOG(Editing, "pos node min/max: %d:%d\n", pos.node()->caretMinOffset(), pos.node()->caretMaxRenderedOffset()); LOG(Editing, "----------------------------------------------------------------------\n"); InlineBox *b1 = renderer ? renderer->inlineBox(offset()) : 0; InlineBox *b2 = posRenderer ? posRenderer->inlineBox(pos.offset()) : 0; if (!b1 || !b2) { return false; } if (b1->root() != b2->root()) { return true; } if (nextRenderedEditable(node()) == pos.node() && thisRenderedOffset == (long)node()->caretMaxRenderedOffset() && posRenderedOffset == 0) { return false; } if (previousRenderedEditable(node()) == pos.node() && thisRenderedOffset == 0 && posRenderedOffset == (long)pos.node()->caretMaxRenderedOffset()) { return false; } return true;}bool Position::isFirstRenderedPositionOnLine() const{ if (isEmpty()) return false; RenderObject *renderer = node()->renderer(); if (!renderer) return false; if (renderer->style()->visibility() != khtml::VISIBLE) return false; Position pos(node(), offset()); PositionIterator it(pos); while (!it.atStart()) { it.previous(); if (it.current().inRenderedContent()) return renderersOnDifferentLine(renderer, offset(), it.current().node()->renderer(), it.current().offset()); } return true;}bool Position::isLastRenderedPositionOnLine() const{ if (isEmpty()) return false; RenderObject *renderer = node()->renderer(); if (!renderer) return false; if (renderer->style()->visibility() != khtml::VISIBLE) return false; if (node()->id() == ID_BR) return true; Position pos(node(), offset()); PositionIterator it(pos); while (!it.atEnd()) { it.next(); if (it.current().inRenderedContent()) return renderersOnDifferentLine(renderer, offset(), it.current().node()->renderer(), it.current().offset()); } return true;}bool Position::isLastRenderedPositionInEditableBlock() const{ if (isEmpty()) return false; RenderObject *renderer = node()->renderer(); if (!renderer) return false; if (renderer->style()->visibility() != khtml::VISIBLE) return false; if (renderedOffset() != (long)node()->caretMaxRenderedOffset()) return false; Position pos(node(), offset()); PositionIterator it(pos); while (!it.atEnd()) { it.next(); if (!it.current().node()->inSameContainingBlockFlowElement(node())) return true; if (it.current().inRenderedContent()) return false; } return true;}bool Position::inFirstEditableInRootEditableElement() const{ if (isEmpty() || !inRenderedContent()) return false; PositionIterator it(*this); while (!it.atStart()) { if (it.previous().inRenderedContent()) return false; } return true;}bool Position::inLastEditableInRootEditableElement() const{ if (isEmpty() || !inRenderedContent()) return false; PositionIterator it(*this); while (!it.atEnd()) { if (it.next().inRenderedContent()) return false; } return true;}bool Position::inFirstEditableInContainingEditableBlock() const{ if (isEmpty() || !inRenderedContent()) return false; NodeImpl *block = node()->enclosingBlockFlowElement(); PositionIterator it(*this); while (!it.atStart()) { it.previous(); if (!it.current().inRenderedContent()) continue; return block != it.current().node()->enclosingBlockFlowElement(); } return true;}bool Position::inLastEditableInContainingEditableBlock() const{ if (isEmpty() || !inRenderedContent()) return false; NodeImpl *block = node()->enclosingBlockFlowElement(); PositionIterator it(*this); while (!it.atEnd()) { it.next(); if (!it.current().inRenderedContent()) continue; return block != it.current().node()->enclosingBlockFlowElement(); } return true;}void Position::debugPosition(const char *msg) const{ if (isEmpty()) fprintf(stderr, "Position [%s]: empty\n", msg); else fprintf(stderr, "Position [%s]: %s at %d\n", msg, getTagName(node()->id()).string().latin1(), (int) offset());}} // namespace DOM
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -