tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

event.html (7171B)


      1 <!doctype html>
      2 <title>Editing event tests</title>
      3 <style>body { font-family: serif }</style>
      4 <script src=/resources/testharness.js></script>
      5 <script src=/resources/testharnessreport.js></script>
      6 <div id=test></div>
      7 <div id=log></div>
      8 <script>
      9 "use strict";
     10 
     11 var div = document.querySelector("#test");
     12 add_completion_callback(function() { div.parentNode.removeChild(div) });
     13 
     14 function copyEvent(e) {
     15    var ret = {};
     16    ret.original = e;
     17    ["type", "target", "currentTarget", "eventPhase", "bubbles", "cancelable",
     18    "defaultPrevented", "isTrusted", "command", "value"].forEach(function(k) {
     19        ret[k] = e[k];
     20    });
     21    return ret;
     22 }
     23 
     24 var tests = [
     25    {
     26        name: "Simple editable div",
     27        html: "<div contenteditable>foo<b>bar</b>baz</div>",
     28        initRange: function(range) {
     29            range.setStart(div.querySelector("b").firstChild, 0);
     30            range.setEnd(div.querySelector("b"), 1);
     31        },
     32        target: function() { return div.firstChild },
     33        command: "bold",
     34        value: "",
     35    },
     36    {
     37        name: "Editable b",
     38        html: "foo<b contenteditable>bar</b>baz",
     39        initRange: function(range) {
     40            range.setStart(div.querySelector("b").firstChild, 0);
     41            range.setEnd(div.querySelector("b"), 1);
     42        },
     43        target: function() { return div.querySelector("b") },
     44        command: "bold",
     45        value: "",
     46    },
     47    {
     48        name: "No editable content",
     49        html: "foo<b>bar</b>baz",
     50        initRange: function(range) {
     51            range.setStart(div.querySelector("b").firstChild, 0);
     52            range.setEnd(div.querySelector("b"), 1);
     53        },
     54        target: function() { return null },
     55        command: "bold",
     56        value: "",
     57    },
     58    {
     59        name: "Partially-selected editable content",
     60        html: "foo<b contenteditable>bar</b>baz",
     61        initRange: function(range) {
     62            range.setStart(div.querySelector("b").firstChild, 0);
     63            range.setEnd(div, 3);
     64        },
     65        target: function() { return null },
     66        command: "bold",
     67        value: "",
     68    },
     69    {
     70        name: "Selection spans two editing hosts",
     71        html: "<div contenteditable>foo</div><div contenteditable>bar</div>",
     72        initRange: function(range) {
     73            range.setStart(div.querySelector("div").firstChild, 2);
     74            range.setEnd(div.querySelector("div + div").firstChild, 1);
     75        },
     76        target: function() { return null },
     77        command: "bold",
     78        value: "",
     79    },
     80    {
     81        name: "Selection includes two editing hosts",
     82        html: "foo<div contenteditable>bar</div>baz<div contenteditable>quz</div>qoz",
     83        initRange: function(range) {
     84            range.setStart(div.firstChild, 2);
     85            range.setEnd(div.lastChild, 1);
     86        },
     87        target: function() { return null },
     88        command: "bold",
     89        value: "",
     90    },
     91    {
     92        name: "Changing selection from handler",
     93        html: "<div contenteditable>foo</div><div contenteditable>bar</div>",
     94        initRange: function(range) {
     95            range.setStart(div.querySelector("div").firstChild, 0);
     96            range.setEnd(div.querySelector("div").firstChild, 3);
     97        },
     98        target: function() { return div.firstChild },
     99        finalTarget: function() { return div.lastChild },
    100        command: "bold",
    101        value: "",
    102    },
    103 ];
    104 
    105 var commandTests = {
    106    backColor: ["green"],
    107    createLink: ["http://www.w3.org/community/editing/"],
    108    fontName: ["serif", "Helvetica"],
    109    fontSize: ["6", "15px"],
    110    foreColor: ["green"],
    111    hiliteColor: ["green"],
    112    italic: [],
    113    removeFormat: [],
    114    strikeThrough: [],
    115    subscript: [],
    116    superscript: [],
    117    underline: [],
    118    unlink: [],
    119    delete: [],
    120    formatBlock: ["p"],
    121    forwardDelete: [],
    122    indent: [],
    123    insertHorizontalRule: ["id"],
    124    insertHTML: ["<b>hi</b>"],
    125    insertImage: ["../images/green.png"],
    126    insertLineBreak: [],
    127    insertOrderedList: [],
    128    insertParagraph: [],
    129    insertText: ["abc"],
    130    insertUnorderedList: [],
    131    justifyCenter: [],
    132    justifyFull: [],
    133    justifyLeft: [],
    134    justifyRight: [],
    135    outdent: [],
    136    redo: [],
    137    selectAll: [],
    138    styleWithCSS: [],
    139    undo: [],
    140    useCSS: [],
    141 };
    142 
    143 Object.keys(commandTests).forEach(function(command) {
    144    commandTests[command] = ["", "quasit"].concat(commandTests[command]);
    145    commandTests[command].forEach(function(value) {
    146        tests.push({
    147            name: "Command " + command + ", value " + format_value(value),
    148            html: "<div contenteditable>foo<b>bar</b>baz</div>",
    149            initRange: function(range) {
    150                range.setStart(div.querySelector("b").firstChild, 0);
    151                range.setEnd(div.querySelector("b"), 1);
    152            },
    153            target: function() {
    154                return ["redo", "selectAll", "styleWithCSS", "undo", "useCSS"]
    155                    .indexOf(command) == -1 ? div.firstChild : null;
    156            },
    157            command: command,
    158            value: value,
    159        });
    160    });
    161 });
    162 
    163 tests.forEach(function(obj) {
    164    // Kill all event handlers first
    165    var newDiv = div.cloneNode(false);
    166    div.parentNode.insertBefore(newDiv, div);
    167    div.parentNode.removeChild(div);
    168    div = newDiv;
    169 
    170    div.innerHTML = obj.html;
    171 
    172    var originalContents = div.cloneNode(true);
    173 
    174    getSelection().removeAllRanges();
    175    var range = document.createRange();
    176    obj.initRange(range);
    177    getSelection().addRange(range);
    178 
    179    var target = obj.target();
    180    var finalTarget = "finalTarget" in obj ? obj.finalTarget() : target;
    181    var command = obj.command;
    182    var value = obj.value;
    183 
    184    var inputEvents = [];
    185    div.addEventListener("input", function(e) { inputEvents.push(copyEvent(e)) });
    186 
    187    var exception = null;
    188    try {
    189        document.execCommand(command, false, value);
    190    } catch(e) {
    191        exception = e;
    192    }
    193 
    194    test(function() {
    195        assert_equals(exception, null, "Unexpected exception");
    196    }, obj.name + ": execCommand() must not throw");
    197 
    198    test(function() {
    199        assert_equals(inputEvents.length, target ? 1 : 0,
    200            "number of input events fired");
    201        if (!target) {
    202            assert_true(originalContents.isEqualNode(div),
    203                "div contents must not be changed");
    204            return;
    205        }
    206        var e = inputEvents[0];
    207        assert_equals(e.type, "input", "event.type");
    208        assert_equals(e.target, finalTarget, "event.target");
    209        assert_equals(e.currentTarget, div, "event.currentTarget");
    210        assert_equals(e.eventPhase, Event.BUBBLING_PHASE, "event.eventPhase");
    211        assert_equals(e.bubbles, true, "event.bubbles");
    212        assert_equals(e.cancelable, false, "event.cancelable");
    213        assert_equals(e.defaultPrevented, false, "event.defaultPrevented");
    214        assert_own_property(window, "InputEvent",
    215            "window.InputEvent must exist");
    216        assert_equals(Object.getPrototypeOf(e.original), InputEvent.prototype,
    217            "event prototype");
    218        assert_equals(e.isTrusted, true, "event.isTrusted");
    219    }, obj.name + ": input event");
    220 });
    221 
    222 // Thanks, Gecko.
    223 document.body.bgColor = "";
    224 </script>