Position HTMLTextFormControlElement::startOfSentence(const Position& position) { HTMLTextFormControlElement* textFormControl = enclosingTextFormControl(position); ASSERT(textFormControl); HTMLElement* innerEditor = textFormControl->innerEditorElement(); if (!innerEditor->childNodes()->length()) return startOfInnerText(textFormControl); const Position innerPosition = position.anchorNode() == innerEditor ? innerNodePosition(position) : position; const Position pivotPosition = previousIfPositionIsAfterLineBreak(innerPosition, innerEditor); if (pivotPosition.isNull()) return startOfInnerText(textFormControl); for (Node* node = pivotPosition.anchorNode(); node; node = NodeTraversal::previous(*node, innerEditor)) { bool isPivotNode = (node == pivotPosition.anchorNode()); if (isHTMLBRElement(node) && (!isPivotNode || pivotPosition.isAfterAnchor())) return Position(node, PositionAnchorType::AfterAnchor); if (node->isTextNode()) { Text* textNode = toText(node); size_t lastLineBreak = textNode->data().substring(0, isPivotNode ? pivotPosition.offsetInContainerNode() : textNode->length()).reverseFind('\n'); if (lastLineBreak != kNotFound) return Position(textNode, lastLineBreak + 1); } } return startOfInnerText(textFormControl); }
Position HTMLTextFormControlElement::endOfSentence(const Position& position) { HTMLTextFormControlElement* textFormControl = enclosingTextFormControl(position); ASSERT(textFormControl); HTMLElement* innerEditor = textFormControl->innerEditorElement(); if (innerEditor->childNodes()->length() == 0) return startOfInnerText(textFormControl); const Position pivotPosition = position.anchorNode() == innerEditor ? innerNodePosition(position) : position; if (pivotPosition.isNull()) return startOfInnerText(textFormControl); for (Node* node = pivotPosition.anchorNode(); node; node = NodeTraversal::next(*node, innerEditor)) { bool isPivotNode = node == pivotPosition.anchorNode(); if (isHTMLBRElement(node)) return Position(node, PositionAnchorType::AfterAnchor); if (node->isTextNode()) { Text* textNode = toText(node); size_t firstLineBreak = textNode->data().find('\n', isPivotNode ? pivotPosition.offsetInContainerNode() : 0); if (firstLineBreak != kNotFound) return Position(textNode, firstLineBreak + 1); } } return endOfInnerText(textFormControl); }
static Position innerNodePosition(const Position& innerPosition) { ASSERT(!innerPosition.isBeforeAnchor()); ASSERT(!innerPosition.isAfterAnchor()); HTMLElement* element = toHTMLElement(innerPosition.anchorNode()); ASSERT(element); NodeList* childNodes = element->childNodes(); if (!childNodes->length()) return Position(element, 0); unsigned offset = 0; if (innerPosition.isOffsetInAnchor()) offset = std::max(0, std::min(innerPosition.offsetInContainerNode(), static_cast<int>(childNodes->length()))); else if (innerPosition.isAfterChildren()) offset = childNodes->length(); if (offset == childNodes->length()) return Position(element->lastChild(), PositionAnchorType::AfterAnchor); Node* node = childNodes->item(offset); if (node->isTextNode()) return Position(toText(node), 0); return Position(node, PositionAnchorType::BeforeAnchor); }
static Position innerNodePosition(const Position& innerPosition) { ASSERT(innerPosition.anchorType() != Position::PositionIsBeforeAnchor); ASSERT(innerPosition.anchorType() != Position::PositionIsAfterAnchor); HTMLElement* element = toHTMLElement(innerPosition.anchorNode()); ASSERT(element); RefPtrWillBeRawPtr<NodeList> childNodes = element->childNodes(); if (!childNodes->length()) return Position(element, 0, Position::PositionIsOffsetInAnchor); unsigned offset = 0; switch (innerPosition.anchorType()) { case Position::PositionIsOffsetInAnchor: offset = std::max(0, std::min(innerPosition.offsetInContainerNode(), static_cast<int>(childNodes->length()))); break; case Position::PositionIsAfterChildren: offset = childNodes->length(); break; default: break; } if (offset == childNodes->length()) return Position(element->lastChild(), Position::PositionIsAfterAnchor); Node* node = childNodes->item(offset); if (node->isTextNode()) return Position(toText(node), 0); return Position(node, Position::PositionIsBeforeAnchor); }
static Position endOfInnerText(const HTMLTextFormControlElement* textFormControl) { HTMLElement* innerEditor = textFormControl->innerEditorElement(); return Position(innerEditor, innerEditor->childNodes()->length()); }