Bug 1432864 - Decouple focussing from moving caret in textual form controls. r?automatedtester draft
authorAndreas Tolfsen <ato@sny.no>
Wed, 24 Jan 2018 19:01:47 +0000
changeset 737944 085aec3a9ee7683a5c1412dc044b3bc5acfdff00
parent 737939 6602576987baec9edbaaad117114ba5227db6261
child 737945 86d6c2cff3948faf38da491ebbdacf14967d92d8
push id96803
push userbmo:ato@sny.no
push dateThu, 25 Jan 2018 12:02:16 +0000
reviewersautomatedtester
bugs1432864
milestone60.0a1
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