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