static inline void appendContextSubtargetsForNode(Node* node, SubtargetGeometryList& subtargets) { // This is a variant of appendBasicSubtargetsForNode that adds special subtargets for // selected or auto-selectable parts of text nodes. ASSERT(node->renderer()); if (!node->isTextNode()) return appendBasicSubtargetsForNode(node, subtargets); Text* textNode = static_cast<WebCore::Text*>(node); RenderText* textRenderer = static_cast<RenderText*>(textNode->renderer()); if (textRenderer->frame()->editor()->behavior().shouldSelectOnContextualMenuClick()) { // Make subtargets out of every word. String textValue = textNode->data(); TextBreakIterator* wordIterator = wordBreakIterator(textValue.characters(), textValue.length()); int lastOffset = textBreakFirst(wordIterator); if (lastOffset == -1) return; int offset; while ((offset = textBreakNext(wordIterator)) != -1) { if (isWordTextBreak(wordIterator)) { Vector<FloatQuad> quads; textRenderer->absoluteQuadsForRange(quads, lastOffset, offset); appendQuadsToSubtargetList(quads, textNode, subtargets); } lastOffset = offset; } } else { if (textRenderer->selectionState() == RenderObject::SelectionNone) return appendBasicSubtargetsForNode(node, subtargets); // If selected, make subtargets out of only the selected part of the text. int startPos, endPos; switch (textRenderer->selectionState()) { case RenderObject::SelectionInside: startPos = 0; endPos = textRenderer->textLength(); break; case RenderObject::SelectionStart: textRenderer->selectionStartEnd(startPos, endPos); endPos = textRenderer->textLength(); break; case RenderObject::SelectionEnd: textRenderer->selectionStartEnd(startPos, endPos); startPos = 0; break; case RenderObject::SelectionBoth: textRenderer->selectionStartEnd(startPos, endPos); break; default: ASSERT_NOT_REACHED(); return; } Vector<FloatQuad> quads; textRenderer->absoluteQuadsForRange(quads, startPos, endPos); appendQuadsToSubtargetList(quads, textNode, subtargets); } }
void RenderTextLineBoxes::setSelectionState(RenderText& renderer, RenderObject::SelectionState state) { if (state == RenderObject::SelectionInside || state == RenderObject::SelectionNone) { for (auto box = m_first; box; box = box->nextTextBox()) box->root().setHasSelectedChildren(state == RenderObject::SelectionInside); return; } int start, end; renderer.selectionStartEnd(start, end); if (state == RenderObject::SelectionStart) { end = renderer.textLength(); // to handle selection from end of text to end of line if (start && start == end) start = end - 1; } else if (state == RenderObject::SelectionEnd) start = 0; for (auto box = m_first; box; box = box->nextTextBox()) { if (box->isSelected(start, end)) box->root().setHasSelectedChildren(true); } }