Bug 1278473 - write shim Services.focus; r=gregtatum

MozReview-Commit-ID: 1D2EjcoiEz6

--HG--
extra : rebase_source : 76077c2c1919372df56a4aacdb62ae1d7f60f224
This commit is contained in:
Tom Tromey 2016-07-26 08:03:24 -06:00
parent 6e07b3929e
commit 0368ffde20
3 changed files with 136 additions and 1 deletions

View File

@ -6,7 +6,7 @@
"use strict";
/* globals localStorage, window */
/* globals localStorage, window, document, NodeFilter */
// Some constants from nsIPrefBranch.idl.
const PREF_INVALID = 0;
@ -519,6 +519,63 @@ const Services = {
};
},
},
/**
* An implementation of Services.focus that holds just the
* properties and methods needed by devtools.
* @see nsIFocusManager.idl for details.
*/
focus: {
// These values match nsIFocusManager in order to make testing a
// bit simpler.
MOVEFOCUS_FORWARD: 1,
MOVEFOCUS_BACKWARD: 2,
get focusedElement() {
if (!document.hasFocus()) {
return null;
}
return document.activeElement;
},
moveFocus: function (window, startElement, type, flags) {
if (flags !== 0) {
throw new Error("shim Services.focus.moveFocus only accepts flags===0");
}
if (type !== Services.focus.MOVEFOCUS_FORWARD
&& type !== Services.focus.MOVEFOCUS_BACKWARD) {
throw new Error("shim Services.focus.moveFocus only supports " +
" MOVEFOCUS_FORWARD and MOVEFOCUS_BACKWARD");
}
if (!startElement) {
startElement = document.activeElement || document;
}
let iter = document.createTreeWalker(document, NodeFilter.SHOW_ELEMENT, {
acceptNode: function (node) {
let tabIndex = node.getAttribute("tabindex");
if (tabIndex === "-1") {
return NodeFilter.FILTER_SKIP;
}
node.focus();
if (document.activeElement == node) {
return NodeFilter.FILTER_ACCEPT;
}
return NodeFilter.FILTER_SKIP;
}
});
iter.currentNode = startElement;
// Sets the focus via side effect in the filter.
if (type === Services.focus.MOVEFOCUS_FORWARD) {
iter.nextNode();
} else {
iter.previousNode();
}
},
},
};
/**

View File

@ -3,4 +3,5 @@ support-files =
prefs-wrapper.js
[test_service_appinfo.html]
[test_service_focus.html]
[test_service_prefs.html]

View File

@ -0,0 +1,77 @@
<!DOCTYPE html>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1278473
-->
<head>
<title>Test for Bug 1278473 - replace Services.focus</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css">
<script type="application/javascript;version=1.8">
"use strict";
var exports = {};
</script>
<script type="application/javascript;version=1.8"
src="resource://devtools/client/shared/shim/Services.js"></script>
</head>
<body>
<span>
<span id="start" testvalue="0" tabindex="0"> </span>
<label>
<input testvalue="1" type="radio">Hi</input>
</label>
<label>
<input type="radio" tabindex="-1">Bye</input>
</label>
<label style="display: none">
<input id="button3" type="radio" tabindex="-1">Invisible</input>
</label>
<input id="button4" type="radio" disabled="true">Disabled</input>
<span testvalue="2" tabindex="0"> </span>
</span>
<script type="application/javascript;version=1.8">
"use strict";
// The test assumes these are identical, so assert it here.
is(Services.focus.MOVEFOCUS_BACKWARD, SpecialPowers.Services.focus.MOVEFOCUS_BACKWARD,
"check MOVEFOCUS_BACKWARD");
is(Services.focus.MOVEFOCUS_FORWARD, SpecialPowers.Services.focus.MOVEFOCUS_FORWARD,
"check MOVEFOCUS_FORWARD");
function moveFocus(element, type, expect) {
let current = document.activeElement;
const suffix = "(type=" + type + ", to=" + expect + ")";
// First try with the platform implementation.
SpecialPowers.Services.focus.moveFocus(window, element, type, 0);
is(document.activeElement.getAttribute("testvalue"), expect,
"platform moveFocus " + suffix);
// Reset the focus and try again with the shim.
current.focus();
is(document.activeElement, current, "reset " + suffix);
Services.focus.moveFocus(window, element, type, 0);
is(document.activeElement.getAttribute("testvalue"), expect,
"shim moveFocus " + suffix);
}
let start = document.querySelector("#start");
start.focus();
is(document.activeElement.getAttribute("testvalue"), "0", "initial focus");
moveFocus(null, Services.focus.MOVEFOCUS_FORWARD, "1");
moveFocus(null, Services.focus.MOVEFOCUS_FORWARD, "2");
let end = document.activeElement;
moveFocus(null, Services.focus.MOVEFOCUS_BACKWARD, "1");
moveFocus(null, Services.focus.MOVEFOCUS_BACKWARD, "0");
moveFocus(start, Services.focus.MOVEFOCUS_FORWARD, "1");
moveFocus(end, Services.focus.MOVEFOCUS_BACKWARD, "1");
</script>
</body>