Playing with web components?

Created: 2016/06/23 20:15:54+0000

I've started playing with web components. It started with a previous post. I decided that it needed some code snippets. Recently for work I had been doing this by embedding Gists. It seemed simpler than working out a different way. It was not. Gists are embedded using document.write which is not supported for XML documents. I can't embed Gists onto my XHTML website, sadface.

I had been hearing about web components for a while but did not have a use case to build one for. I decided that embedding syntax highlighted code was a good one. All I needed to do was glue togeather things implemented by other people and package them in an easy to reuse form.

Who's heard about web components? They are a set of related WC3 standards custom elements, HTML imports, HTML template and shadow DOM. The idea is that they support the creation of reusable components for websites. HTML templating allows you to create inert DOM elements to use as templates. Shadow DOM allows you to a separate DOM tree that is isolated from CSS and JavaScript but still rendered. Custom elements allow you define your own elements you can use in markup. HTML imports allow you to package HTML, JavaScript and CSS into a document fragement that can be easily included on your site.

My code listing web component is simple but manages to use all these new standards. I created an HTML import that registers a custom element (x-code-block), which loads a template into shadow DOM. The custom element provides callbacks for the element life cycle. When a x-code-block is created a shadow root is added to it, a template in the imported document fragment is copied onto the shadow root and an XHR request is made to a URL provided by an attribute on the element. Once the response is received highlight.js is applied to it and the shadow DOM is modified to include the highlighted code. It's as simple as that to create an HTML element that renders syntax highlighted code.

An obvious and well known limitation is the lack of support for stylesheets inside of the shadow DOM. In the end I worked around this by using an @import to load the stylesheet.

I implemented the component as an HTML import. Mozilia have clearly said they are not going to make that standard available for Firefox. I understand why, ES6 modules provide a much more interesting way of managing JavaScript code than imports. I'm not as concerned as they seem to be though because I view imports as a way to share imports across sites not pages. My application server gives me everything I need to share code and HTML across pages. The import allows other people to drop component into their site and use the custom element without any knowledge about how it has been implemented. ES6 modules do not address key needs for web components, importing HTML and stylesheets.