bool VisiblePosition::isCandidate(const Position &pos) { if (pos.isNull()) return false; RenderObject *renderer = pos.node()->renderer(); if (!renderer) return false; if (renderer->style()->visibility() != VISIBLE) return false; if (renderer->isReplaced()) // return true for replaced elements return pos.offset() == 0 || pos.offset() == 1; if (renderer->isBR()) { if (pos.offset() == 0) { InlineBox* box = static_cast<RenderText*>(renderer)->firstTextBox(); if (box) { // return true for offset 0 into BR element on a line by itself RootInlineBox* root = box->root(); if (root) return root->firstLeafChild() == box && root->lastLeafChild() == box; } } return false; } if (renderer->isText()) { RenderText *textRenderer = static_cast<RenderText *>(renderer); for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) { if (pos.offset() >= box->m_start && pos.offset() <= box->m_start + box->m_len) { // return true if in a text node return true; } } } if (renderer->isBlockFlow() && (!renderer->firstChild() || !pos.node()->firstChild()) && (renderer->height() || pos.node()->id() == ID_BODY)) { // return true for offset 0 into rendered blocks that are empty of rendered kids, but have a height return pos.offset() == 0; } return false; }
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.deprecatedEditingOffset() == 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); }