Bug 1432864 - Decouple focussing from moving caret in textual form controls. r=automatedtester
authorAndreas Tolfsen <ato@sny.no>
Thu, 01 Feb 2018 09:05:00 +0200
changeset 454621 a25a343d7937b33a5771db430776c724870e6c8c
parent 454620 54810cf6c8c4fa1f5ac757b607b243fdd3d2e6b8
child 454622 feae5d29e679fb637a0ca44800464fee9f1bc91f
push id1648
push usermtabara@mozilla.com
push dateThu, 01 Mar 2018 12:45:47 +0000
treeherdermozilla-release@cbb9688c2eeb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersautomatedtester
bugs1432864
milestone59.0
Bug 1432864 - Decouple focussing from moving caret in textual form controls. r=automatedtester Renames the interaction.focusElement, which also happened to move the caret in textual form controls, to interaction.moveCaretToEnd, focussed solely on moving the caret. It doesn't make sense to coalesce these two operations into one function. MozReview-Commit-ID: 2QxV8FllW8J
testing/marionette/interaction.js
--- a/testing/marionette/interaction.js
+++ b/testing/marionette/interaction.js
@@ -408,31 +408,37 @@ interaction.flushEventLoop = async funct
     el.removeEventListener("click", clickEv);
   };
 
   return new TimedPromise(spinEventLoop, {timeout: 500, throws: null})
       .then(removeListeners);
 };
 
 /**
- * Focus element and, if a textual input field and no previous selection
- * state exists, move the caret to the end of the input field.
+ * If <var>el<var> is a textual form control and no previous
+ * selection state exists, move the caret to the end of the form control.
  *
- * @param {Element} element
- *     Element to focus.
+ * The element has to be a <code>&lt;input type=text&gt;</code>
+ * or <code>&lt;textarea&gt;</code> element for the cursor to move
+ * be moved.
+ *
+ * @param {Element} el
+ *     Element to potential move the caret in.
  */
-interaction.focusElement = function(el) {
-  let t = el.type;
-  if (t && (t == "text" || t == "textarea")) {
-    if (el.selectionEnd == 0) {
-      let len = el.value.length;
-      el.setSelectionRange(len, len);
-    }
+interaction.moveCaretToEnd = function(el) {
+  if (!element.isDOMElement(el) ||
+      el.localName != "textarea" ||
+      (el.localName != "input" && el.type == "text")) {
+    return;
   }
-  el.focus();
+
+  if (el.selectionEnd == 0) {
+    let len = el.value.length;
+    el.setSelectionRange(len, len);
+  }
 };
 
 /**
  * Performs checks if <var>el</var> is keyboard-interactable.
  *
  * To decide if an element is keyboard-interactable various properties,
  * and computed CSS styles have to be evaluated. Whereby it has to be taken
  * into account that the element can be part of a container (eg. option),
@@ -448,17 +454,16 @@ interaction.isKeyboardInteractable = fun
   const win = getWindow(el);
 
   // body and document element are always keyboard-interactable
   if (el.localName === "body" || el === win.document.documentElement) {
     return true;
   }
 
   el.focus();
-
   return el === win.document.activeElement;
 };
 
 /**
  * Appends <var>path</var> to an <tt>&lt;input type=file&gt;</tt>'s
  * file list.
  *
  * @param {HTMLInputElement} el
@@ -553,17 +558,18 @@ async function webdriverSendKeysToElemen
   if (!interaction.isKeyboardInteractable(containerEl)) {
     throw new ElementNotInteractableError(
         pprint`Element ${el} is not reachable by keyboard`);
   }
 
   let acc = await a11y.getAccessible(el, true);
   a11y.assertActionable(acc, el);
 
-  interaction.focusElement(el);
+  interaction.moveCaretToEnd(el);
+  el.focus();
 
   if (el.type == "file") {
     await interaction.uploadFile(el, value);
   } else if ((el.type == "date" || el.type == "time") &&
       Preferences.get("dom.forms.datetime")) {
     interaction.setFormControlValue(el, value);
   } else {
     event.sendKeysToElement(value, el, win);
@@ -586,17 +592,18 @@ async function legacySendKeysToElement(e
 
     if (!element.isVisible(visibilityCheckEl)) {
       throw new ElementNotInteractableError("Element is not visible");
     }
 
     let acc = await a11y.getAccessible(el, true);
     a11y.assertActionable(acc, el);
 
-    interaction.focusElement(el);
+    interaction.moveCaretToEnd(el);
+    el.focus();
     event.sendKeysToElement(value, el, win);
   }
 }
 
 /**
  * Determine the element displayedness of an element.
  *
  * @param {DOMElement|XULElement} el