dom/imptests/editing/conformancetest/test_event.html

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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";
    11 var div = document.querySelector("#test");
    12 add_completion_callback(function() { div.parentNode.removeChild(div) });
    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 }
    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 		beforeInputAction: function() {
   101 			getSelection().removeAllRanges();
   102 			var range = document.createRange();
   103 			range.setStart(div.querySelector("div + div").firstChild, 0);
   104 			range.setEnd(div.querySelector("div + div").firstChild, 3);
   105 			getSelection().addRange(range);
   106 		},
   107 		command: "bold",
   108 		value: "",
   109 	},
   110 ];
   112 var commandTests = {
   113 	backColor: ["green"],
   114 	createLink: ["http://www.w3.org/community/editing/"],
   115 	fontName: ["serif", "Helvetica"],
   116 	fontSize: ["6", "15px"],
   117 	foreColor: ["green"],
   118 	hiliteColor: ["green"],
   119 	italic: [],
   120 	removeFormat: [],
   121 	strikeThrough: [],
   122 	subscript: [],
   123 	superscript: [],
   124 	underline: [],
   125 	unlink: [],
   126 	delete: [],
   127 	formatBlock: ["p"],
   128 	forwardDelete: [],
   129 	indent: [],
   130 	insertHorizontalRule: ["id"],
   131 	insertHTML: ["<b>hi</b>"],
   132 	insertImage: ["http://example.com/some-image"],
   133 	insertLineBreak: [],
   134 	insertOrderedList: [],
   135 	insertParagraph: [],
   136 	insertText: ["abc"],
   137 	insertUnorderedList: [],
   138 	justifyCenter: [],
   139 	justifyFull: [],
   140 	justifyLeft: [],
   141 	justifyRight: [],
   142 	outdent: [],
   143 	redo: [],
   144 	selectAll: [],
   145 	styleWithCSS: [],
   146 	undo: [],
   147 	useCSS: [],
   148 };
   150 Object.keys(commandTests).forEach(function(command) {
   151 	commandTests[command] = ["", "quasit"].concat(commandTests[command]);
   152 	commandTests[command].forEach(function(value) {
   153 		tests.push({
   154 			name: "Command " + command + ", value " + format_value(value),
   155 			html: "<div contenteditable>foo<b>bar</b>baz</div>",
   156 			initRange: function(range) {
   157 				range.setStart(div.querySelector("b").firstChild, 0);
   158 				range.setEnd(div.querySelector("b"), 1);
   159 			},
   160 			target: function() {
   161 				return ["redo", "selectAll", "styleWithCSS", "undo", "useCSS"]
   162 					.indexOf(command) == -1 ? div.firstChild : null;
   163 			},
   164 			command: command,
   165 			value: value,
   166 		});
   167 	});
   168 });
   170 tests.forEach(function(obj) {
   171 	[true, false].forEach(function(cancel) {
   172 		// Kill all event handlers first
   173 		var newDiv = div.cloneNode(false);
   174 		div.parentNode.insertBefore(newDiv, div);
   175 		div.parentNode.removeChild(div);
   176 		div = newDiv;
   178 		div.innerHTML = obj.html;
   180 		var originalContents = div.cloneNode(true);
   182 		getSelection().removeAllRanges();
   183 		var range = document.createRange();
   184 		obj.initRange(range);
   185 		getSelection().addRange(range);
   187 		var target = obj.target();
   188 		var finalTarget = "finalTarget" in obj ? obj.finalTarget() : target;
   189 		var command = obj.command;
   190 		var value = obj.value;
   192 		var beforeInputEvents = [];
   193 		var inputEvents = [];
   194 		div.addEventListener("beforeinput", function(e) {
   195 			var copied = copyEvent(e);
   196 			copied.inputEventsLength = inputEvents.length;
   197 			beforeInputEvents.push(copied);
   198 			if (cancel) {
   199 				e.preventDefault();
   200 			}
   201 			if ("beforeInputAction" in obj) {
   202 				obj.beforeInputAction();
   203 			}
   204 		});
   205 		div.addEventListener("input", function(e) { inputEvents.push(copyEvent(e)) });
   207 		// Uncomment this code instead of the execCommand() to make all the
   208 		// tests pass, as a sanity check
   209 		//var e = new Event("beforeinput", {bubbles: true, cancelable: true});
   210 		//e.command = command;
   211 		//e.value = value;
   212 		//var ret = target ? target.dispatchEvent(e) : false;
   213 		//if (ret) {
   214 		//	var e = new Event("input", {bubbles: true});
   215 		//	e.command = command;
   216 		//	e.value = value;
   217 		//	finalTarget.dispatchEvent(e);
   218 		//}
   220 		var exception = null;
   221 		try {
   222 			document.execCommand(command, false, value);
   223 		} catch(e) {
   224 			exception = e;
   225 		}
   227 		test(function() {
   228 			assert_equals(exception, null, "Unexpected exception");
   229 		}, obj.name + ": execCommand() must not throw, "
   230 		+ (cancel ? "canceled" : "uncanceled"));
   232 		test(function() {
   233 			assert_equals(beforeInputEvents.length, target ? 1 : 0,
   234 				"number of beforeinput events fired");
   235 			if (beforeInputEvents.length == 0) {
   236 				assert_equals(inputEvents.length, 0, "number of input events fired");
   237 				return;
   238 			}
   239 			var e = beforeInputEvents[0];
   240 			assert_equals(e.inputEventsLength, 0, "number of input events fired");
   241 			assert_equals(e.type, "beforeinput", "event.type");
   242 			assert_equals(e.target, target, "event.target");
   243 			assert_equals(e.currentTarget, div, "event.currentTarget");
   244 			assert_equals(e.eventPhase, Event.BUBBLING_PHASE, "event.eventPhase");
   245 			assert_equals(e.bubbles, true, "event.bubbles");
   246 			assert_equals(e.cancelable, true, "event.cancelable");
   247 			assert_equals(e.defaultPrevented, false, "event.defaultPrevented");
   248 			assert_equals(e.command, command, "e.command");
   249 			assert_equals(e.value, value, "e.value");
   250 			assert_own_property(window, "EditingBeforeInputEvent",
   251 				"window.EditingBeforeInputEvent must exist");
   252 			assert_equals(Object.getPrototypeOf(e.original),
   253 				EditingBeforeInputEvent.prototype,
   254 				"event prototype");
   255 			assert_true(originalContents.isEqualNode(div),
   256 				"div contents not yet changed");
   257 			assert_equals(e.isTrusted, true, "event.isTrusted");
   258 		}, obj.name + ": beforeinput event, " + (cancel ? "canceled" : "uncanceled"));
   260 		test(function() {
   261 			assert_equals(inputEvents.length, target && !cancel ? 1 : 0,
   262 				"number of input events fired");
   263 			if (!target || cancel) {
   264 				assert_true(originalContents.isEqualNode(div),
   265 					"div contents must not be changed");
   266 				return;
   267 			}
   268 			var e = inputEvents[0];
   269 			assert_equals(e.type, "input", "event.type");
   270 			assert_equals(e.target, finalTarget, "event.target");
   271 			assert_equals(e.currentTarget, div, "event.currentTarget");
   272 			assert_equals(e.eventPhase, Event.BUBBLING_PHASE, "event.eventPhase");
   273 			assert_equals(e.bubbles, true, "event.bubbles");
   274 			assert_equals(e.cancelable, false, "event.cancelable");
   275 			assert_equals(e.defaultPrevented, false, "event.defaultPrevented");
   276 			assert_equals(e.command, command, "e.command");
   277 			assert_equals(e.value, value, "e.value");
   278 			assert_own_property(window, "EditingInputEvent",
   279 				"window.EditingInputEvent must exist");
   280 			assert_equals(Object.getPrototypeOf(e.original),
   281 				EditingInputEvent.prototype,
   282 				"event prototype");
   283 			assert_equals(e.isTrusted, true, "event.isTrusted");
   284 		}, obj.name + ": input event, " + (cancel ? "canceled" : "uncanceled"));
   285 	});
   286 });
   288 // Thanks, Gecko.
   289 document.body.bgColor = "";
   290 </script>

mercurial