Coder Social home page Coder Social logo

modulor-js / modulor-html Goto Github PK

View Code? Open in Web Editor NEW
36.0 5.0 2.0 1.63 MB

Missing template engine for Web Components

License: MIT License

JavaScript 99.16% HTML 0.84%
template-engine template-literals js dom web-components webcomponents custom-elements

modulor-html's Introduction

modulor-html Tweet

GitHub license Codecov npm bundle size (minified + gzip) Build Status David (path)

modulor logo    Missing template engine for Web Components

import { html, render } from '@modulor-js/html';

customElements.define('my-component', class extends HTMLElement {
  set props({ first, second }){
    render(html`
      <div>first: ${first}</div>
      <div>second: ${second}</div>
    `, this);
  }
});

const first = 'foo';

render(html`
  <my-component first="${first}" second="bar"></my-conponent>
`, document.getElementById('root'));

...and much more

import { html, render } from '@modulor-js/html';

const tpl = (date) => html`
  <span>Time: ${date.toLocaleTimeString()}</span>
`;

setInterval(() => {
  render(tpl(new Date()), document.getElementById('root'));
}, 1000);

api and examples

Goals

  • Can be used in production and is already battle tested

  • Designed to be compatible with CustomElements

  • Small size (4.2kb minigzipped)

  • High performance

  • Native js syntax for templates (tagged template literals)

Installation

npm install --save @modulor-js/html

Browser support

IE >= 11 and all evergreens

Webpack loader

In real life templates can (and will) be way bigger and more complex so you might want to split them out of js code

For this case there is modulor-html-loader

Build / Test

npm run build: build the app

npm run test: test the app

Benchmark

npm run benchmark: runs node-based benchmarks

npm run benchmark:browser: runs benchmarks in browser

Issues / Bugs

Found a bug or issue? Please report it

modulor-html's People

Contributors

dependabot[bot] avatar ni-azhukov avatar nogizhopaboroda avatar nvignola avatar pankajpatel avatar paralax avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

modulor-html's Issues

Absence of parentNode causing issues

NodesRange.prototype.appendChild = function($el){
this.stopNode.parentNode.insertBefore($el, this.stopNode);
this.update();
};

Due to race condition of UI initialization and User interaction, sometimes the parentNode does not exist and causes the append to fail.

SVG Path corruption

The Uppercase character getting corrupted when passed through the template engine

Ex:

<svg width="34" height="34" viewBox="0 0 34 34">
  <path d="M29.1 26.3L23.8 22.8C22.7 22.1 21.2 22.4 20.5 23.5 19.3 25 17.8 27.5 12.2 21.8 6.6 16.2 9 14.7 10.5 13.5 11.5 12.7 11.8 11.3 11.1 10.2L7.6 4.9C7.2 4.2 6.6 3.1 5.1 3.3 3.7 3.5 0 5.6 0 10.2 0 14.8 3.6 20.4 8.5 25.4 13.5 30.3 19.1 34 23.8 34 28.4 34 30.5 29.9 30.7 28.9 30.9 27.9 29.8 26.8 29.1 26.3Z" fill="#6A3460" />
</svg>

Generates

<svg width="34" height="34" viewBox="0 0 34 34">
  <path d="M29.1 26.3{modulor_capitalize-1549296996649:L}23.8 22.8{modulor_capitalize-1549296996649:C}22.7 22.1 21.2 22.4 20.5 23.5 19.3 25 17.8 27.5 12.2 21.8 6.6 16.2 9 14.7 10.5 13.5 11.5 12.7 11.8 11.3 11.1 10.2{modulor_capitalize-1549296996649:L}7.6 4.9{modulor_capitalize-1549296996649:C}7.2 4.2 6.6 3.1 5.1 3.3 3.7 3.5 0 5.6 0 10.2 0 14.8 3.6 20.4 8.5 25.4 13.5 30.3 19.1 34 23.8 34 28.4 34 30.5 29.9 30.7 28.9 30.9 27.9 29.8 26.8 29.1 26.3Z" fill="#6A3460" />
</svg>

bug in conditional tags

const tpl = (scope) => html`
      ${scope ? html`
        <span></span>
      ` : html`
        <div></div>
        <div></div>
      `}
`;
render(tpl(false), ...);
render(tpl(true), ...);

throws Cannot read property 'replaceChild' of null in NodesRange

bug with rendering table,tr,td

this example:

    render(html`
      <table>${[1, 2, 3].map(i => html`
        <tr>
          <td>number: ${i}</td>
        </tr>
      `)}</table>
    `, <container>);

renders incorrectly:


              number: 1


              number: 2


              number: 3

          <table></table>

the reason is the way DOMParser works. text node in table (and tr, td and some other tags) 'bubbles' to place before table element.

better handling of style attribute

come up with better solution for handling style attribute.
reasons:

  1. breaks old versions of safari
  2. it should not be set as string

simplest solution could be to set it as normal attribute.

falsy values in class names

const tpl = (scope) => html`
  ${[1, 0, 2].map((item, index) => html`
    <div class="foo foo-${index} bar-${item}"></div>
   `)}
`;

results

<div class="foo bar-1"></div>
<div class="foo foo-1"></div>
<div class="foo foo-2 bar-2"></div>

promise resolving after rerender throws error

test case

  it('test', async () => {

    const container = document.createElement('div');

    const tpl = (scope) => html`
      ${scope}
    `;

    render(tpl('asdasd'), container);

    render(tpl(Promise.resolve('test')), container);
   
    //below removes promise's range somehow
    render(tpl('asdasd'), container);
    await new Promise(resolve => setTimeout(resolve, 1));

    expect(true).toBe(true);
  });

bug in conditions

const container = document.createElement('div');

const tpl = (scope) => html`
      ${scope.a ? html`
        ${scope.b ? html`
          foo
        ` : void 0}
        ${scope.c ? html`
          bar
        ` : void 0}
      ` : void 0}
    `;

render(tpl({ a: 1, b: 1 }), container);
render(tpl({ a: 1, c: 1 }), container);

console.log(container.innerHTML);

throws an error

 TypeError: Cannot read property 'removeChild' of null

      27 |
      28 | NodesRange.prototype.removeChild = function($el){
    > 29 |   this.stopNode.parentNode.removeChild($el);
      30 |   this.update();
      31 | };

do not update children nodes of nodes which are also containers

e.g.:

const tpl = html`
  <div id="cont-1"></div>
  <div id="cont-2"></div>
`;

render(tpl, $someElement);

const $anotherElement = $someElement.querySelector('#cont-1');

render(html`
  <span></span>
`, $anotherElement);

//at this point everything is ok, but:

render(tpl, $someElement);

//will remove content of $anotherElement

bug in conditional tag

const tpl = (show) => html`
  ${show ? html`
   <span>ok</span>
  `: ''}
`

render(tpl(true), ...) // works
render(tpl(false), ...) // works
render(tpl(true), ...) // doesn't work

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.