Bug 55133 - An inconsistency between HTMLTextAreaElement::m_value and RenderTextControl::text()
Summary: An inconsistency between HTMLTextAreaElement::m_value and RenderTextControl::...
Alias: None
Product: WebKit
Classification: Unclassified
Component: Text (show other bugs)
Version: 528+ (Nightly build)
Hardware: PC OS X 10.5
: P2 Normal
Assignee: Nobody
URL: http://crbug.com/66848
Depends on:
Reported: 2011-02-24 04:50 PST by Kenichi Ishibashi
Modified: 2014-04-01 19:00 PDT (History)
5 users (show)

See Also:

A page to repro (1.05 KB, text/html)
2011-02-24 04:55 PST, Kenichi Ishibashi
no flags Details
workaround patch for http://crbug.com/66848 (1.54 KB, patch)
2011-02-24 17:39 PST, Kenichi Ishibashi
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Kenichi Ishibashi 2011-02-24 04:50:07 PST
There could be an inconsistency between HTMLTextAreaElement::m_value and RenderTextControl::text() in some cases and it could cause strange bugs.

Suppose a textarea has focus. When a textInput event occur, the text is inserted into m_innerText of the textarea's renderer (RenderTextControl) by calling InsertTextCommand::input() from TypingCommand::insertTextRunWitoutNewlines(). At this point, m_value of HTMLTextAreaElement is not up-to-date so there is an inconsistency between them until calling setFormControlValueMatchesRenderer(false). The problem arises if style update occurs before calling setFormControlValueMatchesRenderer(false). If updateStyleIfNeeded() is called as a result of style update, RenderTextControlMultiLine::updateFromElement() is called and it sets the up-to-date value of the renderer to the m_value of textarea which is obsoleted. In most cases, style update doesn't occur before calling setFormControlValueMatchesRenderer(false), but in some cases, it happens.

An chromium bug reported at http://crbug.com/66848 is one of such cases. When textarea has an event listener that is fired by key events and changes its style attribute, updateStyleIfNeeded() could be called while there is the inconsistency. As the result, inputted text doesn't appear in the textarea. Here is a stack trace of such situation:

