Skip to content

Instantly share code, notes, and snippets.

@TakayoshiKochi
Last active September 3, 2019 13:58
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TakayoshiKochi/93a46a10c056d2a3d70495c6fc025310 to your computer and use it in GitHub Desktop.
Save TakayoshiKochi/93a46a10c056d2a3d70495c6fc025310 to your computer and use it in GitHub Desktop.
CEv1 in classic HTML Imports

Custom Elements V1 in HTML Imports

This document describes how custom elements v1 work when they are defined or used in HTML Imports.

HTML Imports is currently implemented only in Chrome, and this document provides non-normative information about Chrome's implementation in M54 and later, for the reference of future works that tries to achieve similar functionality like HTML Imports.

Defining Custom Element in an imported document

As the global context window is shared with script running in an imported document, you can access the custom elements registry via window.customElements. This is straightforward and no different from the usage in a usual HTML document.

Imported HTML:

<!DOCTYPE html>                                                                                     
<script>                                                                                            
class MyElement extends HTMLElement {}                                                              
window.customElements.define('my-element', MyElement);                                              
</script>

After the definition is registered, new MyElement() will work in any <script>. Any custom element created via new operator will have the master document (i.e. window.document) as its node document (.ownerDocument), regardless of where the new operator is invoked.

Using Custom Elements in an imported document

Using tag in HTML

When you put a custom element tag (e.g. <my-element>...</my-element>), depending on whether the definition is available in the registry, it is created synchronously as parsed, or upgraded when the definition is registered.

On either case node document of each custom element will be the containing imported document.

Creating using createElement() API

When you use createElement() API to create a custom element, you can use the master document or any imported document as the context object. Created element will have the context object of createElement() as its .ownerDocument.

Creating using innerHTML

Putting custom elements in .innerHTML works in script running in imported document. Its node document will be inherited from .innerHTML's context object.

Miscellaneous notes

Timing when custom element definition becomes available

Each definition will be available immediately after customElements.define() call, therefore the availability depends on the order of script execution in HTML imports.

Upgrade order of custom elements

The upgrade order of custom elements follows custom element order defined in HTML Imports spec.

In short, upgrade also happens for imported documents that are completely loaded, and the order is document order, where all <link rel="import"> elements are replaced with imported document.

Async imports and upgrade order

Even when an import is async, upgrade can apply to elements in an asynchrnonously imported document, the order is same without async attribute.

Custom Elements in detached imports

If an import is detached before definition is given, custom elements in the detached imported document will not be upgraded when the definition becomes available. If already upgraded custom elements exist when an imported document is being detached, they keep the same state (custom) after the detachment.

adoptedCallback()

When you move an element from an import to the master (or vice versa), adoptedCallback() for the element will be run.

attributeChangedCallback()

You can expect attributeChangedCallback() for the element will be run in imports.

connectedCallback()

As imports are Documents, when custom elements are created or upgraded in an import's DOM tree, connectedCallback() will be run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment