import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo

This commit is contained in:
Roy Tam 2018-01-19 03:59:58 +08:00
commit dcd9973243
150858 changed files with 23884658 additions and 0 deletions

View file

@ -0,0 +1,6 @@
@ayg
@jdm
@Ms2ger
@plehegar
@zcorpan
@zqzhang

View file

@ -0,0 +1,13 @@
<!doctype html>
<meta charset=utf-8>
<title>Make sure browsers throw when getting .length on some random object whose proto is an HTMLCollection</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script>
test(function() {
var obj = Object.create(document.getElementsByTagName("script"));
assert_throws(new TypeError(), function() {
obj.length;
});
}, "HTMLcollection as a prototype should not allow getting .length on the base object")
</script>

View file

@ -0,0 +1,65 @@
<!doctype html>
<meta charset=utf-8>
<title>HTMLCollection and empty names</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<div id=log></div>
<div id=test>
<div class=a id></div>
<div class=a name></div>
<a class=a name></a>
</div>
<script>
test(function() {
var c = document.getElementsByTagName("*");
assert_false("" in c, "Empty string should not be in the collection.");
assert_equals(c[""], undefined, "Named getter should return undefined for empty string.");
assert_equals(c.namedItem(""), null, "namedItem should return null for empty string.");
}, "Empty string as a name for Document.getElementsByTagName");
test(function() {
var div = document.getElementById("test");
var c = div.getElementsByTagName("*");
assert_false("" in c, "Empty string should not be in the collection.");
assert_equals(c[""], undefined, "Named getter should return undefined for empty string.");
assert_equals(c.namedItem(""), null, "namedItem should return null for empty string.");
}, "Empty string as a name for Element.getElementsByTagName");
test(function() {
var c = document.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "a");
assert_false("" in c, "Empty string should not be in the collection.");
assert_equals(c[""], undefined, "Named getter should return undefined for empty string.");
assert_equals(c.namedItem(""), null, "namedItem should return null for empty string.");
}, "Empty string as a name for Document.getElementsByTagNameNS");
test(function() {
var div = document.getElementById("test");
var c = div.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "a");
assert_false("" in c, "Empty string should not be in the collection.");
assert_equals(c[""], undefined, "Named getter should return undefined for empty string.");
assert_equals(c.namedItem(""), null, "namedItem should return null for empty string.");
}, "Empty string as a name for Element.getElementsByTagNameNS");
test(function() {
var c = document.getElementsByClassName("a");
assert_false("" in c, "Empty string should not be in the collection.");
assert_equals(c[""], undefined, "Named getter should return undefined for empty string.");
assert_equals(c.namedItem(""), null, "namedItem should return null for empty string.");
}, "Empty string as a name for Document.getElementsByClassName");
test(function() {
var div = document.getElementById("test");
var c = div.getElementsByClassName("a");
assert_false("" in c, "Empty string should not be in the collection.");
assert_equals(c[""], undefined, "Named getter should return undefined for empty string.");
assert_equals(c.namedItem(""), null, "namedItem should return null for empty string.");
}, "Empty string as a name for Element.getElementsByClassName");
test(function() {
var div = document.getElementById("test");
var c = div.children;
assert_false("" in c, "Empty string should not be in the collection.");
assert_equals(c[""], undefined, "Named getter should return undefined for empty string.");
assert_equals(c.namedItem(""), null, "namedItem should return null for empty string.");
}, "Empty string as a name for Element.children");
</script>

View file

@ -0,0 +1,179 @@
<!doctype html>
<meta charset=utf-8>
<title></title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<!-- We want to use a tag name that will not interact with our test harness,
so just make one up. "foo" is a good one -->
<!-- Ids that look like negative indices. These should come first, so we can
assert that lookups for nonnegative indices find these by index -->
<foo id="-2"></foo>
<foo id="-1"></foo>
<!-- Ids that look like nonnegative indices -->
<foo id="0"></foo>
<foo id="1"></foo>
<!-- Ids that look like nonnegative indices near 2^31 = 2147483648 -->
<foo id="2147483645"></foo> <!-- 2^31 - 3 -->
<foo id="2147483646"></foo> <!-- 2^31 - 2 -->
<foo id="2147483647"></foo> <!-- 2^31 - 1 -->
<foo id="2147483648"></foo> <!-- 2^31 -->
<foo id="2147483649"></foo> <!-- 2^31 + 1 -->
<!-- Ids that look like nonnegative indices near 2^32 = 4294967296 -->
<foo id="4294967293"></foo> <!-- 2^32 - 3 -->
<foo id="4294967294"></foo> <!-- 2^32 - 2 -->
<foo id="4294967295"></foo> <!-- 2^32 - 1 -->
<foo id="4294967296"></foo> <!-- 2^32 -->
<foo id="4294967297"></foo> <!-- 2^32 + 1 -->
<script>
test(function() {
var collection = document.getElementsByTagName("foo");
assert_equals(collection.item(-2), null);
assert_equals(collection.item(-1), null);
assert_equals(collection.namedItem(-2), document.getElementById("-2"));
assert_equals(collection.namedItem(-1), document.getElementById("-1"));
assert_equals(collection[-2], document.getElementById("-2"));
assert_equals(collection[-1], document.getElementById("-1"));
}, "Handling of property names that look like negative integers");
test(function() {
var collection = document.getElementsByTagName("foo");
assert_equals(collection.item(0), document.getElementById("-2"));
assert_equals(collection.item(1), document.getElementById("-1"));
assert_equals(collection.namedItem(0), document.getElementById("0"));
assert_equals(collection.namedItem(1), document.getElementById("1"));
assert_equals(collection[0], document.getElementById("-2"));
assert_equals(collection[1], document.getElementById("-1"));
}, "Handling of property names that look like small nonnegative integers");
test(function() {
var collection = document.getElementsByTagName("foo");
assert_equals(collection.item(2147483645), null);
assert_equals(collection.item(2147483646), null);
assert_equals(collection.item(2147483647), null);
assert_equals(collection.item(2147483648), null);
assert_equals(collection.item(2147483649), null);
assert_equals(collection.namedItem(2147483645),
document.getElementById("2147483645"));
assert_equals(collection.namedItem(2147483646),
document.getElementById("2147483646"));
assert_equals(collection.namedItem(2147483647),
document.getElementById("2147483647"));
assert_equals(collection.namedItem(2147483648),
document.getElementById("2147483648"));
assert_equals(collection.namedItem(2147483649),
document.getElementById("2147483649"));
assert_equals(collection[2147483645], undefined);
assert_equals(collection[2147483646], undefined);
assert_equals(collection[2147483647], undefined);
assert_equals(collection[2147483648], undefined);
assert_equals(collection[2147483649], undefined);
}, "Handling of property names that look like integers around 2^31");
test(function() {
var collection = document.getElementsByTagName("foo");
assert_equals(collection.item(4294967293), null);
assert_equals(collection.item(4294967294), null);
assert_equals(collection.item(4294967295), null);
assert_equals(collection.item(4294967296), document.getElementById("-2"));
assert_equals(collection.item(4294967297), document.getElementById("-1"));
assert_equals(collection.namedItem(4294967293),
document.getElementById("4294967293"));
assert_equals(collection.namedItem(4294967294),
document.getElementById("4294967294"));
assert_equals(collection.namedItem(4294967295),
document.getElementById("4294967295"));
assert_equals(collection.namedItem(4294967296),
document.getElementById("4294967296"));
assert_equals(collection.namedItem(4294967297),
document.getElementById("4294967297"));
assert_equals(collection[4294967293], undefined);
assert_equals(collection[4294967294], undefined);
assert_equals(collection[4294967295], document.getElementById("4294967295"));
assert_equals(collection[4294967296], document.getElementById("4294967296"));
assert_equals(collection[4294967297], document.getElementById("4294967297"));
}, "Handling of property names that look like integers around 2^32");
test(function() {
var elements = document.getElementsByTagName("foo");
var old_item = elements[0];
var old_desc = Object.getOwnPropertyDescriptor(elements, 0);
assert_equals(old_desc.value, old_item);
assert_true(old_desc.enumerable);
assert_true(old_desc.configurable);
assert_false(old_desc.writable);
elements[0] = 5;
assert_equals(elements[0], old_item);
assert_throws(new TypeError(), function() {
"use strict";
elements[0] = 5;
});
assert_throws(new TypeError(), function() {
Object.defineProperty(elements, 0, { value: 5 });
});
delete elements[0];
assert_equals(elements[0], old_item);
assert_throws(new TypeError(), function() {
"use strict";
delete elements[0];
});
assert_equals(elements[0], old_item);
}, 'Trying to set an expando that would shadow an already-existing indexed property');
test(function() {
var elements = document.getElementsByTagName("foo");
var idx = elements.length;
var old_item = elements[idx];
var old_desc = Object.getOwnPropertyDescriptor(elements, idx);
assert_equals(old_item, undefined);
assert_equals(old_desc, undefined);
// [[DefineOwnProperty]] will disallow defining an indexed expando.
elements[idx] = 5;
assert_equals(elements[idx], undefined);
assert_throws(new TypeError(), function() {
"use strict";
elements[idx] = 5;
});
assert_throws(new TypeError(), function() {
Object.defineProperty(elements, idx, { value: 5 });
});
// Check that deletions out of range do not throw
delete elements[idx];
(function() {
"use strict";
delete elements[idx];
})();
}, 'Trying to set an expando with an indexed property name past the end of the list');
test(function(){
var elements = document.getElementsByTagName("foo");
var old_item = elements[0];
var old_desc = Object.getOwnPropertyDescriptor(elements, 0);
assert_equals(old_desc.value, old_item);
assert_true(old_desc.enumerable);
assert_true(old_desc.configurable);
assert_false(old_desc.writable);
Object.prototype[0] = 5;
this.add_cleanup(function () { delete Object.prototype[0]; });
assert_equals(elements[0], old_item);
delete elements[0];
assert_equals(elements[0], old_item);
assert_throws(new TypeError(), function() {
"use strict";
delete elements[0];
});
assert_equals(elements[0], old_item);
}, 'Trying to delete an indexed property name should never work');
</script>

View file

@ -0,0 +1,135 @@
<!doctype html>
<meta charset=utf-8>
<link rel=help href=https://dom.spec.whatwg.org/#interface-htmlcollection>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<div id=log></div>
<!-- with no attribute -->
<span></span>
<!-- with `id` attribute -->
<span id=''></span>
<span id='some-id'></span>
<span id='some-id'></span><!-- to ensure no duplicates -->
<!-- with `name` attribute -->
<span name=''></span>
<span name='some-name'></span>
<span name='some-name'></span><!-- to ensure no duplicates -->
<!-- with `name` and `id` attribute -->
<span id='another-id' name='another-name'></span>
<script>
test(function () {
var elements = document.getElementsByTagName("span");
assert_array_equals(
Object.getOwnPropertyNames(elements),
['0', '1', '2', '3', '4', '5', '6', '7', 'some-id', 'some-name', 'another-id', 'another-name']
);
}, 'Object.getOwnPropertyNames on HTMLCollection');
test(function () {
var elem = document.createElementNS('some-random-namespace', 'foo');
this.add_cleanup(function () {elem.remove();});
elem.setAttribute("name", "some-name");
document.body.appendChild(elem);
var elements = document.getElementsByTagName("foo");
assert_array_equals(Object.getOwnPropertyNames(elements), ['0']);
}, 'Object.getOwnPropertyNames on HTMLCollection with non-HTML namespace');
test(function () {
var elem = document.createElement('foo');
this.add_cleanup(function () {elem.remove();});
document.body.appendChild(elem);
var elements = document.getElementsByTagName("foo");
elements.someProperty = "some value";
assert_array_equals(Object.getOwnPropertyNames(elements), ['0', 'someProperty']);
}, 'Object.getOwnPropertyNames on HTMLCollection with expando object');
test(function() {
var elements = document.getElementsByTagName("span");
var old_item = elements["some-id"];
var old_desc = Object.getOwnPropertyDescriptor(elements, "some-id");
assert_equals(old_desc.value, old_item);
assert_false(old_desc.enumerable);
assert_true(old_desc.configurable);
assert_false(old_desc.writable);
elements["some-id"] = 5;
assert_equals(elements["some-id"], old_item);
assert_throws(new TypeError(), function() {
"use strict";
elements["some-id"] = 5;
});
assert_throws(new TypeError(), function() {
Object.defineProperty(elements, "some-id", { value: 5 });
});
delete elements["some-id"];
assert_equals(elements["some-id"], old_item);
assert_throws(new TypeError(), function() {
"use strict";
delete elements["some-id"];
});
assert_equals(elements["some-id"], old_item);
}, 'Trying to set an expando that would shadow an already-existing named property');
test(function() {
var elements = document.getElementsByTagName("span");
var old_item = elements["new-id"];
var old_desc = Object.getOwnPropertyDescriptor(elements, "new-id");
assert_equals(old_item, undefined);
assert_equals(old_desc, undefined);
elements["new-id"] = 5;
assert_equals(elements["new-id"], 5);
var span = document.createElement("span");
this.add_cleanup(function () {span.remove();});
span.id = "new-id";
document.body.appendChild(span);
assert_equals(elements.namedItem("new-id"), span);
assert_equals(elements["new-id"], 5);
delete elements["new-id"];
assert_equals(elements["new-id"], span);
}, 'Trying to set an expando that shadows a named property that gets added later');
test(function() {
var elements = document.getElementsByTagName("span");
var old_item = elements["new-id2"];
var old_desc = Object.getOwnPropertyDescriptor(elements, "new-id2");
assert_equals(old_item, undefined);
assert_equals(old_desc, undefined);
Object.defineProperty(elements, "new-id2", { configurable: false, writable:
false, value: 5 });
assert_equals(elements["new-id2"], 5);
var span = document.createElement("span");
this.add_cleanup(function () {span.remove();});
span.id = "new-id2";
document.body.appendChild(span);
assert_equals(elements.namedItem("new-id2"), span);
assert_equals(elements["new-id2"], 5);
delete elements["new-id2"];
assert_equals(elements["new-id2"], 5);
assert_throws(new TypeError(), function() {
"use strict";
delete elements["new-id2"];
});
assert_equals(elements["new-id2"], 5);
}, 'Trying to set a non-configurable expando that shadows a named property that gets added later');
</script>

View file

@ -0,0 +1,54 @@
<!DOCTYPE HTML>
<meta charset=utf-8>
<title>DOMStringMap Test: Supported property names</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<div id="edge1" data-="012">Simple</div>
<div id="edge2" data-id-="012">Simple</div>
<div id="user" data-id="1234567890" data-user="johndoe" data-date-of-birth>
John Doe
</div>
<div id="user2" data-unique-id="1234567890"> Jane Doe </div>
<div id="user3" data-unique-id="4324324241"> Jim Doe </div>
<script>
test(function() {
var element = document.querySelector('#edge1');
assert_array_equals(Object.getOwnPropertyNames(element.dataset),
[""]);
}, "Object.getOwnPropertyNames on DOMStringMap, empty data attribute");
test(function() {
var element = document.querySelector('#edge2');
assert_array_equals(Object.getOwnPropertyNames(element.dataset),
["id-"]);
}, "Object.getOwnPropertyNames on DOMStringMap, data attribute trailing hyphen");
test(function() {
var element = document.querySelector('#user');
assert_array_equals(Object.getOwnPropertyNames(element.dataset),
['id', 'user', 'dateOfBirth']);
}, "Object.getOwnPropertyNames on DOMStringMap, multiple data attributes");
test(function() {
var element = document.querySelector('#user2');
element.dataset.middleName = "mark";
assert_array_equals(Object.getOwnPropertyNames(element.dataset),
['uniqueId', 'middleName']);
}, "Object.getOwnPropertyNames on DOMStringMap, attribute set on dataset in JS");
test(function() {
var element = document.querySelector('#user3');
element.setAttribute("data-age", 30);
assert_array_equals(Object.getOwnPropertyNames(element.dataset),
['uniqueId', 'age']);
}, "Object.getOwnPropertyNames on DOMStringMap, attribute set on element in JS");
</script>

View file

@ -0,0 +1,30 @@
<!DOCTYPE HTML>
<meta charset=utf-8>
<title>NamedNodeMap Test: Supported property names</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<div id="simple" class="fancy">Simple</div>
<input id="result" type="text" value="" width="200px">
<script>
test(function() {
var elt = document.querySelector('#simple');
assert_array_equals(Object.getOwnPropertyNames(elt.attributes),
['0','1','id','class']);
}, "Object.getOwnPropertyNames on NamedNodeMap");
test(function() {
var result = document.getElementById("result");
assert_array_equals(Object.getOwnPropertyNames(result.attributes),
['0','1','2','3','id','type','value','width']);
}, "Object.getOwnPropertyNames on NamedNodeMap of input");
test(function() {
var result = document.getElementById("result");
result.removeAttribute("width");
assert_array_equals(Object.getOwnPropertyNames(result.attributes),
['0','1','2','id','type','value']);
}, "Object.getOwnPropertyNames on NamedNodeMap after attribute removal");
</script>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,11 @@
function testConstants(objects, constants, msg) {
objects.forEach(function(arr) {
var o = arr[0], desc = arr[1];
test(function() {
constants.forEach(function(d) {
assert_true(d[0] in o, "Object " + o + " doesn't have " + d[0])
assert_equals(o[d[0]], d[1], "Object " + o + " value for " + d[0] + " is wrong")
})
}, "Constants for " + msg + " on " + desc + ".")
})
}

View file

@ -0,0 +1,81 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>AddEventListenerOptions.once</title>
<link rel="author" title="Xidorn Quan" href="https://www.upsuper.org">
<link rel="help" href="https://dom.spec.whatwg.org/#dom-addeventlisteneroptions-once">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
test(function() {
var invoked_once = false;
var invoked_normal = false;
function handler_once() {
invoked_once = true;
}
function handler_normal() {
invoked_normal = true;
}
document.addEventListener('test', handler_once, {once: true});
document.addEventListener('test', handler_normal);
document.dispatchEvent(new Event('test'));
assert_equals(invoked_once, true, "Once handler should be invoked");
assert_equals(invoked_normal, true, "Normal handler should be invoked");
invoked_once = false;
invoked_normal = false;
document.dispatchEvent(new Event('test'));
assert_equals(invoked_once, false, "Once handler shouldn't be invoked again");
assert_equals(invoked_normal, true, "Normal handler should be invoked again");
document.removeEventListener('test', handler_normal);
}, "Once listener should be invoked only once");
test(function() {
var invoked_count = 0;
function handler() {
invoked_count++;
if (invoked_count == 1)
document.dispatchEvent(new Event('test'));
}
document.addEventListener('test', handler, {once: true});
document.dispatchEvent(new Event('test'));
assert_equals(invoked_count, 1, "Once handler should only be invoked once");
invoked_count = 0;
function handler2() {
invoked_count++;
if (invoked_count == 1)
document.addEventListener('test', handler2, {once: true});
if (invoked_count <= 2)
document.dispatchEvent(new Event('test'));
}
document.addEventListener('test', handler2, {once: true});
document.dispatchEvent(new Event('test'));
assert_equals(invoked_count, 2, "Once handler should only be invoked once after each adding");
}, "Once listener should be invoked only once even if the event is nested");
test(function() {
var invoked_count = 0;
function handler() {
invoked_count++;
}
document.addEventListener('test', handler, {once: true});
document.addEventListener('test', handler);
document.dispatchEvent(new Event('test'));
assert_equals(invoked_count, 1, "The handler should only be added once");
invoked_count = 0;
document.dispatchEvent(new Event('test'));
assert_equals(invoked_count, 0, "The handler was added as a once listener");
invoked_count = 0;
document.addEventListener('test', handler, {once: true});
document.removeEventListener('test', handler);
document.dispatchEvent(new Event('test'));
assert_equals(invoked_count, 0, "The handler should have been removed");
}, "Once listener should be added / removed like normal listeners");
</script>

View file

@ -0,0 +1,113 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>EventListenerOptions.passive</title>
<link rel="author" title="Rick Byers" href="mailto:rbyers@chromium.org">
<link rel="help" href="https://dom.spec.whatwg.org/#dom-addeventlisteneroptions-passive">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
test(function() {
var supportsPassive = false;
var query_options = {
get passive() {
supportsPassive = true;
return false;
},
get dummy() {
assert_unreached("dummy value getter invoked");
return false;
}
};
document.addEventListener('test_event', null, query_options);
assert_true(supportsPassive, "addEventListener doesn't support the passive option");
supportsPassive = false;
document.removeEventListener('test_event', null, query_options);
assert_false(supportsPassive, "removeEventListener supports the passive option when it should not");
}, "Supports passive option on addEventListener only");
function testPassiveValue(optionsValue, expectedDefaultPrevented) {
var defaultPrevented = undefined;
var handler = function handler(e) {
assert_false(e.defaultPrevented, "Event prematurely marked defaultPrevented");
e.preventDefault();
defaultPrevented = e.defaultPrevented;
}
document.addEventListener('test', handler, optionsValue);
var uncanceled = document.body.dispatchEvent(new Event('test', {bubbles: true, cancelable: true}));
assert_equals(defaultPrevented, expectedDefaultPrevented, "Incorrect defaultPrevented for options: " + JSON.stringify(optionsValue));
assert_equals(uncanceled, !expectedDefaultPrevented, "Incorrect return value from dispatchEvent");
document.removeEventListener('test', handler, optionsValue);
}
test(function() {
testPassiveValue(undefined, true);
testPassiveValue({}, true);
testPassiveValue({passive: false}, true);
testPassiveValue({passive: true}, false);
testPassiveValue({passive: 0}, true);
testPassiveValue({passive: 1}, false);
}, "preventDefault should be ignored if-and-only-if the passive option is true");
function testPassiveWithOtherHandlers(optionsValue, expectedDefaultPrevented) {
var handlerInvoked1 = false;
var dummyHandler1 = function() {
handlerInvoked1 = true;
};
var handlerInvoked2 = false;
var dummyHandler2 = function() {
handlerInvoked2 = true;
};
document.addEventListener('test', dummyHandler1, {passive:true});
document.addEventListener('test', dummyHandler2);
testPassiveValue(optionsValue, expectedDefaultPrevented);
assert_true(handlerInvoked1, "Extra passive handler not invoked");
assert_true(handlerInvoked2, "Extra non-passive handler not invoked");
document.removeEventListener('test', dummyHandler1);
document.removeEventListener('test', dummyHandler2);
}
test(function() {
testPassiveWithOtherHandlers({}, true);
testPassiveWithOtherHandlers({passive: false}, true);
testPassiveWithOtherHandlers({passive: true}, false);
}, "passive behavior of one listener should be unaffeted by the presence of other listeners");
function testOptionEquivalence(optionValue1, optionValue2, expectedEquality) {
var invocationCount = 0;
var handler = function handler(e) {
invocationCount++;
}
document.addEventListener('test', handler, optionValue1);
document.addEventListener('test', handler, optionValue2);
document.body.dispatchEvent(new Event('test', {bubbles: true}));
assert_equals(invocationCount, expectedEquality ? 1 : 2, "equivalence of options " +
JSON.stringify(optionValue1) + " and " + JSON.stringify(optionValue2));
document.removeEventListener('test', handler, optionValue1);
document.removeEventListener('test', handler, optionValue2);
}
test(function() {
// Sanity check options that should be treated as distinct handlers
testOptionEquivalence({capture:true}, {capture:false, passive:false}, false);
testOptionEquivalence({capture:true}, {passive:true}, false);
// Option values that should be treated as equivalent
testOptionEquivalence({}, {passive:false}, true);
testOptionEquivalence({passive:true}, {passive:false}, true);
testOptionEquivalence(undefined, {passive:true}, true);
testOptionEquivalence({capture: true, passive: false}, {capture: true, passive: true}, true);
}, "Equivalence of option values");
</script>

View file

@ -0,0 +1,19 @@
<!doctype html>
<title>CustomEvent</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
test(function() {
var type = "foo";
var target = document.createElement("div");
target.addEventListener(type, this.step_func(function(evt) {
assert_equals(evt.type, type);
}), true);
var fooEvent = document.createEvent("CustomEvent");
fooEvent.initEvent(type, true, true);
target.dispatchEvent(fooEvent);
});
</script>

View file

@ -0,0 +1,23 @@
<!doctype html>
<title>Event constants</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../constants.js"></script>
<div id="log"></div>
<script>
var objects;
setup(function() {
objects = [
[Event, "Event interface object"],
[Event.prototype, "Event prototype object"],
[document.createEvent("Event"), "Event object"],
[document.createEvent("CustomEvent"), "CustomEvent object"]
]
})
testConstants(objects, [
["NONE", 0],
["CAPTURING_PHASE", 1],
["AT_TARGET", 2],
["BUBBLING_PHASE", 3]
], "eventPhase")
</script>

View file

@ -0,0 +1,115 @@
<!doctype html>
<title>Event constructors</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<div id=log></div>
<script>
test(function() {
assert_throws(new TypeError(), function() {
new Event()
})
})
test(function() {
var test_error = { name: "test" }
assert_throws(test_error, function() {
new Event({ toString: function() { throw test_error; } })
})
})
test(function() {
var ev = new Event("")
assert_equals(ev.type, "")
assert_equals(ev.target, null)
assert_equals(ev.currentTarget, null)
assert_equals(ev.eventPhase, Event.NONE)
assert_equals(ev.bubbles, false)
assert_equals(ev.cancelable, false)
assert_equals(ev.defaultPrevented, false)
assert_equals(ev.isTrusted, false)
assert_true(ev.timeStamp > 0)
assert_true("initEvent" in ev)
})
test(function() {
var ev = new Event("test")
assert_equals(ev.type, "test")
assert_equals(ev.target, null)
assert_equals(ev.currentTarget, null)
assert_equals(ev.eventPhase, Event.NONE)
assert_equals(ev.bubbles, false)
assert_equals(ev.cancelable, false)
assert_equals(ev.defaultPrevented, false)
assert_equals(ev.isTrusted, false)
assert_true(ev.timeStamp > 0)
assert_true("initEvent" in ev)
})
test(function() {
assert_throws(new TypeError(), function() { Event("test") },
'Calling Event constructor without "new" must throw');
})
test(function() {
var ev = new Event("I am an event", { bubbles: true, cancelable: false})
assert_equals(ev.type, "I am an event")
assert_equals(ev.bubbles, true)
assert_equals(ev.cancelable, false)
})
test(function() {
var ev = new Event("@", { bubblesIGNORED: true, cancelable: true})
assert_equals(ev.type, "@")
assert_equals(ev.bubbles, false)
assert_equals(ev.cancelable, true)
})
test(function() {
var ev = new Event("@", { "bubbles\0IGNORED": true, cancelable: true})
assert_equals(ev.type, "@")
assert_equals(ev.bubbles, false)
assert_equals(ev.cancelable, true)
})
test(function() {
var ev = new Event("Xx", { cancelable: true})
assert_equals(ev.type, "Xx")
assert_equals(ev.bubbles, false)
assert_equals(ev.cancelable, true)
})
test(function() {
var ev = new Event("Xx", {})
assert_equals(ev.type, "Xx")
assert_equals(ev.bubbles, false)
assert_equals(ev.cancelable, false)
})
test(function() {
var ev = new Event("Xx", {bubbles: true, cancelable: false, sweet: "x"})
assert_equals(ev.type, "Xx")
assert_equals(ev.bubbles, true)
assert_equals(ev.cancelable, false)
assert_equals(ev.sweet, undefined)
})
test(function() {
var called = []
var ev = new Event("Xx", {
get cancelable() {
called.push("cancelable")
return false
},
get bubbles() {
called.push("bubbles")
return true;
},
get sweet() {
called.push("sweet")
return "x"
}
})
assert_array_equals(called, ["bubbles", "cancelable"])
assert_equals(ev.type, "Xx")
assert_equals(ev.bubbles, true)
assert_equals(ev.cancelable, false)
assert_equals(ev.sweet, undefined)
})
test(function() {
var ev = new CustomEvent("$", {detail: 54, sweet: "x", sweet2: "x", cancelable:true})
assert_equals(ev.type, "$")
assert_equals(ev.bubbles, false)
assert_equals(ev.cancelable, true)
assert_equals(ev.sweet, undefined)
assert_equals(ev.detail, 54)
})
</script>

View file

@ -0,0 +1,26 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>Event.defaultPrevented is not reset after dipatchEvent()</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<div id=log></div>
<input id="target" type="hidden" value=""/>
<script>
test(function() {
var EVENT = "foo";
var TARGET = document.getElementById("target");
var evt = document.createEvent("Event");
evt.initEvent(EVENT, true, true);
TARGET.addEventListener(EVENT, this.step_func(function(e) {
e.preventDefault();
assert_true(e.defaultPrevented, "during dispatch");
}), true);
TARGET.dispatchEvent(evt);
assert_true(evt.defaultPrevented, "after dispatch");
assert_equals(evt.target, TARGET);
});
</script>

View file

@ -0,0 +1,42 @@
<!doctype html>
<title>Event.defaultPrevented</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
var ev;
test(function() {
ev = document.createEvent("Event");
assert_equals(ev.defaultPrevented, false, "defaultPrevented");
}, "When an event is created, defaultPrevented should be initialized to false.");
test(function() {
ev.initEvent("foo", true, false);
assert_equals(ev.bubbles, true, "bubbles");
assert_equals(ev.cancelable, false, "cancelable");
assert_equals(ev.defaultPrevented, false, "defaultPrevented");
}, "initEvent should work correctly (not cancelable).");
test(function() {
assert_equals(ev.cancelable, false, "cancelable (before)");
ev.preventDefault();
assert_equals(ev.cancelable, false, "cancelable (after)");
assert_equals(ev.defaultPrevented, false, "defaultPrevented");
}, "preventDefault() should not change defaultPrevented if cancelable is false.");
test(function() {
ev.initEvent("foo", true, true);
assert_equals(ev.bubbles, true, "bubbles");
assert_equals(ev.cancelable, true, "cancelable");
assert_equals(ev.defaultPrevented, false, "defaultPrevented");
}, "initEvent should work correctly (cancelable).");
test(function() {
assert_equals(ev.cancelable, true, "cancelable (before)");
ev.preventDefault();
assert_equals(ev.cancelable, true, "cancelable (after)");
assert_equals(ev.defaultPrevented, true, "defaultPrevented");
}, "preventDefault() should change defaultPrevented if cancelable is true.");
test(function() {
ev.initEvent("foo", true, true);
assert_equals(ev.bubbles, true, "bubbles");
assert_equals(ev.cancelable, true, "cancelable");
assert_equals(ev.defaultPrevented, false, "defaultPrevented");
}, "initEvent should unset defaultPrevented.");
</script>

View file

@ -0,0 +1,98 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title> Event.bubbles attribute is set to false </title>
<link rel="help" href="https://dom.spec.whatwg.org/#dom-event-initevent">
<link rel="help" href="https://dom.spec.whatwg.org/#concept-event-dispatch">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
function targetsForDocumentChain(document) {
return [
document,
document.documentElement,
document.getElementsByTagName("body")[0],
document.getElementById("table"),
document.getElementById("table-body"),
document.getElementById("parent")
];
}
function testChain(document, targetParents, phases, event_type) {
var target = document.getElementById("target");
var targets = targetParents.concat(target);
var expected_targets = targets.concat(target);
var actual_targets = [], actual_phases = [];
var test_event = function(evt) {
actual_targets.push(evt.currentTarget);
actual_phases.push(evt.eventPhase);
}
for (var i = 0; i < targets.length; i++) {
targets[i].addEventListener(event_type, test_event, true);
targets[i].addEventListener(event_type, test_event, false);
}
var evt = document.createEvent("Event");
evt.initEvent(event_type, false, true);
target.dispatchEvent(evt);
assert_array_equals(actual_targets, expected_targets, "targets");
assert_array_equals(actual_phases, phases, "phases");
}
var phasesForDocumentChain = [
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.AT_TARGET,
Event.AT_TARGET,
];
test(function () {
var chainWithWindow = [window].concat(targetsForDocumentChain(document));
testChain(
document, chainWithWindow, [Event.CAPTURING_PHASE].concat(phasesForDocumentChain), "click");
}, "In window.document with click event");
test(function () {
testChain(document, targetsForDocumentChain(document), phasesForDocumentChain, "load");
}, "In window.document with load event")
test(function () {
var documentClone = document.cloneNode(true);
testChain(
documentClone, targetsForDocumentChain(documentClone), phasesForDocumentChain, "click");
}, "In window.document.cloneNode(true)");
test(function () {
var newDocument = new Document();
newDocument.appendChild(document.documentElement.cloneNode(true));
testChain(
newDocument, targetsForDocumentChain(newDocument), phasesForDocumentChain, "click");
}, "In new Document()");
test(function () {
var HTMLDocument = document.implementation.createHTMLDocument();
HTMLDocument.body.appendChild(document.getElementById("table").cloneNode(true));
testChain(
HTMLDocument, targetsForDocumentChain(HTMLDocument), phasesForDocumentChain, "click");
}, "In DOMImplementation.createHTMLDocument()");
</script>

View file

@ -0,0 +1,108 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title> Event.bubbles attribute is set to false </title>
<link rel="help" href="https://dom.spec.whatwg.org/#dom-event-initevent">
<link rel="help" href="https://dom.spec.whatwg.org/#concept-event-dispatch">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
function concatReverse(a) {
return a.concat(a.map(function(x) { return x }).reverse());
}
function targetsForDocumentChain(document) {
return [
document,
document.documentElement,
document.getElementsByTagName("body")[0],
document.getElementById("table"),
document.getElementById("table-body"),
document.getElementById("parent")
];
}
function testChain(document, targetParents, phases, event_type) {
var target = document.getElementById("target");
var targets = targetParents.concat(target);
var expected_targets = concatReverse(targets);
var actual_targets = [], actual_phases = [];
var test_event = function(evt) {
actual_targets.push(evt.currentTarget);
actual_phases.push(evt.eventPhase);
}
for (var i = 0; i < targets.length; i++) {
targets[i].addEventListener(event_type, test_event, true);
targets[i].addEventListener(event_type, test_event, false);
}
var evt = document.createEvent("Event");
evt.initEvent(event_type, true, true);
target.dispatchEvent(evt);
assert_array_equals(actual_targets, expected_targets, "targets");
assert_array_equals(actual_phases, phases, "phases");
}
var phasesForDocumentChain = [
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.AT_TARGET,
Event.AT_TARGET,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
];
test(function () {
var chainWithWindow = [window].concat(targetsForDocumentChain(document));
var phases = [Event.CAPTURING_PHASE].concat(phasesForDocumentChain, Event.BUBBLING_PHASE);
testChain(document, chainWithWindow, phases, "click");
}, "In window.document with click event");
test(function () {
testChain(document, targetsForDocumentChain(document), phasesForDocumentChain, "load");
}, "In window.document with load event")
test(function () {
var documentClone = document.cloneNode(true);
testChain(
documentClone, targetsForDocumentChain(documentClone), phasesForDocumentChain, "click");
}, "In window.document.cloneNode(true)");
test(function () {
var newDocument = new Document();
newDocument.appendChild(document.documentElement.cloneNode(true));
testChain(
newDocument, targetsForDocumentChain(newDocument), phasesForDocumentChain, "click");
}, "In new Document()");
test(function () {
var HTMLDocument = document.implementation.createHTMLDocument();
HTMLDocument.body.appendChild(document.getElementById("table").cloneNode(true));
testChain(
HTMLDocument, targetsForDocumentChain(HTMLDocument), phasesForDocumentChain, "click");
}, "In DOMImplementation.createHTMLDocument()");
</script>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<title>Click event on an element not in the document</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
test(function() {
var EVENT = "click";
var TARGET = document.createElement("somerandomelement");
var t = async_test("Click event can be dispatched to an element that is not in the document.")
TARGET.addEventListener(EVENT, t.step_func(function(evt) {
assert_equals(evt.target, TARGET);
t.done();
}), true);
var e = document.createEvent("Event");
e.initEvent(EVENT, true, true);
TARGET.dispatchEvent(e);
});
</script>

View file

@ -0,0 +1,92 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title> Dispatch additional events inside an event listener </title>
<link rel="help" href="https://dom.spec.whatwg.org/#concept-event-dispatch">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
async_test(function() {
var event_type = "bar";
var target = document.getElementById("target");
var parent = document.getElementById("parent");
var tbody = document.getElementById("table-body");
var table = document.getElementById("table");
var body = document.body;
var html = document.documentElement;
var targets = [window, document, html, body, table, tbody, parent, target];
var expected_targets = [
window,
document,
html,
body,
table,
tbody,
parent,
target,
target,
parent,
tbody,
table,
body,
html,
document,
window
];
var expected_listeners = [0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1];
var actual_targets = [], actual_listeners = [];
var test_event_function = function(i) {
return this.step_func(function(evt) {
actual_targets.push(evt.currentTarget);
actual_listeners.push(i);
if (evt.eventPhase != evt.BUBBLING_PHASE && evt.currentTarget.foo != 1) {
evt.currentTarget.removeEventListener(event_type, event_handlers[0], true);
evt.currentTarget.addEventListener(event_type, event_handlers[2], true);
evt.currentTarget.foo = 1;
}
if (evt.eventPhase != evt.CAPTURING_PHASE && evt.currentTarget.foo != 3) {
evt.currentTarget.removeEventListener(event_type, event_handlers[0], false);
evt.currentTarget.addEventListener(event_type, event_handlers[3], false);
evt.currentTarget.foo = 3;
}
});
}.bind(this);
var event_handlers = [
test_event_function(0),
test_event_function(1),
test_event_function(2),
test_event_function(3),
];
for (var i = 0; i < targets.length; ++i) {
targets[i].addEventListener(event_type, event_handlers[0], true);
targets[i].addEventListener(event_type, event_handlers[1], false);
}
var evt = document.createEvent("Event");
evt.initEvent(event_type, true, true);
target.dispatchEvent(evt);
assert_array_equals(actual_targets, expected_targets, "actual_targets");
assert_array_equals(actual_listeners, expected_listeners, "actual_listeners");
this.done();
});
</script>

View file

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html>
<head>
<title> Multiple dispatchEvent() and stopPropagation() </title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<div id=log></div>
<div id="parent" style="display: none">
<input id="target" type="hidden" value=""/>
</div>
<script>
test(function() {
var event_type = "foo";
var target = document.getElementById("target");
var parent = document.getElementById("parent");
var actual_result;
var test_event = function(evt) {
actual_result.push(evt.currentTarget);
if (parent == evt.currentTarget) {
evt.stopPropagation();
}
};
var evt = document.createEvent("Event");
evt.initEvent(event_type, true, true);
target.addEventListener(event_type, test_event, false);
parent.addEventListener(event_type, test_event, false);
document.addEventListener(event_type, test_event, false);
window.addEventListener(event_type, test_event, false);
actual_result = [];
target.dispatchEvent(evt);
assert_array_equals(actual_result, [target, parent]);
actual_result = [];
parent.dispatchEvent(evt);
assert_array_equals(actual_result, [parent]);
actual_result = [];
document.dispatchEvent(evt);
assert_array_equals(actual_result, [document, window]);
});
</script>
</body>
</html>

View file

@ -0,0 +1,70 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>EventTarget.addEventListener: capture argument omitted</title>
<link rel="help" href="https://dom.spec.whatwg.org/#dom-eventtarget-addeventlistener">
<link rel="help" href="https://dom.spec.whatwg.org/#concept-event-dispatch">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
test(function() {
var event_type = "foo";
var target = document.getElementById("target");
var targets = [
target,
document.getElementById("parent"),
document.getElementById("table-body"),
document.getElementById("table"),
document.body,
document.documentElement,
document,
window
];
var phases = [
Event.AT_TARGET,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE
];
var actual_targets = [], actual_phases = [];
var test_event = function(evt) {
actual_targets.push(evt.currentTarget);
actual_phases.push(evt.eventPhase);
}
for (var i = 0; i < targets.length; i++) {
targets[i].addEventListener(event_type, test_event);
}
var evt = document.createEvent("Event");
evt.initEvent(event_type, true, true);
target.dispatchEvent(evt);
for (var i = 0; i < targets.length; i++) {
targets[i].removeEventListener(event_type, test_event);
}
target.dispatchEvent(evt);
assert_array_equals(actual_targets, targets, "targets");
assert_array_equals(actual_phases, phases, "phases");
}, "EventTarget.addEventListener with the capture argument omitted");
</script>

View file

@ -0,0 +1,26 @@
<!DOCTYPE html>
<title>Event phases order</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
async_test(function() {
document.addEventListener('DOMContentLoaded', this.step_func_done(function() {
var parent = document.getElementById('parent');
var child = document.getElementById('child');
var order = [];
parent.addEventListener('click', this.step_func(function(){ order.push(1) }), true);
child.addEventListener('click', this.step_func(function(){ order.push(2) }), false);
parent.addEventListener('click', this.step_func(function(){ order.push(3) }), false);
child.dispatchEvent(new Event('click', {bubbles: true}));
assert_array_equals(order, [1, 2, 3]);
}));
}, "Event phases order");
</script>
<div id="parent">
<div id="child"></div>
</div>

View file

@ -0,0 +1,22 @@
<!doctype html>
<title>Custom event on an element in another document</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
test(function() {
var doc = document.implementation.createHTMLDocument("Demo");
var element = doc.createElement("div");
var called = false;
element.addEventListener("foo", this.step_func(function(ev) {
assert_false(called);
called = true;
assert_equals(ev.target, element);
}));
doc.body.appendChild(element);
var event = new Event("foo");
element.dispatchEvent(event);
assert_true(called);
});
</script>

View file

@ -0,0 +1,59 @@
<!DOCTYPE html>
<html>
<head>
<title> Calling stopPropagation() prior to dispatchEvent() </title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
test(function() {
var event = "foo";
var target = document.getElementById("target");
var parent = document.getElementById("parent");
var tbody = document.getElementById("table-body");
var table = document.getElementById("table");
var body = document.body;
var html = document.documentElement;
var current_targets = [window, document, html, body, table, tbody, parent, target];
var expected_targets = [];
var actual_targets = [];
var expected_phases = [];
var actual_phases = [];
var test_event = function(evt) {
actual_targets.push(evt.currentTarget);
actual_phases.push(evt.eventPhase);
};
for (var i = 0; i < current_targets.length; ++i) {
current_targets[i].addEventListener(event, test_event, true);
current_targets[i].addEventListener(event, test_event, false);
}
var evt = document.createEvent("Event");
evt.initEvent(event, true, true);
evt.stopPropagation();
target.dispatchEvent(evt);
assert_array_equals(actual_targets, expected_targets, "actual_targets");
assert_array_equals(actual_phases, expected_phases, "actual_phases");
});
</script>
</body>
</html>

View file

@ -0,0 +1,28 @@
<!DOCTYPE html>
<meta charset=urf-8>
<title>EventTarget#dispatchEvent(): redispatching a native event</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
async_test(function() {
var event;
document.addEventListener("DOMContentLoaded", this.step_func(function(e) {
assert_true(e.isTrusted, "Should be trusted when first handled");
event = e;
}), true);
window.onload = this.step_func_done(function() {
var received = 0;
var target = document.createElement("span");
target.addEventListener("DOMContentLoaded", this.step_func(function(e) {
assert_false(e.isTrusted, "Should not be trusted during redispatching");
++received;
}), true);
assert_true(event.isTrusted, "Should be trusted before redispatching");
target.dispatchEvent(event);
assert_false(event.isTrusted, "Should not be trusted after redispatching");
assert_equals(received, 1);
});
});
</script>

View file

@ -0,0 +1,66 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title> Dispatch additional events inside an event listener </title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
test(function() {
var event_type = "foo";
var target = document.getElementById("target");
var parent = document.getElementById("parent");
var tbody = document.getElementById("table-body");
var table = document.getElementById("table");
var body = document.body;
var html = document.documentElement;
var targets = [window, document, html, body, table, tbody, parent, target];
var expected_targets = [
window, document, html, body, table,
target, parent, tbody,
table, body, html, document, window,
tbody, parent, target];
var actual_targets = [];
var expected_types = [
"foo", "foo", "foo", "foo", "foo",
"bar", "bar", "bar",
"bar", "bar", "bar", "bar", "bar",
"foo", "foo", "foo"
];
var actual_targets = [], actual_types = [];
var test_event = this.step_func(function(evt) {
actual_targets.push(evt.currentTarget);
actual_types.push(evt.type);
if (table == evt.currentTarget && event_type == evt.type) {
var e = document.createEvent("Event");
e.initEvent("bar", true, true);
target.dispatchEvent(e);
}
});
for (var i = 0; i < targets.length; ++i) {
targets[i].addEventListener(event_type, test_event, true);
targets[i].addEventListener("bar", test_event, false);
}
var evt = document.createEvent("Event");
evt.initEvent(event_type, false, true);
target.dispatchEvent(evt);
assert_array_equals(actual_targets, expected_targets, "actual_targets");
assert_array_equals(actual_types, expected_types, "actual_types");
});
</script>

View file

@ -0,0 +1,73 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title> Determined event propagation path - target moved </title>
<link rel="help" href="https://dom.spec.whatwg.org/#concept-event-dispatch">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
test(function() {
var event_type = "foo";
var target = document.getElementById("target");
var parent = document.getElementById("parent");
var tbody = document.getElementById("table-body");
var table = document.getElementById("table");
var body = document.body;
var html = document.documentElement;
var targets = [window, document, html, body, table, tbody, parent, target];
var expected_targets = targets.concat([target, parent, tbody, table, body, html, document, window]);
var phases = [
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.AT_TARGET,
Event.AT_TARGET,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
];
var actual_targets = [], actual_phases = [];
var test_event = this.step_func(function(evt) {
if (parent === target.parentNode) {
var table_row = document.getElementById("table-row");
table_row.appendChild(parent.removeChild(target));
}
actual_targets.push(evt.currentTarget);
actual_phases.push(evt.eventPhase);
});
for (var i = 0; i < targets.length; i++) {
targets[i].addEventListener(event_type, test_event, true);
targets[i].addEventListener(event_type, test_event, false);
}
var evt = document.createEvent("Event");
evt.initEvent(event_type, true, true);
target.dispatchEvent(evt);
assert_array_equals(actual_targets, expected_targets, "targets");
assert_array_equals(actual_phases, phases, "phases");
}, "Event propagation path when an element in it is moved within the DOM");
</script>

View file

@ -0,0 +1,72 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>Determined event propagation path - target removed</title>
<link rel="help" href="https://dom.spec.whatwg.org/#concept-event-dispatch">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
test(function() {
var event_type = "foo";
var target = document.getElementById("target");
var parent = document.getElementById("parent");
var tbody = document.getElementById("table-body");
var table = document.getElementById("table");
var body = document.body;
var html = document.documentElement;
var targets = [window, document, html, body, table, tbody, parent, target];
var expected_targets = targets.concat([target, parent, tbody, table, body, html, document, window]);
var phases = [
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.AT_TARGET,
Event.AT_TARGET,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
];
var actual_targets = [], actual_phases = [];
var test_event = this.step_func(function(evt) {
if (parent === target.parentNode) {
parent.removeChild(target);
}
actual_targets.push(evt.currentTarget);
actual_phases.push(evt.eventPhase);
});
for (var i = 0; i < targets.length; i++) {
targets[i].addEventListener(event_type, test_event, true);
targets[i].addEventListener(event_type, test_event, false);
}
var evt = document.createEvent("Event");
evt.initEvent(event_type, true, true);
target.dispatchEvent(evt);
assert_array_equals(actual_targets, expected_targets, "targets");
assert_array_equals(actual_phases, phases, "phases");
}, "Event propagation path when an element in it is removed from the DOM");
</script>

View file

@ -0,0 +1,51 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>Throwing in event listeners</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
setup({allow_uncaught_exception:true})
test(function() {
var errorEvents = 0;
window.onerror = this.step_func(function(e) {
assert_equals(typeof e, 'string');
++errorEvents;
});
var element = document.createElement('div');
element.addEventListener('click', function() {
throw new Error('Error from only listener');
});
element.dispatchEvent(new Event('click'));
assert_equals(errorEvents, 1);
}, "Throwing in event listener with a single listeners");
test(function() {
var errorEvents = 0;
window.onerror = this.step_func(function(e) {
assert_equals(typeof e, 'string');
++errorEvents;
});
var element = document.createElement('div');
var secondCalled = false;
element.addEventListener('click', function() {
throw new Error('Error from first listener');
});
element.addEventListener('click', this.step_func(function() {
secondCalled = true;
}), false);
element.dispatchEvent(new Event('click'));
assert_equals(errorEvents, 1);
assert_true(secondCalled);
}, "Throwing in event listener with multiple listeners");
</script>

View file

@ -0,0 +1,83 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Re-initializing events while dispatching them</title>
<link rel="author" title="Josh Matthews" href="mailto:josh@joshmatthews.net">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
var events = {
'KeyboardEvent': {
'constructor': function() { return new KeyboardEvent("type", {key: "A"}); },
'init': function(ev) { ev.initKeyboardEvent("type2", true, true, null, "a", 1, "", true, "") },
'check': function(ev) {
assert_equals(ev.key, "A", "initKeyboardEvent key setter should short-circuit");
assert_false(ev.repeat, "initKeyboardEvent repeat setter should short-circuit");
assert_equals(ev.location, 0, "initKeyboardEvent location setter should short-circuit");
}
},
'MouseEvent': {
'constructor': function() { return new MouseEvent("type"); },
'init': function(ev) { ev.initMouseEvent("type2", true, true, null, 0, 1, 1, 1, 1, true, true, true, true, 1, null) },
'check': function(ev) {
assert_equals(ev.screenX, 0, "initMouseEvent screenX setter should short-circuit");
assert_equals(ev.screenY, 0, "initMouseEvent screenY setter should short-circuit");
assert_equals(ev.clientX, 0, "initMouseEvent clientX setter should short-circuit");
assert_equals(ev.clientY, 0, "initMouseEvent clientY setter should short-circuit");
assert_false(ev.ctrlKey, "initMouseEvent ctrlKey setter should short-circuit");
assert_false(ev.altKey, "initMouseEvent altKey setter should short-circuit");
assert_false(ev.shiftKey, "initMouseEvent shiftKey setter should short-circuit");
assert_false(ev.metaKey, "initMouseEvent metaKey setter should short-circuit");
assert_equals(ev.button, 0, "initMouseEvent button setter should short-circuit");
}
},
'CustomEvent': {
'constructor': function() { return new CustomEvent("type") },
'init': function(ev) { ev.initCustomEvent("type2", true, true, 1) },
'check': function(ev) {
assert_equals(ev.detail, null, "initCustomEvent detail setter should short-circuit");
}
},
'UIEvent': {
'constructor': function() { return new UIEvent("type") },
'init': function(ev) { ev.initUIEvent("type2", true, true, window, 1) },
'check': function(ev) {
assert_equals(ev.view, null, "initUIEvent view setter should short-circuit");
assert_equals(ev.detail, 0, "initUIEvent detail setter should short-circuit");
}
},
'Event': {
'constructor': function() { return new Event("type") },
'init': function(ev) { ev.initEvent("type2", true, true) },
'check': function(ev) {
assert_equals(ev.bubbles, false, "initEvent bubbles setter should short-circuit");
assert_equals(ev.cancelable, false, "initEvent cancelable setter should short-circuit");
assert_equals(ev.type, "type", "initEvent type setter should short-circuit");
}
}
};
var names = Object.keys(events);
for (var i = 0; i < names.length; i++) {
var t = async_test("Calling init" + names[i] + " while dispatching.");
t.step(function() {
var e = events[names[i]].constructor();
var target = document.createElement("div")
target.addEventListener("type", t.step_func(function() {
events[names[i]].init(e);
var o = e;
while ((o = Object.getPrototypeOf(o))) {
if (!(o.constructor.name in events)) {
break;
}
events[o.constructor.name].check(e);
}
}), false);
assert_equals(target.dispatchEvent(e), true, "dispatchEvent must return true")
});
t.done();
}
</script>

View file

@ -0,0 +1,118 @@
<!DOCTYPE html>
<title>Event.initEvent</title>
<link rel="author" title="Ms2ger" href="mailto:Ms2ger@gmail.com">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
var booleans = [true, false];
booleans.forEach(function(bubbles) {
booleans.forEach(function(cancelable) {
test(function() {
var e = document.createEvent("Event")
e.initEvent("type", bubbles, cancelable)
// Step 3.
// Stop (immediate) propagation flag is tested later
assert_equals(e.defaultPrevented, false, "defaultPrevented")
// Step 4.
assert_equals(e.isTrusted, false, "isTrusted")
// Step 5.
assert_equals(e.target, null, "target")
// Step 6.
assert_equals(e.type, "type", "type")
// Step 7.
assert_equals(e.bubbles, bubbles, "bubbles")
// Step 8.
assert_equals(e.cancelable, cancelable, "cancelable")
}, "Properties of initEvent(type, " + bubbles + ", " + cancelable + ")")
})
})
test(function() {
var e = document.createEvent("Event")
e.initEvent("type 1", true, false)
assert_equals(e.type, "type 1", "type (first init)")
assert_equals(e.bubbles, true, "bubbles (first init)")
assert_equals(e.cancelable, false, "cancelable (first init)")
e.initEvent("type 2", false, true)
assert_equals(e.type, "type 2", "type (second init)")
assert_equals(e.bubbles, false, "bubbles (second init)")
assert_equals(e.cancelable, true, "cancelable (second init)")
}, "Calling initEvent multiple times (getting type).")
test(function() {
// https://bugzilla.mozilla.org/show_bug.cgi?id=998809
var e = document.createEvent("Event")
e.initEvent("type 1", true, false)
assert_equals(e.bubbles, true, "bubbles (first init)")
assert_equals(e.cancelable, false, "cancelable (first init)")
e.initEvent("type 2", false, true)
assert_equals(e.type, "type 2", "type (second init)")
assert_equals(e.bubbles, false, "bubbles (second init)")
assert_equals(e.cancelable, true, "cancelable (second init)")
}, "Calling initEvent multiple times (not getting type).")
// Step 2.
async_test(function() {
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=17715
var e = document.createEvent("Event")
e.initEvent("type", false, false)
assert_equals(e.type, "type", "type (first init)")
assert_equals(e.bubbles, false, "bubbles (first init)")
assert_equals(e.cancelable, false, "cancelable (first init)")
var target = document.createElement("div")
target.addEventListener("type", this.step_func(function() {
e.initEvent("fail", true, true)
assert_equals(e.type, "type", "type (second init)")
assert_equals(e.bubbles, false, "bubbles (second init)")
assert_equals(e.cancelable, false, "cancelable (second init)")
}), false)
assert_equals(target.dispatchEvent(e), true, "dispatchEvent must return true")
this.done()
}, "Calling initEvent must not have an effect during dispatching.")
test(function() {
var e = document.createEvent("Event")
e.stopPropagation()
e.initEvent("type", false, false)
var target = document.createElement("div")
var called = false
target.addEventListener("type", function() { called = true }, false)
assert_true(target.dispatchEvent(e), "dispatchEvent must return true")
assert_true(called, "Listener must be called")
}, "Calling initEvent must unset the stop propagation flag.")
test(function() {
var e = document.createEvent("Event")
e.stopImmediatePropagation()
e.initEvent("type", false, false)
var target = document.createElement("div")
var called = false
target.addEventListener("type", function() { called = true }, false)
assert_true(target.dispatchEvent(e), "dispatchEvent must return true")
assert_true(called, "Listener must be called")
}, "Calling initEvent must unset the stop immediate propagation flag.")
async_test(function() {
var e = document.createEvent("Event")
e.initEvent("type", false, false)
var target = document.createElement("div")
target.addEventListener("type", this.step_func(function() {
e.initEvent("type2", true, true);
assert_equals(e.type, "type", "initEvent type setter should short-circuit");
assert_false(e.bubbles, "initEvent bubbles setter should short-circuit");
assert_false(e.cancelable, "initEvent cancelable setter should short-circuit");
}), false)
assert_equals(target.dispatchEvent(e), true, "dispatchEvent must return true")
this.done()
}, "Calling initEvent during propagation.")
</script>

View file

@ -0,0 +1,41 @@
<!doctype html>
<title>Event propagation tests</title>
<link rel=author title="Aryeh Gregor" href=ayg@aryeh.name>
<div id=log></div>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script>
"use strict";
function testPropagationFlag(ev, expected, desc) {
test(function() {
var called = false;
var callback = function() { called = true };
this.add_cleanup(function() {
document.head.removeEventListener("foo", callback)
});
document.head.addEventListener("foo", callback);
document.head.dispatchEvent(ev);
assert_equals(called, expected, "Propagation flag");
// dispatchEvent resets the propagation flags so it will happily dispatch
// the event the second time around.
document.head.dispatchEvent(ev);
assert_equals(called, true, "Propagation flag after first dispatch");
}, desc);
}
var ev = document.createEvent("Event");
ev.initEvent("foo", true, false);
testPropagationFlag(ev, true, "Newly-created Event");
ev.stopPropagation();
testPropagationFlag(ev, false, "After stopPropagation()");
ev.initEvent("foo", true, false);
testPropagationFlag(ev, true, "Reinitialized after stopPropagation()");
var ev = document.createEvent("Event");
ev.initEvent("foo", true, false);
ev.stopImmediatePropagation();
testPropagationFlag(ev, false, "After stopImmediatePropagation()");
ev.initEvent("foo", true, false);
testPropagationFlag(ev, true, "Reinitialized after stopImmediatePropagation()");
</script>

View file

@ -0,0 +1,153 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Event constructors</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
function assert_props(iface, event, defaults) {
assert_true(event instanceof self[iface]);
expected[iface].properties.forEach(function(p) {
var property = p[0], value = p[defaults ? 1 : 2];
assert_true(property in event,
"Event " + format_value(event) + " should have a " +
property + " property");
assert_equals(event[property], value,
"The value of the " + property + " property should be " +
format_value(value));
});
if ("parent" in expected[iface]) {
assert_props(expected[iface].parent, event, defaults);
}
}
var EventModifierInit = [
["ctrlKey", false, true],
["shiftKey", false, true],
["altKey", false, true],
["metaKey", false, true],
];
var expected = {
"Event": {
"properties": [
["bubbles", false, true],
["cancelable", false, true],
],
},
"UIEvent": {
"parent": "Event",
"properties": [
["view", null, window],
["detail", 0, 7],
],
},
"FocusEvent": {
"parent": "UIEvent",
"properties": [
["relatedTarget", null, document],
],
},
"MouseEvent": {
"parent": "UIEvent",
"properties": EventModifierInit.concat([
["screenX", 0, 40],
["screenY", 0, 40],
["clientX", 0, 40],
["clientY", 0, 40],
["button", 0, 40],
["buttons", 0, 40],
["relatedTarget", null, document],
]),
},
"WheelEvent": {
"parent": "MouseEvent",
"properties": [
["deltaX", 0.0, 3.1],
["deltaY", 0.0, 3.1],
["deltaZ", 0.0, 3.1],
["deltaMode", 0, 40],
],
},
"KeyboardEvent": {
"parent": "UIEvent",
"properties": EventModifierInit.concat([
["key", "", "string"],
["code", "", "string"],
["location", 0, 7],
["repeat", false, true],
["isComposing", false, true],
["charCode", 0, 7],
["keyCode", 0, 7],
["which", 0, 7],
]),
},
"CompositionEvent": {
"parent": "UIEvent",
"properties": [
["data", "", "string"],
],
},
};
Object.keys(expected).forEach(function(iface) {
test(function() {
var event = new self[iface]("type");
assert_props(iface, event, true);
}, iface + " constructor (no argument)");
test(function() {
var event = new self[iface]("type", undefined);
assert_props(iface, event, true);
}, iface + " constructor (undefined argument)");
test(function() {
var event = new self[iface]("type", null);
assert_props(iface, event, true);
}, iface + " constructor (null argument)");
test(function() {
var event = new self[iface]("type", {});
assert_props(iface, event, true);
}, iface + " constructor (empty argument)");
test(function() {
var dictionary = {};
expected[iface].properties.forEach(function(p) {
var property = p[0], value = p[1];
dictionary[property] = value;
});
var event = new self[iface]("type", dictionary);
assert_props(iface, event, true);
}, iface + " constructor (argument with default values)");
test(function() {
function fill_in(iface, dictionary) {
if ("parent" in expected[iface]) {
fill_in(expected[iface].parent, dictionary)
}
expected[iface].properties.forEach(function(p) {
var property = p[0], value = p[2];
dictionary[property] = value;
});
}
var dictionary = {};
fill_in(iface, dictionary);
var event = new self[iface]("type", dictionary);
assert_props(iface, event, false);
}, iface + " constructor (argument with non-default values)");
});
test(function () {
assert_throws(new TypeError(), function() {
new UIEvent("x", { view: 7 })
});
}, "UIEvent constructor (view argument with wrong type)")
</script>

View file

@ -0,0 +1,35 @@
<!DOCTYPE html>
<title>Event.type set to the empty string</title>
<link rel="author" title="Ms2ger" href="mailto:Ms2ger@gmail.com">
<link rel="help" href="https://dom.spec.whatwg.org/#dom-event-type">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
function do_test(t, e) {
assert_equals(e.type, "", "type");
assert_equals(e.bubbles, false, "bubbles");
assert_equals(e.cancelable, false, "cancelable");
var target = document.createElement("div");
var handled = false;
target.addEventListener("", t.step_func(function(e) {
handled = true;
}));
assert_true(target.dispatchEvent(e));
assert_true(handled);
}
async_test(function() {
var e = document.createEvent("Event");
e.initEvent("", false, false);
do_test(this, e);
this.done();
}, "initEvent");
async_test(function() {
var e = new Event("");
do_test(this, e);
this.done();
}, "Constructor");
</script>

View file

@ -0,0 +1,22 @@
<!DOCTYPE html>
<title>Event.type</title>
<link rel="author" title="Ms2ger" href="mailto:Ms2ger@gmail.com">
<link rel="help" href="https://dom.spec.whatwg.org/#dom-event-type">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
test(function() {
var e = document.createEvent("Event")
assert_equals(e.type, "");
}, "Event.type should initially be the empty string");
test(function() {
var e = document.createEvent("Event")
e.initEvent("foo", false, false)
assert_equals(e.type, "foo")
}, "Event.type should be initialized by initEvent");
test(function() {
var e = new Event("bar")
assert_equals(e.type, "bar")
}, "Event.type should be initialized by the constructor");
</script>

View file

@ -0,0 +1,41 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>EventListener::handleEvent()</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
test(function(t) {
var event = "foo";
var target = document.getElementById("target");
var event_listener = {
"handleEvent": function(evt) {
var that = this;
t.step(function() {
assert_equals(evt.type, event);
assert_equals(evt.target, target);
assert_equals(that, event_listener);
});
}
};
var evt = document.createEvent("Event");
evt.initEvent(event, true, true);
target.addEventListener(event, event_listener, true);
target.dispatchEvent(evt);
});
</script>

View file

@ -0,0 +1,20 @@
<!doctype html>
<meta charset=utf-8>
<title></title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<iframe src="{{location[scheme]}}://{{domains[www1]}}:{{ports[http][0]}}{{location[path]}}/../EventListener-incumbent-global-subframe-1.sub.html"></iframe>
<script>
var t = async_test("Check the incumbent global EventListeners are called with");
onload = t.step_func(function() {
onmessage = t.step_func_done(function(e) {
var d = e.data;
assert_equals(d.actual, d.expected, d.reason);
});
frames[0].postMessage("start", "*");
});
</script>

View file

@ -0,0 +1,20 @@
<!doctype html>
<meta charset=utf-8>
<title></title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<iframe src="{{location[scheme]}}://{{domains[www1]}}:{{ports[http][0]}}{{location[path]}}/../EventListener-incumbent-global-subframe-2.sub.html"></iframe>
<script>
var t = async_test("Check the incumbent global EventListeners are called with");
onload = t.step_func(function() {
onmessage = t.step_func_done(function(e) {
var d = e.data;
assert_equals(d.actual, d.expected, d.reason);
});
frames[0].postMessage("start", "*");
});
</script>

View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<iframe src="{{location[scheme]}}://{{domains[www2]}}:{{ports[http][0]}}{{location[path]}}/../EventListener-incumbent-global-subsubframe.sub.html"></iframe>
<script>
document.domain = "{{host}}";
onmessage = function(e) {
if (e.data == "start") {
frames[0].document.body.addEventListener("click", frames[0].postMessage.bind(frames[0], "respond", "*", undefined));
frames[0].postMessage("sendclick", "*");
} else {
parent.postMessage(e.data, "*");
}
}
</script>

View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<iframe src="{{location[scheme]}}://{{domains[www2]}}:{{ports[http][0]}}{{location[path]}}/../EventListener-incumbent-global-subsubframe.sub.html"></iframe>
<script>
document.domain = "{{host}}";
onmessage = function(e) {
if (e.data == "start") {
frames[0].document.body.addEventListener("click", frames[0].getTheListener());
frames[0].postMessage("sendclick", "*");
} else {
parent.postMessage(e.data, "*");
}
}
</script>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<script>
function getTheListener() {
return postMessage.bind(this, "respond", "*", undefined)
}
document.domain = "{{host}}";
onmessage = function (e) {
if (e.data == "sendclick") {
document.body.click();
} else {
parent.postMessage(
{
actual: e.origin,
expected: "{{location[scheme]}}://{{domains[www1]}}:{{ports[http][0]}}",
reason: "Incumbent should have been the caller of addEventListener()"
},
"*")
};
}
</script>

View file

@ -0,0 +1,98 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>EventListenerOptions.capture</title>
<link rel="author" title="Rick Byers" href="mailto:rbyers@chromium.org">
<link rel="help" href="https://dom.spec.whatwg.org/#dom-eventlisteneroptions-capture">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
function testCaptureValue(captureValue, expectedValue) {
var handlerPhase = undefined;
var handler = function handler(e) {
assert_equals(handlerPhase, undefined, "Handler invoked after remove");
handlerPhase = e.eventPhase;
}
document.addEventListener('test', handler, captureValue);
document.body.dispatchEvent(new Event('test', {bubbles: true}));
document.removeEventListener('test', handler, captureValue);
document.body.dispatchEvent(new Event('test', {bubbles: true}));
assert_equals(handlerPhase, expectedValue, "Incorrect event phase for value: " + JSON.stringify(captureValue));
}
test(function() {
testCaptureValue(true, Event.CAPTURING_PHASE);
testCaptureValue(false, Event.BUBBLING_PHASE);
testCaptureValue(null, Event.BUBBLING_PHASE);
testCaptureValue(undefined, Event.BUBBLING_PHASE);
testCaptureValue(2.3, Event.CAPTURING_PHASE);
testCaptureValue(-1000.3, Event.CAPTURING_PHASE);
testCaptureValue(NaN, Event.BUBBLING_PHASE);
testCaptureValue(+0.0, Event.BUBBLING_PHASE);
testCaptureValue(-0.0, Event.BUBBLING_PHASE);
testCaptureValue("", Event.BUBBLING_PHASE);
testCaptureValue("AAAA", Event.CAPTURING_PHASE);
}, "Capture boolean should be honored correctly");
test(function() {
testCaptureValue({}, Event.BUBBLING_PHASE);
testCaptureValue({capture:true}, Event.CAPTURING_PHASE);
testCaptureValue({capture:false}, Event.BUBBLING_PHASE);
testCaptureValue({capture:2}, Event.CAPTURING_PHASE);
testCaptureValue({capture:0}, Event.BUBBLING_PHASE);
}, "Capture option should be honored correctly");
test(function() {
var supportsCapture = false;
var query_options = {
get capture() {
supportsCapture = true;
return false;
},
get dummy() {
assert_unreached("dummy value getter invoked");
return false;
}
};
document.addEventListener('test_event', null, query_options);
assert_true(supportsCapture, "addEventListener doesn't support the capture option");
supportsCapture = false;
document.removeEventListener('test_event', null, query_options);
assert_true(supportsCapture, "removeEventListener doesn't support the capture option");
}, "Supports capture option");
function testOptionEquality(addOptionValue, removeOptionValue, expectedEquality) {
var handlerInvoked = false;
var handler = function handler(e) {
assert_equals(handlerInvoked, false, "Handler invoked multiple times");
handlerInvoked = true;
}
document.addEventListener('test', handler, addOptionValue);
document.removeEventListener('test', handler, removeOptionValue);
document.body.dispatchEvent(new Event('test', {bubbles: true}));
assert_equals(!handlerInvoked, expectedEquality, "equivalence of options " +
JSON.stringify(addOptionValue) + " and " + JSON.stringify(removeOptionValue));
if (handlerInvoked)
document.removeEventListener('test', handler, addOptionValue);
}
test(function() {
// Option values that should be treated as equivalent
testOptionEquality({}, false, true);
testOptionEquality({capture: false}, false, true);
testOptionEquality(true, {capture: true}, true);
testOptionEquality({capture: null}, undefined, true);
testOptionEquality({capture: true}, {dummy: false, capture: 1}, true);
testOptionEquality({dummy: true}, false, true);
// Option values that should be treated as distinct
testOptionEquality(true, false, false);
testOptionEquality(true, {capture:false}, false);
testOptionEquality({}, true, false);
}, "Equivalence of option values");
</script>

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>EventTarget.addEventListener</title>
<link rel="author" title="Ms2ger" href="mailto:Ms2ger@gmail.com">
<link rel="help" href="https://dom.spec.whatwg.org/#dom-eventtarget-addeventlistener">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
// Step 1.
test(function() {
assert_equals(document.addEventListener("x", null, false), undefined);
assert_equals(document.addEventListener("x", null, true), undefined);
assert_equals(document.addEventListener("x", null), undefined);
}, "Adding a null event listener should succeed");
</script>

View file

@ -0,0 +1,43 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>EventTarget.dispatchEvent: return value</title>
<link rel="help" href="https://dom.spec.whatwg.org/#concept-event-dispatch">
<link rel="help" href="https://dom.spec.whatwg.org/#dom-event-preventdefault">
<link rel="help" href="https://dom.spec.whatwg.org/#dom-event-defaultprevented">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
test(function() {
var event_type = "foo";
var target = document.getElementById("target");
var parent = document.getElementById("parent");
var default_prevented;
parent.addEventListener(event_type, function(e) {}, true);
target.addEventListener(event_type, function(e) {
evt.preventDefault();
default_prevented = evt.defaultPrevented;
}, true);
target.addEventListener(event_type, function(e) {}, true);
var evt = document.createEvent("Event");
evt.initEvent(event_type, true, true);
assert_true(parent.dispatchEvent(evt));
assert_false(target.dispatchEvent(evt));
assert_true(default_prevented);
}, "Return value of EventTarget.dispatchEvent.");
</script>

View file

