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

be-overloading

v0.0.2

Published

Script HTML elements like yore, with support for ES modules.

Downloads

12

Readme

be-overloading

Working like it's '95

Script HTML elements like yore, with support for ES modules.

NPM version How big is this package in your project? Playwright Tests

This works, using only the platform:

<button onclick="textContent = 'Try to come to life';"
>Tumble out of bed</button>

But:

  1. There is no event (apparently) that triggers the moment the element becomes connected to the DOM fragment. We might want to do things other than attach event handlers that are built in to the platform. For example, we might want to:
    1. Attach event handlers with custom names (TIL, no need for customEvent object, sounds quite promising).
    2. Initialize properties from the environment (e.g. sessionStorage, IndexedDB, link preconnect tags, etc.)
    3. Invoke some JavaScript API once the element is loaded, applying the locality of behavior principle.
  2. Using ES Modules can be done, but is clunky:
<output test='hello' contenteditable oninput="
      (async () => {
          console.log(getAttribute('test'));
          const {calculator} = await import('./calculator.js');
          console.log(calculator({a: 2, b: 4}));
          test();
      })()
      
      ">starting value</output>

be-overloading helps with these limitations.

Example 1

Not quite as compact as using the platform, but...

<button be-overloading="of click event." onload="
    $0.textContent = 'Try to come to life';
">Tumble out of bed</button>

What this does, behind the scenes:

If the onload text doesn't start with either an open parenthesis, or with e =>, it does quite a bit of wrapping. It turns the previous script into:

export const onload = async ($0, context) => {
    const fn = () => {
        $0.textContent = 'Try to come to life';
    }
    const {events} = context; // events = ['click']
    if(events !== undefined){
        for(const event of events){
            const ab = new AbortController();
            context.abortControllers[event] = ab;
            $0.addEventListener(event, e => {
                fn();
            }, {signal: ab.signal});
        }
    }
}

be-overloading invokes onload right away, passing in the element it adorns, and the event type specified in the attribute. It then detaches itself from memory, as its work is done.

The example above is meant to save the developer from a number of common keystrokes. But if the developer wants to take the reigns, to do anything off the beaten track, we have the following more verbose example:

Example 2

<button be-overloading onload="
($0) => {
    $0.addEventListener('click', e => {
        $0.textContent = 'Try to come to life.';
    });
} 
">Tumble out of bed</button>

What this does behind the scenes: Since the script begins with an open parenthesis, we apply minimal wrapping. It just adds the async keyword, essentially, and then invokes.

This also works:

Example 3

<button be-overloading="of click event." onload="
e => {
    $0.textContent = 'Try to come to life';
}
">Tumble out of bed</button>

Here, it doesn't start with parenthesis, but be-overloading has special logic that looks for script that looks for e =>

It wraps such logic into the same expanded script, yada yada.

This also works:

<button be-overloading="of click, mouseover events." onload="
e => {
    switch(e.type){
        case 'click':
            $0.textContent = 'Try to come to life';
            break;
        case 'mouseover':
            $0.textContent = 'Toss and turn';
            break;
    }
    
}
">Tumble out of bed</button>

Both events (click, mouseover) will invoke the same common script.

The developer can add conditional logic within to do different things based on which event type was triggered.

Example 4 OnUnload [TODO] -- Need strong use case

If attaching event listeners to remote elements and/or mutation observers, it is probably a good idea to clean up those listeners. The challenge is where to store the signals?

That is one of the uses of the "context" parameter.

Example 5 With expressions [TODO] -- Need strong use case

be-computed makes use of another feature (behind the scenes):

<div be-overloading="
    with line1=`Barely gettin' by, it's all takin' and no givin'`.
    With line2=`They just use your mind`.
    With line3=`And you never get the credit`.
    With line4=`It's enough to drive you crazy if you let it`.
    "
    onload="
        const html = String.raw;
        const stanza = html`
            <div>${line1}</div>
            <div>${line2}</div>
            <div>${line3}</div>
            <div>${line4}</div>
        `;
        $0.firstChild.innerHTML = stanza;
        return stanza;
>
    <section></section>
</div>

What this does, behind the scenes:

export const onload = async ($0, context) => {
    const line1 = `Barely gettin' by, it's all takin' and no givin'`;
    const line2 = `They just use your mind`;
    const line3 = `And you never get the credit`;
    const line4 = `It's enough to drive you crazy if you let it`;
    const fn = () => {
        const html = String.raw;
        const stanza = html`
            <div>${line1}</div>
            <div>${line2}</div>
            <div>${line3}</div>
            <div>${line4}</div>
        `;
        $0.firstChild.innerHTML = stanza;
        return stanza;
    }
    const {events} = context; // events = ['click']
    if(events !== undefined){
        for(const event of events){
            const ab = new AbortController();
            context.abortControllers[event] = ab;
            $0.addEventListener(event, e => {
                fn();
            }, {signal: ab.signal});
        }
    }else{
        fn();
    }
}

Viewing Demos Locally

Any web server that can serve static files will do, but...

  1. Install git.
  2. Fork/clone this repo.
  3. Install node.js.
  4. Open command window to folder where you cloned this repo.
  5. npm install

  6. npm run serve

  7. Open http://localhost:3030/demo/ in a modern browser.

Running Tests

> npm run test

Using from ESM Module:

import 'be-overloading/be-overloading.js';

Using from CDN:

<script type=module crossorigin=anonymous>
    import 'https://esm.run/be-overloading';
</script>