| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <title>Custom Elements: CEReactions on Document interface</title> | |
| <meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"> | |
| <meta name="assert" content="importNode and adoptNode of Document interface must have CEReactions"> | |
| <meta name="help" content="https://dom.spec.whatwg.org/#document"> | |
| <meta name="help" content="https://html.spec.whatwg.org/#document"> | |
| <script src="/resources/testharness.js"></script> | |
| <script src="/resources/testharnessreport.js"></script> | |
| <script src="../resources/custom-elements-helpers.js"></script> | |
| <script src="./resources/reactions.js"></script> | |
| </head> | |
| <body> | |
| <div id="log"></div> | |
| <script> | |
| test_with_window(function (contentWindow, contentDocument) { | |
| const element = define_custom_element_in_window(contentWindow, 'custom-element', []); | |
| const instance = contentDocument.createElement('custom-element'); | |
| assert_array_equals(element.takeLog().types(), ['constructed']); | |
| const newDoc = contentDocument.implementation.createHTMLDocument(); | |
| newDoc.importNode(instance); | |
| assert_array_equals(element.takeLog().types(), []); | |
| }, 'importNode on Document must not construct a new custom element when importing a custom element into a window-less document'); | |
| test_with_window(function (contentWindow, contentDocument) { | |
| const element = define_custom_element_in_window(contentWindow, 'custom-element', []); | |
| const template = contentDocument.createElement('template'); | |
| template.innerHTML = '<custom-element></custom-element>'; | |
| assert_array_equals(element.takeLog().types(), []); | |
| contentDocument.importNode(template.content, true); | |
| assert_array_equals(element.takeLog().types(), ['constructed']); | |
| }, 'importNode on Document must construct a new custom element when importing a custom element from a template'); | |
| test_with_window(function (contentWindow, contentDocument) { | |
| const element = define_custom_element_in_window(contentWindow, 'custom-element', []); | |
| const instance = contentDocument.createElement('custom-element'); | |
| assert_array_equals(element.takeLog().types(), ['constructed']); | |
| const newDoc = contentDocument.implementation.createHTMLDocument(); | |
| newDoc.adoptNode(instance); | |
| const logEntries = element.takeLog(); | |
| assert_array_equals(logEntries.types(), ['adopted']); | |
| assert_equals(logEntries.last().oldDocument, contentDocument); | |
| assert_equals(logEntries.last().newDocument, newDoc); | |
| }, 'adoptNode on Document must enqueue an adopted reaction when importing a custom element'); | |
| test_with_window(function (contentWindow, contentDocument) { | |
| const element = define_custom_element_in_window(contentWindow, 'custom-element', []); | |
| const instance = contentDocument.createElement('custom-element'); | |
| const container = contentDocument.createElement('div'); | |
| container.contentEditable = true; | |
| container.appendChild(instance); | |
| contentDocument.body.appendChild(container); | |
| assert_array_equals(element.takeLog().types(), ['constructed', 'connected']); | |
| container.focus(); | |
| contentDocument.execCommand('delete', false, null); | |
| assert_array_equals(element.takeLog().types(), ['disconnected']); | |
| }, 'execCommand on Document must enqueue a disconnected reaction when deleting a custom element from a contenteditable element'); | |
| test_with_window(function (contentWindow, contentDocument) { | |
| const element = define_custom_element_in_window(contentWindow, 'custom-element', []); | |
| contentDocument.title = ''; | |
| const title = contentDocument.querySelector('title'); | |
| const instance = contentDocument.createElement('custom-element'); | |
| title.appendChild(instance); | |
| instance.textContent = 'hello'; | |
| assert_array_equals(element.takeLog().types(), ['constructed', 'connected']); | |
| assert_equals(title.innerHTML, '<custom-element>hello</custom-element>'); | |
| title.text = 'world'; | |
| assert_equals(title.innerHTML, 'world'); | |
| assert_array_equals(element.takeLog().types(), ['disconnected']); | |
| }, 'title on Document must enqueue disconnectedCallback when removing a custom element'); | |
| test_with_window(function (contentWindow, contentDocument) { | |
| const element = define_custom_element_in_window(contentWindow, 'custom-element', []); | |
| const body = contentDocument.body; | |
| body.innerHTML = '<custom-element>hello</custom-element>'; | |
| assert_array_equals(element.takeLog().types(), ['constructed', 'connected']); | |
| assert_equals(body.innerHTML, '<custom-element>hello</custom-element>'); | |
| contentDocument.body = contentDocument.createElement('body'); | |
| assert_array_equals(element.takeLog().types(), ['disconnected']); | |
| }, 'body on Document must enqueue disconnectedCallback when removing a custom element'); | |
| test_with_window(function (contentWindow, contentDocument) { | |
| const element = define_custom_element_in_window(contentWindow, 'custom-element', []); | |
| const instance = contentDocument.createElement('custom-element'); | |
| const body = contentDocument.createElement('body'); | |
| body.appendChild(instance); | |
| assert_array_equals(element.takeLog().types(), ['constructed']); | |
| assert_equals(body.innerHTML, '<custom-element></custom-element>'); | |
| contentDocument.body = body; | |
| assert_array_equals(element.takeLog().types(), ['connected']); | |
| }, 'body on Document must enqueue connectedCallback when inserting a custom element'); | |
| test_with_window(function (contentWindow, contentDocument) { | |
| const element = define_custom_element_in_window(contentWindow, 'custom-element', []); | |
| contentDocument.body.innerHTML = '<custom-element></custom-element>'; | |
| assert_array_equals(element.takeLog().types(), ['constructed', 'connected']); | |
| contentDocument.open(); | |
| assert_array_equals(element.takeLog().types(), ['disconnected']); | |
| }, 'open on Document must enqueue disconnectedCallback when removing a custom element'); | |
| test_with_window(function (contentWindow, contentDocument) { | |
| const element = define_custom_element_in_window(contentWindow, 'custom-element', []); | |
| contentDocument.body.innerHTML = '<custom-element></custom-element>'; | |
| assert_array_equals(element.takeLog().types(), ['constructed', 'connected']); | |
| contentDocument.write(''); | |
| assert_array_equals(element.takeLog().types(), ['disconnected']); | |
| }, 'write on Document must enqueue disconnectedCallback when removing a custom element'); | |
| test_with_window(function (contentWindow, contentDocument) { | |
| contentWindow.document.open(); | |
| const element = define_custom_element_in_window(contentWindow, 'custom-element', []); | |
| contentWindow.document.write('<custom-element></custom-element>'); | |
| assert_array_equals(element.takeLog().types(), ['constructed', 'connected']); | |
| }, 'write on Document must enqueue connectedCallback after constructing a custom element'); | |
| test_with_window(function (contentWindow, contentDocument) { | |
| const element = define_custom_element_in_window(contentWindow, 'custom-element', []); | |
| contentDocument.body.innerHTML = '<custom-element></custom-element>'; | |
| assert_array_equals(element.takeLog().types(), ['constructed', 'connected']); | |
| contentDocument.writeln(''); | |
| assert_array_equals(element.takeLog().types(), ['disconnected']); | |
| }, 'writeln on Document must enqueue disconnectedCallback when removing a custom element'); | |
| test_with_window(function (contentWindow) { | |
| contentWindow.document.open(); | |
| const element = define_custom_element_in_window(contentWindow, 'custom-element', []); | |
| contentWindow.document.writeln('<custom-element></custom-element>'); | |
| assert_array_equals(element.takeLog().types(), ['constructed', 'connected']); | |
| }, 'writeln on Document must enqueue connectedCallback after constructing a custom element'); | |
| </script> | |
| </body> | |
| </html> |