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

dom-compose

v1.1.1

Published

Make DOM from a template string

Downloads

4

Readme

Install

npm install --save dom-compose

Usage

import domCompose from 'dom-compose';
const doc = domCompose();
//With commonjs
//const doc = require('dom-compose')();

const tpl = (input) => doc `
    <div>Hello ${input.text} ${input.div}
    <button onclick=${(event)=>{
        console.log('hello');
    }}>Say</button>
    <input class="greeting">
    </div>
`;

let div = document.createElement('div');
let text = 'world';
div.innerHTML = `I'm a div.`;

let $el = tpl({text, div});
$el.appendTo(document.querySelector('body'));

Template Literal Values

The template literal processed by the doc tag function accepts these values.

  • DOM Nodes
  • Function (DOM event callback)
  • Any primitive Javascript value
  • An object that obeys the appendTo contract

Primitive values

Any primitive is toStringed.

These values can be inserted anywhere in the template string.

DOM Nodes

DOM Nodes are inserted in a logical position relative to a parent element. If you try to insert a Node where it doesn't belong the insertion won't work.

Positions where a DOM Node fits would be anywhere between the tags of a node.

For instance both of these will work:

let location = document.createElement('span');
location.innerHTML = 'world';
//Works
let result = doc `<p>Hello ${location}!</p>`;
let greeting = document.createElement('span');
greeting.innerHTML = 'Hello world!';
//Works
let result = doc `<p>${greeting}</p>`;

But this will not:

let greeting = document.createElement('span');
greeting.innerHTML = 'Hello world!';
//Does not work
let result = doc `<p ${greeting}></p>`;

DOM Event Functions

Function values are processed based on the string to their left like:

doc`<p onclick=${(values)=>{/*Function body*/}}>A paragraph.</p>`

Event attributes used this way don't require quotes. They won't work with quotes.

Events set this way are not true inline events. They are extracted, and set with element.addEventListener. So without hazard you can do something like this:

let result = doc`
    <p onclick=${(values)=>{/*Function body*/}} onclick=${(values)=>{/*Function body*/}}>
        A paragraph.
    </p>
`

The appendTo contract

Most DOM manipulation libraries have an appendTo method that appends their DOM contents to another element. Some of these are:

  • jQuery
  • Zepto
  • spooky-element

Passing an instance from one of the above libraries will append that instance's DOM contents to the DOM created by the dom-compose template literal.

The domCompose Function

The module returns a function that needs to be called to get the doc template tag.

This function domCompose takes an options object.

These options are:

options.domlib

Set this to a function that evaluates the HTML input.

import cheerio from 'cheerio';
import domCompose from 'dom-compose';
const doc = domCompose({
    domlib: (html)=>cheerio.load(html)
});


const tpl = (text1, text2, text3) => html `
    <p>Hello ${text1} ${text2} ${text3}</p>
    `;

const result = tpl('wide', 'wonderful', 'world');
/*The result is a cheerio DOM instance*/
console.log(result.html());

If you use a parser like cheerio you can't set attribute events, or set DOM elements through the template literal.

The default domlib is a miniature DOM library with only a few methods.

These methods are:

result.appendTo(element)

Append the result to another DOM element.

Because this is the appendTo contract the results of the doc tag function can be inserted into other template literals consumed by the doc tag function.

result.html()

Get the html of the result. Unlike most DOM libs result.html() is not a setter.

options.escape

Replace the escape function.

import domCompose from 'dom-compose';
//Here we set escape to not escape at all.
const doc = domCompose({
    escape: (string)=>string
});

options.styleToHead = boolean

The styleToHead option sets whether to move a style tag to the head of the document if your template contains a style tag. The default is false.

Make sure to set a unique id for your style tag. Without it you will get unexpected results.

import domCompose from 'dom-compose';
//Here we set escape to not escape at all.
const doc = domCompose({
    styleToHead: true
});

const tpl = ()=> `
    <div>
        <style id="uniq-id"> #todo-list {border: 1px solid red; } </style>
        <ul id="todo-list">
            <li>Milk</li>
            <li>Bread</li>
        </ul>
    </div>
`

The style tag must be a child of the parent for the move to execute. A leading, or trailing style will error out.

The next example won't work.

//This is going to break your script.
const tpl = ()=> `
    <style id="uniq-id"> #todo-list {border: 1px solid red; } </style>
    <div>
        <ul id="todo-list">
            <li>Milk</li>
            <li>Bread</li>
        </ul>
    </div>
`

Some Info

This library isn't doing anything crazy for now. Who knows where it will go. There are a lot of possibilities.