blob: 6c92421b074c510bba5bfc01f678070fe701b90c [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<script src="../../../resources/js-test-pre.js"></script>
</head>
<body>
<div id="container"></div>
<script>
description("Testing document.register() basic behaviors.");
if (window.testRunner)
testRunner.dumpAsText();
document.register = document.register || document.webkitRegister;
function createRegisterParamters()
{
return {
prototype: Object.create(HTMLElement.prototype, { thisIsPrototype: { value: true } })
};
}
// Invalid names
shouldThrow("document.register('foo', createRegisterParamters())", "'Error: InvalidCharacterError: DOM Exception 5'");
shouldThrow("document.register('xfoo', createRegisterParamters())", "'Error: InvalidCharacterError: DOM Exception 5'");
shouldThrow("document.register('missing-glyph', createRegisterParamters())", "'Error: InvalidCharacterError: DOM Exception 5'");
var fooConstructor = document.register("x-foo", createRegisterParamters());
shouldBe("typeof fooConstructor", "'function'");
shouldBe("fooConstructor.prototype.__proto__", "HTMLElement.prototype");
shouldBeTrue("fooConstructor.prototype.thisIsPrototype");
// Name conflicts
shouldThrow("document.register('x-foo', createRegisterParamters())", "'Error: InvalidStateError: DOM Exception 11'");
shouldThrow("document.register('X-FOO', createRegisterParamters())", "'Error: InvalidStateError: DOM Exception 11'");
// Bad prototype: constructor property exists
shouldThrow("document.register('x-bad-a', { prototype: HTMLElement.prototype })", "'Error: InvalidStateError: DOM Exception 11'");
// Bad prototype: missing __proto__
shouldThrow("document.register('x-bad-b', { prototype: {} })", "'Error: InvalidStateError: DOM Exception 11'");
// Bad prototype: wrong __proto__
shouldThrow("document.register('x-bad-c', { prototype: Object.create(Document.prototype) })", "'Error: InvalidStateError: DOM Exception 11'");
// Call as function
shouldThrow("fooConstructor()", "'TypeError: DOM object constructor cannot be called as a function.'")
// Constructor initiated instantiation
var createdFoo = new fooConstructor();
// JS built-in properties
shouldBe("createdFoo.__proto__", "fooConstructor.prototype");
shouldBe("createdFoo.constructor", "fooConstructor");
// Native getter
shouldBe("createdFoo.tagName", "'X-FOO'");
// Native setter
createdFoo.innerHTML = "Hello";
shouldBe("createdFoo.textContent", "'Hello'");
// Native method
var childDiv = document.createElement("div");
createdFoo.appendChild(childDiv);
shouldBe("createdFoo.lastChild", "childDiv");
// Parser initiated instantiation
var container = document.getElementById("container");
container.innerHTML = "<x-foo></x-foo>";
parsedFoo = container.firstChild;
shouldBe("parsedFoo.__proto__", "fooConstructor.prototype");
shouldBe("parsedFoo.tagName", "'X-FOO'");
// Ensuring the wrapper is retained
parsedFoo.someProperty = "hello";
shouldBe("parsedFoo.someProperty", "container.firstChild.someProperty");
// Having another constructor
var barConstructor = document.register("x-bar", createRegisterParamters());
shouldBeTrue("barConstructor !== fooConstructor");
var createdBar = new barConstructor();
shouldBe("createdBar.tagName", "'X-BAR'");
// Having a subclass
var bazConstructor = document.register("x-baz", { prototype: Object.create(fooConstructor.prototype, { thisIsAlsoPrototype: { value: true } }) });
var createdBaz = new bazConstructor();
shouldBe("createdBaz.tagName", "'X-BAZ'");
shouldBeTrue("createdBaz.thisIsPrototype");
shouldBeTrue("createdBaz.thisIsAlsoPrototype");
// With irregular cases
var createdUpperBar = document.createElement("X-BAR");
var createdMixedBar = document.createElement("X-Bar");
shouldBe("createdUpperBar.constructor", "barConstructor");
shouldBe("createdUpperBar.tagName", "'X-BAR'");
shouldBe("createdMixedBar.constructor", "barConstructor");
shouldBe("createdMixedBar.tagName", "'X-BAR'");
container.innerHTML = "<X-BAR></X-BAR><X-Bar></X-Bar>";
shouldBe("container.firstChild.constructor", "barConstructor");
shouldBe("container.firstChild.tagName", "'X-BAR'");
shouldBe("container.lastChild.constructor", "barConstructor");
shouldBe("container.lastChild.tagName", "'X-BAR'");
// Strange but valid names
shouldBe("(new (document.register('y-bar', createRegisterParamters()))()).tagName", "'Y-BAR'");
shouldBe("(new (document.register('yz-bar', createRegisterParamters()))()).tagName", "'YZ-BAR'");
shouldBe("(new (document.register('y-z-bar', createRegisterParamters()))()).tagName", "'Y-Z-BAR'");
shouldBe("(new (document.register('y--bar', createRegisterParamters()))()).tagName", "'Y--BAR'");
// Constructor shouldn't interfere each otehr
shouldBe("(new fooConstructor).tagName", "'X-FOO'");
shouldBe("(new barConstructor).tagName", "'X-BAR'");
shouldBe("(new bazConstructor).tagName", "'X-BAZ'");
</script>
<script src="../../../resources/js-test-post.js"></script>
</body>
</html>