15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *           (C) 1999 Antti Koivisto (koivisto@kde.org)
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *           (C) 2001 Dirk Mueller (mueller@kde.org)
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *           (C) 2006 Alexey Proskuryakov (ap@nypop.com)
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLTextFormControlElement.h"
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
28197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionState.h"
29197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionStatePlaceholder.h"
305d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/HTMLNames.h"
3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/accessibility/AXObjectCache.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h"
33197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/dom/NodeList.h"
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/NodeTraversal.h"
3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Text.h"
369bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)#include "core/dom/shadow/ShadowRoot.h"
37c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/editing/Editor.h"
3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/FrameSelection.h"
3953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/TextIterator.h"
40c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/editing/htmlediting.h"
411e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/events/Event.h"
42d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/frame/LocalFrame.h"
43d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/frame/UseCounter.h"
4453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLBRElement.h"
459bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)#include "core/html/shadow/ShadowElementNames.h"
46c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/page/FocusController.h"
47c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/page/Page.h"
48c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/rendering/RenderBlock.h"
49197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/rendering/RenderBlockFlow.h"
5053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderTheme.h"
51a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#include "platform/heap/Handle.h"
52197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "platform/text/TextBoundaries.h"
53e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/text/StringBuilder.h"
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
55c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace HTMLNames;
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
598abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)HTMLTextFormControlElement::HTMLTextFormControlElement(const QualifiedName& tagName, Document& doc, HTMLFormElement* form)
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : HTMLFormControlElementWithState(tagName, doc, form)
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_lastChangeWasUserEdit(false)
626f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    , m_cachedSelectionStart(0)
636f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    , m_cachedSelectionEnd(0)
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_cachedSelectionDirection(SelectionHasNoDirection)
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)HTMLTextFormControlElement::~HTMLTextFormControlElement()
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node::InsertionNotificationRequest HTMLTextFormControlElement::insertedInto(ContainerNode* insertionPoint)
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    HTMLFormControlElementWithState::insertedInto(insertionPoint);
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!insertionPoint->inDocument())
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return InsertionDone;
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String initialValue = value();
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setTextAsOfLastFormControlChangeEvent(initialValue.isNull() ? emptyString() : initialValue);
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return InsertionDone;
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void HTMLTextFormControlElement::dispatchFocusEvent(Element* oldFocusedElement, FocusType type)
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (supportsPlaceholder())
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        updatePlaceholderVisibility(false);
8609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    handleFocusEvent(oldFocusedElement, type);
8709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    HTMLFormControlElementWithState::dispatchFocusEvent(oldFocusedElement, type);
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdochvoid HTMLTextFormControlElement::dispatchBlurEvent(Element* newFocusedElement)
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (supportsPlaceholder())
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        updatePlaceholderVisibility(false);
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    handleBlurEvent();
9502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    HTMLFormControlElementWithState::dispatchBlurEvent(newFocusedElement);
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void HTMLTextFormControlElement::defaultEventHandler(Event* event)
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1001e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (event->type() == EventTypeNames::webkitEditableContentChanged && renderer() && renderer()->isTextControl()) {
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_lastChangeWasUserEdit = true;
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        subtreeHasChanged();
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLFormControlElementWithState::defaultEventHandler(event);
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void HTMLTextFormControlElement::forwardEvent(Event* event)
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1111e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (event->type() == EventTypeNames::blur || event->type() == EventTypeNames::focus)
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
11376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    innerEditorElement()->defaultEventHandler(event);
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String HTMLTextFormControlElement::strippedPlaceholder() const
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // According to the HTML5 specification, we need to remove CR and LF from
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // the attribute value.
120926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const AtomicString& attributeValue = fastGetAttribute(placeholderAttr);
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!attributeValue.contains(newlineCharacter) && !attributeValue.contains(carriageReturn))
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return attributeValue;
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder stripped;
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned length = attributeValue.length();
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    stripped.reserveCapacity(length);
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned i = 0; i < length; ++i) {
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        UChar character = attributeValue[i];
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (character == newlineCharacter || character == carriageReturn)
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        stripped.append(character);
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return stripped.toString();
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool isNotLineBreak(UChar ch) { return ch != newlineCharacter && ch != carriageReturn; }
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool HTMLTextFormControlElement::isPlaceholderEmpty() const
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
140926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const AtomicString& attributeValue = fastGetAttribute(placeholderAttr);
14106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    return attributeValue.string().find(isNotLineBreak) == kNotFound;
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool HTMLTextFormControlElement::placeholderShouldBeVisible() const
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return supportsPlaceholder()
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        && isEmptyValue()
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        && isEmptySuggestedValue()
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        && !isPlaceholderEmpty()
1508abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        && (document().focusedElement() != this || (RenderTheme::theme().shouldShowPlaceholderWhenFocused()))
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        && (!renderer() || renderer()->style()->visibility() == VISIBLE);
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1549bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)HTMLElement* HTMLTextFormControlElement::placeholderElement() const
1559bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles){
1569bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    return toHTMLElement(userAgentShadowRoot()->getElementById(ShadowElementNames::placeholder()));
1579bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)}
1589bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void HTMLTextFormControlElement::updatePlaceholderVisibility(bool placeholderValueChanged)
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!supportsPlaceholder())
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!placeholderElement() || placeholderValueChanged)
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        updatePlaceholderText();
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLElement* placeholder = placeholderElement();
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!placeholder)
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
16883750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch    placeholder->setInlineStyleProperty(CSSPropertyVisibility, placeholderShouldBeVisible() ? CSSValueVisible : CSSValueHidden);
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void HTMLTextFormControlElement::setSelectionStart(int start)
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1735d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    setSelectionRange(start, std::max(start, selectionEnd()), selectionDirection());
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void HTMLTextFormControlElement::setSelectionEnd(int end)
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1785d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    setSelectionRange(std::min(end, selectionStart()), end, selectionDirection());
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void HTMLTextFormControlElement::setSelectionDirection(const String& direction)
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setSelectionRange(selectionStart(), selectionEnd(), direction);
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void HTMLTextFormControlElement::select()
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
188c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    document().updateLayoutIgnorePendingStylesheets();
189f542a0e9557608d421c9d165487573efa35a5f91Ben Murdoch    setSelectionRange(0, std::numeric_limits<int>::max(), SelectionHasNoDirection, isFocusable() ? ChangeSelectionAndFocus : NotChangeSelection);
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
192323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)bool HTMLTextFormControlElement::shouldDispatchFormControlChangeEvent(String& oldValue, String& newValue)
193323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles){
194323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    return !equalIgnoringNullity(oldValue, newValue);
195323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)}
196323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void HTMLTextFormControlElement::dispatchFormControlChangeEvent()
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
199323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    String newValue = value();
200323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (shouldDispatchFormControlChangeEvent(m_textAsOfLastFormControlChangeEvent, newValue)) {
201323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        setTextAsOfLastFormControlChangeEvent(newValue);
202f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        dispatchChangeEvent();
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setChangedSinceLastFormControlChangeEvent(false);
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void HTMLTextFormControlElement::setRangeText(const String& replacement, ExceptionState& exceptionState)
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
20951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    setRangeText(replacement, selectionStart(), selectionEnd(), String(), exceptionState);
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
21251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void HTMLTextFormControlElement::setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode, ExceptionState& exceptionState)
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (start > end) {
215a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        exceptionState.throwDOMException(IndexSizeError, "The provided start value (" + String::number(start) + ") is larger than the provided end value (" + String::number(end) + ").");
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
218d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (hasAuthorShadowRoot())
219d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
22176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    String text = innerEditorValue();
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned textLength = text.length();
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned replacementLength = replacement.length();
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned newSelectionStart = selectionStart();
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned newSelectionEnd = selectionEnd();
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    start = std::min(start, textLength);
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    end = std::min(end, textLength);
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (start < end)
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        text.replace(start, end - start, replacement);
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        text.insert(replacement, start);
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
23576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    setInnerEditorValue(text);
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: What should happen to the value (as in value()) if there's no renderer?
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!renderer())
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    subtreeHasChanged();
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (equalIgnoringCase(selectionMode, "select")) {
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        newSelectionStart = start;
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        newSelectionEnd = start + replacementLength;
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else if (equalIgnoringCase(selectionMode, "start"))
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        newSelectionStart = newSelectionEnd = start;
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else if (equalIgnoringCase(selectionMode, "end"))
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        newSelectionStart = newSelectionEnd = start + replacementLength;
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else {
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Default is "preserve".
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        long delta = replacementLength - (end - start);
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (newSelectionStart > end)
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            newSelectionStart += delta;
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else if (newSelectionStart > start)
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            newSelectionStart = start;
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (newSelectionEnd > end)
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            newSelectionEnd += delta;
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else if (newSelectionEnd > start)
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            newSelectionEnd = start + replacementLength;
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setSelectionRange(newSelectionStart, newSelectionEnd, SelectionHasNoDirection);
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void HTMLTextFormControlElement::setSelectionRange(int start, int end, const String& directionString)
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TextFieldSelectionDirection direction = SelectionHasNoDirection;
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (directionString == "forward")
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        direction = SelectionHasForwardDirection;
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else if (directionString == "backward")
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        direction = SelectionHasBackwardDirection;
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
276c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (direction == SelectionHasNoDirection && document().frame() && document().frame()->editor().behavior().shouldConsiderSelectionAsDirectional())
277c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        direction = SelectionHasForwardDirection;
278c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return setSelectionRange(start, end, direction);
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
282c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)static Position positionForIndex(HTMLElement* innerEditor, int index)
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
284c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ASSERT(index >= 0);
285c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (index == 0) {
286c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        Node* node = NodeTraversal::next(*innerEditor, innerEditor);
287c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (node && node->isTextNode())
288c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            return Position(node, 0, Position::PositionIsOffsetInAnchor);
289c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return Position(innerEditor, 0, Position::PositionIsOffsetInAnchor);
290c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
291c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    int remainingCharactersToMoveForward = index;
292c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    Node* lastBrOrText = innerEditor;
293c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    for (Node* node = NodeTraversal::next(*innerEditor, innerEditor); node; node = NodeTraversal::next(*node, innerEditor)) {
294c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ASSERT(remainingCharactersToMoveForward >= 0);
295c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (node->hasTagName(brTag)) {
296c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            if (remainingCharactersToMoveForward == 0)
297c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                return positionBeforeNode(node);
298c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            --remainingCharactersToMoveForward;
299c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            lastBrOrText = node;
300c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            continue;
301c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        }
302c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
303c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (node->isTextNode()) {
304c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            Text& text = toText(*node);
305c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            if (remainingCharactersToMoveForward < static_cast<int>(text.length()))
306c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                return Position(&text, remainingCharactersToMoveForward);
307c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            remainingCharactersToMoveForward -= text.length();
308c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            lastBrOrText = node;
309c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            continue;
310c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        }
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
312c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ASSERT_NOT_REACHED();
313c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
314c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return lastPositionInOrAfterNode(lastBrOrText);
315c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
316c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
317c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)static int indexForPosition(HTMLElement* innerEditor, const Position& passedPosition)
318c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
319c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (!innerEditor || !innerEditor->contains(passedPosition.anchorNode()) || passedPosition.isNull())
320c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return 0;
321c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
322c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (positionBeforeNode(innerEditor) == passedPosition)
323c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return 0;
324c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
325c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    int index = 0;
326c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    Node* startNode = passedPosition.computeNodeBeforePosition();
327c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (!startNode)
328c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        startNode = passedPosition.containerNode();
329c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ASSERT(startNode);
330c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ASSERT(innerEditor->contains(startNode));
331c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
332c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    for (Node* node = startNode; node; node = NodeTraversal::previous(*node, innerEditor)) {
333c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (node->isTextNode()) {
334c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            int length = toText(*node).length();
335c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            if (node == passedPosition.containerNode())
336c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                index += std::min(length, passedPosition.offsetInContainerNode());
337c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            else
338c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                index += length;
339c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        } else if (node->hasTagName(brTag)) {
340c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            ++index;
341c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        }
342c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
343c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
344c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ASSERT(index >= 0);
345c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return index;
346c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
347c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
348c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextFieldSelectionDirection direction, SelectionOption selectionOption)
349c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
350c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (hasAuthorShadowRoot() || !isTextFormControl())
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
353c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    const int editorValueLength = static_cast<int>(innerEditorValue().length());
354c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ASSERT(editorValueLength >= 0);
355c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    end = std::max(std::min(end, editorValueLength), 0);
3565d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    start = std::min(std::max(start, 0), end);
357c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    cacheSelection(start, end, direction);
3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
359f542a0e9557608d421c9d165487573efa35a5f91Ben Murdoch    if (selectionOption == NotChangeSelection || (selectionOption == ChangeSelectionIfFocused && document().focusedElement() != this))
360f542a0e9557608d421c9d165487573efa35a5f91Ben Murdoch        return;
361f542a0e9557608d421c9d165487573efa35a5f91Ben Murdoch
362c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    LocalFrame* frame = document().frame();
363c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    HTMLElement* innerEditor = innerEditorElement();
364c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (!frame || !innerEditor)
3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
366c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
367c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    Position startPosition = positionForIndex(innerEditor, start);
368c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    Position endPosition = start == end ? startPosition : positionForIndex(innerEditor, end);
369c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
370c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ASSERT(start == indexForPosition(innerEditor, startPosition));
371c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ASSERT(end == indexForPosition(innerEditor, endPosition));
3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // startPosition and endPosition can be null position for example when
3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // "-webkit-user-select: none" style attribute is specified.
3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (startPosition.isNotNull() && endPosition.isNotNull()) {
376c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ASSERT(startPosition.anchorNode()->shadowHost() == this
377c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            && endPosition.anchorNode()->shadowHost() == this);
3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    VisibleSelection newSelection;
3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (direction == SelectionHasBackwardDirection)
381c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        newSelection.setWithoutValidation(endPosition, startPosition);
3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
383c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        newSelection.setWithoutValidation(startPosition, endPosition);
3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    newSelection.setIsDirectional(direction != SelectionHasNoDirection);
3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
386f542a0e9557608d421c9d165487573efa35a5f91Ben Murdoch    frame->selection().setSelection(newSelection, FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle | (selectionOption == ChangeSelectionAndFocus ? 0 : FrameSelection::DoNotSetFocus));
3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
38953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)VisiblePosition HTMLTextFormControlElement::visiblePositionForIndex(int index) const
39053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
39153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (index <= 0)
39276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        return VisiblePosition(firstPositionInNode(innerEditorElement()), DOWNSTREAM);
3937242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    Position start, end;
3947242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool selected = Range::selectNodeContents(innerEditorElement(), start, end);
3957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!selected)
3967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return VisiblePosition();
3977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    CharacterIterator it(start, end);
39853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    it.advance(index - 1);
3997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return VisiblePosition(it.endPosition(), UPSTREAM);
40053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
40153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int HTMLTextFormControlElement::indexForVisiblePosition(const VisiblePosition& pos) const
4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Position indexPosition = pos.deepEquivalent().parentAnchoredEquivalent();
4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (enclosingTextFormControl(indexPosition) != this)
4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
4078abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    ASSERT(indexPosition.document());
408a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    RefPtrWillBeRawPtr<Range> range = Range::create(*indexPosition.document());
40976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    range->setStart(innerEditorElement(), 0, ASSERT_NO_EXCEPTION);
4101fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    range->setEnd(indexPosition.containerNode(), indexPosition.offsetInContainerNode(), ASSERT_NO_EXCEPTION);
4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return TextIterator::rangeLength(range.get());
4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int HTMLTextFormControlElement::selectionStart() const
4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!isTextFormControl())
4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
4186f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    if (document().focusedElement() != this)
4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return m_cachedSelectionStart;
4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return computeSelectionStart();
4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int HTMLTextFormControlElement::computeSelectionStart() const
4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(isTextFormControl());
427d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    LocalFrame* frame = document().frame();
4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!frame)
4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
431c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return indexForPosition(innerEditorElement(), frame->selection().start());
4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int HTMLTextFormControlElement::selectionEnd() const
4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!isTextFormControl())
4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
4386f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    if (document().focusedElement() != this)
4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return m_cachedSelectionEnd;
4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return computeSelectionEnd();
4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int HTMLTextFormControlElement::computeSelectionEnd() const
4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(isTextFormControl());
446d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    LocalFrame* frame = document().frame();
4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!frame)
4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
450c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return indexForPosition(innerEditorElement(), frame->selection().end());
4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const AtomicString& directionString(TextFieldSelectionDirection direction)
4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DEFINE_STATIC_LOCAL(const AtomicString, none, ("none", AtomicString::ConstructFromLiteral));
4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DEFINE_STATIC_LOCAL(const AtomicString, forward, ("forward", AtomicString::ConstructFromLiteral));
4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DEFINE_STATIC_LOCAL(const AtomicString, backward, ("backward", AtomicString::ConstructFromLiteral));
4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (direction) {
4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SelectionHasNoDirection:
4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return none;
4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SelectionHasForwardDirection:
4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return forward;
4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SelectionHasBackwardDirection:
4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return backward;
4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT_NOT_REACHED();
4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return none;
4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const AtomicString& HTMLTextFormControlElement::selectionDirection() const
4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!isTextFormControl())
4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return directionString(SelectionHasNoDirection);
4766f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    if (document().focusedElement() != this)
4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return directionString(m_cachedSelectionDirection);
4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return directionString(computeSelectionDirection());
4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TextFieldSelectionDirection HTMLTextFormControlElement::computeSelectionDirection() const
4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(isTextFormControl());
485d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    LocalFrame* frame = document().frame();
4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!frame)
4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return SelectionHasNoDirection;
4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4898abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    const VisibleSelection& selection = frame->selection().selection();
4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return selection.isDirectional() ? (selection.isBaseFirst() ? SelectionHasForwardDirection : SelectionHasBackwardDirection) : SelectionHasNoDirection;
4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline void setContainerAndOffsetForRange(Node* node, int offset, Node*& containerNode, int& offsetInContainer)
4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (node->isTextNode()) {
4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        containerNode = node;
4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        offsetInContainer = offset;
4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        containerNode = node->parentNode();
5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        offsetInContainer = node->nodeIndex() + offset;
5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
504a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben MurdochPassRefPtrWillBeRawPtr<Range> HTMLTextFormControlElement::selection() const
5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5066f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    if (!renderer() || !isTextFormControl())
507d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
5085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int start = m_cachedSelectionStart;
5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int end = m_cachedSelectionEnd;
5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(start <= end);
51376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    HTMLElement* innerText = innerEditorElement();
5145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!innerText)
515d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
517c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (!innerText->hasChildren())
5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return Range::create(document(), innerText, 0, innerText, 0);
5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int offset = 0;
5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* startNode = 0;
5225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* endNode = 0;
52351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    for (Node* node = innerText->firstChild(); node; node = NodeTraversal::next(*node, innerText)) {
524c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ASSERT(!node->hasChildren());
525d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        ASSERT(node->isTextNode() || isHTMLBRElement(*node));
5265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int length = node->isTextNode() ? lastOffsetInNode(node) : 1;
5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (offset <= start && start <= offset + length)
5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            setContainerAndOffsetForRange(node, start - offset, startNode, start);
5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (offset <= end && end <= offset + length) {
5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            setContainerAndOffsetForRange(node, end - offset, endNode, end);
5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        offset += length;
5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!startNode || !endNode)
540d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return Range::create(document(), startNode, start, endNode, end);
5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void HTMLTextFormControlElement::restoreCachedSelection()
5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd, m_cachedSelectionDirection);
5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void HTMLTextFormControlElement::selectionChanged(bool userTriggered)
5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!renderer() || !isTextFormControl())
5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
5545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // selectionStart() or selectionEnd() will return cached selection when this node doesn't have focus
5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    cacheSelection(computeSelectionStart(), computeSelectionEnd(), computeSelectionDirection());
5575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
558d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (LocalFrame* frame = document().frame()) {
5598abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        if (frame->selection().isRange() && userTriggered)
5601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            dispatchEvent(Event::createBubble(EventTypeNames::select));
5615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
564926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void HTMLTextFormControlElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
5655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
566926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (name == placeholderAttr) {
5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        updatePlaceholderVisibility(true);
5681e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        UseCounter::count(document(), UseCounter::PlaceholderAttribute);
56953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    } else
570926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        HTMLFormControlElementWithState::parseAttribute(name, value);
5715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool HTMLTextFormControlElement::lastChangeWasUserEdit() const
5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!isTextFormControl())
5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_lastChangeWasUserEdit;
5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
58076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)void HTMLTextFormControlElement::setInnerEditorValue(const String& value)
5815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
582d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(!hasAuthorShadowRoot());
583d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!isTextFormControl() || hasAuthorShadowRoot())
5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
58676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    bool textIsChanged = value != innerEditorValue();
58776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    if (textIsChanged || !innerEditorElement()->hasChildren()) {
5888abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        if (textIsChanged && renderer()) {
5898abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            if (AXObjectCache* cache = document().existingAXObjectCache())
590926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                cache->postNotification(this, AXObjectCache::AXValueChanged, false);
5915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
59276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        innerEditorElement()->setInnerText(value, ASSERT_NO_EXCEPTION);
593926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
594926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (value.endsWith('\n') || value.endsWith('\r'))
59576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)            innerEditorElement()->appendChild(HTMLBRElement::create(document()));
5965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static String finishText(StringBuilder& result)
6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Remove one trailing newline; there's always one that's collapsed out by rendering.
6025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t size = result.length();
6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (size && result[size - 1] == '\n')
6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result.resize(--size);
6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result.toString();
6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
60876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)String HTMLTextFormControlElement::innerEditorValue() const
6095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
610d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(!hasAuthorShadowRoot());
61176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    HTMLElement* innerEditor = innerEditorElement();
61276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    if (!innerEditor || !isTextFormControl())
6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return emptyString();
6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder result;
61676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    for (Node* node = innerEditor; node; node = NodeTraversal::next(*node, innerEditor)) {
617d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (isHTMLBRElement(*node))
6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result.append(newlineCharacter);
6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else if (node->isTextNode())
6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result.append(toText(node)->data());
6215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return finishText(result);
6235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void getNextSoftBreak(RootInlineBox*& line, Node*& breakNode, unsigned& breakOffset)
6265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RootInlineBox* next;
6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (; line; line = next) {
6295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        next = line->nextRootBox();
6305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (next && !line->endsWithBreak()) {
6315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(line->lineBreakObj());
6325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            breakNode = line->lineBreakObj()->node();
6335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            breakOffset = line->lineBreakPos();
6345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            line = next;
6355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
6365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
6375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    breakNode = 0;
6395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    breakOffset = 0;
6405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String HTMLTextFormControlElement::valueWithHardLineBreaks() const
6435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: It's not acceptable to ignore the HardWrap setting when there is no renderer.
6455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // While we have no evidence this has ever been a practical problem, it would be best to fix it some day.
64676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    HTMLElement* innerText = innerEditorElement();
6475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!innerText || !isTextFormControl())
6485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return value();
6495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
650197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    RenderBlockFlow* renderer = toRenderBlockFlow(innerText->renderer());
6515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!renderer)
6525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return value();
6535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* breakNode;
6555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned breakOffset;
6565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RootInlineBox* line = renderer->firstRootBox();
6575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!line)
6585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return value();
6595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    getNextSoftBreak(line, breakNode, breakOffset);
6615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder result;
66351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    for (Node* node = innerText->firstChild(); node; node = NodeTraversal::next(*node, innerText)) {
664d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (isHTMLBRElement(*node))
6655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result.append(newlineCharacter);
6665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else if (node->isTextNode()) {
6675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            String data = toText(node)->data();
6685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            unsigned length = data.length();
6695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            unsigned position = 0;
6705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            while (breakNode == node && breakOffset <= length) {
6715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (breakOffset > position) {
672591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch                    result.append(data, position, breakOffset - position);
6735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    position = breakOffset;
6745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    result.append(newlineCharacter);
6755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
6765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                getNextSoftBreak(line, breakNode, breakOffset);
6775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
678591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch            result.append(data, position, length - position);
6795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
6805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        while (breakNode == node)
6815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            getNextSoftBreak(line, breakNode, breakOffset);
6825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return finishText(result);
6845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)HTMLTextFormControlElement* enclosingTextFormControl(const Position& position)
6875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(position.isNull() || position.anchorType() == Position::PositionIsOffsetInAnchor
689926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        || position.containerNode() || !position.anchorNode()->shadowHost()
690926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        || (position.anchorNode()->parentNode() && position.anchorNode()->parentNode()->isShadowRoot()));
6915d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    return enclosingTextFormControl(position.containerNode());
6925d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)}
69302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
6945d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)HTMLTextFormControlElement* enclosingTextFormControl(Node* container)
6955d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles){
6965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!container)
6975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
698926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    Element* ancestor = container->shadowHost();
699d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return ancestor && isHTMLTextFormControlElement(*ancestor) && container->containingShadowRoot()->type() == ShadowRoot::UserAgentShadowRoot ? toHTMLTextFormControlElement(ancestor) : 0;
7005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String HTMLTextFormControlElement::directionForFormData() const
7035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7049e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    for (const HTMLElement* element = this; element; element = Traversal<HTMLElement>::firstAncestor(*element)) {
7055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const AtomicString& dirAttributeValue = element->fastGetAttribute(dirAttr);
7065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (dirAttributeValue.isNull())
7075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
7085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (equalIgnoringCase(dirAttributeValue, "rtl") || equalIgnoringCase(dirAttributeValue, "ltr"))
7105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return dirAttributeValue;
7115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (equalIgnoringCase(dirAttributeValue, "auto")) {
7135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            bool isAuto;
71409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            TextDirection textDirection = element->directionalityIfhasDirAutoAttribute(isAuto);
7155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return textDirection == RTL ? "rtl" : "ltr";
7165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
7175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return "ltr";
7205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
72276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)HTMLElement* HTMLTextFormControlElement::innerEditorElement() const
723f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){
724f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    return toHTMLElement(userAgentShadowRoot()->getElementById(ShadowElementNames::innerEditor()));
725f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)}
726f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
727197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic Position innerNodePosition(const Position& innerPosition)
728197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
729197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(innerPosition.anchorType() != Position::PositionIsBeforeAnchor);
730197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(innerPosition.anchorType() != Position::PositionIsAfterAnchor);
731197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    HTMLElement* element = toHTMLElement(innerPosition.anchorNode());
732197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(element);
733197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    RefPtrWillBeRawPtr<NodeList> childNodes = element->childNodes();
734197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (!childNodes->length())
735197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return Position(element, 0, Position::PositionIsOffsetInAnchor);
736197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
737197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    unsigned offset = 0;
738197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
739197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    switch (innerPosition.anchorType()) {
740197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    case Position::PositionIsOffsetInAnchor:
741197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        offset = std::max(0, std::min(innerPosition.offsetInContainerNode(), static_cast<int>(childNodes->length())));
742197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        break;
743197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    case Position::PositionIsAfterChildren:
744197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        offset = childNodes->length();
745197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        break;
746197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    default:
747197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        break;
748197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
749197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
750197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (offset == childNodes->length())
751197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return Position(element->lastChild(), Position::PositionIsAfterAnchor);
752197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
753197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    Node* node = childNodes->item(offset);
754197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (node->isTextNode())
755197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return Position(toText(node), 0);
756197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
757197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return Position(node, Position::PositionIsBeforeAnchor);
758197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
759197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
760197021e6b966cfb06891637935ef33fff06433d1Ben Murdochenum FindOption {
761197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    FindStart,
762197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    FindEnd
763197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch};
764197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
765197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic Position findWordBoundary(const HTMLElement* innerEditor, const Position& startPosition, const Position& endPosition, FindOption findOption)
766197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
767197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    StringBuilder concatTexts;
768197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    Vector<unsigned> lengthList;
769197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    Vector<Text*> textList;
770197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
771197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (startPosition.anchorNode()->isTextNode())
772197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        ASSERT(startPosition.anchorType() == Position::PositionIsOffsetInAnchor);
773197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (endPosition.anchorNode()->isTextNode())
774197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        ASSERT(endPosition.anchorType() == Position::PositionIsOffsetInAnchor);
775197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
776197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // Traverse text nodes.
777197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    for (Node* node = startPosition.anchorNode(); node; node = NodeTraversal::next(*node, innerEditor)) {
778197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        bool isStartNode = node == startPosition.anchorNode();
779197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        bool isEndNode = node == endPosition.anchorNode();
780197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (node->isTextNode()) {
781197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            Text* text = toText(node);
782197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            const unsigned start = isStartNode ? startPosition.offsetInContainerNode() : 0;
783197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            const unsigned end = isEndNode ? endPosition.offsetInContainerNode() : text->data().length();
784197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            const unsigned length = end - start;
785197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
786197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            concatTexts.append(text->data(), start, length);
787197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            lengthList.append(length);
788197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            textList.append(text);
789197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        }
790197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
791197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (isEndNode)
792197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            break;
793197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
794197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
795197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (concatTexts.length() == 0)
796197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return startPosition;
797197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
798197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    int start, end;
799197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (findOption == FindEnd && concatTexts[0] == '\n') {
800197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // findWordBoundary("\ntext", 0, &start, &end) assigns 1 to |end| but
801197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // we expect 0 at the case.
802197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        start = 0;
803197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        end = 0;
804197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    } else {
805197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        Vector<UChar> characters;
806197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        concatTexts.toString().appendTo(characters);
807197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        findWordBoundary(characters.data(), characters.size(), findOption == FindStart ? characters.size() : 0, &start, &end);
808197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
809197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(start >= 0);
810197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(end >= 0);
811197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    unsigned remainingOffset = findOption == FindStart ? start : end;
812197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // Find position.
813197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    for (unsigned i = 0; i < lengthList.size(); ++i) {
814197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (remainingOffset <= lengthList[i])
815197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            return Position(textList[i], (textList[i] == startPosition.anchorNode()) ? remainingOffset + startPosition.offsetInContainerNode() : remainingOffset);
816197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        remainingOffset -= lengthList[i];
817197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
818197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
819197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT_NOT_REACHED();
820197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return Position();
821197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
822197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
823197021e6b966cfb06891637935ef33fff06433d1Ben MurdochPosition HTMLTextFormControlElement::startOfWord(const Position& position)
824197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
825197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const HTMLTextFormControlElement* textFormControl = enclosingTextFormControl(position);
826197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(textFormControl);
827197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    HTMLElement* innerEditor = textFormControl->innerEditorElement();
828197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
829197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const Position startPosition = startOfSentence(position);
830197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (startPosition == position)
831197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return position;
832197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const Position endPosition = (position.anchorNode() == innerEditor) ? innerNodePosition(position) : position;
833197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
834197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return findWordBoundary(innerEditor, startPosition, endPosition, FindStart);
835197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
836197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
837197021e6b966cfb06891637935ef33fff06433d1Ben MurdochPosition HTMLTextFormControlElement::endOfWord(const Position& position)
838197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
839197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const HTMLTextFormControlElement* textFormControl = enclosingTextFormControl(position);
840197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(textFormControl);
841197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    HTMLElement* innerEditor = textFormControl->innerEditorElement();
842197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
843197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const Position endPosition = endOfSentence(position);
844197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (endPosition == position)
845197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return position;
846197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const Position startPosition = (position.anchorNode() == innerEditor) ? innerNodePosition(position) : position;
847197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
848197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return findWordBoundary(innerEditor, startPosition, endPosition, FindEnd);
849197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
850197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
851197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic Position endOfPrevious(const Node& node, HTMLElement* innerEditor)
852197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
853197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    Node* previousNode = NodeTraversal::previous(node, innerEditor);
854197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (!previousNode)
855197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return Position();
856197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
857197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (isHTMLBRElement(previousNode))
858197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return Position(previousNode, Position::PositionIsAfterAnchor);
859197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
860197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (previousNode->isTextNode())
861197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return Position(toText(previousNode), toText(previousNode)->length());
862197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
863197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return Position();
864197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
865197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
866197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic Position previousIfPositionIsAfterLineBreak(const Position& position, HTMLElement* innerEditor)
867197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
868197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (position.isNull())
869197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return Position();
870197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
871197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // Move back if position is just after line break.
872197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (isHTMLBRElement(*position.anchorNode())) {
873197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        switch (position.anchorType()) {
874197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        case Position::PositionIsAfterAnchor:
875197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            return Position(position.anchorNode(), Position::PositionIsBeforeAnchor);
876197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        case Position::PositionIsBeforeAnchor:
877197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            return previousIfPositionIsAfterLineBreak(endOfPrevious(*position.anchorNode(), innerEditor), innerEditor);
878197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        default:
879197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            ASSERT_NOT_REACHED();
880197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        }
881197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    } else if (position.anchorNode()->isTextNode()) {
882197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        Text* textNode = toText(position.anchorNode());
883197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        unsigned offset = position.offsetInContainerNode();
884197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (textNode->length() == 0 || offset == 0) {
885197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            return previousIfPositionIsAfterLineBreak(endOfPrevious(*position.anchorNode(), innerEditor), innerEditor);
886197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        }
887197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
888197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (offset <= textNode->length() && textNode->data()[offset - 1] == '\n') {
889197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            return Position(textNode, offset - 1);
890197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        }
891197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
892197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
893197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return position;
894197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
895197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
896197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic inline Position startOfInnerText(const HTMLTextFormControlElement* textFormControl)
897197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
898197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return Position(textFormControl->innerEditorElement(), 0, Position::PositionIsOffsetInAnchor);
899197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
900197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
901197021e6b966cfb06891637935ef33fff06433d1Ben MurdochPosition HTMLTextFormControlElement::startOfSentence(const Position& position)
902197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
903197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    HTMLTextFormControlElement* textFormControl = enclosingTextFormControl(position);
904197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(textFormControl);
905197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
906197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    HTMLElement* innerEditor = textFormControl->innerEditorElement();
907197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (!innerEditor->childNodes()->length())
908197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return startOfInnerText(textFormControl);
909197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
910197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const Position innerPosition = position.anchorNode() == innerEditor ? innerNodePosition(position) : position;
911197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const Position pivotPosition = previousIfPositionIsAfterLineBreak(innerPosition, innerEditor);
912197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (pivotPosition.isNull())
913197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return startOfInnerText(textFormControl);
914197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
915197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    for (Node* node = pivotPosition.anchorNode(); node; node = NodeTraversal::previous(*node, innerEditor)) {
916197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        bool isPivotNode = (node == pivotPosition.anchorNode());
917197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
918197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (isHTMLBRElement(node) && (!isPivotNode || pivotPosition.anchorType() == Position::PositionIsAfterAnchor))
919197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            return Position(node, Position::PositionIsAfterAnchor);
920197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
921197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (node->isTextNode()) {
922197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            Text* textNode = toText(node);
923197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            size_t lastLineBreak = textNode->data().substring(0, isPivotNode ? pivotPosition.offsetInContainerNode() : textNode->length()).reverseFind('\n');
924197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            if (lastLineBreak != kNotFound)
925197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                return Position(textNode, lastLineBreak + 1);
926197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        }
927197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
928197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return startOfInnerText(textFormControl);
929197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
930197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
931197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic Position endOfInnerText(const HTMLTextFormControlElement* textFormControl)
932197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
933197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    HTMLElement* innerEditor = textFormControl->innerEditorElement();
934197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return Position(innerEditor, innerEditor->childNodes()->length(), Position::PositionIsOffsetInAnchor);
935197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
936197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
937197021e6b966cfb06891637935ef33fff06433d1Ben MurdochPosition HTMLTextFormControlElement::endOfSentence(const Position& position)
938197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
939197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    HTMLTextFormControlElement* textFormControl = enclosingTextFormControl(position);
940197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(textFormControl);
941197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
942197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    HTMLElement* innerEditor = textFormControl->innerEditorElement();
943197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (innerEditor->childNodes()->length() == 0)
944197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return startOfInnerText(textFormControl);
945197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
946197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const Position pivotPosition = position.anchorNode() == innerEditor ? innerNodePosition(position) : position;
947197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (pivotPosition.isNull())
948197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return startOfInnerText(textFormControl);
949197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
950197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    for (Node* node = pivotPosition.anchorNode(); node; node = NodeTraversal::next(*node, innerEditor)) {
951197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        bool isPivotNode = node == pivotPosition.anchorNode();
952197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
953197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (isHTMLBRElement(node))
954197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            return Position(node, Position::PositionIsAfterAnchor);
955197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
956197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (node->isTextNode()) {
957197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            Text* textNode = toText(node);
958197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            size_t firstLineBreak = textNode->data().find('\n', isPivotNode ? pivotPosition.offsetInContainerNode() : 0);
959197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            if (firstLineBreak != kNotFound)
960197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                return Position(textNode, firstLineBreak + 1);
961197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        }
962197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
963197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return endOfInnerText(textFormControl);
964197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
965197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
9667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} // namespace blink
967