Bug 1354211 - Add element.isEditingHost and element.isEditable. r=automatedtester

Introduces two new functions called element.isEditingHost, for
determining if an element is content-editable or part of a document
in design mode, and element.isEditable, which implements the
WebDriver-defined concept of what it means for an element to be editable.

WebDriver consideres an element editable if it is not read-only or
disabled, and one of the following conditions are met:

  - It is a <textarea> element.

  - It is an element that is not of the checkbox, radio, hidden,
    submit, button, or image types.

  - It is content-editable.

  - It belongs to a document in design mode.

MozReview-Commit-ID: 6U71uSUNwoI

--HG--
extra : rebase_source : c5702362d5be531b2e5b764fac13bb9db9f20f23
This commit is contained in:
Andreas Tolfsen 2017-12-31 14:52:46 +00:00
Родитель e2bea6dd58
Коммит 730854f761
2 изменённых файлов: 93 добавлений и 0 удалений

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

@ -34,6 +34,15 @@ 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";
@ -834,6 +843,60 @@ element.isDisabled = function(el) {
}
};
/**
* An editing host is a node that is either an HTML element with a
* <code>contenteditable</code> attribute, or the HTML element child
* of a document whose <code>designMode</code> is enabled.
*
* @param {Element} el
* Element to determine if is an editing host.
*
* @return {boolean}
* True if editing host, false otherwise.
*/
element.isEditingHost = function(el) {
return element.isDOMElement(el) &&
(el.isContentEditable || el.ownerDocument.designMode == "on");
};
/**
* Determines if an element is editable according to WebDriver.
*
* An element is considered editable if it is not read-only or
* disabled, and one of the following conditions are met:
*
* <ul>
* <li>It is a <code>&lt;textarea&gt;</code> element.
*
* <li>It is an <code>&lt;input&gt;</code> element that is not of
* the <code>checkbox</code>, <code>radio</code>, <code>hidden</code>,
* <code>submit</code>, <code>button</code>, or <code>image</code> types.
*
* <li>It is content-editable.
*
* <li>It belongs to a document in design mode.
* </ul>
*
* @param {Element}
* Element to test if editable.
*
* @return {boolean}
* True if editable, false otherwise.
*/
element.isEditable = function(el) {
if (!element.isDOMElement(el)) {
return false;
}
if (element.isReadOnly(el) || element.isDisabled(el)) {
return false;
}
return (el.localName == "input" && !UNEDITABLE_INPUTS.has(el.type)) ||
el.localName == "textarea" ||
element.isEditingHost(el);
};
/**
* This function generates a pair of coordinates relative to the viewport
* given a target element and coordinates relative to that element's

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

@ -45,6 +45,9 @@ class DOMElement extends Element {
super(tagName, attrs);
this.namespaceURI = XHTMLNS;
if (typeof this.ownerDocument == "undefined") {
this.ownerDocument = {designMode: "off"};
}
if (this.localName == "option") {
this.selected = false;
@ -228,6 +231,33 @@ add_test(function test_isDisabled() {
run_next_test();
});
add_test(function test_isEditingHost() {
ok(!element.isEditingHost(null));
ok(element.isEditingHost(new DOMElement("p", {isContentEditable: true})));
ok(element.isEditingHost(new DOMElement("p", {ownerDocument: {designMode: "on"}})));
run_next_test();
});
add_test(function test_isEditable() {
ok(!element.isEditable(null));
ok(!element.isEditable(domEl));
ok(!element.isEditable(new DOMElement("textarea", {readOnly: true})));
ok(!element.isEditable(new DOMElement("textarea", {disabled: true})));
for (let type of ["checkbox", "radio", "hidden", "submit", "button", "image"]) {
ok(!element.isEditable(new DOMElement("input", {type})));
}
ok(element.isEditable(new DOMElement("input", {type: "text"})));
ok(element.isEditable(new DOMElement("input")));
ok(element.isEditable(new DOMElement("textarea")));
ok(element.isEditable(new DOMElement("p", {ownerDocument: {designMode: "on"}})));
ok(element.isEditable(new DOMElement("p", {isContentEditable: true})));
run_next_test();
});
add_test(function test_coordinates() {
let p = element.coordinates(domEl);
ok(p.hasOwnProperty("x"));