Bug 1343037 part 14. Implement nsTextEditorState::SetSelectionDirection. r=ehsan
authorBoris Zbarsky <bzbarsky@mit.edu>
Thu, 09 Mar 2017 14:44:06 -0500
changeset 395230 2ed58ad7b2d59e3e100858764c884f92b004e3c6
parent 395229 301369c6601ce010962483ac4a72f9b1ea309583
child 395231 6628ee6c224890bb4d4f411ab00d9336544476e5
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs1343037
milestone55.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 1343037 part 14. Implement nsTextEditorState::SetSelectionDirection. r=ehsan This introduces two behavior changes: 1) In cached mode, we used to treat unknown selection directions as "none". Now we treat it like "forward", consistently with the "have an editor" mode. 2) Before this change, in cached mode, we did not fire "select" events on selectionDirection changes. MozReview-Commit-ID: 4nBCAm3mAiz
dom/html/HTMLInputElement.cpp
dom/html/HTMLTextAreaElement.cpp
dom/html/nsTextEditorState.cpp
dom/html/nsTextEditorState.h
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -6556,32 +6556,18 @@ void
 HTMLInputElement::SetSelectionDirection(const nsAString& aDirection, ErrorResult& aRv)
 {
   if (!SupportsTextSelection()) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return;
   }
 
   nsTextEditorState* state = GetEditorState();
-  if (state && state->IsSelectionCached()) {
-    nsITextControlFrame::SelectionDirection dir = nsITextControlFrame::eNone;
-    if (aDirection.EqualsLiteral("forward")) {
-      dir = nsITextControlFrame::eForward;
-    } else if (aDirection.EqualsLiteral("backward")) {
-      dir = nsITextControlFrame::eBackward;
-    }
-    state->GetSelectionProperties().SetDirection(dir);
-    return;
-  }
-
-  int32_t start, end;
-  GetSelectionRange(&start, &end, aRv);
-  if (!aRv.Failed()) {
-    aRv = SetSelectionRange(start, end, aDirection);
-  }
+  MOZ_ASSERT(state, "SupportsTextSelection came back true!");
+  state->SetSelectionDirection(aDirection, aRv);
 }
 
 NS_IMETHODIMP
 HTMLInputElement::GetPhonetic(nsAString& aPhonetic)
 {
   aPhonetic.Truncate();
   nsIFormControlFrame* formControlFrame = GetFormControlFrame(true);
   nsITextControlFrame* textControlFrame = do_QueryFrame(formControlFrame);
--- a/dom/html/HTMLTextAreaElement.cpp
+++ b/dom/html/HTMLTextAreaElement.cpp
@@ -760,37 +760,17 @@ HTMLTextAreaElement::GetSelectionDirecti
   }
   DirectionToName(dir, aDirection);
 }
 
 void
 HTMLTextAreaElement::SetSelectionDirection(const nsAString& aDirection,
                                            ErrorResult& aError)
 {
-  if (mState.IsSelectionCached()) {
-    nsITextControlFrame::SelectionDirection dir = nsITextControlFrame::eNone;
-    if (aDirection.EqualsLiteral("forward")) {
-      dir = nsITextControlFrame::eForward;
-    } else if (aDirection.EqualsLiteral("backward")) {
-      dir = nsITextControlFrame::eBackward;
-    }
-    mState.GetSelectionProperties().SetDirection(dir);
-    return;
-  }
-
-  int32_t start, end;
-  GetSelectionRange(&start, &end, aError);
-  if (aError.Failed()) {
-    return;
-  }
-
-  nsresult rv = SetSelectionRange(start, end, aDirection);
-  if (NS_FAILED(rv)) {
-    aError.Throw(rv);
-  }
+  mState.SetSelectionDirection(aDirection, aError);
 }
 
 NS_IMETHODIMP
 HTMLTextAreaElement::SetSelectionRange(int32_t aSelectionStart,
                                        int32_t aSelectionEnd,
                                        const nsAString& aDirection)
 {
   ErrorResult error;
--- a/dom/html/nsTextEditorState.cpp
+++ b/dom/html/nsTextEditorState.cpp
@@ -1757,16 +1757,48 @@ nsTextEditorState::SetSelectionEnd(const
   nsITextControlFrame::SelectionDirection dir = GetSelectionDirection(aRv);
   if (aRv.Failed()) {
     return;
   }
 
   SetSelectionRange(start, end, dir, aRv);
 }
 
+static nsITextControlFrame::SelectionDirection
+DirectionStringToSelectionDirection(const nsAString& aDirection)
+{
+  if (aDirection.EqualsLiteral("backward")) {
+    return nsITextControlFrame::eBackward;
+  }
+
+  // We don't support directionless selections.
+  return nsITextControlFrame::eForward;
+}
+
+void
+nsTextEditorState::SetSelectionDirection(const nsAString& aDirection,
+                                         ErrorResult& aRv)
+{
+  nsITextControlFrame::SelectionDirection dir =
+    DirectionStringToSelectionDirection(aDirection);
+
+  if (IsSelectionCached()) {
+    GetSelectionProperties().SetDirection(dir);
+    return;
+  }
+
+  int32_t start, end;
+  GetSelectionRange(&start, &end, aRv);
+  if (aRv.Failed()) {
+    return;
+  }
+
+  SetSelectionRange(start, end, dir, aRv);
+}
+
 HTMLInputElement*
 nsTextEditorState::GetParentNumberControl(nsFrame* aFrame) const
 {
   MOZ_ASSERT(aFrame);
   nsIContent* content = aFrame->GetContent();
   MOZ_ASSERT(content);
   nsIContent* parent = content->GetParent();
   if (!parent) {
--- a/dom/html/nsTextEditorState.h
+++ b/dom/html/nsTextEditorState.h
@@ -305,16 +305,22 @@ public:
                          mozilla::ErrorResult& aRv);
 
   // Set the selection end.  This basically implements the
   // https://html.spec.whatwg.org/multipage/forms.html#dom-textarea/input-selectionend
   // setter.
   void SetSelectionEnd(const mozilla::dom::Nullable<uint32_t>& aEnd,
                        mozilla::ErrorResult& aRv);
 
+  // Set the selection direction.  This basically implements the
+  // https://html.spec.whatwg.org/multipage/forms.html#dom-textarea/input-selectiondirection
+  // setter.
+  void SetSelectionDirection(const nsAString& aDirection,
+                             mozilla::ErrorResult& aRv);
+
   void UpdateEditableState(bool aNotify) {
     if (mRootNode) {
       mRootNode->UpdateEditableState(aNotify);
     }
   }
 
 private:
   friend class RestoreSelectionState;