@ -0,0 +1,104 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>EventTarget.dispatchEvent</title>
<link rel="author" title="Olli Pettay" href="mailto:Olli.Pettay@gmail.com">
<link rel="author" title="Ms2ger" href="mailto:Ms2ger@gmail.com">
<link rel="help" href="https://dom.spec.whatwg.org/#dom-eventtarget-dispatchevent">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/dom/nodes/Document-createEvent.js"></script>
<div id="log"></div>
<script>
setup({
"allow_uncaught_exception": true,
})
test(function() {
assert_throws(new TypeError(), function() { document.dispatchEvent(null) })
}, "Calling dispatchEvent(null).")
for (var alias in aliases) {
test(function() {
var e = document.createEvent(alias)
assert_equals(e.type, "", "Event type should be empty string before initialization")
assert_throws("InvalidStateError", function() { document.dispatchEvent(e) })
}, "If the event's initialized flag is not set, an InvalidStateError must be thrown (" + alias + ").")
}
var dispatch_dispatch = async_test("If the event's dispatch flag is set, an InvalidStateError must be thrown.")
dispatch_dispatch.step(function() {
var e = document.createEvent("Event")
e.initEvent("type", false, false)
var target = document.createElement("div")
target.addEventListener("type", dispatch_dispatch.step_func(function() {
assert_throws("InvalidStateError", function() {
target.dispatchEvent(e)
})
assert_throws("InvalidStateError", function() {
document.dispatchEvent(e)
})
}), false)
assert_equals(target.dispatchEvent(e), true, "dispatchEvent must return true")
dispatch_dispatch.done()
})
test(function() {
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=17713
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=17714
var e = document.createEvent("Event")
e.initEvent("type", false, false)
var called = []
var target = document.createElement("div")
target.addEventListener("type", function() {
called.push("First")
throw new Error()
}, false)
target.addEventListener("type", function() {
called.push("Second")
}, false)
assert_equals(target.dispatchEvent(e), true, "dispatchEvent must return true")
assert_array_equals(called, ["First", "Second"],
"Should have continued to call other event listeners")
}, "Exceptions from event listeners must not be propagated.")
async_test(function() {
var results = []
var outerb = document.createElement("b")
var middleb = outerb.appendChild(document.createElement("b"))
var innerb = middleb.appendChild(document.createElement("b"))
outerb.addEventListener("x", this.step_func(function() {
middleb.addEventListener("x", this.step_func(function() {
results.push("middle")
}), true)
results.push("outer")
}), true)
innerb.dispatchEvent(new Event("x"))
assert_array_equals(results, ["outer", "middle"])
this.done()
}, "Event listeners added during dispatch should be called");
async_test(function() {
var results = []
var b = document.createElement("b")
b.addEventListener("x", this.step_func(function() {
results.push(1)
}), true)
b.addEventListener("x", this.step_func(function() {
results.push(2)
}), false)
b.addEventListener("x", this.step_func(function() {
results.push(3)
}), true)
b.dispatchEvent(new Event("x"))
assert_array_equals(results, [1, 2, 3])
this.done()
}, "Event listeners should be called in order of addition")
</script>

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>EventTarget.removeEventListener</title>
<link rel="author" title="Ms2ger" href="mailto:Ms2ger@gmail.com">
<link rel="help" href="https://dom.spec.whatwg.org/#dom-eventtarget-removeeventlistener">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
// Step 1.
test(function() {
assert_equals(document.removeEventListener("x", null, false), undefined);
assert_equals(document.removeEventListener("x", null, true), undefined);
assert_equals(document.removeEventListener("x", null), undefined);
}, "removing a null event listener should succeed");
</script>

View file

@ -0,0 +1,25 @@
<!doctype html>
<title>ProgressEvent constructor</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<div id=log></div>
<script>
test(function() {
var ev = new ProgressEvent("test")
assert_equals(ev.type, "test")
assert_equals(ev.target, null)
assert_equals(ev.currentTarget, null)
assert_equals(ev.eventPhase, Event.NONE)
assert_equals(ev.bubbles, false)
assert_equals(ev.cancelable, false)
assert_equals(ev.defaultPrevented, false)
assert_equals(ev.isTrusted, false)
assert_true(ev.timeStamp > 0)
assert_true("initEvent" in ev)
}, "Default event values.")
test(function() {
var e = document.createEvent("ProgressEvent");
var eProto = Object.getPrototypeOf(e);
assert_equals(eProto, ProgressEvent.prototype);
}, "document.createEvent() should work with ProgressEvent.");
</script>

View file

@ -0,0 +1,132 @@
<!DOCTYPE html>
<title>Historical DOM features must be removed</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
function isInterfaceNuked(name) {
test(function() {
assert_equals(window[name], undefined)
}, "Historical DOM features must be removed: " + name)
}
var nukedInterfaces = [
"DOMConfiguration",
"DOMError",
"DOMErrorHandler",
"DOMImplementationList",
"DOMImplementationSource",
"DOMLocator",
"DOMObject",
"DOMSettableTokenList",
"DOMUserData",
"Entity",
"EntityReference",
"EventException", // DOM Events
"NameList",
"Notation",
"TypeInfo",
"UserDataHandler",
"RangeException" // DOM Range
]
nukedInterfaces.forEach(isInterfaceNuked)
function isNukedFromDocument(name) {
test(function() {
var doc = document.implementation.createDocument(null,null,null)
assert_equals(document[name], undefined)
assert_equals(doc[name], undefined)
}, "Historical DOM features must be removed: " + name)
}
var documentNuked = [
"createEntityReference",
"xmlEncoding",
"xmlStandalone",
"xmlVersion",
"strictErrorChecking",
"domConfig",
"normalizeDocument",
"renameNode",
"defaultCharset",
"height",
"width"
]
documentNuked.forEach(isNukedFromDocument)
test(function() {
assert_equals(document.implementation["getFeature"], undefined)
}, "DOMImplementation.getFeature() must be nuked.")
function isNukedFromElement(name) {
test(function() {
var ele = document.createElementNS("test", "test")
assert_equals(document.body[name], undefined)
assert_equals(ele[name], undefined)
}, "Historical DOM features must be removed: " + name)
}
var elementNuked = [
"schemaTypeInfo",
"setIdAttribute",
"setIdAttributeNS",
"setIdAttributeNode"
]
elementNuked.forEach(isNukedFromElement)
function isNukedFromDoctype(name) {
test(function() {
var doctype = document.implementation.createDocumentType("test", "", "")
assert_equals(doctype[name], undefined)
}, "DocumentType member must be nuked: " + name)
}
var doctypeNuked = [
"entities",
"notations",
"internalSubset"
]
doctypeNuked.forEach(isNukedFromDoctype)
function isNukedFromText(name) {
test(function() {
var text = document.createTextNode("test")
assert_equals(text[name], undefined)
}, "Text member must be nuked: " + name)
}
var textNuked = [
"isElementContentWhitespace",
"replaceWholeText"
]
textNuked.forEach(isNukedFromText)
function isNukedFromNode(name) {
test(function() {
var doc = document.implementation.createDocument(null,null,null)
var doctype = document.implementation.createDocumentType("test", "", "")
var text = document.createTextNode("test")
assert_equals(doc[name], undefined)
assert_equals(doctype[name], undefined)
assert_equals(text[name], undefined)
}, "Node member must be nuked: " + name)
}
var nodeNuked = [
"hasAttributes",
"attributes",
"namespaceURI",
"prefix",
"localName",
"isSupported",
"getFeature",
"getUserData",
"setUserData",
"rootNode",
]
nodeNuked.forEach(isNukedFromNode)
function isNukedFromWindow(name) {
test(function() {
assert_equals(window[name], undefined)
}, "Window member must be nuked: " + name)
}
var windowNuked = [
"attachEvent"
]
windowNuked.forEach(isNukedFromWindow)
</script>

View file

@ -0,0 +1,44 @@
<!DOCTYPE html>
<title>Interfaces</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
function testInterfaceDeletable(iface) {
test(function() {
assert_true(!!window[iface], "Interface should exist.")
assert_true(delete window[iface], "The delete operator should return true.")
assert_equals(window[iface], undefined, "Interface should be gone.")
}, "Should be able to delete " + iface + ".")
}
var interfaces = [
"Event",
"CustomEvent",
"EventTarget",
"Node",
"Document",
"DOMImplementation",
"DocumentFragment",
"ProcessingInstruction",
"DocumentType",
"Element",
"Attr",
"CharacterData",
"Text",
"Comment",
"NodeIterator",
"TreeWalker",
"NodeFilter",
"NodeList",
"HTMLCollection",
"DOMTokenList"
];
test(function() {
for (var p in window) {
interfaces.forEach(function(i) {
assert_not_equals(p, i)
})
}
}, "Interface objects properties should not be Enumerable")
interfaces.forEach(testInterfaceDeletable);
</script>

View file

@ -0,0 +1,598 @@
<!doctype html>
<meta charset=utf-8>
<title>DOM IDL tests</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/resources/WebIDLParser.js></script>
<script src=/resources/idlharness.js></script>
<h1>DOM IDL tests</h1>
<div id=log></div>
<script type=text/plain>
[Constructor(DOMString type, optional EventInit eventInitDict)/*,
Exposed=(Window,Worker)*/]
interface Event {
readonly attribute DOMString type;
readonly attribute EventTarget? target;
readonly attribute EventTarget? currentTarget;
const unsigned short NONE = 0;
const unsigned short CAPTURING_PHASE = 1;
const unsigned short AT_TARGET = 2;
const unsigned short BUBBLING_PHASE = 3;
readonly attribute unsigned short eventPhase;
void stopPropagation();
void stopImmediatePropagation();
readonly attribute boolean bubbles;
readonly attribute boolean cancelable;
void preventDefault();
readonly attribute boolean defaultPrevented;
[Unforgeable] readonly attribute boolean isTrusted;
readonly attribute DOMTimeStamp timeStamp;
void initEvent(DOMString type, boolean bubbles, boolean cancelable);
};
dictionary EventInit {
boolean bubbles = false;
boolean cancelable = false;
};
[Constructor(DOMString type, optional CustomEventInit eventInitDict)/*,
Exposed=(Window,Worker)*/]
interface CustomEvent : Event {
readonly attribute any detail;
void initCustomEvent(DOMString type, boolean bubbles, boolean cancelable, any detail);
};
dictionary CustomEventInit : EventInit {
any detail = null;
};
//[Exposed=(Window,Worker)]
interface EventTarget {
void addEventListener(DOMString type, EventListener? callback, optional (EventListenerOptions or boolean) options);
void removeEventListener(DOMString type, EventListener? callback, optional (EventListenerOptions or boolean) options);
boolean dispatchEvent(Event event);
};
callback interface EventListener {
void handleEvent(Event event);
};
dictionary EventListenerOptions {
boolean capture;
boolean passive;
};
[NoInterfaceObject,
Exposed=Window]
interface NonElementParentNode {
Element? getElementById(DOMString elementId);
};
Document implements NonElementParentNode;
DocumentFragment implements NonElementParentNode;
[NoInterfaceObject,
Exposed=Window]
interface DocumentOrShadowRoot {
};
Document implements DocumentOrShadowRoot;
ShadowRoot implements DocumentOrShadowRoot;
[NoInterfaceObject,
Exposed=Window]
interface ParentNode {
[SameObject] readonly attribute HTMLCollection children;
readonly attribute Element? firstElementChild;
readonly attribute Element? lastElementChild;
readonly attribute unsigned long childElementCount;
[Unscopable] void prepend((Node or DOMString)... nodes);
[Unscopable] void append((Node or DOMString)... nodes);
Element? querySelector(DOMString selectors);
[NewObject] NodeList querySelectorAll(DOMString selectors);
};
Document implements ParentNode;
DocumentFragment implements ParentNode;
Element implements ParentNode;
[NoInterfaceObject,
Exposed=Window]
interface NonDocumentTypeChildNode {
readonly attribute Element? previousElementSibling;
readonly attribute Element? nextElementSibling;
};
Element implements NonDocumentTypeChildNode;
CharacterData implements NonDocumentTypeChildNode;
[NoInterfaceObject,
Exposed=Window]
interface ChildNode {
[Unscopable] void before((Node or DOMString)... nodes);
[Unscopable] void after((Node or DOMString)... nodes);
[Unscopable] void replaceWith((Node or DOMString)... nodes);
[Unscopable] void remove();
};
DocumentType implements ChildNode;
Element implements ChildNode;
CharacterData implements ChildNode;
[NoInterfaceObject,
Exposed=Window]
interface Slotable {
readonly attribute HTMLSlotElement? assignedSlot;
};
Element implements Slotable;
Text implements Slotable;
[Exposed=Window]
interface NodeList {
getter Node? item(unsigned long index);
readonly attribute unsigned long length;
// iterable<Node>;
};
[Exposed=Window, LegacyUnenumerableNamedProperties]
interface HTMLCollection {
readonly attribute unsigned long length;
getter Element? item(unsigned long index);
getter Element? namedItem(DOMString name);
};
[Constructor(MutationCallback callback)]
interface MutationObserver {
void observe(Node target, optional MutationObserverInit options);
void disconnect();
sequence<MutationRecord> takeRecords();
};
callback MutationCallback = void (sequence<MutationRecord> mutations, MutationObserver observer);
dictionary MutationObserverInit {
boolean childList = false;
boolean attributes;
boolean characterData;
boolean subtree = false;
boolean attributeOldValue;
boolean characterDataOldValue;
sequence<DOMString> attributeFilter;
};
[Exposed=Window]
interface MutationRecord {
readonly attribute DOMString type;
[SameObject] readonly attribute Node target;
[SameObject] readonly attribute NodeList addedNodes;
[SameObject] readonly attribute NodeList removedNodes;
readonly attribute Node? previousSibling;
readonly attribute Node? nextSibling;
readonly attribute DOMString? attributeName;
readonly attribute DOMString? attributeNamespace;
readonly attribute DOMString? oldValue;
};
[Exposed=Window]
interface Node : EventTarget {
const unsigned short ELEMENT_NODE = 1;
const unsigned short ATTRIBUTE_NODE = 2; // historical
const unsigned short TEXT_NODE = 3;
const unsigned short CDATA_SECTION_NODE = 4;
const unsigned short ENTITY_REFERENCE_NODE = 5; // historical
const unsigned short ENTITY_NODE = 6; // historical
const unsigned short PROCESSING_INSTRUCTION_NODE = 7;
const unsigned short COMMENT_NODE = 8;
const unsigned short DOCUMENT_NODE = 9;
const unsigned short DOCUMENT_TYPE_NODE = 10;
const unsigned short DOCUMENT_FRAGMENT_NODE = 11;
const unsigned short NOTATION_NODE = 12; // historical
readonly attribute unsigned short nodeType;
readonly attribute DOMString nodeName;
readonly attribute DOMString baseURI;
readonly attribute boolean isConnected;
readonly attribute Document? ownerDocument;
Node getRootNode(optional GetRootNodeOptions options);
readonly attribute Node? parentNode;
readonly attribute Element? parentElement;
boolean hasChildNodes();
[SameObject] readonly attribute NodeList childNodes;
readonly attribute Node? firstChild;
readonly attribute Node? lastChild;
readonly attribute Node? previousSibling;
readonly attribute Node? nextSibling;
attribute DOMString? nodeValue;
attribute DOMString? textContent;
void normalize();
[NewObject] Node cloneNode(optional boolean deep = false);
boolean isEqualNode(Node? otherNode);
boolean isSameNode(Node? otherNode); // historical alias of ===
const unsigned short DOCUMENT_POSITION_DISCONNECTED = 0x01;
const unsigned short DOCUMENT_POSITION_PRECEDING = 0x02;
const unsigned short DOCUMENT_POSITION_FOLLOWING = 0x04;
const unsigned short DOCUMENT_POSITION_CONTAINS = 0x08;
const unsigned short DOCUMENT_POSITION_CONTAINED_BY = 0x10;
const unsigned short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;
unsigned short compareDocumentPosition(Node other);
boolean contains(Node? other);
DOMString? lookupPrefix(DOMString? namespace);
DOMString? lookupNamespaceURI(DOMString? prefix);
boolean isDefaultNamespace(DOMString? namespace);
Node insertBefore(Node node, Node? child);
Node appendChild(Node node);
Node replaceChild(Node node, Node child);
Node removeChild(Node child);
};
dictionary GetRootNodeOptions {
boolean composed = false;
};
[Constructor,
Exposed=Window]
interface Document : Node {
[SameObject] readonly attribute DOMImplementation implementation;
readonly attribute DOMString URL;
readonly attribute DOMString documentURI;
readonly attribute DOMString origin;
readonly attribute DOMString compatMode;
readonly attribute DOMString characterSet;
readonly attribute DOMString charset; // historical alias of .characterSet
readonly attribute DOMString inputEncoding; // historical alias of .characterSet
readonly attribute DOMString contentType;
readonly attribute DocumentType? doctype;
readonly attribute Element? documentElement;
HTMLCollection getElementsByTagName(DOMString qualifiedName);
HTMLCollection getElementsByTagNameNS(DOMString? namespace, DOMString localName);
HTMLCollection getElementsByClassName(DOMString classNames);
[NewObject] Element createElement(DOMString localName, optional ElementCreationOptions options);
[NewObject] Element createElementNS(DOMString? namespace, DOMString qualifiedName, optional ElementCreationOptions options);
[NewObject] DocumentFragment createDocumentFragment();
[NewObject] Text createTextNode(DOMString data);
[NewObject] CDATASection createCDATASection(DOMString data);
[NewObject] Comment createComment(DOMString data);
[NewObject] ProcessingInstruction createProcessingInstruction(DOMString target, DOMString data);
[NewObject] Node importNode(Node node, optional boolean deep = false);
Node adoptNode(Node node);
[NewObject] Attr createAttribute(DOMString localName);
[NewObject] Attr createAttributeNS(DOMString? namespace, DOMString qualifiedName);
[NewObject] Event createEvent(DOMString interface);
[NewObject] Range createRange();
// NodeFilter.SHOW_ALL = 0xFFFFFFFF
[NewObject] NodeIterator createNodeIterator(Node root, optional unsigned long whatToShow = 0xFFFFFFFF, optional NodeFilter? filter = null);
[NewObject] TreeWalker createTreeWalker(Node root, optional unsigned long whatToShow = 0xFFFFFFFF, optional NodeFilter? filter = null);
};
[Exposed=Window]
interface XMLDocument : Document {};
dictionary ElementCreationOptions {
DOMString is;
};
[Exposed=Window]
interface DOMImplementation {
[NewObject] DocumentType createDocumentType(DOMString qualifiedName, DOMString publicId, DOMString systemId);
[NewObject] XMLDocument createDocument(DOMString? namespace, [TreatNullAs=EmptyString] DOMString qualifiedName, optional DocumentType? doctype = null);
[NewObject] Document createHTMLDocument(optional DOMString title);
boolean hasFeature(); // useless; always returns true
};
[Exposed=Window]
interface DocumentType : Node {
readonly attribute DOMString name;
readonly attribute DOMString publicId;
readonly attribute DOMString systemId;
};
[Constructor,
Exposed=Window]
interface DocumentFragment : Node {
};
[Exposed=Window]
interface ShadowRoot : DocumentFragment {
readonly attribute ShadowRootMode mode;
readonly attribute Element host;
};
enum ShadowRootMode { "open", "closed" };
[Exposed=Window]
interface Element : Node {
readonly attribute DOMString? namespaceURI;
readonly attribute DOMString? prefix;
readonly attribute DOMString localName;
readonly attribute DOMString tagName;
attribute DOMString id;
attribute DOMString className;
[SameObject, PutForwards=value] readonly attribute DOMTokenList classList;
attribute DOMString slot;
boolean hasAttributes();
[SameObject] readonly attribute NamedNodeMap attributes;
sequence<DOMString> getAttributeNames();
DOMString? getAttribute(DOMString qualifiedName);
DOMString? getAttributeNS(DOMString? namespace, DOMString localName);
void setAttribute(DOMString qualifiedName, DOMString value);
void setAttributeNS(DOMString? namespace, DOMString qualifiedName, DOMString value);
void removeAttribute(DOMString qualifiedName);
void removeAttributeNS(DOMString? namespace, DOMString localName);
boolean hasAttribute(DOMString qualifiedName);
boolean hasAttributeNS(DOMString? namespace, DOMString localName);
Attr? getAttributeNode(DOMString qualifiedName);
Attr? getAttributeNodeNS(DOMString? namespace, DOMString localName);
Attr? setAttributeNode(Attr attr);
Attr? setAttributeNodeNS(Attr attr);
Attr removeAttributeNode(Attr attr);
ShadowRoot attachShadow(ShadowRootInit init);
readonly attribute ShadowRoot? shadowRoot;
Element? closest(DOMString selectors);
boolean matches(DOMString selectors);
boolean webkitMatchesSelector(DOMString selectors); // historical alias of .matches
HTMLCollection getElementsByTagName(DOMString qualifiedName);
HTMLCollection getElementsByTagNameNS(DOMString? namespace, DOMString localName);
HTMLCollection getElementsByClassName(DOMString classNames);
Element? insertAdjacentElement(DOMString where, Element element); // historical
void insertAdjacentText(DOMString where, DOMString data); // historical
};
dictionary ShadowRootInit {
// required ShadowRootMode mode;
};
[Exposed=Window, LegacyUnenumerableNamedProperties]
interface NamedNodeMap {
readonly attribute unsigned long length;
getter Attr? item(unsigned long index);
getter Attr? getNamedItem(DOMString qualifiedName);
Attr? getNamedItemNS(DOMString? namespace, DOMString localName);
Attr? setNamedItem(Attr attr);
Attr? setNamedItemNS(Attr attr);
Attr removeNamedItem(DOMString qualifiedName);
Attr removeNamedItemNS(DOMString? namespace, DOMString localName);
};
[Exposed=Window]
interface Attr : Node {
readonly attribute DOMString? namespaceURI;
readonly attribute DOMString? prefix;
readonly attribute DOMString localName;
readonly attribute DOMString name;
attribute DOMString value;
readonly attribute Element? ownerElement;
readonly attribute boolean specified; // useless; always returns true
};
[Exposed=Window]
interface CharacterData : Node {
[TreatNullAs=EmptyString] attribute DOMString data;
readonly attribute unsigned long length;
DOMString substringData(unsigned long offset, unsigned long count);
void appendData(DOMString data);
void insertData(unsigned long offset, DOMString data);
void deleteData(unsigned long offset, unsigned long count);
void replaceData(unsigned long offset, unsigned long count, DOMString data);
};
[Constructor(optional DOMString data = ""),
Exposed=Window]
interface Text : CharacterData {
[NewObject] Text splitText(unsigned long offset);
readonly attribute DOMString wholeText;
};
[Exposed=Window]
interface CDATASection : Text {
};
[Exposed=Window]
interface ProcessingInstruction : CharacterData {
readonly attribute DOMString target;
};
[Constructor(optional DOMString data = ""),
Exposed=Window]
interface Comment : CharacterData {
};
[Constructor,
Exposed=Window]
interface Range {
readonly attribute Node startContainer;
readonly attribute unsigned long startOffset;
readonly attribute Node endContainer;
readonly attribute unsigned long endOffset;
readonly attribute boolean collapsed;
readonly attribute Node commonAncestorContainer;
void setStart(Node node, unsigned long offset);
void setEnd(Node node, unsigned long offset);
void setStartBefore(Node node);
void setStartAfter(Node node);
void setEndBefore(Node node);
void setEndAfter(Node node);
void collapse(optional boolean toStart = false);
void selectNode(Node node);
void selectNodeContents(Node node);
const unsigned short START_TO_START = 0;
const unsigned short START_TO_END = 1;
const unsigned short END_TO_END = 2;
const unsigned short END_TO_START = 3;
short compareBoundaryPoints(unsigned short how, Range sourceRange);
void deleteContents();
[NewObject] DocumentFragment extractContents();
[NewObject] DocumentFragment cloneContents();
void insertNode(Node node);
void surroundContents(Node newParent);
[NewObject] Range cloneRange();
void detach();
boolean isPointInRange(Node node, unsigned long offset);
short comparePoint(Node node, unsigned long offset);
boolean intersectsNode(Node node);
stringifier;
};
[Exposed=Window]
interface NodeIterator {
[SameObject] readonly attribute Node root;
readonly attribute Node referenceNode;
readonly attribute boolean pointerBeforeReferenceNode;
readonly attribute unsigned long whatToShow;
readonly attribute NodeFilter? filter;
Node? nextNode();
Node? previousNode();
void detach();
};
[Exposed=Window]
interface TreeWalker {
[SameObject] readonly attribute Node root;
readonly attribute unsigned long whatToShow;
readonly attribute NodeFilter? filter;
attribute Node currentNode;
Node? parentNode();
Node? firstChild();
Node? lastChild();
Node? previousSibling();
Node? nextSibling();
Node? previousNode();
Node? nextNode();
};
[Exposed=Window]
callback interface NodeFilter {
// Constants for acceptNode()
const unsigned short FILTER_ACCEPT = 1;
const unsigned short FILTER_REJECT = 2;
const unsigned short FILTER_SKIP = 3;
// Constants for whatToShow
const unsigned long SHOW_ALL = 0xFFFFFFFF;
const unsigned long SHOW_ELEMENT = 0x1;
const unsigned long SHOW_ATTRIBUTE = 0x2; // historical
const unsigned long SHOW_TEXT = 0x4;
const unsigned long SHOW_CDATA_SECTION = 0x8;
const unsigned long SHOW_ENTITY_REFERENCE = 0x10; // historical
const unsigned long SHOW_ENTITY = 0x20; // historical
const unsigned long SHOW_PROCESSING_INSTRUCTION = 0x40;
const unsigned long SHOW_COMMENT = 0x80;
const unsigned long SHOW_DOCUMENT = 0x100;
const unsigned long SHOW_DOCUMENT_TYPE = 0x200;
const unsigned long SHOW_DOCUMENT_FRAGMENT = 0x400;
const unsigned long SHOW_NOTATION = 0x800; // historical
unsigned short acceptNode(Node node);
};
interface DOMTokenList {
readonly attribute unsigned long length;
getter DOMString? item(unsigned long index);
boolean contains(DOMString token);
[CEReactions] void add(DOMString... tokens);
[CEReactions] void remove(DOMString... tokens);
[CEReactions] boolean toggle(DOMString token, optional boolean force);
[CEReactions] void replace(DOMString token, DOMString newToken);
boolean supports(DOMString token);
[CEReactions] stringifier attribute DOMString value;
// iterable<DOMString>;
};
</script>
<script>
"use strict";
var xmlDoc, detachedRange, element;
var idlArray;
setup(function() {
xmlDoc = document.implementation.createDocument(null, "", null);
detachedRange = document.createRange();
detachedRange.detach();
element = xmlDoc.createElementNS(null, "test");
element.setAttribute("bar", "baz");
idlArray = new IdlArray();
idlArray.add_idls(document.querySelector("script[type=text\\/plain]").textContent);
idlArray.add_objects({
Event: ['document.createEvent("Event")', 'new Event("foo")'],
CustomEvent: ['new CustomEvent("foo")'],
Document: ['new Document()'],
XMLDocument: ['xmlDoc'],
DOMImplementation: ['document.implementation'],
DocumentFragment: ['document.createDocumentFragment()'],
DocumentType: ['document.doctype'],
Element: ['element'],
Attr: ['document.querySelector("[id]").attributes[0]'],
Text: ['document.createTextNode("abc")'],
ProcessingInstruction: ['xmlDoc.createProcessingInstruction("abc", "def")'],
Comment: ['document.createComment("abc")'],
Range: ['document.createRange()', 'detachedRange'],
NodeIterator: ['document.createNodeIterator(document.body, NodeFilter.SHOW_ALL, null, false)'],
TreeWalker: ['document.createTreeWalker(document.body, NodeFilter.SHOW_ALL, null, false)'],
NodeList: ['document.querySelectorAll("script")'],
HTMLCollection: ['document.body.children'],
DOMTokenList: ['document.body.classList'],
});
});
idlArray.test();
</script>

View file

@ -0,0 +1,34 @@
<!doctype html>
<meta charset="utf-8">
<title>DOMTokenList Iterable Test</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<span class="foo Foo foo "></span>
<script>
var elementClasses;
setup(function() {
elementClasses = document.querySelector("span").classList;
})
test(function() {
assert_true('length' in elementClasses);
}, 'DOMTokenList has length method.');
test(function() {
assert_true('values' in elementClasses);
}, 'DOMTokenList has values method.');
test(function() {
assert_true('entries' in elementClasses);
}, 'DOMTokenList has entries method.');
test(function() {
assert_true('forEach' in elementClasses);
}, 'DOMTokenList has forEach method.');
test(function() {
assert_true(Symbol.iterator in elementClasses);
}, 'DOMTokenList has Symbol.iterator.');
test(function() {
var classList = [];
for (var className of elementClasses){
classList.push(className);
}
assert_array_equals(classList, ['foo', 'Foo']);
}, 'DOMTokenList is iterable via for-of loop.');
</script>

View file

@ -0,0 +1,51 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>DOMTokenList coverage for attributes</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
"use strict";
var pairs = [
// Defined in DOM
{attr: "classList", sup: ["anyElement"]},
// Defined in HTML
{attr: "dropzone", sup: ["anyHTMLElement"]},
{attr: "htmlFor", sup: ["output"]},
{attr: "relList", sup: ["a", "area", "link"]},
{attr: "sandbox", sup: ["iframe"]},
{attr: "sizes", sup: ["link"]}
];
var namespaces = [
"http://www.w3.org/1999/xhtml",
"http://www.w3.org/2000/svg",
"http://www.w3.org/1998/Math/MathML",
"http://example.com/",
""
];
var elements = ["a", "area", "link", "iframe", "output", "td", "th"];
function testAttr(pair, new_el){
return (pair.attr === "classList" || (new_el.namespaceURI === "http://www.w3.org/1999/xhtml" && (pair.attr === "dropzone" || pair.sup.indexOf(new_el.localName) != -1)));
}
pairs.forEach(function(pair) {
namespaces.forEach(function(ns) {
elements.forEach(function(el) {
var new_el = document.createElementNS(ns, el);
if (testAttr(pair, new_el)) {
test(function() {
assert_class_string(new_el[pair.attr], "DOMTokenList");
}, new_el.localName + "." + pair.attr + " in " + new_el.namespaceURI + " namespace should be DOMTokenList.");
}
else {
test(function() {
assert_equals(new_el[pair.attr], undefined);
}, new_el.localName + "." + pair.attr + " in " + new_el.namespaceURI + " namespace should be undefined.");
}
});
});
});
</script>

View file

@ -0,0 +1,50 @@
<!doctype html>
<meta charset=utf-8>
<title>DOMTokenList iteration: keys, values, etc.</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<span class=" a a b "></span>
<script>
test(function() {
var list = document.querySelector("span").classList;
assert_array_equals([...list], ["a", "a", "b"]);
var keys = list.keys();
assert_false(keys instanceof Array);
keys = [...keys];
assert_array_equals(keys, [0, 1, 2]);
var values = list.values();
assert_false(values instanceof Array);
values = [...values];
assert_array_equals(values, ["a", "a", "b"]);
var entries = list.entries();
assert_false(entries instanceof Array);
entries = [...entries];
assert_equals(entries.length, keys.length);
assert_equals(entries.length, values.length);
for (var i = 0; i < entries.length; ++i) {
assert_array_equals(entries[i], [keys[i], values[i]]);
}
var cur = 0;
var thisObj = {};
list.forEach(function(value, key, listObj) {
assert_equals(listObj, list);
assert_equals(this, thisObj);
assert_equals(value, values[cur]);
assert_equals(key, keys[cur]);
cur++;
}, thisObj);
assert_equals(cur, entries.length);
assert_equals(list[Symbol.iterator], Array.prototype[Symbol.iterator]);
assert_equals(list.keys, Array.prototype.keys);
if (Array.prototype.values) {
assert_equals(list.values, Array.prototype.values);
}
assert_equals(list.entries, Array.prototype.entries);
assert_equals(list.forEach, Array.prototype.forEach);
});
</script>

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>DOMTokenList stringifier</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-domtokenlist-stringifier">
<link rel=author title=Ms2ger href="mailto:Ms2ger@gmail.com">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<span class=" a a b "></span>
<script>
test(function() {
assert_equals(String(document.createElement("span").classList), "",
"String(classList) should return the empty list for an undefined class attribute");
var span = document.querySelector("span");
assert_equals(span.getAttribute("class"), " a a b ",
"getAttribute should return the literal value");
assert_equals(span.className, " a a b ",
"className should return the literal value");
assert_equals(String(span.classList), " a a b ",
"String(classList) should return the literal value");
assert_equals(span.classList.toString(), " a a b ",
"classList.toString() should return the literal value");
assert_class_string(span.classList, "DOMTokenList");
});
</script>

View file

@ -0,0 +1,24 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>DOMTokenList value</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-domtokenlist-value">
<link rel=author title=Tangresh href="mailto:dmenzi@tangresh.ch">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<span class=" a a b "></span>
<script>
test(function() {
assert_equals(String(document.createElement("span").classList.value), "",
"classList.value should return the empty list for an undefined class attribute");
var span = document.querySelector("span");
assert_equals(span.classList.value, " a a b ",
"value should return the literal value");
span.classList.value = " foo bar foo ";
assert_equals(span.classList.value, " foo bar foo ",
"assigning value should set the literal value");
assert_equals(span.classList.length, 2,
"length should be the number of tokens");
assert_class_string(span.classList, "DOMTokenList");
assert_class_string(span.classList.value, "String");
});
</script>

View file

@ -0,0 +1,34 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>Node.appendChild applied to CharacterData</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-node-appendchild">
<link rel=help href="https://dom.spec.whatwg.org/#introduction-to-the-dom">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
function create(type) {
switch (type) {
case "Text": return document.createTextNode("test"); break;
case "Comment": return document.createComment("test"); break;
case "ProcessingInstruction": return document.createProcessingInstruction("target", "test"); break;
}
}
function testNode(type1, type2) {
test(function() {
var node1 = create(type1);
var node2 = create(type2);
assert_throws("HierarchyRequestError", function () {
node1.appendChild(node2);
}, "CharacterData type " + type1 + " must not have children");
}, type1 + ".appendChild(" + type2 + ")");
}
var types = ["Text", "Comment", "ProcessingInstruction"];
types.forEach(function(type1) {
types.forEach(function(type2) {
testNode(type1, type2);
});
});
</script>

View file

@ -0,0 +1,70 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>CharacterData.appendData</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-characterdata-appenddata">
<link rel=help href="https://dom.spec.whatwg.org/#dom-characterdata-data">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
function testNode(create, type) {
test(function() {
var node = create()
assert_equals(node.data, "test")
node.appendData("bar")
assert_equals(node.data, "testbar")
}, type + ".appendData('bar')")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.appendData("")
assert_equals(node.data, "test")
}, type + ".appendData('')")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.appendData(", append more 資料,測試資料");
assert_equals(node.data, "test, append more 資料,測試資料");
assert_equals(node.length, 25);
}, type + ".appendData(non-ASCII)")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.appendData(null)
assert_equals(node.data, "testnull")
}, type + ".appendData(null)")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.appendData(undefined)
assert_equals(node.data, "testundefined")
}, type + ".appendData(undefined)")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.appendData("", "bar")
assert_equals(node.data, "test")
}, type + ".appendData('', 'bar')")
test(function() {
var node = create()
assert_equals(node.data, "test")
assert_throws(new TypeError(), function() { node.appendData() });
assert_equals(node.data, "test")
}, type + ".appendData()")
}
testNode(function() { return document.createTextNode("test") }, "Text")
testNode(function() { return document.createComment("test") }, "Comment")
</script>

View file

@ -0,0 +1,82 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>CharacterData.data</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-characterdata-data">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
function testNode(create, type) {
test(function() {
var node = create()
assert_equals(node.data, "test")
assert_equals(node.length, 4)
}, type + ".data initial value")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.data = null;
assert_equals(node.data, "")
assert_equals(node.length, 0)
}, type + ".data = null")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.data = undefined;
assert_equals(node.data, "undefined")
assert_equals(node.length, 9)
}, type + ".data = undefined")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.data = 0;
assert_equals(node.data, "0")
assert_equals(node.length, 1)
}, type + ".data = 0")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.data = "";
assert_equals(node.data, "")
assert_equals(node.length, 0)
}, type + ".data = ''")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.data = "--";
assert_equals(node.data, "--")
assert_equals(node.length, 2)
}, type + ".data = '--'")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.data = "資料";
assert_equals(node.data, "資料")
assert_equals(node.length, 2)
}, type + ".data = '資料'")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.data = "🌠 test 🌠 TEST";
assert_equals(node.data, "🌠 test 🌠 TEST")
assert_equals(node.length, 15) // Counting UTF-16 code units
}, type + ".data = '🌠 test 🌠 TEST'")
}
testNode(function() { return document.createTextNode("test") }, "Text")
testNode(function() { return document.createComment("test") }, "Comment")
</script>

View file

@ -0,0 +1,95 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>CharacterData.deleteData</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-characterdata-deletedata">
<link rel=help href="https://dom.spec.whatwg.org/#dom-characterdata-data">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
function testNode(create, type) {
test(function() {
var node = create()
assert_equals(node.data, "test")
assert_throws("INDEX_SIZE_ERR", function() { node.deleteData(5, 10) })
assert_throws("INDEX_SIZE_ERR", function() { node.deleteData(5, 0) })
assert_throws("INDEX_SIZE_ERR", function() { node.deleteData(-1, 10) })
assert_throws("INDEX_SIZE_ERR", function() { node.deleteData(-1, 0) })
}, type + ".deleteData() out of bounds")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.deleteData(0, 2)
assert_equals(node.data, "st")
}, type + ".deleteData() at the start")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.deleteData(2, 10)
assert_equals(node.data, "te")
}, type + ".deleteData() at the end")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.deleteData(1, 1)
assert_equals(node.data, "tst")
}, type + ".deleteData() in the middle")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.deleteData(2, 0)
assert_equals(node.data, "test")
node.deleteData(0, 0)
assert_equals(node.data, "test")
}, type + ".deleteData() with zero count")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.deleteData(2, -1)
assert_equals(node.data, "te")
}, type + ".deleteData() with small negative count")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.deleteData(1, -0x100000000 + 2)
assert_equals(node.data, "tt")
}, type + ".deleteData() with large negative count")
test(function() {
var node = create()
node.data = "This is the character data test, append more 資料,更多測試資料";
node.deleteData(40, 5);
assert_equals(node.data, "This is the character data test, append 資料,更多測試資料");
node.deleteData(45, 2);
assert_equals(node.data, "This is the character data test, append 資料,更多資料");
}, type + ".deleteData() with non-ascii data")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.data = "🌠 test 🌠 TEST"
node.deleteData(5, 8); // Counting UTF-16 code units
assert_equals(node.data, "🌠 teST");
}, type + ".deleteData() with non-BMP data")
}
testNode(function() { return document.createTextNode("test") }, "Text")
testNode(function() { return document.createComment("test") }, "Comment")
</script>

View file

@ -0,0 +1,90 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>CharacterData.insertData</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-characterdata-insertdata">
<link rel=help href="https://dom.spec.whatwg.org/#dom-characterdata-data">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
function testNode(create, type) {
test(function() {
var node = create()
assert_equals(node.data, "test")
assert_throws("INDEX_SIZE_ERR", function() { node.insertData(5, "x") })
assert_throws("INDEX_SIZE_ERR", function() { node.insertData(5, "") })
}, type + ".insertData() out of bounds")
test(function() {
var node = create()
assert_equals(node.data, "test")
assert_throws("INDEX_SIZE_ERR", function() { node.insertData(-1, "x") })
assert_throws("INDEX_SIZE_ERR", function() { node.insertData(-0x100000000 + 5, "x") })
}, type + ".insertData() negative out of bounds")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.insertData(-0x100000000 + 2, "X")
assert_equals(node.data, "teXst")
}, type + ".insertData() negative in bounds")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.insertData(0, "")
assert_equals(node.data, "test")
}, type + ".insertData('')")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.insertData(0, "X")
assert_equals(node.data, "Xtest")
}, type + ".insertData() at the start")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.insertData(2, "X")
assert_equals(node.data, "teXst")
}, type + ".insertData() in the middle")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.insertData(4, "ing")
assert_equals(node.data, "testing")
}, type + ".insertData() at the end")
test(function() {
var node = create()
node.data = "This is the character data, append more 資料,測試資料";
node.insertData(26, " test");
assert_equals(node.data, "This is the character data test, append more 資料,測試資料");
node.insertData(48, "更多");
assert_equals(node.data, "This is the character data test, append more 資料,更多測試資料");
}, type + ".insertData() with non-ascii data")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.data = "🌠 test 🌠 TEST"
node.insertData(5, "--"); // Counting UTF-16 code units
assert_equals(node.data, "🌠 te--st 🌠 TEST");
}, type + ".insertData() with non-BMP data")
}
testNode(function() { return document.createTextNode("test") }, "Text")
testNode(function() { return document.createComment("test") }, "Comment")
</script>

View file

@ -0,0 +1,24 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>CharacterData.remove</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-childnode-remove">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="ChildNode-remove.js"></script>
<div id=log></div>
<script>
var text, text_parent,
comment, comment_parent,
pi, pi_parent;
setup(function() {
text = document.createTextNode("text");
text_parent = document.createElement("div");
comment = document.createComment("comment");
comment_parent = document.createElement("div");
pi = document.createProcessingInstruction("foo", "bar");
pi_parent = document.createElement("div");
});
testRemove(text, text_parent, "text");
testRemove(comment, comment_parent, "comment");
testRemove(pi, pi_parent, "PI");
</script>

View file

@ -0,0 +1,163 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>CharacterData.replaceData</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-characterdata-replacedata">
<link rel=help href="https://dom.spec.whatwg.org/#dom-characterdata-data">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
function testNode(create, type) {
// Step 2.
test(function() {
var node = create()
assert_equals(node.data, "test")
assert_throws("IndexSizeError", function() { node.replaceData(5, 1, "x") })
assert_throws("IndexSizeError", function() { node.replaceData(5, 0, "") })
assert_throws("IndexSizeError", function() { node.replaceData(-1, 1, "x") })
assert_throws("IndexSizeError", function() { node.replaceData(-1, 0, "") })
assert_equals(node.data, "test")
}, type + ".replaceData() with invalid offset")
// Step 3.
test(function() {
var node = create()
assert_equals(node.data, "test")
node.replaceData(2, 10, "yo")
assert_equals(node.data, "teyo")
}, type + ".replaceData() with clamped count")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.replaceData(2, -1, "yo")
assert_equals(node.data, "teyo")
}, type + ".replaceData() with negative clamped count")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.replaceData(0, 0, "yo")
assert_equals(node.data, "yotest")
}, type + ".replaceData() before the start")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.replaceData(0, 2, "y")
assert_equals(node.data, "yst")
}, type + ".replaceData() at the start (shorter)")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.replaceData(0, 2, "yo")
assert_equals(node.data, "yost")
}, type + ".replaceData() at the start (equal length)")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.replaceData(0, 2, "yoa")
assert_equals(node.data, "yoast")
}, type + ".replaceData() at the start (longer)")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.replaceData(1, 2, "o")
assert_equals(node.data, "tot")
}, type + ".replaceData() in the middle (shorter)")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.replaceData(1, 2, "yo")
assert_equals(node.data, "tyot")
}, type + ".replaceData() in the middle (equal length)")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.replaceData(1, 1, "waddup")
assert_equals(node.data, "twaddupst")
node.replaceData(1, 1, "yup")
assert_equals(node.data, "tyupaddupst")
}, type + ".replaceData() in the middle (longer)")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.replaceData(1, 20, "yo")
assert_equals(node.data, "tyo")
}, type + ".replaceData() at the end (shorter)")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.replaceData(2, 20, "yo")
assert_equals(node.data, "teyo")
}, type + ".replaceData() at the end (same length)")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.replaceData(4, 20, "yo")
assert_equals(node.data, "testyo")
}, type + ".replaceData() at the end (longer)")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.replaceData(0, 4, "quux")
assert_equals(node.data, "quux")
}, type + ".replaceData() the whole string")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.replaceData(0, 4, "")
assert_equals(node.data, "")
}, type + ".replaceData() with the empty string")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.data = "This is the character data test, append 資料,更多資料";
node.replaceData(33, 6, "other");
assert_equals(node.data, "This is the character data test, other 資料,更多資料");
node.replaceData(44, 2, "文字");
assert_equals(node.data, "This is the character data test, other 資料,更多文字");
}, type + ".replaceData() with non-ASCII data")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.data = "🌠 test 🌠 TEST"
node.replaceData(5, 8, "--"); // Counting UTF-16 code units
assert_equals(node.data, "🌠 te--ST");
}, type + ".replaceData() with non-BMP data")
}
testNode(function() { return document.createTextNode("test") }, "Text")
testNode(function() { return document.createComment("test") }, "Comment")
</script>

View file

@ -0,0 +1,137 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>CharacterData.substringData</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-characterdata-substringdata">
<link rel=help href="https://dom.spec.whatwg.org/#dom-characterdata-data">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
function testNode(create, type) {
test(function() {
var node = create()
assert_equals(node.data, "test")
assert_throws(new TypeError(), function() { node.substringData() })
assert_throws(new TypeError(), function() { node.substringData(0) })
}, type + ".substringData() with too few arguments")
test(function() {
var node = create()
assert_equals(node.data, "test")
assert_equals(node.substringData(0, 1, "test"), "t")
}, type + ".substringData() with too many arguments")
test(function() {
var node = create()
assert_equals(node.data, "test")
assert_throws("IndexSizeError", function() { node.substringData(5, 0) })
assert_throws("IndexSizeError", function() { node.substringData(6, 0) })
assert_throws("IndexSizeError", function() { node.substringData(-1, 0) })
}, type + ".substringData() with invalid offset")
test(function() {
var node = create()
assert_equals(node.data, "test")
assert_equals(node.substringData(0, 1), "t")
assert_equals(node.substringData(1, 1), "e")
assert_equals(node.substringData(2, 1), "s")
assert_equals(node.substringData(3, 1), "t")
assert_equals(node.substringData(4, 1), "")
}, type + ".substringData() with in-bounds offset")
test(function() {
var node = create()
assert_equals(node.data, "test")
assert_equals(node.substringData(0, 0), "")
assert_equals(node.substringData(1, 0), "")
assert_equals(node.substringData(2, 0), "")
assert_equals(node.substringData(3, 0), "")
assert_equals(node.substringData(4, 0), "")
}, type + ".substringData() with zero count")
test(function() {
var node = create()
assert_equals(node.data, "test")
assert_equals(node.substringData(0x100000000 + 0, 1), "t")
assert_equals(node.substringData(0x100000000 + 1, 1), "e")
assert_equals(node.substringData(0x100000000 + 2, 1), "s")
assert_equals(node.substringData(0x100000000 + 3, 1), "t")
assert_equals(node.substringData(0x100000000 + 4, 1), "")
}, type + ".substringData() with very large offset")
test(function() {
var node = create()
assert_equals(node.data, "test")
assert_equals(node.substringData(-0x100000000 + 2, 1), "s")
}, type + ".substringData() with negative offset")
test(function() {
var node = create()
assert_equals(node.data, "test")
assert_equals(node.substringData("test", 3), "tes")
}, type + ".substringData() with string offset")
test(function() {
var node = create()
assert_equals(node.data, "test")
assert_equals(node.substringData(0, 1), "t")
assert_equals(node.substringData(0, 2), "te")
assert_equals(node.substringData(0, 3), "tes")
assert_equals(node.substringData(0, 4), "test")
}, type + ".substringData() with in-bounds count")
test(function() {
var node = create()
assert_equals(node.data, "test")
assert_equals(node.substringData(0, 5), "test")
assert_equals(node.substringData(2, 20), "st")
}, type + ".substringData() with large count")
test(function() {
var node = create()
assert_equals(node.data, "test")
assert_equals(node.substringData(2, 0x100000000 + 1), "s")
}, type + ".substringData() with very large count")
test(function() {
var node = create()
assert_equals(node.data, "test")
assert_equals(node.substringData(0, -1), "test")
assert_equals(node.substringData(0, -0x100000000 + 2), "te")
}, type + ".substringData() with negative count")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.data = "This is the character data test, other 資料,更多文字"
assert_equals(node.substringData(12, 4), "char")
assert_equals(node.substringData(39, 2), "資料")
}, type + ".substringData() with non-ASCII data")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.data = "🌠 test 🌠 TEST"
assert_equals(node.substringData(5, 8), "st 🌠 TE") // Counting UTF-16 code units
}, type + ".substringData() with non-BMP data")
}
testNode(function() { return document.createTextNode("test") }, "Text")
testNode(function() { return document.createComment("test") }, "Comment")
</script>

View file

