layout/generic/test/test_backspace_delete.xul

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/generic/test/test_backspace_delete.xul	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,280 @@
     1.4 +<?xml version="1.0"?>
     1.5 +<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
     1.6 +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
     1.7 +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
     1.8 +        xmlns:html="http://www.w3.org/1999/xhtml"
     1.9 +        title="Test BackSpace/Delete Keys">
    1.10 +  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
    1.11 +
    1.12 +<script class="testbody" type="application/javascript">
    1.13 +<![CDATA[
    1.14 +
    1.15 +function execTests() {
    1.16 +  var e = document.getElementById("edit");
    1.17 +  var doc = e.contentDocument;
    1.18 +  var win = e.contentWindow;
    1.19 +  var root = doc.documentElement;
    1.20 +  var editor = doc.body;
    1.21 +  var sel = win.getSelection();
    1.22 +  win.focus();
    1.23 +
    1.24 +  function setupTest(html, firstChildOffsetForCaret, node) {
    1.25 +    // Work around bug 474255 --- we need to have nonempty content before we turn on
    1.26 +    // editing, or the tests below break because the editor doesn't notice when we
    1.27 +    // insert non-empty content using innerHTML.
    1.28 +    doc.designMode = 'off';
    1.29 +    editor.innerHTML = html;
    1.30 +    doc.designMode = 'on';
    1.31 +    var n = editor.firstChild;
    1.32 +    if (node) {
    1.33 +      n = node();
    1.34 +    }
    1.35 +    sel.collapse(n, firstChildOffsetForCaret);
    1.36 +  }
    1.37 +
    1.38 +  var eatSpace;
    1.39 +
    1.40 +  function getPrefs() {
    1.41 +    const prefSvcContractID = "@mozilla.org/preferences-service;1";
    1.42 +    const prefSvcIID = Components.interfaces.nsIPrefService;
    1.43 +    return Components.classes[prefSvcContractID].getService(prefSvcIID)
    1.44 +                                                 .getBranch("layout.word_select.");
    1.45 +  }
    1.46 +
    1.47 +  function setEatSpace(newValue) {
    1.48 +    getPrefs().setBoolPref("eat_space_to_next_word", newValue);
    1.49 +    eatSpace = newValue;
    1.50 +  }
    1.51 +
    1.52 +  function restoreEatSpace() {
    1.53 +    try {
    1.54 +      getPrefs().clearUserPref("eat_space_to_next_word");
    1.55 +    } catch(ex) {}
    1.56 +  }
    1.57 +
    1.58 +  function doCommand(cmd) {
    1.59 +    var controller = document.commandDispatcher.getControllerForCommand(cmd);
    1.60 +    if (controller) {
    1.61 +      try {
    1.62 +        controller.doCommand(cmd);
    1.63 +        ok(true, 'doCommand(' + cmd + ') succeeded');
    1.64 +      } catch(ex) {
    1.65 +        ok(false, 'exception in doCommand(' + cmd + '): ', ex.message);
    1.66 +      }
    1.67 +    }
    1.68 +  }
    1.69 +
    1.70 +  function testRight(node, offset) {
    1.71 +    doCommand("cmd_charNext");
    1.72 +    var msg = "Right movement broken in \"" + editor.innerHTML + "\", offset " + offset;
    1.73 +    is(sel.anchorNode, node, msg);
    1.74 +    is(sel.anchorOffset, offset, msg);
    1.75 +  }
    1.76 +
    1.77 +  function selErrString(dir) {
    1.78 +    return dir + " selection broken with eatSpace=" + eatSpace + " in \"" + editor.innerHTML + "\"";
    1.79 +  }
    1.80 +
    1.81 +  function testWordSelRight(startNode, startOffset, endNode, endOffset) {
    1.82 +    doCommand("cmd_selectWordNext");
    1.83 +    var selRange = sel.getRangeAt(0);
    1.84 +    is(selRange.startContainer, startNode, selErrString("Word right"));
    1.85 +    is(selRange.startOffset, startOffset, selErrString("Word right"));
    1.86 +    is(selRange.endContainer, endNode, selErrString("Word right"));
    1.87 +    is(selRange.endOffset, endOffset, selErrString("Word right"));
    1.88 +  }
    1.89 +
    1.90 +  function testDelete(node, offset, text, richtext) {
    1.91 +    doCommand("cmd_deleteCharForward");
    1.92 +    var msg = "Delete broken in \"" + editor.innerHTML + "\", offset " + offset;
    1.93 +    if(typeof node == 'function'){
    1.94 +      node = node();
    1.95 +    }
    1.96 +    is(sel.anchorNode, node, msg);
    1.97 +
    1.98 +    is(sel.anchorOffset, offset, msg);
    1.99 +    let text_result = richtext ? editor.innerHTML : editor.textContent;
   1.100 +    is(text_result, text, msg);
   1.101 +  }
   1.102 +
   1.103 +  function testBackspace(node, offset, text) {
   1.104 +    doCommand("cmd_deleteCharBackward");
   1.105 +    var msg = "Backspace broken in \"" + editor.innerHTML + "\", offset " + offset;
   1.106 +    is(sel.anchorNode, node, msg);
   1.107 +
   1.108 +    is(sel.anchorOffset, offset, msg);
   1.109 +    is(editor.textContent, text, msg);
   1.110 +  }
   1.111 +
   1.112 +  function testDeletePrevWord(node, offset, text) {
   1.113 +    doCommand("cmd_deleteWordBackward");
   1.114 +    var msg = "Delete previous word broken in \"" + editor.innerHTML + "\", offset " + offset;
   1.115 +    is(sel.anchorNode, node, msg);
   1.116 +    is(sel.anchorOffset, offset, msg);
   1.117 +    is(editor.textContent, text, msg);
   1.118 +  }
   1.119 +
   1.120 +  function testDeleteNextWord(node, offset, text) {
   1.121 +    doCommand("cmd_deleteWordForward");
   1.122 +    var msg = "Delete next word broken in \"" + editor.innerHTML + "\", offset " + offset;
   1.123 +    is(sel.anchorNode, node, msg);
   1.124 +    is(sel.anchorOffset, offset, msg);
   1.125 +    todo_is(editor.textContent, text, msg);
   1.126 +  }
   1.127 +
   1.128 +  // Test cell-wise deletion of Delete
   1.129 +  setupTest("สวัสดีพ่อแม่พี่น้อง", 0);
   1.130 +  testRight(editor.firstChild, 1);
   1.131 +  testDelete(editor.firstChild, 1, "สสดีพ่อแม่พี่น้อง");
   1.132 +  testRight(editor.firstChild, 2);
   1.133 +  testDelete(editor.firstChild, 2, "สสพ่อแม่พี่น้อง");
   1.134 +  testRight(editor.firstChild, 4);
   1.135 +  testDelete(editor.firstChild, 4, "สสพ่แม่พี่น้อง");
   1.136 +  testRight(editor.firstChild, 5);
   1.137 +  testDelete(editor.firstChild, 5, "สสพ่แพี่น้อง", false);
   1.138 +  testRight(editor.firstChild, 8);
   1.139 +  testDelete(editor.firstChild, 8, "สสพ่แพี่อง", false);
   1.140 +  testRight(editor.firstChild, 9);
   1.141 +  testDelete(editor.firstChild, 9, "สสพ่แพี่อ", false);
   1.142 +
   1.143 +  // Test character-wise deletion of Backspace
   1.144 +  setupTest("สวัสดีพ่อแม่พี่น้อง", 0);
   1.145 +  testRight(editor.firstChild, 1);
   1.146 +  testBackspace(editor.firstChild, 0, "วัสดีพ่อแม่พี่น้อง");
   1.147 +  testRight(editor.firstChild, 2);
   1.148 +  testBackspace(editor.firstChild, 1, "วสดีพ่อแม่พี่น้อง");
   1.149 +  testRight(editor.firstChild, 2);
   1.150 +  testBackspace(editor.firstChild, 1, "วดีพ่อแม่พี่น้อง");
   1.151 +  testRight(editor.firstChild, 3);
   1.152 +  testBackspace(editor.firstChild, 2, "วดพ่อแม่พี่น้อง");
   1.153 +  testRight(editor.firstChild, 4);
   1.154 +  testBackspace(editor.firstChild, 3, "วดพอแม่พี่น้อง");
   1.155 +  testRight(editor.firstChild, 4);
   1.156 +  testBackspace(editor.firstChild, 3, "วดพแม่พี่น้อง");
   1.157 +  testRight(editor.firstChild, 4);
   1.158 +  testBackspace(editor.firstChild, 3, "วดพม่พี่น้อง");
   1.159 +  testRight(editor.firstChild, 5);
   1.160 +  testBackspace(editor.firstChild, 4, "วดพมพี่น้อง");
   1.161 +  testRight(editor.firstChild, 7);
   1.162 +  testBackspace(editor.firstChild, 6, "วดพมพีน้อง");
   1.163 +  testRight(editor.firstChild, 8);
   1.164 +  testBackspace(editor.firstChild, 7, "วดพมพีนอง");
   1.165 +  testRight(editor.firstChild, 8);
   1.166 +  testBackspace(editor.firstChild, 7, "วดพมพีนง");
   1.167 +  testRight(editor.firstChild, 8);
   1.168 +  testBackspace(editor.firstChild, 7, "วดพมพีน");
   1.169 +
   1.170 +  // Tests for Bug 417745
   1.171 +
   1.172 +  setEatSpace(true);
   1.173 +
   1.174 +  setupTest("Quick yellow fox", 0);
   1.175 +  testWordSelRight(editor.firstChild, 0, editor.firstChild, 6);
   1.176 +  testDelete(editor.firstChild, 0, "yellow fox");
   1.177 +  testWordSelRight(editor.firstChild, 0, editor.firstChild, 7);
   1.178 +  testDelete(editor.firstChild, 0, "fox");
   1.179 +
   1.180 +  setEatSpace(false);
   1.181 +
   1.182 +  setupTest("Quick yellow fox", 0);
   1.183 +  testWordSelRight(editor.firstChild, 0, editor.firstChild, 5);
   1.184 +  // editor converts the leading space to an &nbsp;, otherwise it
   1.185 +  // wouldn't show up which would confuse users
   1.186 +  testDelete(editor.firstChild, 0, "\u00A0yellow fox");
   1.187 +  testWordSelRight(editor.firstChild, 0, editor.firstChild, 7);
   1.188 +  testDelete(editor.firstChild, 0, "\u00A0fox");
   1.189 +  testWordSelRight(editor.firstChild, 0, editor.firstChild, 4);
   1.190 +  testDelete(editor, 0, "");
   1.191 +
   1.192 +  restoreEatSpace();
   1.193 +
   1.194 +  // Tests for Bug 419217
   1.195 +
   1.196 +  setupTest("foo<div>bar</div>", 3);
   1.197 +  testDelete(function(){return editor.firstChild;}, 3, "foobar", true);
   1.198 +
   1.199 +  // Tests for Bug 419406
   1.200 +  var s = "helloשלום";
   1.201 +  setupTest(s, 4);
   1.202 +  testRight(editor.firstChild, 5);
   1.203 +  testDelete(editor.firstChild, 5, "helloשלום");
   1.204 +
   1.205 +  // Tests for Bug 462188
   1.206 +  setupTest("You should not see this text.", 29);
   1.207 +  testDeletePrevWord(editor.firstChild, 24, "You should not see this ");
   1.208 +  testDeletePrevWord(editor.firstChild, 19, "You should not see ");
   1.209 +  testDeletePrevWord(editor.firstChild, 15, "You should not ");
   1.210 +  testDeletePrevWord(editor.firstChild, 11, "You should ");
   1.211 +  testDeletePrevWord(editor.firstChild,  4, "You ");
   1.212 +  testDeletePrevWord(editor,  0, "");
   1.213 +
   1.214 +  setupTest("You should not see this text.", 0);
   1.215 +  testDeleteNextWord(editor.firstChild, 0, "\u00A0should not see this text.");
   1.216 +  testDeleteNextWord(editor.firstChild, 0, "\u00A0not see this text.");
   1.217 +  testDeleteNextWord(editor.firstChild, 0, "\u00A0see this text.");
   1.218 +  testDeleteNextWord(editor.firstChild, 0, "\u00A0this text.");
   1.219 +  testDeleteNextWord(editor.firstChild, 0, "\u00A0text.");
   1.220 +  // testDeleteNextWord(editor, 0, "");
   1.221 +
   1.222 +  // Tests for Bug 502259
   1.223 +  setupTest("<p>Bug</p>\n<p>502259</p>", 1);
   1.224 +  testDelete(function(){return editor.firstChild.firstChild;}, 3, "<p>Bug502259</p>", true);
   1.225 +
   1.226 +  // Tests for Bug 507936
   1.227 +  var nodecallback = function(){return editor.firstChild.firstChild.lastChild.firstChild.lastChild;};
   1.228 +  setupTest("<ol><li>one<ol><li>two</li></ol></li></ol>\n<p>three</p>", 3, nodecallback);
   1.229 +  testDelete(nodecallback, 0, "<ol><li>one<ol><li>twothree</li></ol></li></ol>", true);
   1.230 +
   1.231 +  setupTest("<ol><li>one<ol><li>two</li></ol></li></ol>\n<hr>\n<p>three</p>", 3, nodecallback);
   1.232 +  testDelete(nodecallback, 3, 
   1.233 +    "<ol><li>one<ol><li>two</li></ol></li></ol><p>three</p>", true);
   1.234 +
   1.235 +  // Tests for Bug 519751
   1.236 +  var nodecallback = function(){return editor.firstChild.lastChild;};
   1.237 +  setupTest("<p>one</p><ol><li>two</li><li>three</li></ol>", 3, nodecallback);
   1.238 +  testDelete(nodecallback, 0, "<p>onetwo</p><ol><li>three</li></ol>", true);
   1.239 +
   1.240 +  nodecallback = function(){return editor.firstChild.childNodes[1].firstChild;};
   1.241 +  setupTest("<ol><li>one</li><li>two</li></ol><ol><li>three</li><li>four</li></ol>", 3, nodecallback);
   1.242 +  testDelete(function(){return editor.firstChild.childNodes[2].firstChild;}, 
   1.243 +    0, "<ol><li>one</li><li>two</li><li>three</li><li>four</li></ol>", true);
   1.244 +  /*todo_is(false, true, 'The above testDelete should use the same nodecallback' +
   1.245 +    'as in the proceeding setupTest: the cursor should stay at the end of "two", while currently it is at the beginning of "three" after delete');*/
   1.246 +
   1.247 +  // More Tests for Bug 507936
   1.248 +  nodecallback = function(){return editor.firstChild.firstChild.firstChild;}
   1.249 +  setupTest("<div><div>abcdef</div><div>bar</div><div>ghi</div></div>", 5, nodecallback);
   1.250 +  sel.extend(editor.lastChild.lastChild.lastChild, 1);
   1.251 +  testDelete(editor.lastChild.lastChild.lastChild, 5, "<div><div>abcdehi</div></div>", true);
   1.252 +
   1.253 +  setupTest("<div><div>abcdef</div><div>ghi</div></div>", 5, nodecallback);
   1.254 +  sel.extend(editor.lastChild.lastChild.lastChild, 1);
   1.255 +  testDelete(editor.lastChild.lastChild.lastChild, 5, "<div><div>abcdehi</div></div>", true);
   1.256 +
   1.257 +  nodecallback = function(){return editor.firstChild.firstChild;}
   1.258 +  setupTest("<div>abcdef<div><div>bar</div>ghi</div></div>", 5, nodecallback);
   1.259 +  sel.extend(editor.lastChild.lastChild.lastChild, 1);
   1.260 +  expectednodecallback = function(){return editor.lastChild.lastChild;}
   1.261 +  testDelete(expectednodecallback, 0, "<div>abcdehi</div>", true);
   1.262 +
   1.263 +  setupTest("<div>abcdef<div>ghi</div></div>", 5, nodecallback);
   1.264 +  sel.extend(editor.lastChild.lastChild.lastChild, 1);
   1.265 +  testDelete(expectednodecallback, 0, "<div>abcdehi</div>", true);
   1.266 +
   1.267 +  SimpleTest.finish();
   1.268 +}
   1.269 +
   1.270 +SimpleTest.waitForExplicitFinish();
   1.271 +addLoadEvent(execTests);
   1.272 +]]>
   1.273 +</script>
   1.274 +
   1.275 +<body  id="html_body" xmlns="http://www.w3.org/1999/xhtml">
   1.276 +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=462188">Mozilla Bug 462188</a>
   1.277 +<p id="display"></p>
   1.278 +
   1.279 +<pre id="test">
   1.280 +</pre>
   1.281 +<iframe id="edit" width="200" height="100" src="about:blank"/>
   1.282 +</body>
   1.283 +</window>

mercurial