Bug 611189 - Parchment IF Reader Misbehaves; r=bzbarsky a=blocking-final+
authorEhsan Akhgari <ehsan@mozilla.com>
Mon, 22 Nov 2010 03:12:56 -0500
changeset 58181 a664aa828e62d6a5880308ff2190963d0e8f8916
parent 58180 605656b6f7798199e79938098bbd5e629dd84edb
child 58182 6a1c5a9da215a0e11e31968f7f56224919025e13
push id17187
push usereakhgari@mozilla.com
push dateWed, 24 Nov 2010 18:43:21 +0000
treeherdermozilla-central@6a1c5a9da215 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky, blocking-final
bugs611189
milestone2.0b8pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 611189 - Parchment IF Reader Misbehaves; r=bzbarsky a=blocking-final+ This patch makes sure that we don't try to read the value from the editor if we haven't started to initialize the editor yet. This ensures that the UpdateValueDisplay calls before we start to initialize the editor will always end up reading the value from the content node, and do not rely on the data returned by the editor, which might be stale.
content/html/content/src/nsTextEditorState.cpp
content/html/content/test/Makefile.in
content/html/content/test/test_bug611189.html
layout/forms/nsTextControlFrame.cpp
--- a/content/html/content/src/nsTextEditorState.cpp
+++ b/content/html/content/src/nsTextEditorState.cpp
@@ -1631,17 +1631,17 @@ nsTextEditorState::GetMaxLength(PRInt32*
   }
 
   return PR_FALSE;
 }
 
 void
 nsTextEditorState::GetValue(nsAString& aValue, PRBool aIgnoreWrap) const
 {
-  if (mEditor && mBoundFrame) {
+  if (mEditor && mBoundFrame && (mEditorInitialized || !IsSingleLineTextControl())) {
     PRBool canCache = aIgnoreWrap && !IsSingleLineTextControl();
     if (canCache && !mCachedValue.IsEmpty()) {
       aValue = mCachedValue;
       return;
     }
 
     aValue.Truncate(); // initialize out param
 
@@ -1708,18 +1708,32 @@ nsTextEditorState::SetValue(const nsAStr
     // PrepareEditor cannot be called prematurely.
     nsAutoScriptBlocker scriptBlocker;
 
     PRBool fireChangeEvent = mBoundFrame->GetFireChangeEventState();
     if (aUserInput) {
       mBoundFrame->SetFireChangeEventState(PR_TRUE);
     }
 
+    NS_ASSERTION(mEditorInitialized || mInitializing,
+      "We should never try to use the editor if we're not initialized unless we're being initialized");
+
     nsAutoString currentValue;
-    mBoundFrame->GetText(currentValue);
+    if (!mEditorInitialized && IsSingleLineTextControl()) {
+      // Grab the current value directly from the text node to make sure that we
+      // deal with stale data correctly.
+      NS_ASSERTION(mRootNode, "We should have a root node here");
+      nsIContent *textContent = mRootNode->GetChildAt(0);
+      nsCOMPtr<nsIDOMCharacterData> textNode = do_QueryInterface(textContent);
+      if (textNode) {
+        textNode->GetData(currentValue);
+      }
+    } else {
+      mBoundFrame->GetText(currentValue);
+    }
 
     nsWeakFrame weakFrame(mBoundFrame);
 
     // this is necessary to avoid infinite recursion
     if (!currentValue.Equals(aValue))
     {
       nsTextControlFrame::ValueSetter valueSetter(mBoundFrame,
                                                   mBoundFrame->mFocusedValue.Equals(currentValue));
--- a/content/html/content/test/Makefile.in
+++ b/content/html/content/test/Makefile.in
@@ -237,16 +237,17 @@ include $(topsrcdir)/config/rules.mk
 		test_bug556007.html \
 		test_bug606817.html \
 		test_bug297761.html \
 		file_bug297761.html \
 		test_bug607145.html \
 		test_bug601061.html \
 		test_bug596511.html \
 		reflect.js \
+		test_bug611189.html \
 		test_bug613113.html \
 		test_bug605124-1.html \
 		test_bug605124-2.html \
 		test_bug605125-1.html \
 		test_bug605125-2.html \
 		test_bug612730.html \
 		$(NULL)
 
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_bug611189.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=611189
+-->
+<head>
+  <title>Test for Bug 611189</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=611189">Mozilla Bug 611189</a>
+<p id="display"></p>
+<div id="content">
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 611189 **/
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(function() {
+  var i = document.createElement("input");
+  var b = document.getElementById("content");
+  b.appendChild(i);
+  b.clientWidth; // bind to frame
+  i.focus(); // initialize editor
+  var before = snapshotWindow(window, true);
+  i.value = "L"; // set the value
+  i.style.display = "none";
+  b.clientWidth; // unbind from frame
+  i.value = ""; // set the value without a frame
+  i.style.display = "";
+  b.clientWidth; // rebind to frame
+  is(i.value, "", "Input's value should be correctly updated");
+  var after = snapshotWindow(window, true);
+  ok(compareSnapshots(before, after, true), "The correct value should be rendered inside the control");
+  SimpleTest.finish();
+});
+
+</script>
+</pre>
+</body>
+</html>
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -876,16 +876,19 @@ nsresult
 nsTextControlFrame::SelectAllOrCollapseToEndOfText(PRBool aSelect)
 {
   nsCOMPtr<nsIDOMElement> rootElement;
   nsresult rv = GetRootNodeAndInitializeEditor(getter_AddRefs(rootElement));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIContent> rootContent = do_QueryInterface(rootElement);
   nsCOMPtr<nsIDOMNode> rootNode(do_QueryInterface(rootElement));
+
+  NS_ENSURE_TRUE(rootNode && rootContent, NS_ERROR_FAILURE);
+
   PRInt32 numChildren = rootContent->GetChildCount();
 
   if (numChildren > 0) {
     // We never want to place the selection after the last
     // br under the root node!
     nsIContent *child = rootContent->GetChildAt(numChildren - 1);
     if (child) {
       if (child->Tag() == nsGkAtoms::br)