Bug 1430575 - Adjust editable definition to match WebDriver. r=automatedtester

Introduces a new function, isMutableFormControl, to the element
module in Marionette that tests if an element is a form control
that can be edited by the user.  This replaces the proprietary
UNEDITABLE_INPUTS set used previously.

An editable element is, according to the WebDriver standard, an
element which belongs to the two subcategories of editable elements.
This patch implements the first category of the mutable form controls.

MozReview-Commit-ID: Aix19mq3lcb

--HG--
extra : rebase_source : 1e3d671cd2d3ff618bf2fff3a2d8dadbd82d0540
This commit is contained in:
Andreas Tolfsen 2018-01-15 17:14:37 +00:00
Родитель ac5db38313
Коммит 44b2be2861
2 изменённых файлов: 95 добавлений и 13 удалений

Просмотреть файл

@ -34,15 +34,6 @@ const {
const ELEMENT_NODE = 1;
const DOCUMENT_NODE = 9;
const UNEDITABLE_INPUTS = new Set([
"checkbox",
"radio",
"hidden",
"submit",
"button",
"image",
]);
const XBLNS = "http://www.mozilla.org/xbl";
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
@ -843,6 +834,60 @@ element.isDisabled = function(el) {
}
};
/**
* Denotes elements that can be used for typing and clearing.
*
* Elements that are considered WebDriver-editable are non-readonly
* and non-disabled <code>&lt;input&gt;</code> elements in the Text,
* Search, URL, Telephone, Email, Password, Date, Month, Date and
* Time Local, Number, Range, Color, and File Upload states, and
* <code>&lt;textarea&gt;</code> elements.
*
* @param {Element} el
* Element to test.
*
* @return {boolean}
* True if editable, false otherwise.
*/
element.isMutableFormControl = function(el) {
if (!element.isDOMElement(el)) {
return false;
}
if (element.isReadOnly(el) || element.isDisabled(el)) {
return false;
}
if (el.localName == "textarea") {
return true;
}
if (el.localName != "input") {
return false;
}
switch (el.type) {
case "color":
case "date":
case "datetime-local":
case "email":
case "file":
case "month":
case "number":
case "password":
case "range":
case "search":
case "tel":
case "text":
case "time":
case "url":
case "week":
return true;
default:
return false;
}
};
/**
* An editing host is a node that is either an HTML element with a
* <code>contenteditable</code> attribute, or the HTML element child
@ -892,9 +937,7 @@ element.isEditable = function(el) {
return false;
}
return (el.localName == "input" && !UNEDITABLE_INPUTS.has(el.type)) ||
el.localName == "textarea" ||
element.isEditingHost(el);
return element.isMutableFormControl(el) || element.isEditingHost(el);
};
/**

Просмотреть файл

@ -44,10 +44,15 @@ class DOMElement extends Element {
constructor(tagName, attrs = {}) {
super(tagName, attrs);
this.namespaceURI = XHTMLNS;
if (typeof this.namespaceURI == "undefined") {
this.namespaceURI = XHTMLNS;
}
if (typeof this.ownerDocument == "undefined") {
this.ownerDocument = {designMode: "off"};
}
if (typeof this.type == "undefined") {
this.type = "text";
}
if (this.localName == "option") {
this.selected = false;
@ -258,6 +263,40 @@ add_test(function test_isEditable() {
run_next_test();
});
add_test(function test_isMutableFormControlElement() {
ok(!element.isMutableFormControl(null));
ok(!element.isMutableFormControl(new DOMElement("textarea", {readOnly: true})));
ok(!element.isMutableFormControl(new DOMElement("textarea", {disabled: true})));
const mutableStates = new Set([
"color",
"date",
"datetime-local",
"email",
"file",
"month",
"number",
"password",
"range",
"search",
"tel",
"text",
"url",
"week",
]);
for (let type of mutableStates) {
ok(element.isMutableFormControl(new DOMElement("input", {type})));
}
ok(element.isMutableFormControl(new DOMElement("textarea")));
ok(!element.isMutableFormControl(new DOMElement("input", {type: "hidden"})));
ok(!element.isMutableFormControl(new DOMElement("p")));
ok(!element.isMutableFormControl(new DOMElement("p", {isContentEditable: true})));
ok(!element.isMutableFormControl(new DOMElement("p", {ownerDocument: {designMode: "on"}})));
run_next_test();
});
add_test(function test_coordinates() {
let p = element.coordinates(domEl);
ok(p.hasOwnProperty("x"));