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
--- 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><input type=text></code>
+ * or <code><textarea></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><input type=file></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