#0  WebCore::RenderTextControl::setInnerTextValue (this=0x45b73e8, innerTextValue="bar") at third_party/WebKit/Source/WebCore/rendering/RenderTextControl.cpp:183
#1  0x0000000001498c27 in WebCore::RenderTextControlMultiLine::updateFromElement (this=0x45b73e8) at third_party/WebKit/Source/WebCore/rendering/RenderTextControlMultiLine.cpp:107
#2  0x00000000005a3862 in WebCore::updateFromElementCallback (node=0x45b6af0) at third_party/WebKit/Source/WebCore/html/HTMLFormControlElement.cpp:222
#3  0x0000000000f693e0 in WebCore::ContainerNode::dispatchPostAttachCallbacks () at third_party/WebKit/Source/WebCore/dom/ContainerNode.cpp:707
#4  0x0000000000f69272 in WebCore::ContainerNode::resumePostAttachCallbacks (this=0x44d0e20) at third_party/WebKit/Source/WebCore/dom/ContainerNode.cpp:674
#5  0x0000000000f7e428 in WebCore::Document::recalcStyle (this=0x44d0e20, change=WebCore::Node::NoChange) at third_party/WebKit/Source/WebCore/dom/Document.cpp:1542
#6  0x0000000000f7e5d7 in WebCore::Document::updateStyleIfNeeded (this=0x44d0e20) at third_party/WebKit/Source/WebCore/dom/Document.cpp:1565
#7  0x0000000000f7e770 in WebCore::Document::updateLayout (this=0x44d0e20) at third_party/WebKit/Source/WebCore/dom/Document.cpp:1592
#8  0x0000000000f7e8c2 in WebCore::Document::updateLayoutIgnorePendingStylesheets (this=0x44d0e20) at third_party/WebKit/Source/WebCore/dom/Document.cpp:1628
#9  0x000000000107b0a8 in WebCore::VisiblePosition::canonicalPosition (this=0x7fffffffa190, passedPosition=...) at third_party/WebKit/Source/WebCore/editing/VisiblePosition.cpp:459
#10 0x000000000107971b in WebCore::VisiblePosition::init (this=0x7fffffffa190, position=..., affinity=WebCore::DOWNSTREAM) at third_party/WebKit/Source/WebCore/editing/VisiblePosition.cpp:61
#11 0x0000000001079571 in WebCore::VisiblePosition::VisiblePosition (this=0x7fffffffa190, pos=..., affinity=WebCore::DOWNSTREAM) at third_party/WebKit/Source/WebCore/editing/VisiblePosition.cpp:48
#12 0x0000000001076880 in WebCore::TypingCommand::markMisspellingsAfterTyping (this=0x45f2a20, commandType=WebCore::TypingCommand::InsertText) at third_party/WebKit/Source/WebCore/editing/TypingCommand.cpp:322
#13 0x00000000010769b9 in WebCore::TypingCommand::typingAddedToOpenCommand (this=0x45f2a20, commandTypeForAddedTyping=WebCore::TypingCommand::InsertText) at third_party/WebKit/Source/WebCore/editing/TypingCommand.cpp:348
#14 0x0000000001076d3a in WebCore::TypingCommand::insertTextRunWithoutNewlines (this=0x45f2a20, text="z", selectInsertedText=false) at third_party/WebKit/Source/WebCore/editing/TypingCommand.cpp:395
#15 0x0000000001076acc in WebCore::TypingCommand::insertText (this=0x45f2a20, text="z", selectInsertedText=false) at third_party/WebKit/Source/WebCore/editing/TypingCommand.cpp:369
#16 0x000000000107679b in WebCore::TypingCommand::doApply (this=0x45f2a20) at third_party/WebKit/Source/WebCore/editing/TypingCommand.cpp:293
#17 0x00000000010303e9 in WebCore::EditCommand::apply (this=0x45f2a20) at third_party/WebKit/Source/WebCore/editing/EditCommand.cpp:92
#18 0x0000000001030a4a in WebCore::applyCommand (command=...) at third_party/WebKit/Source/WebCore/editing/EditCommand.cpp:214
#19 0x00000000010760b6 in WebCore::TypingCommand::insertText (document=0x44d0e20, text="z", selectionForInsertion=..., selectInsertedText=false, compositionType=WebCore::TypingCommand::TextCompositionNone) at third_party/WebKit/Source/WebCore/editing/TypingCommand.cpp:198

Basically, this problem can avoid calling setFormControlValueMatchesRenderer(false) immediately after updating text value of the renderer. IMHO, calling appliedEditing() just after calling InsertTextCommand::input() is the simplest way to do it, as Safari on SnowLoepard do. However, as the comments on https://bugs.webkit.org/show_bug.cgi?id=49523 describe, it somehow complicated.

I didn't investigated in detail, but I think this is the primary cause of bug 49523 and 46868.

I'd like to fix the problem by removing PLATFORM(MAC) from TypingCommand::typingAddedToOpenCommand() because I think it is simple and natural way to resolve the inconsistency. However, I'm not familiar with the code, I'd like to ask advice.

Comment 1 Kenichi Ishibashi 2011-02-24 04:55:54 PST
Created attachment 83636 [details]
A page to repro

To see the problem, type some characters in the textarea. Note that the problem could happen on Chromium and will not happen on Safari.
Comment 2 Kenichi Ishibashi 2011-02-24 17:39:09 PST
Created attachment 83754 [details]
workaround patch for http://crbug.com/66848
Comment 3 Kenichi Ishibashi 2011-02-24 17:49:41 PST
(In reply to comment #2)
> Created an attachment (id=83754) [details]
> workaround patch for http://crbug.com/66848

This is workaround patch to fix http://crbug.com/66848 without removing PLATFORM(MAC) macro. spellcheckAttributeState() is called from typingAddedToOpenCommand() and hasAttribute() and getAttribute() eventually call updateStyleAttribute(), which causes calling updateStyleIfNeeded(). We can avoid this using fastHasAttribute()/fastGetAttribute() because they don't call updateStyleAttribute(). If removing PLATFORM(MAC) is not good for fixing the problem, I'd like to land this patch.