Learning Custom Elements

 from Red Blob Games
18 Jun 2022

Following the guide here: https://javascript.info/custom-elements[1]

This is an example paragraph with a   clock.

Try editing the paragraph. I set contenteditable on it. You can copy and paste the clock (in webkit not gecko), making multiple clocks! With a non-svg custom element, the entire element can be selected or not selected, but you can’t selected text inside the custom element. With an svg custom element, the element can be selected but doesn’t show the highlight color (this is actually an issue even outside of contenteditable).

In Chrome: you can’t backspace over the initial clock. You can copy & paste the clock. You can backspace over clocks you paste in. If two clocks are adjacent, backspace will delete both at once.

In Safari: you can backspace over the intial clock. You can copy & paste the clock. You can backspace over clocks you paste in. If two clocks are adjacent, backspace will delete both at once.

In Firefox: you can backspace over the initial clock. You can’t copy & paste the clock.

But what’s going on underneath? On Copy, Chrome and Safari are copying a huge amount of html, as you can see in the PASTED box. This includes the shadow dom, even if the shadow dom is marked “closed”. Firefox seems to be copying a small amount of html. This is not only true of web components, but also if you try copying the word Following from the beginning of the page, or a word inside the <pre> box. Chrome and Safari are copying the background color under the word Following. Firefox copies only the word.

On Paste, Chrome and Safari are stripping some of the html instead of putting it directly into the edit box. Firefox is also stripping some of the html, including the <a-clock>. So that means we can copy the web component but we can’t paste it.

But wait, there’s more!

I can copy from Chrome or Safari into Firefox. I just can’t copy from Firefox into Firefox. And I can copy from Firefox into Chrome or Safari. This is so weird. I don’t yet have a mental model for what would allow this.

A workaround for Chrome not letting you backspace over the initial clock: put some text inside <a-clock>DUMMY TEXT</a-clock>. Even though the dummytext makes no visible difference, it affects the way the backspace works! Also, the dummy text does not get copied when you paste a second copy of the clock. In Firefox though, the dummy text gets copied but the clock does not. Argh.

I also get into situations where I can no longer edit in Chrome. I think contenteditable is just a mess.

TODO: https://javascript.info/mutation-observer[2]

TODO: https://web.dev/declarative-shadow-dom/[3]

==

Note to self: also consider lit.dev[4], a library that makes it easier to make web components. But contenteditable is a mess, and I should probably use TipTap.

Email me , or tweet @redblobgames, or comment: