Bug 686247 - Text control frames should accept dynamic changes to the CSS overflow property; r=bzbarsky,surkov
☠☠ backed out by 1ec4fc4006e0 ☠ ☠
authorEhsan Akhgari <ehsan@mozilla.com>
Tue, 13 Sep 2011 11:45:54 -0400
changeset 76913 c9013399fa39ce78f3a1fdbd1cb175770295cce4
parent 76912 ee7c98d1ec1badbd5202d78ef43c6a23cf65c8f8
child 76914 1ec4fc4006e04608968818eeab728c6fb23fbc32
push id21154
push usereakhgari@mozilla.com
push dateTue, 13 Sep 2011 19:43:58 +0000
treeherdermozilla-central@d86ee57cdbcc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky, surkov
bugs686247
milestone9.0a1
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 686247 - Text control frames should accept dynamic changes to the CSS overflow property; r=bzbarsky,surkov
accessible/tests/mochitest/tree/test_cssoverflow.html
content/html/content/src/nsTextEditorState.cpp
content/html/content/src/nsTextEditorState.h
layout/reftests/editor/dynamic-overflow-change-ref.html
layout/reftests/editor/dynamic-overflow-change.html
layout/reftests/editor/reftest.list
layout/style/nsStyleStruct.cpp
--- a/accessible/tests/mochitest/tree/test_cssoverflow.html
+++ b/accessible/tests/mochitest/tree/test_cssoverflow.html
@@ -27,62 +27,56 @@
     // Invokers
 
     function focusAnchor(aID)
     {
       this.linkNode = getNode(aID);
       this.link = getAccessible(this.linkNode);
 
       this.eventSeq = [
-        new invokerChecker(EVENT_FOCUS, getAccessible, this.linkNode)
-      ];
-
-      this.unexpectedEventSeq = [
-        new invokerChecker(EVENT_REORDER, this.linkNode.parentNode)
+        new invokerChecker(EVENT_FOCUS, getAccessible, this.linkNode),
+        new asyncInvokerChecker(EVENT_REORDER, this.linkNode.parentNode)
       ];
 
       this.invoke = function focusAnchor_invoke()
       {
         this.linkNode.focus();
       }
 
       this.check = function focusAnchor_check(aEvent)
       {
-        is(this.link, aEvent.accessible,
-           "The link accessible shouldn't be recreated!");
+        todo_is(this.link, aEvent.accessible,
+                "Focus should be fired against new link accessible!");
       }
 
       this.getID = function focusAnchor_getID()
       {
         return "focus a:focus{overflow:scroll} #1";
       }
     }
 
     function tabAnchor(aID)
     {
       this.linkNode = getNode(aID);
       this.link = getAccessible(this.linkNode);
 
       this.eventSeq = [
-        new invokerChecker(EVENT_FOCUS, getAccessible, this.linkNode)
-      ];
-
-      this.unexpectedEventSeq = [
-        new invokerChecker(EVENT_REORDER, this.linkNode.parentNode)
+        new invokerChecker(EVENT_FOCUS, getAccessible, this.linkNode),
+        new asyncInvokerChecker(EVENT_REORDER, this.linkNode.parentNode)
       ];
 
       this.invoke = function tabAnchor_invoke()
       {
         synthesizeKey("VK_TAB", { shiftKey: false });
       }
 
       this.check = function tabAnchor_check(aEvent)
       {
-        is(this.link, aEvent.accessible,
-           "The link accessible shouldn't be recreated!");
+        todo_isnot(this.link, aEvent.accessible,
+                   "Focus should be fired against new link accessible!");
       }
 
       this.getID = function tabAnchor_getID()
       {
         return "focus a:focus{overflow:scroll} #2";
       }
     }
 
@@ -121,19 +115,19 @@
     Mozilla Bug 591163
   </a><br>
   <a target="_blank"
      title="Rework accessible tree update code"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=570275">
     Mozilla Bug 570275
   </a><br>
   <a target="_blank"
-     title="Don't recreate frames for inlines with overflow style applied"
-     href="https://bugzilla.mozilla.org/show_bug.cgi?id=606087">
-    Mozilla Bug 606087
+     title="Text control frames should accept dynamic changes to the CSS overflow property"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=686247">
+    Mozilla Bug 686247
   </a><br>
 
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
   <div id="eventdump"></div>
 
--- a/content/html/content/src/nsTextEditorState.cpp
+++ b/content/html/content/src/nsTextEditorState.cpp
@@ -1053,16 +1053,19 @@ nsTextEditorState::BindToFrame(nsTextCon
   if (mEditor) {
     GetValue(currentValue, PR_TRUE);
   }
 
   mBoundFrame = aFrame;
 
   nsIContent *rootNode = GetRootNode();
 
+  nsresult rv = InitializeRootNode();
+  NS_ENSURE_SUCCESS(rv, rv);
+
   nsIPresShell *shell = mBoundFrame->PresContext()->GetPresShell();
   NS_ENSURE_TRUE(shell, NS_ERROR_FAILURE);
 
   // Create selection
   nsRefPtr<nsFrameSelection> frameSel = new nsFrameSelection();
 
   // Create a SelectionController
   mSelCon = new nsTextInputSelectionImpl(frameSel, shell, rootNode);
@@ -1540,16 +1543,27 @@ nsTextEditorState::CreateRootNode()
                                                  kNameSpaceID_XHTML,
                                                  nsIDOMNode::ELEMENT_NODE);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   nsresult rv = NS_NewHTMLElement(getter_AddRefs(mRootNode), nodeInfo.forget(),
                                   NOT_FROM_PARSER);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  if (!IsSingleLineTextControl()) {
+    mMutationObserver = new nsAnonDivObserver(this);
+    mRootNode->AddMutationObserver(mMutationObserver);
+  }
+
+  return rv;
+}
+
+nsresult
+nsTextEditorState::InitializeRootNode()
+{
   // Set the necessary classes on the text control. We use class values
   // instead of a 'style' attribute so that the style comes from a user-agent
   // style sheet and is still applied even if author styles are disabled.
   nsAutoString classValue;
   classValue.AppendLiteral("anonymous-div");
   PRInt32 wrapCols = GetWrapCols();
   if (wrapCols >= 0) {
     classValue.AppendLiteral(" wrap");
@@ -1559,29 +1573,22 @@ nsTextEditorState::CreateRootNode()
     // crash when the number of lines exceeds the height of the textarea and
     // setting -moz-hidden-unscrollable overflow (NS_STYLE_OVERFLOW_CLIP)
     // doesn't paint the caret for some reason.
     const nsStyleDisplay* disp = mBoundFrame->GetStyleDisplay();
     if (disp->mOverflowX != NS_STYLE_OVERFLOW_VISIBLE &&
         disp->mOverflowX != NS_STYLE_OVERFLOW_CLIP) {
       classValue.AppendLiteral(" inherit-overflow");
     }
-
-    mMutationObserver = new nsAnonDivObserver(this);
-    NS_ENSURE_TRUE(mMutationObserver, NS_ERROR_OUT_OF_MEMORY);
-    mRootNode->AddMutationObserver(mMutationObserver);
   }
-  rv = mRootNode->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
-                          classValue, PR_FALSE);
+  nsresult rv = mRootNode->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
+                                   classValue, PR_FALSE);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = mBoundFrame->UpdateValueDisplay(PR_FALSE);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return rv;
+  return mBoundFrame->UpdateValueDisplay(PR_FALSE);
 }
 
 nsresult
 nsTextEditorState::CreatePlaceholderNode()
 {
 #ifdef DEBUG
   {
     nsCOMPtr<nsIContent> content = do_QueryInterface(mTextCtrlElement);
--- a/content/html/content/src/nsTextEditorState.h
+++ b/content/html/content/src/nsTextEditorState.h
@@ -248,16 +248,18 @@ private:
 
   nsresult CreateRootNode();
 
   void ValueWasChanged(PRBool aNotify);
 
   void DestroyEditor();
   void Clear();
 
+  nsresult InitializeRootNode();
+
   void FinishedRestoringSelection() { mRestoringSelection = nsnull; }
 
   class InitializationGuard {
   public:
     explicit InitializationGuard(nsTextEditorState& aState) :
       mState(aState),
       mGuardSet(PR_FALSE)
     {
new file mode 100644
--- /dev/null
+++ b/layout/reftests/editor/dynamic-overflow-change-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <textarea rows="2" style="overflow: hidden;">
+      this
+      is
+      a
+      textarea
+      with
+      overflow
+    </textarea>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/editor/dynamic-overflow-change.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <body onload="document.querySelector('textarea').style.overflow='hidden'">
+    <textarea rows="2">
+      this
+      is
+      a
+      textarea
+      with
+      overflow
+    </textarea>
+  </body>
+</html>
--- a/layout/reftests/editor/reftest.list
+++ b/layout/reftests/editor/reftest.list
@@ -64,8 +64,9 @@ fails-if(Android) != spellcheck-hyphen-m
 != selection_visibility_after_reframe-2.html selection_visibility_after_reframe-ref.html
 != selection_visibility_after_reframe-3.html selection_visibility_after_reframe-ref.html
 == 672709.html 672709-ref.html
 == 338427-1.html 338427-1-ref.html
 skip-if(Android) == 674212-spellcheck.html 674212-spellcheck-ref.html
 skip-if(Android) == 338427-2.html 338427-2-ref.html
 skip-if(Android) == 338427-3.html 338427-3-ref.html
 skip-if(Android) == 462758-grabbers-resizers.html 462758-grabbers-resizers-ref.html
+== dynamic-overflow-change.html dynamic-overflow-change-ref.html
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -2175,18 +2175,18 @@ nsStyleDisplay::nsStyleDisplay(const nsS
 nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const
 {
   nsChangeHint hint = nsChangeHint(0);
 
   if (!EqualURIs(mBinding, aOther.mBinding)
       || mPosition != aOther.mPosition
       || mDisplay != aOther.mDisplay
       || (mFloats == NS_STYLE_FLOAT_NONE) != (aOther.mFloats == NS_STYLE_FLOAT_NONE)
-      || (mOverflowX != aOther.mOverflowX && mDisplay != NS_STYLE_DISPLAY_INLINE)
-      || (mOverflowY != aOther.mOverflowY && mDisplay != NS_STYLE_DISPLAY_INLINE)
+      || mOverflowX != aOther.mOverflowX
+      || mOverflowY != aOther.mOverflowY
       || mResize != aOther.mResize)
     NS_UpdateHint(hint, nsChangeHint_ReconstructFrame);
 
   if (mFloats != aOther.mFloats) {
     // Changing which side we float on doesn't affect descendants directly
     NS_UpdateHint(hint,
        NS_SubtractHint(nsChangeHint_ReflowFrame,
                        NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics,