blob: d82bb8fcb275a1cb27f1e5418c42907567708410 [file] [log] [blame]
<!DOCTYPE html>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="test-harness-utils.js"></script>
<body>
<script>
function TestRegistrationContextIsolation(windowA, documentA,
windowB, documentB) {
this.windowA = windowA;
this.documentA = documentA;
this.windowB = windowB;
this.documentB = documentB;
}
TestRegistrationContextIsolation.prototype.
testRegistrationContextIsNotShared = function () {
this.testRegisterInAInstantiateInB_shouldNotActivateDefinition();
this.testRegisterSameName_definitionsShouldNotConflict();
this.testRegisterSameName_lazyWrappingShouldNotSharePrototypes();
};
TestRegistrationContextIsolation.prototype.
testRegisterInAInstantiateInB_shouldNotActivateDefinition = function () {
// Test that element x-u registered in document A is not activated when
// x-u is parsed in document B
var protoU = Object.create(this.windowA.HTMLElement.prototype);
protoU.createdCallback = function () {
assert_unreached('creating an x-u in a different context should ' +
'not invoke a callback in this context');
};
this.documentA.registerElement('x-u', {prototype: protoU});
var container = this.documentB.createElement('div');
container.innerHTML = '<x-u></x-u>';
// if protoU.createdCallback is not invoked; this passed
};
TestRegistrationContextIsolation.prototype.
testRegisterSameName_definitionsShouldNotConflict = function () {
// Test that registering two different custom elements with the same
// tag name in each document doesn't lead to any crossed wires
var invocations = [];
function created(name) {
return function () {
invocations.push('created ' + name + ' in ' + this.dataset.doc);
};
}
var protoAV = Object.create(this.windowA.HTMLElement.prototype);
protoAV.createdCallback = created('document A\'s element V');
this.documentA.registerElement('x-v', {prototype: protoAV});
var protoBV = Object.create(this.windowB.HTMLElement.prototype);
protoBV.createdCallback = created('document B\'s element V');
this.documentB.registerElement('x-v', {prototype: protoBV});
var containerB = this.documentB.createElement('div');
containerB.innerHTML = '<x-v data-doc="document B"></x-v>';
var containerA = this.documentA.createElement('div');
containerA.innerHTML = '<x-v data-doc="document A"></x-v>';
assert_array_equals(
invocations,
['created document B\'s element V in document B',
'created document A\'s element V in document A'],
'should have invoked the created callbacks in reverse creation order');
assert_equals(
Object.getPrototypeOf(containerA.firstChild),
protoAV,
'the prototype of element V in document A should be the prototype ' +
'registered in document A');
assert_equals(
Object.getPrototypeOf(containerB.firstChild),
protoBV,
'the prototype of element V in document B should be the prototype ' +
'registered in document B');
};
TestRegistrationContextIsolation.prototype.
testRegisterSameName_lazyWrappingShouldNotSharePrototypes = function () {
// Registering two different custom elements with the same tag
// name should not mix up prototypes. These do not have any
// callbacks, to try to tickle lazy wrapping.
var protoAW = Object.create(this.windowA.HTMLElement.prototype);
this.documentA.registerElement('x-w', {prototype: protoAW});
var protoBW = Object.create(this.windowB.HTMLElement.prototype);
protoBW.createdCallback = function () {};
this.documentB.registerElement('x-w', {prototype: protoBW});
var elementA = this.documentA.createElement('x-w');
var elementB = this.documentB.createElement('x-w');
assert_equals(
Object.getPrototypeOf(elementB), protoBW,
'the prototype of element W in document B should be the prototype ' +
'registered in document B');
assert_equals(
Object.getPrototypeOf(elementA), protoAW,
'the prototype of element W in document A should be the prototype ' +
'registered in document A');
};
(function () {
var t = async_test('registration context should not be shared with an ' +
'iframe\'s document');
withFrame(t.step_func(function (frameA) {
withFrame(t.step_func(function (frameB) {
var documentA = frameA.contentDocument;
var documentB = frameB.contentDocument;
var tester = new TestRegistrationContextIsolation(
frameA.contentWindow, frameA.contentDocument,
frameB.contentWindow, frameB.contentDocument);
tester.testRegistrationContextIsNotShared();
frameA.remove();
frameB.remove();
t.done();
}));
}));
})();
(function () {
var t = async_test('registration context should not be shared with the ' +
'template document');
withFrame(t.step_func(function (frame) {
var documentA = frame.contentDocument;
documentA.body.innerHTML = '<template>foo</template>';
var documentB = documentA.body.firstChild.content.ownerDocument;
var tester = new TestRegistrationContextIsolation(
frame.contentWindow, documentA,
frame.contentWindow, documentB);
tester.testRegistrationContextIsNotShared();
frame.remove();
t.done();
}));
})();
(function () {
var t = async_test('registration context should not be created by ' +
'DOMImplementation-created documents');
withFrame(t.step_func(function (frame) {
// Test transitively sloughing off a registration context through
// multiple createDocument/createHTMLDocument steps.
var documentA = frame.contentDocument;
// This document is not HTML, XHTML; it will not process custom elements.
var documentB = documentA.implementation.createDocument(null, '');
assert_throws(
'NOT_SUPPORTED_ERR',
function() { documentB.registerElement('x-a'); });
// This document will not process custom elements because there is
// nothing to inherit from B.
var documentC = documentB.implementation.createHTMLDocument();
assert_throws(
'NOT_SUPPORTED_ERR',
function() { documentC.registerElement('x-b'); });
// Nor this one.
var documentD = documentC.implementation.createDocument(
'http://www.w3.org/1999/xhtml', 'html');
assert_throws(
'NOT_SUPPORTED_ERR',
function() { documentD.registerElement('x-c'); });
frame.remove();
t.done();
}));
})();
</script>