@ -0,0 +1,74 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>Splitting and joining surrogate pairs in CharacterData methods</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-characterdata-substringdata">
<link rel=help href="https://dom.spec.whatwg.org/#dom-characterdata-replacedata">
<link rel=help href="https://dom.spec.whatwg.org/#dom-characterdata-insertdata">
<link rel=help href="https://dom.spec.whatwg.org/#dom-characterdata-deletedata">
<link rel=help href="https://dom.spec.whatwg.org/#dom-characterdata-data">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
function testNode(create, type) {
test(function() {
var node = create()
assert_equals(node.data, "test")
node.data = "🌠 test 🌠 TEST"
assert_equals(node.substringData(1, 8), "\uDF20 test \uD83C")
}, type + ".substringData() splitting surrogate pairs")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.data = "🌠 test 🌠 TEST"
node.replaceData(1, 4, "--");
assert_equals(node.data, "\uD83C--st 🌠 TEST");
node.replaceData(1, 2, "\uDF1F ");
assert_equals(node.data, "🌟 st 🌠 TEST");
node.replaceData(5, 2, "---");
assert_equals(node.data, "🌟 st---\uDF20 TEST");
node.replaceData(6, 2, " \uD83D");
assert_equals(node.data, "🌟 st- 🜠 TEST");
}, type + ".replaceData() splitting and creating surrogate pairs")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.data = "🌠 test 🌠 TEST"
node.deleteData(1, 4);
assert_equals(node.data, "\uD83Cst 🌠 TEST");
node.deleteData(1, 4);
assert_equals(node.data, "🌠 TEST");
}, type + ".deleteData() splitting and creating surrogate pairs")
test(function() {
var node = create()
assert_equals(node.data, "test")
node.data = "🌠 test 🌠 TEST"
node.insertData(1, "--");
assert_equals(node.data, "\uD83C--\uDF20 test 🌠 TEST");
node.insertData(1, "\uDF1F ");
assert_equals(node.data, "🌟 --\uDF20 test 🌠 TEST");
node.insertData(5, " \uD83D");
assert_equals(node.data, "🌟 -- 🜠 test 🌠 TEST");
}, type + ".insertData() splitting and creating surrogate pairs")
}
testNode(function() { return document.createTextNode("test") }, "Text")
testNode(function() { return document.createComment("test") }, "Comment")
</script>

View file

@ -0,0 +1,166 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>ChildNode.after</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-childnode-after">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
function test_after(child, nodeName, innerHTML) {
test(function() {
var parent = document.createElement('div');
parent.appendChild(child);
child.after();
assert_equals(parent.innerHTML, innerHTML);
}, nodeName + '.after() without any argument.');
test(function() {
var parent = document.createElement('div');
parent.appendChild(child);
child.after(null);
var expected = innerHTML + 'null';
assert_equals(parent.innerHTML, expected);
}, nodeName + '.after() with null as an argument.');
test(function() {
var parent = document.createElement('div');
parent.appendChild(child);
child.after(undefined);
var expected = innerHTML + 'undefined';
assert_equals(parent.innerHTML, expected);
}, nodeName + '.after() with undefined as an argument.');
test(function() {
var parent = document.createElement('div');
parent.appendChild(child);
child.after('');
assert_equals(parent.lastChild.data, '');
}, nodeName + '.after() with the empty string as an argument.');
test(function() {
var parent = document.createElement('div');
parent.appendChild(child);
child.after('text');
var expected = innerHTML + 'text';
assert_equals(parent.innerHTML, expected);
}, nodeName + '.after() with only text as an argument.');
test(function() {
var parent = document.createElement('div');
var x = document.createElement('x');
parent.appendChild(child);
child.after(x);
var expected = innerHTML + '<x></x>';
assert_equals(parent.innerHTML, expected);
}, nodeName + '.after() with only one element as an argument.');
test(function() {
var parent = document.createElement('div');
var x = document.createElement('x');
parent.appendChild(child);
child.after(x, 'text');
var expected = innerHTML + '<x></x>text';
assert_equals(parent.innerHTML, expected);
}, nodeName + '.after() with one element and text as arguments.');
test(function() {
var parent = document.createElement('div');
parent.appendChild(child);
child.after('text', child);
var expected = 'text' + innerHTML;
assert_equals(parent.innerHTML, expected);
}, nodeName + '.after() with context object itself as the argument.');
test(function() {
var parent = document.createElement('div')
var x = document.createElement('x');
parent.appendChild(x);
parent.appendChild(child);
child.after(child, x);
var expected = innerHTML + '<x></x>';
assert_equals(parent.innerHTML, expected);
}, nodeName + '.after() with context object itself and node as the arguments, switching positions.');
test(function() {
var parent = document.createElement('div');
var x = document.createElement('x');
var y = document.createElement('y');
var z = document.createElement('z');
parent.appendChild(y);
parent.appendChild(child);
parent.appendChild(x);
child.after(x, y, z);
var expected = innerHTML + '<x></x><y></y><z></z>';
assert_equals(parent.innerHTML, expected);
}, nodeName + '.after() with all siblings of child as arguments.');
test(function() {
var parent = document.createElement('div')
var x = document.createElement('x');
var y = document.createElement('y');
var z = document.createElement('z');
parent.appendChild(child);
parent.appendChild(x);
parent.appendChild(y);
parent.appendChild(z);
child.after(x, y);
var expected = innerHTML + '<x></x><y></y><z></z>';
assert_equals(parent.innerHTML, expected);
}, nodeName + '.before() with some siblings of child as arguments; no changes in tree; viable sibling is first child.');
test(function() {
var parent = document.createElement('div')
var v = document.createElement('v');
var x = document.createElement('x');
var y = document.createElement('y');
var z = document.createElement('z');
parent.appendChild(child);
parent.appendChild(v);
parent.appendChild(x);
parent.appendChild(y);
parent.appendChild(z);
child.after(v, x);
var expected = innerHTML + '<v></v><x></x><y></y><z></z>';
assert_equals(parent.innerHTML, expected);
}, nodeName + '.after() with some siblings of child as arguments; no changes in tree.');
test(function() {
var parent = document.createElement('div');
var x = document.createElement('x');
var y = document.createElement('y');
parent.appendChild(child);
parent.appendChild(x);
parent.appendChild(y);
child.after(y, x);
var expected = innerHTML + '<y></y><x></x>';
assert_equals(parent.innerHTML, expected);
}, nodeName + '.after() when pre-insert behaves like append.');
test(function() {
var parent = document.createElement('div');
var x = document.createElement('x');
var y = document.createElement('y');
parent.appendChild(child);
parent.appendChild(x);
parent.appendChild(document.createTextNode('1'));
parent.appendChild(y);
child.after(x, '2');
var expected = innerHTML + '<x></x>21<y></y>';
assert_equals(parent.innerHTML, expected);
}, nodeName + '.after() with one sibling of child and text as arguments.');
test(function() {
var x = document.createElement('x');
var y = document.createElement('y');
x.after(y);
assert_equals(x.nextSibling, null);
}, nodeName + '.after() on a child without any parent.');
}
test_after(document.createComment('test'), 'Comment', '<!--test-->');
test_after(document.createElement('test'), 'Element', '<test></test>');
test_after(document.createTextNode('test'), 'Text', 'test');
</script>
</html>

View file

@ -0,0 +1,166 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>ChildNode.before</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-childnode-before">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
function test_before(child, nodeName, innerHTML) {
test(function() {
var parent = document.createElement('div');
parent.appendChild(child);
child.before();
assert_equals(parent.innerHTML, innerHTML);
}, nodeName + '.before() without any argument.');
test(function() {
var parent = document.createElement('div');
parent.appendChild(child);
child.before(null);
var expected = 'null' + innerHTML;
assert_equals(parent.innerHTML, expected);
}, nodeName + '.before() with null as an argument.');
test(function() {
var parent = document.createElement('div');
parent.appendChild(child);
child.before(undefined);
var expected = 'undefined' + innerHTML;
assert_equals(parent.innerHTML, expected);
}, nodeName + '.before() with undefined as an argument.');
test(function() {
var parent = document.createElement('div');
parent.appendChild(child);
child.before('');
assert_equals(parent.firstChild.data, '');
}, nodeName + '.before() with the empty string as an argument.');
test(function() {
var parent = document.createElement('div');
parent.appendChild(child);
child.before('text');
var expected = 'text' + innerHTML;
assert_equals(parent.innerHTML, expected);
}, nodeName + '.before() with only text as an argument.');
test(function() {
var parent = document.createElement('div');
var x = document.createElement('x');
parent.appendChild(child);
child.before(x);
var expected = '<x></x>' + innerHTML;
assert_equals(parent.innerHTML, expected);
}, nodeName + '.before() with only one element as an argument.');
test(function() {
var parent = document.createElement('div');
var x = document.createElement('x');
parent.appendChild(child);
child.before(x, 'text');
var expected = '<x></x>text' + innerHTML;
assert_equals(parent.innerHTML, expected);
}, nodeName + '.before() with one element and text as arguments.');
test(function() {
var parent = document.createElement('div');
parent.appendChild(child);
child.before('text', child);
var expected = 'text' + innerHTML;
assert_equals(parent.innerHTML, expected);
}, nodeName + '.before() with context object itself as the argument.');
test(function() {
var parent = document.createElement('div')
var x = document.createElement('x');
parent.appendChild(child);
parent.appendChild(x);
child.before(x, child);
var expected = '<x></x>' + innerHTML;
assert_equals(parent.innerHTML, expected);
}, nodeName + '.before() with context object itself and node as the arguments, switching positions.');
test(function() {
var parent = document.createElement('div');
var x = document.createElement('x');
var y = document.createElement('y');
var z = document.createElement('z');
parent.appendChild(y);
parent.appendChild(child);
parent.appendChild(x);
child.before(x, y, z);
var expected = '<x></x><y></y><z></z>' + innerHTML;
assert_equals(parent.innerHTML, expected);
}, nodeName + '.before() with all siblings of child as arguments.');
test(function() {
var parent = document.createElement('div')
var x = document.createElement('x');
var y = document.createElement('y');
var z = document.createElement('z');
parent.appendChild(x);
parent.appendChild(y);
parent.appendChild(z);
parent.appendChild(child);
child.before(y, z);
var expected = '<x></x><y></y><z></z>' + innerHTML;
assert_equals(parent.innerHTML, expected);
}, nodeName + '.before() with some siblings of child as arguments; no changes in tree; viable sibling is first child.');
test(function() {
var parent = document.createElement('div')
var v = document.createElement('v');
var x = document.createElement('x');
var y = document.createElement('y');
var z = document.createElement('z');
parent.appendChild(v);
parent.appendChild(x);
parent.appendChild(y);
parent.appendChild(z);
parent.appendChild(child);
child.before(y, z);
var expected = '<v></v><x></x><y></y><z></z>' + innerHTML;
assert_equals(parent.innerHTML, expected);
}, nodeName + '.before() with some siblings of child as arguments; no changes in tree.');
test(function() {
var parent = document.createElement('div');
var x = document.createElement('x');
var y = document.createElement('y');
parent.appendChild(x);
parent.appendChild(y);
parent.appendChild(child);
child.before(y, x);
var expected = '<y></y><x></x>' + innerHTML;
assert_equals(parent.innerHTML, expected);
}, nodeName + '.before() when pre-insert behaves like prepend.');
test(function() {
var parent = document.createElement('div');
var x = document.createElement('x');
parent.appendChild(x);
parent.appendChild(document.createTextNode('1'));
var y = document.createElement('y');
parent.appendChild(y);
parent.appendChild(child);
child.before(x, '2');
var expected = '1<y></y><x></x>2' + innerHTML;
assert_equals(parent.innerHTML, expected);
}, nodeName + '.before() with one sibling of child and text as arguments.');
test(function() {
var x = document.createElement('x');
var y = document.createElement('y');
x.before(y);
assert_equals(x.previousSibling, null);
}, nodeName + '.before() on a child without any parent.');
}
test_before(document.createComment('test'), 'Comment', '<!--test-->');
test_before(document.createElement('test'), 'Element', '<test></test>');
test_before(document.createTextNode('test'), 'Text', 'test');
</script>
</html>

View file

@ -0,0 +1,30 @@
function testRemove(node, parent, type) {
test(function() {
assert_true("remove" in node);
assert_equals(typeof node.remove, "function");
assert_equals(node.remove.length, 0);
}, type + " should support remove()");
test(function() {
assert_equals(node.parentNode, null, "Node should not have a parent");
assert_equals(node.remove(), undefined);
assert_equals(node.parentNode, null, "Removed new node should not have a parent");
}, "remove() should work if " + type + " doesn't have a parent");
test(function() {
assert_equals(node.parentNode, null, "Node should not have a parent");
parent.appendChild(node);
assert_equals(node.parentNode, parent, "Appended node should have a parent");
assert_equals(node.remove(), undefined);
assert_equals(node.parentNode, null, "Removed node should not have a parent");
assert_array_equals(parent.childNodes, [], "Parent should not have children");
}, "remove() should work if " + type + " does have a parent");
test(function() {
assert_equals(node.parentNode, null, "Node should not have a parent");
var before = parent.appendChild(document.createComment("before"));
parent.appendChild(node);
var after = parent.appendChild(document.createComment("after"));
assert_equals(node.parentNode, parent, "Appended node should have a parent");
assert_equals(node.remove(), undefined);
assert_equals(node.parentNode, null, "Removed node should not have a parent");
assert_array_equals(parent.childNodes, [before, after], "Parent should have two children left");
}, "remove() should work if " + type + " does have a parent and siblings");
}

View file

@ -0,0 +1,110 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>ChildNode.replaceWith</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-childnode-replaceWith">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
function test_replaceWith(child, nodeName, innerHTML) {
test(function() {
var parent = document.createElement('div');
parent.appendChild(child);
child.replaceWith();
assert_equals(parent.innerHTML, '');
}, nodeName + '.replaceWith() without any argument.');
test(function() {
var parent = document.createElement('div');
parent.appendChild(child);
child.replaceWith(null);
assert_equals(parent.innerHTML, 'null');
}, nodeName + '.replaceWith() with null as an argument.');
test(function() {
var parent = document.createElement('div');
parent.appendChild(child);
child.replaceWith(undefined);
assert_equals(parent.innerHTML, 'undefined');
}, nodeName + '.replaceWith() with undefined as an argument.');
test(function() {
var parent = document.createElement('div');
parent.appendChild(child);
child.replaceWith('');
assert_equals(parent.innerHTML, '');
}, nodeName + '.replaceWith() with empty string as an argument.');
test(function() {
var parent = document.createElement('div');
parent.appendChild(child);
child.replaceWith('text');
assert_equals(parent.innerHTML, 'text');
}, nodeName + '.replaceWith() with only text as an argument.');
test(function() {
var parent = document.createElement('div');
var x = document.createElement('x');
parent.appendChild(child);
child.replaceWith(x);
assert_equals(parent.innerHTML, '<x></x>');
}, nodeName + '.replaceWith() with only one element as an argument.');
test(function() {
var parent = document.createElement('div');
var x = document.createElement('x');
var y = document.createElement('y');
var z = document.createElement('z');
parent.appendChild(y);
parent.appendChild(child);
parent.appendChild(x);
child.replaceWith(x, y, z);
assert_equals(parent.innerHTML, '<x></x><y></y><z></z>');
}, nodeName + '.replaceWith() with sibling of child as arguments.');
test(function() {
var parent = document.createElement('div');
var x = document.createElement('x');
parent.appendChild(child);
parent.appendChild(x);
parent.appendChild(document.createTextNode('1'));
child.replaceWith(x, '2');
assert_equals(parent.innerHTML, '<x></x>21');
}, nodeName + '.replaceWith() with one sibling of child and text as arguments.');
test(function() {
var parent = document.createElement('div');
var x = document.createElement('x');
parent.appendChild(child);
parent.appendChild(x);
parent.appendChild(document.createTextNode('text'));
child.replaceWith(x, child);
assert_equals(parent.innerHTML, '<x></x>' + innerHTML + 'text');
}, nodeName + '.replaceWith() with one sibling of child and child itself as arguments.');
test(function() {
var parent = document.createElement('div');
var x = document.createElement('x');
parent.appendChild(child);
child.replaceWith(x, 'text');
assert_equals(parent.innerHTML, '<x></x>text');
}, nodeName + '.replaceWith() with one element and text as arguments.');
test(function() {
var parent = document.createElement('div');
var x = document.createElement('x');
var y = document.createElement('y');
parent.appendChild(x);
parent.appendChild(y);
child.replaceWith(x, y);
assert_equals(parent.innerHTML, '<x></x><y></y>');
}, nodeName + '.replaceWith() on a parentless child with two elements as arguments.');
}
test_replaceWith(document.createComment('test'), 'Comment', '<!--test-->');
test_replaceWith(document.createElement('test'), 'Element', '<test></test>');
test_replaceWith(document.createTextNode('test'), 'Text', 'test');
</script>
</html>

View file

@ -0,0 +1,77 @@
function test_constructor(ctor) {
test(function() {
var object = new window[ctor]();
assert_equals(Object.getPrototypeOf(object),
window[ctor].prototype, "Prototype chain: " + ctor);
assert_equals(Object.getPrototypeOf(Object.getPrototypeOf(object)),
CharacterData.prototype, "Prototype chain: CharacterData");
assert_equals(Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(object))),
Node.prototype, "Prototype chain: Node");
}, "new " + ctor + "(): prototype chain");
test(function() {
var object = new window[ctor]();
assert_true(object instanceof Node, "Should be a Node");
assert_true(object instanceof CharacterData, "Should be a CharacterData");
assert_true(object instanceof window[ctor], "Should be a " + ctor);
}, "new " + ctor + "(): instanceof");
test(function() {
var object = new window[ctor]();
assert_equals(object.data, "");
assert_equals(object.nodeValue, "");
assert_equals(object.ownerDocument, document);
}, "new " + ctor + "(): no arguments");
var arguments = [
[undefined, ""],
[null, "null"],
[42, "42"],
["", ""],
["-", "-"],
["--", "--"],
["-->", "-->"],
["<!--", "<!--"],
["\u0000", "\u0000"],
["\u0000test", "\u0000test"],
["&amp;", "&amp;"],
];
arguments.forEach(function(a) {
var argument = a[0], expected = a[1];
test(function() {
var object = new window[ctor](argument);
assert_equals(object.data, expected);
assert_equals(object.nodeValue, expected);
assert_equals(object.ownerDocument, document);
}, "new " + ctor + "(): " + format_value(argument));
});
test(function() {
var called = [];
var object = new window[ctor]({
toString: function() {
called.push("first");
return "text";
}
}, {
toString: function() {
called.push("second");
assert_unreached("Should not look at the second argument.");
}
});
assert_equals(object.data, "text");
assert_equals(object.nodeValue, "text");
assert_equals(object.ownerDocument, document);
assert_array_equals(called, ["first"]);
}, "new " + ctor + "(): two arguments")
async_test("new " + ctor + "() should get the correct ownerDocument across globals").step(function() {
var iframe = document.createElement("iframe");
iframe.onload = this.step_func_done(function() {
var object = new iframe.contentWindow[ctor]();
assert_equals(object.ownerDocument, iframe.contentDocument);
});
document.body.appendChild(iframe);
});
}

View file

@ -0,0 +1,11 @@
<!doctype html>
<meta charset=utf-8>
<title>Comment constructor</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-comment">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="Comment-Text-constructor.js"></script>
<div id="log"></div>
<script>
test_constructor("Comment");
</script>

View file

