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 startPositionForLine(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 positionAvoidingFirstPositionInTable(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 follows instead. InlineBox *startBox = rootBox->firstLeafChild(); Node *startNode; while (1) { if (!startBox) return VisiblePosition(); RenderObject *startRenderer = startBox->renderer(); if (!startRenderer) return VisiblePosition(); startNode = startRenderer->node(); if (startNode) break; startBox = startBox->nextLeafChild(); } int startOffset = 0; if (startBox->isInlineTextBox()) { InlineTextBox *startTextBox = static_cast<InlineTextBox *>(startBox); startOffset = startTextBox->start(); } VisiblePosition visPos = VisiblePosition(startNode, startOffset, DOWNSTREAM); return positionAvoidingFirstPositionInTable(visPos); }