This experimental library patches the global custom elements registry to allow re-defining or reload a custom element.

Overview

Redefine Custom Elements

This experimental library patches the global custom elements registry to allow re-defining a custom element. Based on the spec, a custom element can be defined for a qualifying name only once, the class itself cannot be reused for a different name as well. These two restrictions often pushes developers away from using custom elements, or even supporting custom elements in their platforms, specifically, any framework that allows live refresh of the code without reloading the page will eventually encounter that these restrictions will prevent this from happening.

Use Cases

Allowing redefinition of a custom element via customElements.define() API can help with the following use-cases:

  • Hot module replacement.
  • Designing Custom Elements at runtime.
  • Testing and Automation.

Usage

Installation:

npm i redefine-custom-elements

Then just import the library to patch the custom elements registry:

import "redefine-custom-elements";
customElements.define('x-foo', class Foo extends HTMLElement {});
customElements.define('x-foo', class Bar extends HTMLElement {});

Design

The concept of a pivot constructor is well proven now, it is used by the scoped custom elements registry polyfill as well, which inspire many parts of this library. This library relies on this concept to install a pivotal constructor into the custom elements registry, and whenever that pivot constructor is called by the engine, a corresponding (user-defined) constructor can be used to construct the final version of the instance before handing that over to user-land. To achieve this, we need to patch various methods of the CustomElementRegistry.prototype, and the HTMLElement constructor.

Performance

This library is intended to be used during the development. Nevertheless, when patching DOM APIs, you're often going to get performance degradation, and this library is not the exception. The good news is that it doesn't affect, in any way, the element after it is created. The main concern in terms of performance will be the time to create an instance.

Side effects

These patches are meant to be transparent, and should not be observed by user-land code, but this is hard to achieve when it comes to the DOM APIs. Execute this code first to avoid mismatches.

Limitations

  1. Any custom element defined before this library runs will not be replaceable. In this case, it will simply throw the built-in error.
  2. If you rely on options when defining a custom element (e.g.: customElements.define(name, constructor, options)), non-equivalent options when redefining the element will not be recognized.
  3. If it unclear how this can work with scoped custom elements, if that proposal moves forward.

Browsers Support and Stats

  • Modern browsers with support for custom elements.
  • This library: <2kb gzip/minify (no external dependencies).
Comments
  • Fire Event on redefined

    Fire Event on redefined

    By firing an event on definition, it makes it easier to integrate into HMR solutions.

    See:

    https://stackblitz.com/edit/vitejs-vite-y8sona?file=lit-hmr.ts

    This is a bespoke solution for Lit but I'd be cool to make a common static function on WC library base classes that can implement their own upgrade / update so that this HMR solution can be generalized to any WC library

    opened by e111077 1
  • Add support for `static formAssociated`

    Add support for `static formAssociated`

    Although there is some support here for form associated callbacks, the static formAssocated property is not honored (see https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-face-example). Without this, some default browser behavior like label activation is not supported.

    opened by sorvell 0
  • Use a single definition per tag name

    Use a single definition per tag name

    Update it when the tag is redefined.

    This way LatestCtor and the callbacks are updated for all instances immediately on redefinition.

    I'm not certain this change is an improvement in all cases, but it's the behavior that I think we generally want when doing HMR in google, but I could see the value in making it an option.

    opened by rictic 2
  • Don't use the constructor call trick when a custom element is constructed with new

    Don't use the constructor call trick when a custom element is constructed with new

    We need to use the constructor call trick in the PivotCtor when the element has been created by the browser directly (e.g. document.createElement, or via the parser) because in that case the only constructor that's called is the PivotCtor.

    However, if the element is called via new MyElement() then the MyElement constructor (and any superclass constructors) will be called properly without any work on our part.

    This change fixes a bug we noticed where calling new MyElement() was running constructors twice.

    opened by rictic 2
  • Separate code out into an implementaiton file that does not activate when imported.

    Separate code out into an implementaiton file that does not activate when imported.

    The main index file behaves the same so this is backwards compatible.

    I'm working on using this library at google, and I want to make sure we only use it in development (using a technique similar to if (process.env === 'dev') { activate() }). We also patch HTMLElement in the custom elements es5 shim, and we need to apply that patch before we apply this one, and exporting the activate function makes it somewhat easier to ensure that the patches are applied in the correct order.

    opened by rictic 1
