DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (c68fe15a81fc)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
<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>