Chromium Code Reviews| Index: third_party/WebKit/Source/core/html/HTMLTextFormControlElement.cpp |
| diff --git a/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.cpp b/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.cpp |
| index 9d23449d46b8bcd35297a599851842c4013dbab0..ef454c2e5443ef389c67cc7d172fe62193eab76f 100644 |
| --- a/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.cpp |
| +++ b/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.cpp |
| @@ -620,6 +620,24 @@ bool HTMLTextFormControlElement::lastChangeWasUserEdit() const |
| return m_lastChangeWasUserEdit; |
| } |
| +PassRefPtrWillBeRawPtr<Node> HTMLTextFormControlElement::createPlaceholderBreakElement() const |
| +{ |
| + return HTMLBRElement::create(document()); |
| +} |
| + |
| +void HTMLTextFormControlElement::addPlaceholderBreakElementIfNecessary() |
| +{ |
| + HTMLElement* innerEditor = innerEditorElement(); |
| + ASSERT(innerEditor); |
|
yosin_UTC9
2016/03/10 08:33:15
Q: do we need to have this assert? following line
tkent
2016/03/10 08:42:38
We may remove it. Removed.
|
| + if (innerEditor->layoutObject() && !innerEditor->layoutObject()->style()->preserveNewline()) |
| + return; |
| + Node* lastChild = innerEditor->lastChild(); |
| + if (!lastChild || !lastChild->isTextNode()) |
| + return; |
| + if (toText(lastChild)->data().endsWith('\n') || toText(lastChild)->data().endsWith('\r')) |
| + innerEditor->appendChild(createPlaceholderBreakElement()); |
| +} |
| + |
| void HTMLTextFormControlElement::setInnerEditorValue(const String& value) |
| { |
| ASSERT(!openShadowRoot()); |
| @@ -642,8 +660,9 @@ void HTMLTextFormControlElement::setInnerEditorValue(const String& value) |
| else |
| replaceChildrenWithText(innerEditor, value, ASSERT_NO_EXCEPTION); |
| - if (value.endsWith('\n') || value.endsWith('\r')) |
| - innerEditor->appendChild(HTMLBRElement::create(document())); |
| + // Add <br> so that we can put the caret at the next line of the last |
| + // newline. |
| + addPlaceholderBreakElementIfNecessary(); |
| if (textIsChanged && layoutObject()) { |
| if (AXObjectCache* cache = document().existingAXObjectCache()) |
| @@ -651,15 +670,6 @@ void HTMLTextFormControlElement::setInnerEditorValue(const String& value) |
| } |
| } |
| -static String finishText(StringBuilder& result) |
| -{ |
| - // Remove one trailing newline; there's always one that's collapsed out by layoutObject. |
| - size_t size = result.length(); |
| - if (size && result[size - 1] == '\n') |
| - result.resize(--size); |
| - return result.toString(); |
| -} |
| - |
| String HTMLTextFormControlElement::innerEditorValue() const |
| { |
| ASSERT(!openShadowRoot()); |
| @@ -669,12 +679,15 @@ String HTMLTextFormControlElement::innerEditorValue() const |
| StringBuilder result; |
| for (Node& node : NodeTraversal::inclusiveDescendantsOf(*innerEditor)) { |
| - if (isHTMLBRElement(node)) |
| - result.append(newlineCharacter); |
| - else if (node.isTextNode()) |
| + if (isHTMLBRElement(node)) { |
| + ASSERT(&node == innerEditor->lastChild()); |
| + if (&node != innerEditor->lastChild()) |
| + result.append(newlineCharacter); |
| + } else if (node.isTextNode()) { |
| result.append(toText(node).data()); |
| + } |
| } |
| - return finishText(result); |
| + return result.toString(); |
| } |
| static void getNextSoftBreak(RootInlineBox*& line, Node*& breakNode, unsigned& breakOffset) |
| @@ -717,7 +730,9 @@ String HTMLTextFormControlElement::valueWithHardLineBreaks() const |
| StringBuilder result; |
| for (Node& node : NodeTraversal::descendantsOf(*innerText)) { |
| if (isHTMLBRElement(node)) { |
| - result.append(newlineCharacter); |
| + ASSERT(&node == innerText->lastChild()); |
| + if (&node != innerText->lastChild()) |
| + result.append(newlineCharacter); |
| } else if (node.isTextNode()) { |
| String data = toText(node).data(); |
| unsigned length = data.length(); |
| @@ -735,7 +750,7 @@ String HTMLTextFormControlElement::valueWithHardLineBreaks() const |
| while (breakNode == node) |
| getNextSoftBreak(line, breakNode, breakOffset); |
| } |
| - return finishText(result); |
| + return result.toString(); |
| } |
| HTMLTextFormControlElement* enclosingTextFormControl(const Position& position) |