Example #1
0
static Position previousIfPositionIsAfterLineBreak(const Position& position, HTMLElement* innerEditor)
{
    if (position.isNull())
        return Position();

    // Move back if position is just after line break.
    if (isHTMLBRElement(*position.anchorNode())) {
        if (position.isAfterAnchor())
            return Position(position.anchorNode(), PositionAnchorType::BeforeAnchor);
        if (position.isBeforeAnchor())
            return previousIfPositionIsAfterLineBreak(endOfPrevious(*position.anchorNode(), innerEditor), innerEditor);
        // We don't place caret into BR element, since well-formed BR element
        // doesn't have child nodes.
        ASSERT_NOT_REACHED();
        return position;
    }

    if (!position.anchorNode()->isTextNode())
        return position;

    Text* textNode = toText(position.anchorNode());
    unsigned offset = position.offsetInContainerNode();
    if (textNode->length() == 0 || offset == 0)
        return previousIfPositionIsAfterLineBreak(endOfPrevious(*position.anchorNode(), innerEditor), innerEditor);

    if (offset <= textNode->length() && textNode->data()[offset - 1] == '\n')
        return Position(textNode, offset - 1);

    return position;
}
static Position previousIfPositionIsAfterLineBreak(const Position& position, HTMLElement* innerEditor)
{
    if (position.isNull())
        return Position();

    // Move back if position is just after line break.
    if (isHTMLBRElement(*position.anchorNode())) {
        switch (position.anchorType()) {
        case Position::PositionIsAfterAnchor:
            return Position(position.anchorNode(), Position::PositionIsBeforeAnchor);
        case Position::PositionIsBeforeAnchor:
            return previousIfPositionIsAfterLineBreak(endOfPrevious(*position.anchorNode(), innerEditor), innerEditor);
        default:
            ASSERT_NOT_REACHED();
        }
    } else if (position.anchorNode()->isTextNode()) {
        Text* textNode = toText(position.anchorNode());
        unsigned offset = position.offsetInContainerNode();
        if (textNode->length() == 0 || offset == 0) {
            return previousIfPositionIsAfterLineBreak(endOfPrevious(*position.anchorNode(), innerEditor), innerEditor);
        }

        if (offset <= textNode->length() && textNode->data()[offset - 1] == '\n') {
            return Position(textNode, offset - 1);
        }
    }

    return position;
}
Example #3
0
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);
}