<!DOCTYPE> <html> <head> <title>-moz-user-select selection tests</title> <script src="/tests/SimpleTest/SimpleTest.js"></script> <script src="/tests/SimpleTest/EventUtils.js"></script> <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> <style type="text/css"> @font-face { font-family: Ahem; src: url("Ahem.ttf"); } body { font-family: Ahem; font-size: 20px; } s, .non-selectable { -moz-user-select: none; } n { display: none; } a { position:absolute; bottom: 0; right:0; } .text { -moz-user-select: text; } </style> </head> <body> <div id="test1">aaaaaaa<s>bbbbbbbb</s>ccccccc</div> <div id="test2"><s>aaaaaaa</s>bbbbbbbbccccccc</div> <div id="test3">aaaaaaabbbbbbbb<s>ccccccc</s></div> <div id="test4">aaaaaaa<x><s>bbbbbbbb</s></x>ccccccc</div> <div id="test5"><x><s>aaaaaaa</s></x>bbbbbbbbccccccc</div> <div id="test6">aaaaaaabbbbbbbb<x><s>ccccccc</s></x></div> <div id="test7">aaaaaaa<x><s><n>bbbb</n>bbbb</s></x>ccccccc</div> <div id="test8"><x><s>aa<n>aaa</n>aa</s></x>bbbbbbbbccccccc</div> <div id="test9">aaaaaaabbbbbbbb<x><s>cc<n>ccccc</n></s></x></div> <div id="testA">aaaaaaa<n>bbb<s>bbbbb</s></n>ccccccc</div> <div id="testB"><n><s>aaaa</s>aaa</n>bbbbbbbbccccccc</div> <div id="testC">aaaaaaabbbbbbbb<n>cc<s>c</s>cccc</n></div> <div id="testE">aaa<s id="testEc1">aaaa<a class="text">bbbb</a>dd<a>cccc</a>ddddddd</s>eeee</div> <div id="testF">aaaa <div class="non-selectable">x</div> <div class="non-selectable">x</div> <div class="non-selectable">x</div> bbbb</div> <div id="testG" style="white-space:pre">aaaa <div class="non-selectable">x</div> <div class="non-selectable">x</div> <div class="non-selectable">x</div> bbbb</div> <div id="testH" style="white-space:pre">aaaa <div class="non-selectable">x</div><input> bbbbbbb</div> <iframe id="testD" src="data:text/html,<body>aaaa<span style='-moz-user-select:none'>bbbb</span>cccc"></iframe> <pre id="test"> <script class="testbody" type="text/javascript"> function test() { function clear(w) { var sel = (w ? w : window).getSelection(); sel.removeAllRanges(); } function doneTest(e) { // We hide the elements we're done with so that later tests // are inside the rather narrow iframe mochitest gives us. // It matters for synthesizeMouse event tests. e.style.display = 'none'; e.offsetHeight; } function dragSelect(e, x1, x2, x3) { dir = x2 > x1 ? 1 : -1; synthesizeMouse(e, x1, 5, { type: "mousedown" }); synthesizeMouse(e, x1 + dir, 5, { type: "mousemove" }); if (x3) synthesizeMouse(e, x3, 5, { type: "mousemove" }); synthesizeMouse(e, x2 - dir, 5, { type: "mousemove" }); synthesizeMouse(e, x2, 5, { type: "mouseup" }); } function shiftClick(e, x) { synthesizeMouse(e, x, 5, { type: "mousedown", shiftKey: true }); synthesizeMouse(e, x, 5, { type: "mouseup", shiftKey: true }); } function init(arr, e) { clear(); var sel = window.getSelection(); for (i = 0; i < arr.length; ++i) { var data = arr[i]; var r = new Range() r.setStart(node(e, data[0]), data[1]); r.setEnd(node(e, data[2]), data[3]); sel.addRange(r); } } function NL(s) { return s.replace(/(\r\n|\n\r|\r)/g, '\n'); } function checkText(text, e) { var sel = window.getSelection(); is(NL(sel.toString()), text, e.id + ": selected text") } function checkRangeText(text, index) { var r = window.getSelection().getRangeAt(index); is(NL(r.toString()), text, e.id + ": range["+index+"].toString()") } function node(e, arg) { if (typeof arg == "number") return arg == -1 ? e : e.childNodes[arg]; return arg; } function checkRangeCount(n, e) { var sel = window.getSelection(); is(sel.rangeCount, n, e.id + ": Selection range count"); } function checkRange(i, expected, e) { var sel = window.getSelection(); var r = sel.getRangeAt(i); is(r.startContainer, node(e, expected[0]), e.id + ": range["+i+"].startContainer"); is(r.startOffset, expected[1], e.id + ": range["+i+"].startOffset"); is(r.endContainer, node(e, expected[2]), e.id + ": range["+i+"].endContainer"); is(r.endOffset, expected[3], e.id + ": range["+i+"].endOffset"); } function checkRanges(arr, e) { checkRangeCount(arr.length, e); for (i = 0; i < arr.length; ++i) { var expected = arr[i]; checkRange(i, expected, e); } } // ====================================================== // ================== dragSelect tests ================== // ====================================================== var e = document.getElementById('test1'); dragSelect(e, 20, 340); checkText('aaaaaacc', e); checkRanges([[0,1,-1,1], [2,0,2,2]], e); clear(); dragSelect(e, 20, 260, 120); checkText('aaaaa', e); checkRanges([[0,1,0,6]], e); doneTest(e); clear(); e = document.getElementById('test2'); dragSelect(e, 20, 340); checkText('', e); checkRanges([], e); clear(); dragSelect(e, 340, 20, 140); checkText('bbbbbbbbcc', e); checkRanges([[1,0,1,10]], e); // #test2 is used again below clear(); e = document.getElementById('test3'); dragSelect(e, 20, 340, 295); checkText('aaaaaabbbbbbbb', e); checkRanges([[0,1,0,15]], e); // #test3 is used again below clear(); e = document.getElementById('test4'); dragSelect(e, 20, 340); checkText('aaaaaacc', e); checkRanges([[0,1,1,0], [2,0,2,2]], e); doneTest(e); clear(); e = document.getElementById('test5'); dragSelect(e, 340, 20, 140); checkText('bbbbbbbbcc', e); checkRanges([[1,0,1,10]], e); doneTest(e); clear(); e = document.getElementById('test6'); dragSelect(e, 20, 340, 295); checkText('aaaaaabbbbbbbb', e); checkRanges([[0,1,0,15]], e); doneTest(e); clear(); e = document.getElementById('test7'); dragSelect(e, 20, 340); checkText('aaaaaacccccc', e); checkRanges([[0,1,1,0], [2,0,2,6]], e); doneTest(e); clear(); e = document.getElementById('test8'); dragSelect(e, 340, 20, 140); checkText('bbbbbccccc', e); checkRanges([[1,3,1,13]], e); doneTest(e); clear(); e = document.getElementById('test9'); dragSelect(e, 20, 340, 295); checkText('aaaaaabbbbbbbb', e); checkRanges([[0,1,0,15]], e); doneTest(e); clear(); e = document.getElementById('testA'); dragSelect(e, 20, 340); checkText('aaaaaaccccccc', e); checkRanges([[0,1,2,7]], e); checkRangeText('aaaaaabbbbbbbbccccccc', 0); doneTest(e); clear(); e = document.getElementById('testB'); dragSelect(e, 340, 20, 140); checkText('bbbbbbbccccccc', e); checkRanges([[1,1,1,15]], e); doneTest(e); clear(); e = document.getElementById('testE'); dragSelect(e, 20, 360, 295); checkText('aa\nbbbb\nee', e); checkRangeCount(3, e); checkRange(0, [0,1,-1,1], e); checkRange(1, [1,0,-1,2], e.children[0]); checkRange(2, [2,0,2,2], e); doneTest(e); // ====================================================== // ================== shift+click tests ================= // ====================================================== // test extending a selection that starts in a -moz-user-select:none node clear(); e = document.getElementById('test2'); init([[0,0,0,1]], e); checkRangeText('aaaaaaa', 0); checkText('', e); shiftClick(e, 340); checkRangeText('bbbbbbbbcc', 0); checkText('bbbbbbbbcc', e); checkRanges([[-1,1,1,10]], e); doneTest(e); // test extending a selection that end in a -moz-user-select:none node clear(); e = document.getElementById('test3'); init([[1,0,1,1]], e); checkRangeText('ccccccc', 0); checkText('', e); shiftClick(e, 20); checkRangeText('aaaaaabbbbbbbb', 0); checkText('aaaaaabbbbbbbb', e); checkRanges([[0,1,-1,1]], e); doneTest(e); clear(); e = document.getElementById('testF'); synthesizeMouse(e, 1, 1, {}); synthesizeMouse(e, 400, 100, { shiftKey: true }); checkText("aaaa bbbb", e); checkRanges([[0,0,-1,1],[6,0,6,5]], e); doneTest(e); clear(); e = document.getElementById('testG'); synthesizeMouse(e, 1, 1, {}); synthesizeMouse(e, 400, 180, { shiftKey: true }); checkText("aaaa bbbb", e); // XXX this doesn't seem right - bug 1247799 checkRanges([[0,0,-1,1],[2,0,-1,3],[4,0,-1,5],[6,0,6,5]], e); doneTest(e); clear(); e = document.getElementById('testH'); synthesizeMouse(e, 1, 1, {}); synthesizeMouse(e, 30, 90, { shiftKey: true }); synthesizeMouse(e, 50, 90, { shiftKey: true }); synthesizeMouse(e, 70, 90, { shiftKey: true }); checkText("aaaa bbb", e); checkRanges([[0,0,-1,1],[-1,2,3,4]], e); doneTest(e); // ====================================================== // ==================== Script tests ==================== // ====================================================== clear(); e = document.getElementById('testD'); clear(e.contentWindow); sel = e.contentWindow.getSelection(); sel.selectAllChildren(e.contentDocument.body); is(window.getSelection().rangeCount, 0, "testD: no selection in outer window"); is(sel.toString(), 'aaaacccc', "testD: scripted selection"); is(sel.rangeCount, 1, "testD: scripted selection isn't filtered"); is(sel.getRangeAt(0).toString(), 'aaaabbbbcccc', "testD: scripted selection isn't filtered"); // ====================================================== // ================== Kbd command tests ================= // ====================================================== clear(); e = document.getElementById('testD'); clear(e.contentWindow); e.contentWindow.focus(); synthesizeKey("a", { accelKey:true }, e.contentWindow); sel = e.contentWindow.getSelection(); is(window.getSelection().rangeCount, 0, "testD: no selection in outer window"); is(sel.toString(), 'aaaacccc', "testD: kbd selection"); is(sel.rangeCount, 2, "testD: kbd selection is filtered"); is(sel.getRangeAt(0).toString(), 'aaaa', "testD: kbd selection is filtered"); is(sel.getRangeAt(1).toString(), 'cccc', "testD: kbd selection is filtered"); doneTest(e); clear(); SimpleTest.finish(); } window.onload = function() { setTimeout(test, 0); }; SimpleTest.waitForExplicitFinish(); </script> </pre> </body> </html>