Owner
Caridy Patiño
Computer Scientist, ECMA TC39 Member, Former Editor of ECMA402 Spec. Principal Architect at Salesforce. Yahoo! Alumni and Former YUI Core Team Member.
Caridy Patiño
Automaticly parses known pocket ips patch resources, scans folders or zip files for matching roms and applies the patches.

Pocket Automaton Automaticly parses known pocket ips patch resources, scans folders or zip files for matching roms and applies the patches. Usage pock

null 3 Nov 27, 2022
🔂 Send patches around to keep the system in sync.

The core idea is to use patches to keep the UI in sync between client and server, multiple clients, or multiple windows. It uses Immer as an interface

Webstudio 27 Sep 15, 2022
Patches the AssemblyScript compiler to utilize WASI imports instead of Web APIs.

WASI shim for AssemblyScript Patches the AssemblyScript compiler to utilize WASI imports instead of Web APIs. Note that this shim also serves a higher

The AssemblyScript Project 37 Dec 23, 2022
npm registry proxy with on-the-fly filtering

npm-registry-firewall ?? ?? ?? npm registry proxy with on-the-fly filtering Key Features Restricts access to remote packages by predicate: name org ve

Anton Golub 48 Dec 16, 2022
Cosmos chain registry ⚛️

chain-registry The npm package for the Official Cosmos chain registry npm install chain-registry example import { assets, chains, ibc } from 'chain-r

Cosmology 19 Dec 8, 2022
An oversimplification of the TypeScript Compiler API for defining and generating source files.

Tanu ?? A simplified abstraction of the TypeScript Compiler API for defining and generating source files. Tanu ?? Why? What does Tanu mean? ?? How do

Aries 124 Oct 29, 2022
Fully-typed utilities for defining, validating and building your document

zhead Typed utilities for defining, validating and building best-practice document <head>'s. Status: Pre-release Please report any issues ?? Made poss

Harlan Wilton 70 Dec 21, 2022
This is service registry server based on Spring Cloud Config, Netflix and Eureka

Servicec Discovery and Registry This is service registry, based on Spring Cloud Netflix, Eureka and Spring Cloud Config. Full documentation is availab

Mohammad Nuruzzaman 1 Oct 11, 2022
JavaScript micro-library: pass in an element and a callback and this will trigger when you click anywhere other than the element

Add a click listener to fire a callback for everywhere on the window except your chosen element. Installation run npm install @lukeboyle/when-clicked-

Boyleing Point 5 May 13, 2021
Refresh - Simple browser reload on file change middleware for your Deno web applications.

refresh Simple browser reload on file change middleware for your Deno web applications. Usage To use refresh middleware, just add a few extra lines to

Craig Morten 13 Dec 19, 2022
Live Reload Examples

Live Reload Examples Examples of live reloading code to create a fast feedback loop. Examples in this code repo accompany a soon to be published blog

Ashley Davis 16 Sep 29, 2022
Implements live reload functionality to Adobe extension development.

Adobe Live Reload Adobe Live Reload implements live reload functionality to Adobe extension development. Features Reload Adobe Extensions on file save

Duncan Lutz 4 Apr 24, 2022
Browser tab reload automation.

SpeedFeed Browser tab reload automation. Report Bug · Request Feature · View License (back to top) Contributing Contributions are what make the open s

Start Rev Technology 4 Aug 10, 2022
Detect webpage updates and notify user to reload. support vite and umijs

English | 简体中文 plugin-web-update-notification Detect webpage updates and notify user to reload. support vite and umijs. Take the git commit hash as th

Utopia 57 Dec 26, 2022
Wrap a function with bun-livereload to automatically reload any imports inside the function the next time it is called

bun-livereload Wrap a function with bun-livereload to automatically reload any imports inside the function the next time it is called. import liveRelo

Jarred Sumner 19 Dec 19, 2022
Automatically reload the frontend when content changes are saved in the panel.

Kirby Reload On Save This plugin for Kirby 3 automatically reloads the frontend when content changes are saved in the panel. It uses the Broadcast Cha

JUNO 21 Jun 7, 2023
Solid.js library adding a services layer for global shared state.

Solid Services Services are "global" objects useful for features that require shared state or persistent connections. Example uses of services might i

Maciej Kwaśniak 55 Dec 30, 2022
An unreliable and overall unusable sorting library for numbers with a global cache on the edge.

unsort An unreliable and overall unusable sorting library for numbers with a global cache on the edge. the algorithm This library implements a number

Jonas Wanner 6 May 19, 2022