@ -0,0 +1,166 @@
<!doctype html>
<meta charset=utf-8>
<title>DOMImplementation.createDocument(namespace, qualifiedName, doctype)</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-domimplementation-createdocument">
<link rel=help href="https://dom.spec.whatwg.org/#dom-document-createelementns">
<link rel=help href="https://dom.spec.whatwg.org/#dom-node-nodetype">
<link rel=help href="https://dom.spec.whatwg.org/#dom-document-documentelement">
<link rel=help href="https://dom.spec.whatwg.org/#dom-document-doctype">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="Document-createElementNS.js"></script>
<div id="log"></div>
<script>
var htmlNamespace = "http://www.w3.org/1999/xhtml"
var svgNamespace = "http://www.w3.org/2000/svg"
var mathMLNamespace = "http://www.w3.org/1998/Math/MathML"
// Make DocumentTypes distinct
function my_format_value(val) {
if (val instanceof DocumentType) {
return "DocumentType node <!DOCTYPE " + val.name
+ (val.publicId ? " " + val.publicId : "")
+ (val.systemId ? " " + val.systemId : "")
+ ">";
}
return format_value(val);
}
test(function() {
var tests = createElementNS_tests.map(function(t) {
return [t[0], t[1], null, t[2]]
}).concat([
/* Arrays with four elements:
* the namespace argument
* the qualifiedName argument
* the doctype argument
* the expected exception, or null if none
*/
[null, null, false, new TypeError()],
[null, null, null, null],
[null, "", null, null],
[undefined, null, undefined, null],
[undefined, undefined, undefined, null],
[undefined, "", undefined, null],
["http://example.com/", null, null, null],
["http://example.com/", "", null, null],
["/", null, null, null],
["/", "", null, null],
["http://www.w3.org/XML/1998/namespace", null, null, null],
["http://www.w3.org/XML/1998/namespace", "", null, null],
["http://www.w3.org/2000/xmlns/", null, null, null],
["http://www.w3.org/2000/xmlns/", "", null, null],
["foo:", null, null, null],
["foo:", "", null, null],
[null, null, document.implementation.createDocumentType("foo", "", ""), null],
[null, null, document.doctype, null], // This causes a horrible WebKit bug (now fixed in trunk).
[null, null, function() {
var foo = document.implementation.createDocumentType("bar", "", "");
document.implementation.createDocument(null, null, foo);
return foo;
}(), null], // DOCTYPE already associated with a document.
[null, null, function() {
var bar = document.implementation.createDocument(null, null, null);
return bar.implementation.createDocumentType("baz", "", "");
}(), null], // DOCTYPE created by a different implementation.
[null, null, function() {
var bar = document.implementation.createDocument(null, null, null);
var magic = bar.implementation.createDocumentType("quz", "", "");
bar.implementation.createDocument(null, null, magic);
return magic;
}(), null], // DOCTYPE created by a different implementation and already associated with a document.
[null, "foo", document.implementation.createDocumentType("foo", "", ""), null],
["foo", null, document.implementation.createDocumentType("foo", "", ""), null],
["foo", "bar", document.implementation.createDocumentType("foo", "", ""), null],
[htmlNamespace, "", null, null],
[svgNamespace, "", null, null],
[mathMLNamespace, "", null, null],
[null, "html", null, null],
[null, "svg", null, null],
[null, "math", null, null],
[null, "", document.implementation.createDocumentType("html",
"-//W3C//DTD XHTML 1.0 Transitional//EN",
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd")],
[null, "", document.implementation.createDocumentType("svg",
"-//W3C//DTD SVG 1.1//EN",
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd")],
[null, "", document.implementation.createDocumentType("math",
"-//W3C//DTD MathML 2.0//EN",
"http://www.w3.org/Math/DTD/mathml2/mathml2.dtd")],
])
tests.forEach(function(t, i) {
var namespace = t[0], qualifiedName = t[1], doctype = t[2], expected = t[3]
test(function() {
if (expected != null) {
assert_throws(expected, function() { document.implementation.createDocument(namespace, qualifiedName, doctype) })
} else {
var doc = document.implementation.createDocument(namespace, qualifiedName, doctype)
assert_equals(doc.nodeType, Node.DOCUMENT_NODE)
assert_equals(doc.nodeType, doc.DOCUMENT_NODE)
assert_equals(doc.nodeName, "#document")
assert_equals(doc.nodeValue, null)
assert_equals(Object.getPrototypeOf(doc), XMLDocument.prototype)
var omitRootElement = qualifiedName === null || String(qualifiedName) === ""
if (omitRootElement) {
assert_equals(doc.documentElement, null)
} else {
var element = doc.documentElement
assert_not_equals(element, null)
assert_equals(element.nodeType, Node.ELEMENT_NODE)
assert_equals(element.ownerDocument, doc)
var qualified = String(qualifiedName), names = []
if (qualified.indexOf(":") >= 0) {
names = qualified.split(":", 2)
} else {
names = [null, qualified]
}
assert_equals(element.prefix, names[0])
assert_equals(element.localName, names[1])
assert_equals(element.namespaceURI, namespace === undefined ? null : namespace)
}
if (!doctype) {
assert_equals(doc.doctype, null)
} else {
assert_equals(doc.doctype, doctype)
assert_equals(doc.doctype.ownerDocument, doc)
}
assert_equals(doc.childNodes.length, !omitRootElement + !!doctype)
}
}, "createDocument test: " + t.map(my_format_value))
if (expected === null) {
test(function() {
var doc = document.implementation.createDocument(namespace, qualifiedName, doctype)
assert_equals(doc.compatMode, "CSS1Compat")
assert_equals(doc.characterSet, "UTF-8")
assert_equals(doc.contentType, namespace == htmlNamespace ? "application/xhtml+xml"
: namespace == svgNamespace ? "image/svg+xml"
: "application/xml")
assert_equals(doc.URL, "about:blank")
assert_equals(doc.documentURI, "about:blank")
assert_equals(doc.createElement("DIV").localName, "DIV");
}, "createDocument test " + i + ": metadata for " +
[namespace, qualifiedName, doctype].map(my_format_value))
test(function() {
var doc = document.implementation.createDocument(namespace, qualifiedName, doctype)
assert_equals(doc.characterSet, "UTF-8", "characterSet");
assert_equals(doc.charset, "UTF-8", "charset");
assert_equals(doc.inputEncoding, "UTF-8", "inputEncoding");
}, "createDocument test " + i + ": characterSet aliases for " +
[namespace, qualifiedName, doctype].map(my_format_value))
}
})
})
test(function() {
assert_throws(new TypeError(), function() {
document.implementation.createDocument()
}, "createDocument() should throw")
assert_throws(new TypeError(), function() {
document.implementation.createDocument('')
}, "createDocument('') should throw")
}, "createDocument with missing arguments");
</script>

View file

@ -0,0 +1,123 @@
<!doctype html>
<meta charset=utf-8>
<title>DOMImplementation.createDocumentType(qualifiedName, publicId, systemId)</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype">
<link rel=help href="https://dom.spec.whatwg.org/#dom-documenttype-name">
<link rel=help href="https://dom.spec.whatwg.org/#dom-documenttype-publicid">
<link rel=help href="https://dom.spec.whatwg.org/#dom-documenttype-systemid">
<link rel=help href="https://dom.spec.whatwg.org/#dom-node-ownerdocument">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
test(function() {
var tests = [
["", "", "", "INVALID_CHARACTER_ERR"],
["test:root", "1234", "", null],
["test:root", "1234", "test", null],
["test:root", "test", "", null],
["test:root", "test", "test", null],
["_:_", "", "", null],
["_:h0", "", "", null],
["_:test", "", "", null],
["_:_.", "", "", null],
["_:a-", "", "", null],
["l_:_", "", "", null],
["ns:_0", "", "", null],
["ns:a0", "", "", null],
["ns0:test", "", "", null],
["ns:EEE.", "", "", null],
["ns:_-", "", "", null],
["a.b:c", "", "", null],
["a-b:c.j", "", "", null],
["a-b:c", "", "", null],
["foo", "", "", null],
["1foo", "", "", "INVALID_CHARACTER_ERR"],
["foo1", "", "", null],
["f1oo", "", "", null],
["@foo", "", "", "INVALID_CHARACTER_ERR"],
["foo@", "", "", "INVALID_CHARACTER_ERR"],
["f@oo", "", "", "INVALID_CHARACTER_ERR"],
["edi:{", "", "", "INVALID_CHARACTER_ERR"],
["edi:}", "", "", "INVALID_CHARACTER_ERR"],
["edi:~", "", "", "INVALID_CHARACTER_ERR"],
["edi:'", "", "", "INVALID_CHARACTER_ERR"],
["edi:!", "", "", "INVALID_CHARACTER_ERR"],
["edi:@", "", "", "INVALID_CHARACTER_ERR"],
["edi:#", "", "", "INVALID_CHARACTER_ERR"],
["edi:$", "", "", "INVALID_CHARACTER_ERR"],
["edi:%", "", "", "INVALID_CHARACTER_ERR"],
["edi:^", "", "", "INVALID_CHARACTER_ERR"],
["edi:&", "", "", "INVALID_CHARACTER_ERR"],
["edi:*", "", "", "INVALID_CHARACTER_ERR"],
["edi:(", "", "", "INVALID_CHARACTER_ERR"],
["edi:)", "", "", "INVALID_CHARACTER_ERR"],
["edi:+", "", "", "INVALID_CHARACTER_ERR"],
["edi:=", "", "", "INVALID_CHARACTER_ERR"],
["edi:[", "", "", "INVALID_CHARACTER_ERR"],
["edi:]", "", "", "INVALID_CHARACTER_ERR"],
["edi:\\", "", "", "INVALID_CHARACTER_ERR"],
["edi:/", "", "", "INVALID_CHARACTER_ERR"],
["edi:;", "", "", "INVALID_CHARACTER_ERR"],
["edi:`", "", "", "INVALID_CHARACTER_ERR"],
["edi:<", "", "", "INVALID_CHARACTER_ERR"],
["edi:>", "", "", "INVALID_CHARACTER_ERR"],
["edi:,", "", "", "INVALID_CHARACTER_ERR"],
["edi:a ", "", "", "INVALID_CHARACTER_ERR"],
["edi:\"", "", "", "INVALID_CHARACTER_ERR"],
["{", "", "", "INVALID_CHARACTER_ERR"],
["}", "", "", "INVALID_CHARACTER_ERR"],
["'", "", "", "INVALID_CHARACTER_ERR"],
["~", "", "", "INVALID_CHARACTER_ERR"],
["`", "", "", "INVALID_CHARACTER_ERR"],
["@", "", "", "INVALID_CHARACTER_ERR"],
["#", "", "", "INVALID_CHARACTER_ERR"],
["$", "", "", "INVALID_CHARACTER_ERR"],
["%", "", "", "INVALID_CHARACTER_ERR"],
["^", "", "", "INVALID_CHARACTER_ERR"],
["&", "", "", "INVALID_CHARACTER_ERR"],
["*", "", "", "INVALID_CHARACTER_ERR"],
["(", "", "", "INVALID_CHARACTER_ERR"],
[")", "", "", "INVALID_CHARACTER_ERR"],
["f:oo", "", "", null],
[":foo", "", "", "NAMESPACE_ERR"],
["foo:", "", "", "NAMESPACE_ERR"],
["prefix::local", "", "", "NAMESPACE_ERR"],
["foo", "foo", "", null],
["foo", "", "foo", null],
["foo", "f'oo", "", null],
["foo", "", "f'oo", null],
["foo", 'f"oo', "", null],
["foo", "", 'f"oo', null],
["foo", "f'o\"o", "", null],
["foo", "", "f'o\"o", null],
["foo", "foo>", "", null],
["foo", "", "foo>", null]
]
var doc = document.implementation.createHTMLDocument("title");
var doTest = function(aDocument, aQualifiedName, aPublicId, aSystemId) {
var doctype = aDocument.implementation.createDocumentType(aQualifiedName, aPublicId, aSystemId);
assert_equals(doctype.name, aQualifiedName, "name")
assert_equals(doctype.nodeName, aQualifiedName, "nodeName")
assert_equals(doctype.publicId, aPublicId, "publicId")
assert_equals(doctype.systemId, aSystemId, "systemId")
assert_equals(doctype.ownerDocument, aDocument, "ownerDocument")
assert_equals(doctype.nodeValue, null, "nodeValue")
}
tests.forEach(function(t) {
var qualifiedName = t[0], publicId = t[1], systemId = t[2], expected = t[3]
test(function() {
if (expected) {
assert_throws(expected, function() {
document.implementation.createDocumentType(qualifiedName, publicId, systemId)
})
} else {
doTest(document, qualifiedName, publicId, systemId);
doTest(doc, qualifiedName, publicId, systemId);
}
}, "createDocumentType(" + format_value(qualifiedName) + ", " + format_value(publicId) + ", " + format_value(systemId) + ") should " +
(expected ? "throw " + expected : "work"));
});
})
</script>

View file

@ -0,0 +1,90 @@
<!DOCTYPE html>
<meta charset=windows-1252>
<!-- Using windows-1252 to ensure that DOMImplementation.createHTMLDocument()
doesn't inherit utf-8 from the parent document. -->
<title>DOMImplementation.createHTMLDocument</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument">
<link rel=help href="https://dom.spec.whatwg.org/#dom-documenttype-name">
<link rel=help href="https://dom.spec.whatwg.org/#dom-documenttype-publicid">
<link rel=help href="https://dom.spec.whatwg.org/#dom-documenttype-systemid">
<link rel=help href="https://dom.spec.whatwg.org/#dom-document-documentelement">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="DOMImplementation-createHTMLDocument.js"></script>
<div id="log"></div>
<script>
createHTMLDocuments(function(doc, expectedtitle, normalizedtitle) {
assert_true(doc instanceof Document, "Should be a Document")
assert_true(doc instanceof Node, "Should be a Node")
assert_equals(doc.childNodes.length, 2,
"Document should have two child nodes")
var doctype = doc.doctype
assert_true(doctype instanceof DocumentType,
"Doctype should be a DocumentType")
assert_true(doctype instanceof Node, "Doctype should be a Node")
assert_equals(doctype.name, "html")
assert_equals(doctype.publicId, "")
assert_equals(doctype.systemId, "")
var documentElement = doc.documentElement
assert_true(documentElement instanceof HTMLHtmlElement,
"Document element should be a HTMLHtmlElement")
assert_equals(documentElement.childNodes.length, 2,
"Document element should have two child nodes")
assert_equals(documentElement.localName, "html")
assert_equals(documentElement.tagName, "HTML")
var head = documentElement.firstChild
assert_true(head instanceof HTMLHeadElement,
"Head should be a HTMLHeadElement")
assert_equals(head.localName, "head")
assert_equals(head.tagName, "HEAD")
if (expectedtitle !== undefined) {
assert_equals(head.childNodes.length, 1)
var title = head.firstChild
assert_true(title instanceof HTMLTitleElement,
"Title should be a HTMLTitleElement")
assert_equals(title.localName, "title")
assert_equals(title.tagName, "TITLE")
assert_equals(title.childNodes.length, 1)
assert_equals(title.firstChild.data, expectedtitle)
} else {
assert_equals(head.childNodes.length, 0)
}
var body = documentElement.lastChild
assert_true(body instanceof HTMLBodyElement,
"Body should be a HTMLBodyElement")
assert_equals(body.localName, "body")
assert_equals(body.tagName, "BODY")
assert_equals(body.childNodes.length, 0)
})
test(function() {
var doc = document.implementation.createHTMLDocument("test");
assert_equals(doc.URL, "about:blank");
assert_equals(doc.documentURI, "about:blank");
assert_equals(doc.compatMode, "CSS1Compat");
assert_equals(doc.characterSet, "UTF-8");
assert_equals(doc.contentType, "text/html");
assert_equals(doc.createElement("DIV").localName, "div");
}, "createHTMLDocument(): metadata")
test(function() {
var doc = document.implementation.createHTMLDocument("test");
assert_equals(doc.characterSet, "UTF-8", "characterSet");
assert_equals(doc.charset, "UTF-8", "charset");
assert_equals(doc.inputEncoding, "UTF-8", "inputEncoding");
}, "createHTMLDocument(): characterSet aliases")
test(function() {
var doc = document.implementation.createHTMLDocument("test");
var a = doc.createElement("a");
// In UTF-8: 0xC3 0xA4
a.href = "http://example.org/?\u00E4";
assert_equals(a.href, "http://example.org/?%C3%A4");
}, "createHTMLDocument(): URL parsing")
</script>

View file

@ -0,0 +1,25 @@
function createHTMLDocuments(checkDoc) {
var tests = [
["", "", ""],
[null, "null", "null"],
[undefined, undefined, ""],
["foo bar baz", "foo bar baz", "foo bar baz"],
["foo\t\tbar baz", "foo\t\tbar baz", "foo bar baz"],
["foo\n\nbar baz", "foo\n\nbar baz", "foo bar baz"],
["foo\f\fbar baz", "foo\f\fbar baz", "foo bar baz"],
["foo\r\rbar baz", "foo\r\rbar baz", "foo bar baz"],
]
tests.forEach(function(t, i) {
var title = t[0], expectedtitle = t[1], normalizedtitle = t[2]
test(function() {
var doc = document.implementation.createHTMLDocument(title);
checkDoc(doc, expectedtitle, normalizedtitle)
}, "createHTMLDocument test " + i + ": " + t.map(function(el) { return format_value(el) }))
})
test(function() {
var doc = document.implementation.createHTMLDocument();
checkDoc(doc, undefined, "")
}, "Missing title argument");
}

View file

@ -0,0 +1,155 @@
<!doctype html>
<meta charset=utf-8>
<title>DOMImplementation.hasFeature(feature, version)</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
test(function() {
var tests = [
[],
["Core"],
["XML"],
["org.w3c.svg"],
["org.w3c.dom.svg"],
["http://www.w3.org/TR/SVG11/feature#Script"],
["Core", "1.0"],
["Core", "2.0"],
["Core", "3.0"],
["Core", "100.0"],
["XML", "1.0"],
["XML", "2.0"],
["XML", "3.0"],
["XML", "100.0"],
["Core", "1"],
["Core", "2"],
["Core", "3"],
["Core", "100"],
["XML", "1"],
["XML", "2"],
["XML", "3"],
["XML", "100"],
["Core", "1.1"],
["Core", "2.1"],
["Core", "3.1"],
["Core", "100.1"],
["XML", "1.1"],
["XML", "2.1"],
["XML", "3.1"],
["XML", "100.1"],
["Core", ""],
["XML", ""],
["core", ""],
["xml", ""],
["CoRe", ""],
["XmL", ""],
[" Core", ""],
[" XML", ""],
["Core ", ""],
["XML ", ""],
["Co re", ""],
["XM L", ""],
["aCore", ""],
["aXML", ""],
["Corea", ""],
["XMLa", ""],
["Coare", ""],
["XMaL", ""],
["Core", " "],
["XML", " "],
["Core", " 1.0"],
["Core", " 2.0"],
["Core", " 3.0"],
["Core", " 100.0"],
["XML", " 1.0"],
["XML", " 2.0"],
["XML", " 3.0"],
["XML", " 100.0"],
["Core", "1.0 "],
["Core", "2.0 "],
["Core", "3.0 "],
["Core", "100.0 "],
["XML", "1.0 "],
["XML", "2.0 "],
["XML", "3.0 "],
["XML", "100.0 "],
["Core", "1. 0"],
["Core", "2. 0"],
["Core", "3. 0"],
["Core", "100. 0"],
["XML", "1. 0"],
["XML", "2. 0"],
["XML", "3. 0"],
["XML", "100. 0"],
["Core", "a1.0"],
["Core", "a2.0"],
["Core", "a3.0"],
["Core", "a100.0"],
["XML", "a1.0"],
["XML", "a2.0"],
["XML", "a3.0"],
["XML", "a100.0"],
["Core", "1.0a"],
["Core", "2.0a"],
["Core", "3.0a"],
["Core", "100.0a"],
["XML", "1.0a"],
["XML", "2.0a"],
["XML", "3.0a"],
["XML", "100.0a"],
["Core", "1.a0"],
["Core", "2.a0"],
["Core", "3.a0"],
["Core", "100.a0"],
["XML", "1.a0"],
["XML", "2.a0"],
["XML", "3.a0"],
["XML", "100.a0"],
["Core", 1],
["Core", 2],
["Core", 3],
["Core", 100],
["XML", 1],
["XML", 2],
["XML", 3],
["XML", 100],
["Core", null],
["XML", null],
["core", null],
["xml", null],
["CoRe", null],
["XmL", null],
[" Core", null],
[" XML", null],
["Core ", null],
["XML ", null],
["Co re", null],
["XM L", null],
["aCore", null],
["aXML", null],
["Corea", null],
["XMLa", null],
["Coare", null],
["XMaL", null],
["Core", undefined],
["XML", undefined],
["This is filler text.", ""],
[null, ""],
[undefined, ""],
["org.w3c.svg", ""],
["org.w3c.svg", "1.0"],
["org.w3c.svg", "1.1"],
["org.w3c.dom.svg", ""],
["org.w3c.dom.svg", "1.0"],
["org.w3c.dom.svg", "1.1"],
["http://www.w3.org/TR/SVG11/feature#Script", "7.5"],
];
tests.forEach(function(data) {
test(function() {
assert_equals(document.implementation.hasFeature
.apply(document.implementation, data), true)
}, "hasFeature(" + data.map(format_value).join(", ") + ")")
})
})
</script>

View file

@ -0,0 +1,193 @@
function test_getElementsByTagName(context, element) {
// TODO: getElementsByTagName("*")
test(function() {
assert_false(context.getElementsByTagName("html") instanceof NodeList,
"Should not return a NodeList")
assert_true(context.getElementsByTagName("html") instanceof HTMLCollection,
"Should return an HTMLCollection")
}, "Interfaces")
test(function() {
var firstCollection = context.getElementsByTagName("html"),
secondCollection = context.getElementsByTagName("html")
assert_true(firstCollection !== secondCollection ||
firstCollection === secondCollection)
}, "Caching is allowed")
test(function() {
var l = context.getElementsByTagName("nosuchtag")
l[5] = "foopy"
assert_equals(l[5], undefined)
assert_equals(l.item(5), null)
}, "Shouldn't be able to set unsigned properties on a HTMLCollection (non-strict mode)")
test(function() {
var l = context.getElementsByTagName("nosuchtag")
assert_throws(new TypeError(), function() {
"use strict";
l[5] = "foopy"
})
assert_equals(l[5], undefined)
assert_equals(l.item(5), null)
}, "Shouldn't be able to set unsigned properties on a HTMLCollection (strict mode)")
test(function() {
var l = context.getElementsByTagName("nosuchtag")
var fn = l.item;
assert_equals(fn, HTMLCollection.prototype.item);
l.item = "pass"
assert_equals(l.item, "pass")
assert_equals(HTMLCollection.prototype.item, fn);
}, "Should be able to set expando shadowing a proto prop (item)")
test(function() {
var l = context.getElementsByTagName("nosuchtag")
var fn = l.namedItem;
assert_equals(fn, HTMLCollection.prototype.namedItem);
l.namedItem = "pass"
assert_equals(l.namedItem, "pass")
assert_equals(HTMLCollection.prototype.namedItem, fn);
}, "Should be able to set expando shadowing a proto prop (namedItem)")
test(function() {
var t1 = element.appendChild(document.createElement("pre"));
t1.id = "x";
var t2 = element.appendChild(document.createElement("pre"));
t2.setAttribute("name", "y");
var t3 = element.appendChild(document.createElementNS("", "pre"));
t3.setAttribute("id", "z");
var t4 = element.appendChild(document.createElementNS("", "pre"));
t4.setAttribute("name", "w");
this.add_cleanup(function() {
element.removeChild(t1)
element.removeChild(t2)
element.removeChild(t3)
element.removeChild(t4)
});
var list = context.getElementsByTagName('pre');
var pre = list[0];
assert_equals(pre.id, "x");
var exposedNames = { 'x': 0, 'y': 1, 'z': 2 };
for (var exposedName in exposedNames) {
assert_equals(list[exposedName], list[exposedNames[exposedName]]);
assert_equals(list[exposedName], list.namedItem(exposedName));
assert_true(exposedName in list, "'" + exposedName + "' in list");
assert_true(list.hasOwnProperty(exposedName),
"list.hasOwnProperty('" + exposedName + "')");
}
var unexposedNames = ["w"];
for (var unexposedName of unexposedNames) {
assert_false(unexposedName in list);
assert_false(list.hasOwnProperty(unexposedName));
assert_equals(list[unexposedName], undefined);
assert_equals(list.namedItem(unexposedName), null);
}
assert_array_equals(Object.getOwnPropertyNames(list).sort(),
["0", "1", "2", "3", "x", "y", "z"]);
var desc = Object.getOwnPropertyDescriptor(list, '0');
assert_equals(typeof desc, "object", "descriptor should be an object");
assert_true(desc.enumerable, "desc.enumerable");
assert_true(desc.configurable, "desc.configurable");
desc = Object.getOwnPropertyDescriptor(list, 'x');
assert_equals(typeof desc, "object", "descriptor should be an object");
assert_false(desc.enumerable, "desc.enumerable");
assert_true(desc.configurable, "desc.configurable");
}, "hasOwnProperty, getOwnPropertyDescriptor, getOwnPropertyNames")
test(function() {
assert_equals(document.createElementNS("http://www.w3.org/1999/xhtml", "i").localName, "i") // Sanity
var t = element.appendChild(document.createElementNS("http://www.w3.org/1999/xhtml", "I"))
this.add_cleanup(function() {element.removeChild(t)})
assert_equals(t.localName, "I")
assert_equals(t.tagName, "I")
assert_equals(context.getElementsByTagName("I").length, 0)
assert_equals(context.getElementsByTagName("i").length, 0)
}, "HTML element with uppercase tagName never matches in HTML Documents")
test(function() {
var t = element.appendChild(document.createElementNS("test", "st"))
this.add_cleanup(function() {element.removeChild(t)})
assert_array_equals(context.getElementsByTagName("st"), [t])
assert_array_equals(context.getElementsByTagName("ST"), [])
}, "Element in non-HTML namespace, no prefix, lowercase name")
test(function() {
var t = element.appendChild(document.createElementNS("test", "ST"))
this.add_cleanup(function() {element.removeChild(t)})
assert_array_equals(context.getElementsByTagName("ST"), [t])
assert_array_equals(context.getElementsByTagName("st"), [])
}, "Element in non-HTML namespace, no prefix, uppercase name")
test(function() {
var t = element.appendChild(document.createElementNS("test", "te:st"))
this.add_cleanup(function() {element.removeChild(t)})
assert_array_equals(context.getElementsByTagName("st"), [])
assert_array_equals(context.getElementsByTagName("ST"), [])
assert_array_equals(context.getElementsByTagName("te:st"), [t])
assert_array_equals(context.getElementsByTagName("te:ST"), [])
}, "Element in non-HTML namespace, prefix, lowercase name")
test(function() {
var t = element.appendChild(document.createElementNS("test", "te:ST"))
this.add_cleanup(function() {element.removeChild(t)})
assert_array_equals(context.getElementsByTagName("st"), [])
assert_array_equals(context.getElementsByTagName("ST"), [])
assert_array_equals(context.getElementsByTagName("te:st"), [])
assert_array_equals(context.getElementsByTagName("te:ST"), [t])
}, "Element in non-HTML namespace, prefix, uppercase name")
test(function() {
var t = element.appendChild(document.createElement("aÇ"))
this.add_cleanup(function() {element.removeChild(t)})
assert_equals(t.localName, "aÇ")
assert_array_equals(context.getElementsByTagName("AÇ"), [t], "All uppercase input")
assert_array_equals(context.getElementsByTagName("aÇ"), [t], "Ascii lowercase input")
assert_array_equals(context.getElementsByTagName("aç"), [], "All lowercase input")
}, "Element in HTML namespace, no prefix, non-ascii characters in name")
test(function() {
var t = element.appendChild(document.createElementNS("test", "AÇ"))
this.add_cleanup(function() {element.removeChild(t)})
assert_array_equals(context.getElementsByTagName("AÇ"), [t])
assert_array_equals(context.getElementsByTagName("aÇ"), [])
assert_array_equals(context.getElementsByTagName("aç"), [])
}, "Element in non-HTML namespace, non-ascii characters in name")
test(function() {
var t = element.appendChild(document.createElementNS("http://www.w3.org/1999/xhtml", "test:aÇ"))
this.add_cleanup(function() {element.removeChild(t)})
assert_array_equals(context.getElementsByTagName("TEST:AÇ"), [t], "All uppercase input")
assert_array_equals(context.getElementsByTagName("test:aÇ"), [t], "Ascii lowercase input")
assert_array_equals(context.getElementsByTagName("test:aç"), [], "All lowercase input")
}, "Element in HTML namespace, prefix, non-ascii characters in name")
test(function() {
var t = element.appendChild(document.createElementNS("test", "TEST:AÇ"))
this.add_cleanup(function() {element.removeChild(t)})
assert_array_equals(context.getElementsByTagName("TEST:AÇ"), [t], "All uppercase input")
assert_array_equals(context.getElementsByTagName("test:aÇ"), [], "Ascii lowercase input")
assert_array_equals(context.getElementsByTagName("test:aç"), [], "All lowercase input")
}, "Element in non-HTML namespace, prefix, non-ascii characters in name")
test(function() {
var actual = context.getElementsByTagName("*");
var expected = [];
var get_elements = function(node) {
for (var i = 0; i < node.childNodes.length; i++) {
var child = node.childNodes[i];
if (child.nodeType === child.ELEMENT_NODE) {
expected.push(child);
get_elements(child);
}
}
}
get_elements(context);
assert_array_equals(actual, expected);
}, "getElementsByTagName('*')")
}

View file

@ -0,0 +1,128 @@
function test_getElementsByTagNameNS(context, element) {
test(function() {
assert_false(context.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "html") instanceof NodeList, "NodeList")
assert_true(context.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "html") instanceof HTMLCollection, "HTMLCollection")
var firstCollection = context.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "html"),
secondCollection = context.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "html")
assert_true(firstCollection !== secondCollection || firstCollection === secondCollection,
"Caching is allowed.")
})
test(function() {
var t = element.appendChild(document.createElementNS("test", "body"))
this.add_cleanup(function() {element.removeChild(t)})
var actual = context.getElementsByTagNameNS("*", "body");
var expected = [];
var get_elements = function(node) {
for (var i = 0; i < node.childNodes.length; i++) {
var child = node.childNodes[i];
if (child.nodeType === child.ELEMENT_NODE) {
if (child.localName == "body") {
expected.push(child);
}
get_elements(child);
}
}
}
get_elements(context);
assert_array_equals(actual, expected);
}, "getElementsByTagNameNS('*', 'body')")
test(function() {
assert_array_equals(context.getElementsByTagNameNS("", "*"), []);
var t = element.appendChild(document.createElementNS("", "body"))
this.add_cleanup(function() {element.removeChild(t)})
assert_array_equals(context.getElementsByTagNameNS("", "*"), [t]);
}, "Empty string namespace")
test(function() {
var t = element.appendChild(document.createElementNS("test", "body"))
this.add_cleanup(function() {element.removeChild(t)})
assert_array_equals(context.getElementsByTagNameNS("test", "body"), [t]);
}, "body element in test namespace, no prefix")
test(function() {
var t = element.appendChild(document.createElementNS("test", "test:body"))
this.add_cleanup(function() {element.removeChild(t)})
assert_array_equals(context.getElementsByTagNameNS("test", "body"), [t]);
}, "body element in test namespace, prefix")
test(function() {
var t = element.appendChild(document.createElementNS("test", "BODY"))
this.add_cleanup(function() {element.removeChild(t)})
assert_array_equals(context.getElementsByTagNameNS("test", "BODY"), [t]);
assert_array_equals(context.getElementsByTagNameNS("test", "body"), []);
}, "BODY element in test namespace, no prefix")
test(function() {
var t = element.appendChild(document.createElementNS("http://www.w3.org/1999/xhtml", "abc"))
this.add_cleanup(function() {element.removeChild(t)})
assert_array_equals(context.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "abc"), [t]);
assert_array_equals(context.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "ABC"), []);
assert_array_equals(context.getElementsByTagNameNS("test", "ABC"), []);
}, "abc element in html namespace")
test(function() {
var t = element.appendChild(document.createElementNS("http://www.w3.org/1999/xhtml", "ABC"))
this.add_cleanup(function() {element.removeChild(t)})
assert_array_equals(context.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "abc"), []);
assert_array_equals(context.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "ABC"), [t]);
}, "ABC element in html namespace")
test(function() {
var t = element.appendChild(document.createElementNS("http://www.w3.org/1999/xhtml", "AÇ"))
this.add_cleanup(function() {element.removeChild(t)})
assert_array_equals(context.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "AÇ"), [t]);
assert_array_equals(context.getElementsByTagNameNS("test", "aÇ"), []);
assert_array_equals(context.getElementsByTagNameNS("test", "aç"), []);
}, "AÇ, case sensitivity")
test(function() {
var t = element.appendChild(document.createElementNS("test", "test:BODY"))
this.add_cleanup(function() {element.removeChild(t)})
assert_array_equals(context.getElementsByTagNameNS("test", "BODY"), [t]);
assert_array_equals(context.getElementsByTagNameNS("test", "body"), []);
}, "BODY element in test namespace, prefix")
test(function() {
var t = element.appendChild(document.createElementNS("test", "test:test"))
this.add_cleanup(function() {element.removeChild(t)})
var actual = context.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "*");
var expected = [];
var get_elements = function(node) {
for (var i = 0; i < node.childNodes.length; i++) {
var child = node.childNodes[i];
if (child.nodeType === child.ELEMENT_NODE) {
if (child !== t) {
expected.push(child);
}
get_elements(child);
}
}
}
get_elements(context);
assert_array_equals(actual, expected);
}, "getElementsByTagNameNS('http://www.w3.org/1999/xhtml', '*')")
test(function() {
var actual = context.getElementsByTagNameNS("*", "*");
var expected = [];
var get_elements = function(node) {
for (var i = 0; i < node.childNodes.length; i++) {
var child = node.childNodes[i];
if (child.nodeType === child.ELEMENT_NODE) {
expected.push(child);
get_elements(child);
}
}
}
get_elements(context);
assert_array_equals(actual, expected);
}, "getElementsByTagNameNS('*', '*')")
test(function() {
assert_array_equals(context.getElementsByTagNameNS("**", "*"), []);
assert_array_equals(context.getElementsByTagNameNS(null, "0"), []);
assert_array_equals(context.getElementsByTagNameNS(null, "div"), []);
}, "Empty lists")
}

View file

@ -0,0 +1,18 @@
<!doctype html>
<meta charset=utf-8>
<title>Document.URL with redirect</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
async_test(function() {
var iframe = document.createElement("iframe");
iframe.src = "/common/redirect.py?location=/common/blank.html";
document.body.appendChild(iframe);
this.add_cleanup(function() { document.body.removeChild(iframe); });
iframe.onload = this.step_func_done(function() {
assert_equals(iframe.contentDocument.URL,
"http://{{host}}:{{ports[http][0]}}/common/blank.html");
});
})
</script>

View file

@ -0,0 +1,50 @@
<!doctype html>
<meta charset=utf-8>
<title>Document.adoptNode</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-document-adoptnode">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<!--creates an element with local name "x<": --><x<>x</x<>
<script>
test(function() {
var y = document.getElementsByTagName("x<")[0]
var child = y.firstChild
assert_equals(y.parentNode, document.body)
assert_equals(y.ownerDocument, document)
assert_equals(document.adoptNode(y), y)
assert_equals(y.parentNode, null)
assert_equals(y.firstChild, child)
assert_equals(y.ownerDocument, document)
assert_equals(child.ownerDocument, document)
var doc = document.implementation.createDocument(null, null, null)
assert_equals(doc.adoptNode(y), y)
assert_equals(y.parentNode, null)
assert_equals(y.firstChild, child)
assert_equals(y.ownerDocument, doc)
assert_equals(child.ownerDocument, doc)
}, "Adopting an Element called 'x<' should work.")
test(function() {
var x = document.createElement(":good:times:")
assert_equals(document.adoptNode(x), x);
var doc = document.implementation.createDocument(null, null, null)
assert_equals(doc.adoptNode(x), x)
assert_equals(x.parentNode, null)
assert_equals(x.ownerDocument, doc)
}, "Adopting an Element called ':good:times:' should work.")
test(function() {
var doctype = document.doctype;
assert_equals(doctype.parentNode, document)
assert_equals(doctype.ownerDocument, document)
assert_equals(document.adoptNode(doctype), doctype)
assert_equals(doctype.parentNode, null)
assert_equals(doctype.ownerDocument, document)
}, "Explicitly adopting a DocumentType should work.")
test(function() {
var doc = document.implementation.createDocument(null, null, null)
assert_throws("NOT_SUPPORTED_ERR", function() { document.adoptNode(doc) })
}, "Adopting a Document should throw.")
</script>

View file

@ -0,0 +1,373 @@
<!doctype html>
<title>document.characterSet (inputEncoding and charset as aliases) normalization tests</title>
<link rel=author title="Aryeh Gregor" href=ayg@aryeh.name>
<meta name=timeout content=long>
<div id=log></div>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<style>iframe { display: none }</style>
<script>
"use strict";
// Taken straight from https://encoding.spec.whatwg.org/
var encodingMap = {
"UTF-8": [
"unicode-1-1-utf-8",
"utf-8",
"utf8",
// As we use <meta>, utf-16 will map to utf-8 per
// https://html.spec.whatwg.org/multipage/#documentEncoding
"utf-16",
"utf-16le",
"utf-16be",
],
"IBM866": [
"866",
"cp866",
"csibm866",
"ibm866",
],
"ISO-8859-2": [
"csisolatin2",
"iso-8859-2",
"iso-ir-101",
"iso8859-2",
"iso88592",
"iso_8859-2",
"iso_8859-2:1987",
"l2",
"latin2",
],
"ISO-8859-3": [
"csisolatin3",
"iso-8859-3",
"iso-ir-109",
"iso8859-3",
"iso88593",
"iso_8859-3",
"iso_8859-3:1988",
"l3",
"latin3",
],
"ISO-8859-4": [
"csisolatin4",
"iso-8859-4",
"iso-ir-110",
"iso8859-4",
"iso88594",
"iso_8859-4",
"iso_8859-4:1988",
"l4",
"latin4",
],
"ISO-8859-5": [
"csisolatincyrillic",
"cyrillic",
"iso-8859-5",
"iso-ir-144",
"iso8859-5",
"iso88595",
"iso_8859-5",
"iso_8859-5:1988",
],
"ISO-8859-6": [
"arabic",
"asmo-708",
"csiso88596e",
"csiso88596i",
"csisolatinarabic",
"ecma-114",
"iso-8859-6",
"iso-8859-6-e",
"iso-8859-6-i",
"iso-ir-127",
"iso8859-6",
"iso88596",
"iso_8859-6",
"iso_8859-6:1987",
],
"ISO-8859-7": [
"csisolatingreek",
"ecma-118",
"elot_928",
"greek",
"greek8",
"iso-8859-7",
"iso-ir-126",
"iso8859-7",
"iso88597",
"iso_8859-7",
"iso_8859-7:1987",
"sun_eu_greek",
],
"ISO-8859-8": [
"csiso88598e",
"csisolatinhebrew",
"hebrew",
"iso-8859-8",
"iso-8859-8-e",
"iso-ir-138",
"iso8859-8",
"iso88598",
"iso_8859-8",
"iso_8859-8:1988",
"visual",
],
"ISO-8859-8-I": [
"csiso88598i",
"iso-8859-8-i",
"logical",
],
"ISO-8859-10": [
"csisolatin6",
"iso-8859-10",
"iso-ir-157",
"iso8859-10",
"iso885910",
"l6",
"latin6",
],
"ISO-8859-13": [
"iso-8859-13",
"iso8859-13",
"iso885913",
],
"ISO-8859-14": [
"iso-8859-14",
"iso8859-14",
"iso885914",
],
"ISO-8859-15": [
"csisolatin9",
"iso-8859-15",
"iso8859-15",
"iso885915",
"iso_8859-15",
"l9",
],
"ISO-8859-16": [
"iso-8859-16",
],
"KOI8-R": [
"cskoi8r",
"koi",
"koi8",
"koi8-r",
"koi8_r",
],
"KOI8-U": [
"koi8-ru",
"koi8-u",
],
"macintosh": [
"csmacintosh",
"mac",
"macintosh",
"x-mac-roman",
],
"windows-874": [
"dos-874",
"iso-8859-11",
"iso8859-11",
"iso885911",
"tis-620",
"windows-874",
],
"windows-1250": [
"cp1250",
"windows-1250",
"x-cp1250",
],
"windows-1251": [
"cp1251",
"windows-1251",
"x-cp1251",
],
"windows-1252": [
"ansi_x3.4-1968",
"ascii",
"cp1252",
"cp819",
"csisolatin1",
"ibm819",
"iso-8859-1",
"iso-ir-100",
"iso8859-1",
"iso88591",
"iso_8859-1",
"iso_8859-1:1987",
"l1",
"latin1",
"us-ascii",
"windows-1252",
"x-cp1252",
// As we use <meta>, x-user-defined will map to windows-1252 per
// https://html.spec.whatwg.org/multipage/#documentEncoding
"x-user-defined"
],
"windows-1253": [
"cp1253",
"windows-1253",
"x-cp1253",
],
"windows-1254": [
"cp1254",
"csisolatin5",
"iso-8859-9",
"iso-ir-148",
"iso8859-9",
"iso88599",
"iso_8859-9",
"iso_8859-9:1989",
"l5",
"latin5",
"windows-1254",
"x-cp1254",
],
"windows-1255": [
"cp1255",
"windows-1255",
"x-cp1255",
],
"windows-1256": [
"cp1256",
"windows-1256",
"x-cp1256",
],
"windows-1257": [
"cp1257",
"windows-1257",
"x-cp1257",
],
"windows-1258": [
"cp1258",
"windows-1258",
"x-cp1258",
],
"x-mac-cyrillic": [
"x-mac-cyrillic",
"x-mac-ukrainian",
],
"GBK": [
"chinese",
"csgb2312",
"csiso58gb231280",
"gb2312",
"gb_2312",
"gb_2312-80",
"gbk",
"iso-ir-58",
"x-gbk",
],
"gb18030": [
"gb18030",
],
"Big5": [
"big5",
"big5-hkscs",
"cn-big5",
"csbig5",
"x-x-big5",
],
"EUC-JP": [
"cseucpkdfmtjapanese",
"euc-jp",
"x-euc-jp",
],
"ISO-2022-JP": [
"csiso2022jp",
"iso-2022-jp",
],
"Shift_JIS": [
"csshiftjis",
"ms932",
"ms_kanji",
"shift-jis",
"shift_jis",
"sjis",
"windows-31j",
"x-sjis",
],
"EUC-KR": [
"cseuckr",
"csksc56011987",
"euc-kr",
"iso-ir-149",
"korean",
"ks_c_5601-1987",
"ks_c_5601-1989",
"ksc5601",
"ksc_5601",
"windows-949",
],
"replacement": [
"csiso2022kr",
"hz-gb-2312",
"iso-2022-cn",
"iso-2022-cn-ext",
"iso-2022-kr",
],
};
// Add spaces and mix up case
Object.keys(encodingMap).forEach(function(name) {
var lower = encodingMap[name];
var upper = encodingMap[name].map(function(s) { return s.toUpperCase() });
var mixed = encodingMap[name].map(function(s) {
var ret = "";
for (var i = 0; i < s.length; i += 2) {
ret += s[i].toUpperCase();
if (i + 1 < s.length) {
ret += s[i + 1];
}
}
return ret;
});
var spacey = encodingMap[name].map(function(s) {
return " \t\n\f\r" + s + " \t\n\f\r";
});
encodingMap[name] = [];
for (var i = 0; i < lower.length; i++) {
encodingMap[name].push(lower[i]);
/*
if (lower[i] != upper[i]) {
encodingMap[name].push(upper[i]);
}
if (lower[i] != mixed[i] && upper[i] != mixed[i]) {
encodingMap[name].push(mixed[i]);
}
encodingMap[name].push(spacey[i]);
*/
}
});
Object.keys(encodingMap).forEach(function(name) {
encodingMap[name].forEach(function(label) {
var iframe = document.createElement("iframe");
var t = async_test("Name " + format_value(name) +
" has label " + format_value(label) + " (characterSet)");
var t2 = async_test("Name " + format_value(name) +
" has label " + format_value(label) + " (inputEncoding)");
var t3 = async_test("Name " + format_value(name) +
" has label " + format_value(label) + " (charset)");
iframe.src = "encoding.py?label=" + label;
iframe.onload = function() {
t.step(function() {
assert_equals(iframe.contentDocument.characterSet, name);
});
t2.step(function() {
assert_equals(iframe.contentDocument.inputEncoding, name);
});
t3.step(function() {
assert_equals(iframe.contentDocument.charset, name);
});
document.body.removeChild(iframe);
t.done();
t2.done();
t3.done();
};
document.body.appendChild(iframe);
});
});
</script>
<!-- vim: set expandtab tabstop=2 shiftwidth=2: -->

View file

@ -0,0 +1,53 @@
<!doctype html>
<meta charset=windows-1252>
<!-- Using windows-1252 to ensure that new Document() doesn't inherit utf-8
from the parent document. -->
<title>Document constructor</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-document">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
test(function() {
var doc = new Document();
assert_true(doc instanceof Node, "Should be a Node");
assert_true(doc instanceof Document, "Should be a Document");
assert_false(doc instanceof XMLDocument, "Should not be an XMLDocument");
assert_equals(Object.getPrototypeOf(doc), Document.prototype,
"Document should be the primary interface");
}, "new Document(): interfaces")
test(function() {
var doc = new Document();
assert_equals(doc.firstChild, null, "firstChild");
assert_equals(doc.lastChild, null, "lastChild");
assert_equals(doc.doctype, null, "doctype");
assert_equals(doc.documentElement, null, "documentElement");
assert_array_equals(doc.childNodes, [], "childNodes");
}, "new Document(): children")
test(function() {
var doc = new Document();
assert_equals(doc.URL, "about:blank");
assert_equals(doc.documentURI, "about:blank");
assert_equals(doc.compatMode, "CSS1Compat");
assert_equals(doc.characterSet, "UTF-8");
assert_equals(doc.contentType, "application/xml");
assert_equals(doc.createElement("DIV").localName, "DIV");
}, "new Document(): metadata")
test(function() {
var doc = new Document();
assert_equals(doc.characterSet, "UTF-8", "characterSet");
assert_equals(doc.charset, "UTF-8", "charset");
assert_equals(doc.inputEncoding, "UTF-8", "inputEncoding");
}, "new Document(): characterSet aliases")
test(function() {
var doc = new Document();
var a = doc.createElement("a");
// In UTF-8: 0xC3 0xA4
a.href = "http://example.org/?\u00E4";
assert_equals(a.href, "http://example.org/?%C3%A4");
}, "new Document(): URL parsing")
</script>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<title>BMP document.contentType === 'image/bmp'</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
async_test(function() {
var iframe = document.createElement('iframe');
iframe.addEventListener('load', this.step_func_done(function() {
assert_equals(iframe.contentDocument.contentType, "image/bmp");
}), false);
iframe.src = "../resources/t.bmp";
document.body.appendChild(iframe);
});
</script>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<title>CSS document.contentType === 'text/css'</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
async_test(function() {
var iframe = document.createElement('iframe');
iframe.addEventListener('load', this.step_func_done(function() {
assert_equals(iframe.contentDocument.contentType, "text/css");
}), false);
iframe.src = "../resources/style.css";
document.body.appendChild(iframe);
});
</script>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<title>Data URI document.contentType === 'text/plain' when data URI MIME type is not set</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
async_test(function() {
var iframe = document.createElement('iframe');
iframe.addEventListener('load', this.step_func_done(function() {
assert_equals(iframe.contentDocument.contentType, "text/plain");
}), false);
iframe.src = "data:;,<!DOCTYPE html>";
document.body.appendChild(iframe);
});
</script>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<title>Data URI document.contentType === 'text/html' when data URI MIME type is set</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
async_test(function() {
var iframe = document.createElement('iframe');
iframe.addEventListener('load', this.step_func_done(function() {
assert_equals(iframe.contentDocument.contentType, "text/html");
}), false);
iframe.src = "data:text/html;charset=utf-8,<!DOCTYPE html>";
document.body.appendChild(iframe);
});
</script>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<title>GIF document.contentType === 'image/gif'</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
async_test(function() {
var iframe = document.createElement('iframe');
iframe.addEventListener('load', this.step_func_done(function() {
assert_equals(iframe.contentDocument.contentType, "image/gif");
}), false);
iframe.src = "../resources/t.gif";
document.body.appendChild(iframe);
});
</script>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<title>HTM document.contentType === 'text/html'</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
async_test(function() {
var iframe = document.createElement('iframe');
iframe.addEventListener('load', this.step_func_done(function() {
assert_equals(iframe.contentDocument.contentType, "text/html");
}), false);
iframe.src = "../resources/blob.htm";
document.body.appendChild(iframe);
});
</script>

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<title>Javascript URI document.contentType === 'text/html'</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
async_test(function() {
var iframe = document.createElement('iframe');
iframe.addEventListener('load', this.step_func_done(function() {
assert_equals(iframe.contentDocument.contentType, "text/html");
assert_equals(iframe.contentDocument.documentElement.textContent, "text/html");
}), false);
iframe.src = "javascript:document.contentType";
document.body.appendChild(iframe);
});
</script>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<title>JPG document.contentType === 'image/jpeg'</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
async_test(function() {
var iframe = document.createElement('iframe');
iframe.addEventListener('load', this.step_func_done(function() {
assert_equals(iframe.contentDocument.contentType, "image/jpeg");
}), false);
iframe.src = "../resources/t.jpg";
document.body.appendChild(iframe);
});
</script>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<title>Custom document.contentType === 'text/xml' when explicitly set to this value</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
async_test(function() {
var iframe = document.createElement('iframe');
iframe.addEventListener('load', this.step_func_done(function() {
assert_equals(iframe.contentDocument.contentType, "text/xml");
}), false);
iframe.src = "../support/contenttype_setter.py?type=text&subtype=xml";
document.body.appendChild(iframe);
});
</script>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<title>Custom document.contentType === 'text/html' when explicitly set to this value and an attempt is made to override this value in an HTML meta header</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
async_test(function() {
var iframe = document.createElement('iframe');
iframe.addEventListener('load', this.step_func_done(function() {
assert_equals(iframe.contentDocument.contentType, "text/html");
}), false);
iframe.src = "../support/contenttype_setter.py?type=text&subtype=html&mimeHead=text%2Fxml";
document.body.appendChild(iframe);
});
</script>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<title>PNG document.contentType === 'image/png'</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
async_test(function() {
var iframe = document.createElement('iframe');
iframe.addEventListener('load', this.step_func_done(function() {
assert_equals(iframe.contentDocument.contentType, "image/png");
}), false);
iframe.src = "../resources/t.png";
document.body.appendChild(iframe);
});
</script>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<title>TXT document.contentType === 'text/plain'</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
async_test(function() {
var iframe = document.createElement('iframe');
iframe.addEventListener('load', this.step_func_done(function() {
assert_equals(iframe.contentDocument.contentType, "text/plain");
}), false);
iframe.src = "../resources/blob.txt";
document.body.appendChild(iframe);
});
</script>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<title>XML document.contentType === 'application/xml'</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
async_test(function() {
var iframe = document.createElement('iframe');
iframe.addEventListener('load', this.step_func_done(function() {
assert_equals(iframe.contentDocument.contentType, "application/xml");
}), false);
iframe.src = "../resources/blob.xml";
document.body.appendChild(iframe);
});
</script>

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<title>document.implementation.createDocument: document.contentType === 'application/xhtml+xml'</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
test(function() {
var doc = document.implementation.createDocument("http://www.w3.org/1999/xhtml", "html", null);
assert_equals(doc.contentType, "application/xhtml+xml");
});
</script>

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<title>document.implementation.createHTMLDocument: document.contentType === 'text/html'</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
test(function() {
var doc = document.implementation.createHTMLDocument("test");
assert_equals(doc.contentType, "text/html");
});
</script>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<title>XHR - retrieve HTML document: document.contentType === 'application/xml'</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
async_test(function() {
var xhr = new XMLHttpRequest();
xhr.open("GET", "../resources/blob.xml");
xhr.responseType = "document";
xhr.onload = this.step_func_done(function(response) {
assert_equals(xhr.readyState, 4);
assert_equals(xhr.status, 200);
assert_equals(xhr.responseXML.contentType, "application/xml");
});
xhr.send(null);
});
</script>

View file

@ -0,0 +1 @@
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

View file

@ -0,0 +1 @@
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

Some files were not shown because too many files have changed in this diff Show more