| <!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> |