npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

lit-html-scoped-registry-helper

v1.0.1

Published

This library provides some lit-html helper functions to make working with scoped custom elements easier until scoped custom element registries are supported by the platform.

Downloads

3

Readme

lit-html-scoped-registry-helper

This library provides some lit-html helper functions to make working with scoped custom elements easier until scoped custom element registries are supported by the platform.

Installation

npm install lit-html-scoped-registry-helper

Compatibility/Requirements

Currently lit-html version >=1.1.2 are supported. At the moment only the default renderer is supported not the shady renderer function (could be supported with cloning the code of the shady renderer).

  • IE: not supported
  • Edge: not supported
  • Edge (Chromium): 76+
  • Chome: 60+
  • Safari: 11+ (no support for extending built-in elements)
  • Firefox: 65+

Usage

preHTML helper

The preHTML helper can be used as a replacement for lit-htmls' native html tagged template function. It is inspired by @darioncos gist

import { render } from 'lit-html'
import { preHTML } from 'lit-html-scoped-registry-helper'

class CustomElements extends HTMLElement {}

const doRender = () => render(preHTML`<div><${CustomElement}></${CustomElement}></div>`, document.body);

createReplaceTemplateFactory and createScopedTemplateFactory

these two helper create a template factory which can be used instead of the built in one provided by lit-html. The createScopedTemplateFactory factory is backed by the html5 tokenizer included in this library, for smaller html templates its slightly faster (see test/templateinstantiation.bench.ts or run npm run benchmark in this repository). Both factories create a template factory scoped to the passed registry.

import { render } from 'lit-html'
import { createScopedTemplateFactory, createScopedTemplateFactory } from 'lit-html-scoped-registry-helper'

class CustomElement extends HTMLElement {}
class CustomElementBuiltIn extends HTMLButtonElement {} // needs polyfill in safari

// you can either create a scoped registry with just the constructor functions (these must be named, no anonymous classes are supported)
const registry = [CustomElement, CustomElementBuiltin];
// or you can explicitly state the custom elements (here you could define anonymouse custom elements)
const alternativeRegistry = { 
    'custom-element': CustomElement, 
    'custom-element-builtin' : CustomElementBuiltin
}

// call with registry with named constructors
const renderFuncImplicit = () => render(html`<CustomElement></CustomElement><button is="CustomElementBuiltin"></button>`, document.body, { templateFactory: createScopedTemplateFactory(registry)}); // you can also use createReplaceTemplateFactory

// call with registry with explicit custom-element names
const renderFuncExplicit = () => render(html`<custom-element></custom-element><button is="custom-element-builtin"></button>`, document.body, { templateFactory: createScopedTemplateFactory(alternativeRegistry)}); // you can also use createReplaceTemplateFactory

Important: the created template factories are cached and bound to the identity of the scoped registry createXXXTemplateFactory([CustomElement]) will always create a new template factory whereas createXXXTemplateFactory(myScopedRegistry) will reuse template factories.

Caveats

  • possible memory leak: both factories and the preHTML helper cache the mapping of a custom element constructor to the generated custom element name, so there is always only one custom element tag for every custom element constructor (already defined custom elements are automatically detected and will be used). Due to the nature of custom elements there is no way to clean up custom elements which are no longer needed, so all defined custom elements will remain in memory until the complete site is refreshed
  • tag css selectors don't work If you use selectors on tags in your <style> these will not work, because this library will generate a random name for the scoped custom elements (<constructorname-xxxx-xxxx>) so please use class or id selectors.

Bonus: HTML5 Tokenizer

This library contains a small and fast HTML5 tokenizer/parser inspired by ObservableHQ which is used by createScopedTemplateFactory

Usage

import { tokenizer } from 'lit-html-scoped-registry-helper'

const parser = tokenizer`<div style="test">${test}text</div>`;

parser.on('tagopen', (name) => { 
    console.log(`tag open: ${name}`)
});

parser.parse();

The following string

const parser = tokenizer`<div style="color: ${'#fff'}">
<span style="background-color: #fff">${test}text</span>
</div>`

will output the following events in order

  • start
  • tagopen div
  • attributestart style
  • text color:
  • substitution : #fff
  • attributeend: style
  • tagopenend: div
  • text: \n
  • tagopen span
  • attributestart style
  • text background-color: #fff
  • attributeend style
  • tagopenend span
  • substitution test
  • text text
  • tagclose span
  • text \n
  • tagclose div
  • end

Comments and CDATA segments are also supported.