Bug 675579 - Part 1: Set the dir attribute on the input/textarea element when switching the text direction; r=roc
authorEhsan Akhgari <ehsan.akhgari@gmail.com>
Fri, 17 Jan 2014 10:31:03 -0500
changeset 163968 3475821c244889b1c09922d83ca44a81971ff118
parent 163967 defc74986fccde79bae762114ad023d6137b0edd
child 163969 8f1ffc0fe9142b397041bd35f010c6355f648815
push id38598
push usereakhgari@mozilla.com
push dateFri, 17 Jan 2014 15:32:47 +0000
treeherdermozilla-inbound@8f1ffc0fe914 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs675579
milestone29.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 675579 - Part 1: Set the dir attribute on the input/textarea element when switching the text direction; r=roc
editor/libeditor/base/nsEditor.cpp
editor/libeditor/base/nsEditor.h
editor/libeditor/text/tests/test_bug629172.html
--- a/editor/libeditor/base/nsEditor.cpp
+++ b/editor/libeditor/base/nsEditor.cpp
@@ -387,27 +387,21 @@ nsEditor::GetDesiredSpellCheckState()
   if (presShell) {
     nsPresContext* context = presShell->GetPresContext();
     if (context && !context->IsDynamic()) {
       return false;
     }
   }
 
   // Check DOM state
-  nsCOMPtr<nsIContent> content = GetRoot();
+  nsCOMPtr<nsIContent> content = GetExposedRoot();
   if (!content) {
     return false;
   }
 
-  // For plaintext editors, we just want to check whether the textarea/input
-  // itself is editable.
-  if (content->IsRootOfNativeAnonymousSubtree()) {
-    content = content->GetParent();
-  }
-
   nsCOMPtr<nsIDOMHTMLElement> element = do_QueryInterface(content);
   if (!element) {
     return false;
   }
 
   if (!IsPlaintextEditor()) {
     // Some of the page content might be editable and some not, if spellcheck=
     // is explicitly set anywhere, so if there's anything editable on the page,
@@ -5002,21 +4996,34 @@ nsEditor::GetRoot()
 }
 
 dom::Element*
 nsEditor::GetEditorRoot()
 {
   return GetRoot();
 }
 
+Element*
+nsEditor::GetExposedRoot()
+{
+  Element* rootElement = GetRoot();
+
+  // For plaintext editors, we need to ask the input/textarea element directly.
+  if (rootElement && rootElement->IsRootOfNativeAnonymousSubtree()) {
+    rootElement = rootElement->GetParent()->AsElement();
+  }
+
+  return rootElement;
+}
+
 nsresult
 nsEditor::DetermineCurrentDirection()
 {
   // Get the current root direction from its frame
-  dom::Element *rootElement = GetRoot();
+  nsIContent* rootElement = GetExposedRoot();
 
   // If we don't have an explicit direction, determine our direction
   // from the content's direction
   if (!(mFlags & (nsIPlaintextEditor::eEditorLeftToRight |
                   nsIPlaintextEditor::eEditorRightToLeft))) {
 
     nsIFrame* frame = rootElement->GetPrimaryFrame();
     NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
@@ -5032,17 +5039,18 @@ nsEditor::DetermineCurrentDirection()
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsEditor::SwitchTextDirection()
 {
   // Get the current root direction from its frame
-  dom::Element *rootElement = GetRoot();
+  nsIContent* rootElement = GetExposedRoot();
+
   nsresult rv = DetermineCurrentDirection();
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Apply the opposite direction
   if (mFlags & nsIPlaintextEditor::eEditorRightToLeft) {
     NS_ASSERTION(!(mFlags & nsIPlaintextEditor::eEditorLeftToRight),
                  "Unexpected mutually exclusive flag");
     mFlags &= ~nsIPlaintextEditor::eEditorRightToLeft;
@@ -5058,17 +5066,18 @@ nsEditor::SwitchTextDirection()
 
   return rv;
 }
 
 void
 nsEditor::SwitchTextDirectionTo(uint32_t aDirection)
 {
   // Get the current root direction from its frame
-  dom::Element *rootElement = GetRoot();
+  nsIContent* rootElement = GetExposedRoot();
+
   nsresult rv = DetermineCurrentDirection();
   NS_ENSURE_SUCCESS_VOID(rv);
 
   // Apply the requested direction
   if (aDirection == nsIPlaintextEditor::eEditorLeftToRight &&
       (mFlags & nsIPlaintextEditor::eEditorRightToLeft)) {
     NS_ASSERTION(!(mFlags & nsIPlaintextEditor::eEditorLeftToRight),
                  "Unexpected mutually exclusive flag");
--- a/editor/libeditor/base/nsEditor.h
+++ b/editor/libeditor/base/nsEditor.h
@@ -665,16 +665,20 @@ public:
 
   // Fast non-refcounting editor root element accessor
   mozilla::dom::Element *GetRoot();
 
   // Likewise, but gets the editor's root instead, which is different for HTML
   // editors
   virtual mozilla::dom::Element* GetEditorRoot();
 
+  // Likewise, but gets the text control element instead of the root for
+  // plaintext editors
+  mozilla::dom::Element* GetExposedRoot();
+
   // Accessor methods to flags
   bool IsPlaintextEditor() const
   {
     return (mFlags & nsIPlaintextEditor::eEditorPlaintextMask) != 0;
   }
 
   bool IsSingleLineEditor() const
   {
--- a/editor/libeditor/text/tests/test_bug629172.html
+++ b/editor/libeditor/text/tests/test_bug629172.html
@@ -50,22 +50,24 @@ SimpleTest.waitForFocus(function() {
     t.value = "test.";
     document.getElementById("content").appendChild(t);
     document.body.clientWidth;
     var s1 = snapshotWindow(window);
     ok(compareSnapshots(s1, Screenshots.get(initialDir, false), true)[0],
        "Textarea should appear correctly before switching the direction (" + initialDir + ")");
     t.focus();
     synthesizeKey("x", {accelKey: true, shiftKey: true});
+    is(t.getAttribute("dir"), initialDir == "ltr" ? "rtl" : "ltr", "The dir attribute must be correctly updated");
     t.blur();
     var s2 = snapshotWindow(window);
     ok(compareSnapshots(s2, Screenshots.get(initialDir, true), true)[0],
        "Textarea should appear correctly after switching the direction (" + initialDir + ")");
     t.focus();
     synthesizeKey("x", {accelKey: true, shiftKey: true});
+    is(t.getAttribute("dir"), initialDir == "ltr" ? "ltr" : "rtl", "The dir attribute must be correctly updated");
     t.blur();
     var s3 = snapshotWindow(window);
     ok(compareSnapshots(s3, Screenshots.get(initialDir, false), true)[0],
        "Textarea should appear correctly after switching back the direction (" + initialDir + ")");
     t.parentNode.removeChild(t);
   }
 
   testDirection("ltr");