Source code

Revision control

Other Tools

Test Info:

<html>
<head>
<title>Test for contenteditable focus</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css"
href="/tests/SimpleTest/test.css" />
</head>
<body>
<div id="display">
First text in this document.<br>
<input id="inputText" type="text"><br>
<input id="inputTextReadonly" type="text" readonly><br>
<input id="inputButton" type="button" value="input[type=button]"><br>
<button id="button">button</button><br>
<div id="editor" contenteditable="true">
editable contents.<br>
<input id="inputTextInEditor" type="text"><br>
<input id="inputTextReadonlyInEditor" type="text" readonly><br>
<input id="inputButtonInEditor" type="button" value="input[type=button]"><br>
<button id="buttonInEditor">button</button><br>
<div id="noeditableInEditor" contenteditable="false">
<span id="spanInNoneditableInEditor">span element in noneditable in editor</span><br>
<input id="inputTextInNoneditableInEditor" type="text"><br>
<input id="inputTextReadonlyInNoneditableInEditor" type="text" readonly><br>
<input id="inputButtonInNoneditableInEditor" type="button" value="input[type=button]"><br>
<button id="buttonInNoneditableInEditor">button</button><br>
</div>
<span id="spanInEditor">span element in editor</span><br>
</div>
<div id="otherEditor" contenteditable="true">
other editor.
</div>
</div>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
<script class="testbody" type="application/javascript">
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(runTests, window);
function runTests() {
runTestsInternal();
SimpleTest.finish();
}
function runTestsInternal() {
var fm = SpecialPowers.Services.focus;
// XXX using selCon for checking the visibility of the caret, however,
// selCon is shared in document, cannot get the element of owner of the
// caret from javascript?
var selCon = SpecialPowers.wrap(window).docShell.
QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor).
getInterface(SpecialPowers.Ci.nsISelectionDisplay).
QueryInterface(SpecialPowers.Ci.nsISelectionController);
var selection = window.getSelection();
var editor = document.getElementById("editor");
var inputTextInEditor = document.getElementById("inputTextInEditor");
var spanInEditor = document.getElementById("spanInEditor");
var otherEditor = document.getElementById("otherEditor");
// XXX if there is a contenteditable element, HTML editor sets dom selection
// to first editable node, but this makes inconsistency with normal document
// behavior.
todo_is(selection.rangeCount, 0, "unexpected selection range is there");
ok(!selCon.caretVisible, "caret is visible in the document");
// Move focus to inputTextInEditor
inputTextInEditor.focus();
is(SpecialPowers.unwrap(fm.focusedElement), inputTextInEditor,
"inputTextInEditor didn't get focus");
todo_is(selection.rangeCount, 0, "unexpected selection range is there");
ok(selCon.caretVisible, "caret isn't visible in the inputTextInEditor");
// Move focus to the editor
editor.focus();
is(SpecialPowers.unwrap(fm.focusedElement), editor,
"editor didn't get focus");
is(selection.rangeCount, 1,
"there is no selection range when editor has focus");
var range = selection.getRangeAt(0);
ok(range.collapsed, "the selection range isn't collapsed");
var startNode = range.startContainer;
is(startNode.nodeType, Node.TEXT_NODE, "the caret isn't set to the first text node");
is(startNode, editor.firstChild, "the caret isn't set to the editor");
ok(selCon.caretVisible, "caret isn't visible in the editor");
// Move focus to other editor
otherEditor.focus();
is(SpecialPowers.unwrap(fm.focusedElement), otherEditor,
"the other editor didn't get focus");
is(selection.rangeCount, 1,
"there is no selection range when the other editor has focus");
range = selection.getRangeAt(0);
ok(range.collapsed, "the selection range isn't collapsed");
startNode = range.startContainer;
is(startNode.nodeType, Node.TEXT_NODE, "the caret isn't set to the text node");
is(startNode, otherEditor.firstChild, "the caret isn't set to the other editor");
ok(selCon.caretVisible, "caret isn't visible in the other editor");
// Move focus to inputTextInEditor
inputTextInEditor.focus();
is(SpecialPowers.unwrap(fm.focusedElement), inputTextInEditor,
"inputTextInEditor didn't get focus #2");
is(selection.rangeCount, 1, "selection range is lost from the document");
range = selection.getRangeAt(0);
ok(range.collapsed, "the selection range isn't collapsed");
startNode = range.startContainer;
is(startNode.nodeType, Node.TEXT_NODE, "the caret isn't set to the first text node");
// XXX maybe, the caret can stay on the other editor if it's better.
is(startNode, editor.firstChild,
"the caret should stay on the other editor");
ok(selCon.caretVisible,
"caret isn't visible in the inputTextInEditor");
// Move focus to the other editor again
otherEditor.focus();
is(SpecialPowers.unwrap(fm.focusedElement), otherEditor,
"the other editor didn't get focus #2");
// Set selection to the span element in the editor.
range = document.createRange();
range.setStart(spanInEditor.firstChild, 5);
selection.removeAllRanges();
selection.addRange(range);
is(selection.rangeCount, 1, "selection range is lost from the document");
is(SpecialPowers.unwrap(fm.focusedElement), editor,
"the other editor should lose focus by selection range change");
ok(selCon.caretVisible, "caret isn't visible in inputTextInEditor");
// Move focus to the editor
editor.focus();
is(SpecialPowers.unwrap(fm.focusedElement), editor,
"the editor didn't get focus #2");
is(selection.rangeCount, 1, "selection range is lost from the document");
range = selection.getRangeAt(0);
ok(range.collapsed, "the selection range isn't collapsed");
is(range.startOffset, 5,
"the caret is moved when the editor was focused (offset)");
startNode = range.startContainer;
is(startNode.nodeType, 3, "the caret isn't in text node");
is(startNode.parentNode, spanInEditor,
"the caret is moved when the editor was focused (node)");
ok(selCon.caretVisible, "caret isn't visible in the editor (spanInEditor)");
// Move focus to each focusable element in the editor.
function testFocusMove(aSetFocusElementID, aFocusable, aCaretVisible) {
editor.focus();
is(SpecialPowers.unwrap(fm.focusedElement), editor,
"testFocusMove: the editor didn't get focus at initializing (" +
aSetFocusElementID + ")");
var setFocusElement = document.getElementById(aSetFocusElementID);
setFocusElement.focus();
if (aFocusable) {
is(SpecialPowers.unwrap(fm.focusedElement), setFocusElement,
"testFocusMove: the " + aSetFocusElementID +
" didn't get focus");
} else {
is(SpecialPowers.unwrap(fm.focusedElement), editor,
"testFocusMove: the editor lost focus by focus() of the " +
aSetFocusElementID);
}
if (aCaretVisible) {
ok(selCon.caretVisible,
"testFocusMove: caret isn't visible when the " +
aSetFocusElementID + " has focus");
} else {
ok(!selCon.caretVisible,
"testFocusMove: caret is visible when the " +
aSetFocusElementID + " has focus");
}
}
testFocusMove("inputTextInEditor", true, true);
testFocusMove("inputTextReadonlyInEditor", true, true);
// XXX shouldn't the caret become invisible?
testFocusMove("inputButtonInEditor", true, true);
testFocusMove("noeditableInEditor", false, true);
testFocusMove("spanInNoneditableInEditor", false, true);
testFocusMove("inputTextInNoneditableInEditor", true, true);
testFocusMove("inputTextReadonlyInNoneditableInEditor", true, true);
testFocusMove("inputButtonInNoneditableInEditor", true, false);
testFocusMove("buttonInNoneditableInEditor", true, false);
testFocusMove("spanInEditor", false, true);
testFocusMove("inputText", true, true);
testFocusMove("inputTextReadonly", true, true);
testFocusMove("inputButton", true, false);
testFocusMove("button", true, false);
}
</script>
</body>
</html>