GithubHelp home page GithubHelp logo

h2spec's Introduction

h2spec (WIP)

A specification for proper h() calls.

Abstract

Libraries such as hyperapp, hyperscript, choo and snabbdom often feature a notable discrepancy in their implementations of the h() function. The goal of h2spec is to revise and standardize the signature for h() functions under the name "h2" or "hyper2". These projects make the usage consistent no matter what view you're working with: DOM, virtual DOM, server rendering, terminal, canvas, etc. The spec itself is oriented around simplicity, usability, and ease of implementation.

Once the spec is more mature, several of these libraries will be forked and aligned with the spec. Patches will be sent upstream where it can be merged/rejected by the authors. But, there will also be several "official" implementations before this as a proof-of-concept. Ones that get rejected may be maintained on their own.

Specification

h(tag, data?, children?) -> node

  1. tag: a string denoting the desired tag name. Cannot contain extra data like classes or ids (e.g. div.foo or div#bar).
  2. data (optional): a plain JavaScript object which maps attributes to values, otherwise null or undefined.
  3. children (optional): an array of node objects (i.e. whatever the h function in question returns) and/or primitive values.

A primitive value is a boolean, number, string, null, or undefined (as specified by ECMAScript).

Examples

h('br')
h('div', { foo: 'bar' }, [ 'baz' ])
h('span', null, [ 'foo' ])
h('header', null, [
  h('h1', null, [ 'hello world' ]),
  h('nav', null, [
    h('a', { href: '#foo' }, [ 'foo' ]),
    h('a', { href: '#bar' }, [ 'bar' ]),
    h('a', { href: '#baz' }, [ 'baz' ])
  ])
])

Projects

  • h2spec (this)
  • h2dom creates DOM nodes
  • h2ml creates HTML strings
  • h2array creates array trees resembling h() calls

FAQ

Should the return types of h-libraries (DOM, VDOMs, strings, etc) cross into each other?

This spec isolates h functions' children to their own return type for a reason. Do not mix return types outside of something experimental. However, you can change your entire project tree to DOM, VDOM, and strings, because the elements created are compatible.

Elements are symbolized through combining { tag, data, children }. The h(tag, data?, children?) function is what ties the production of a DOM node, VDOM object, string, or anything, together with consistent usage under that simple combination.

While some of these return types do mix well (i.e. VDOMs + strings = SSR) most do not. Handling several content types in each creates needless complexity. This is exactly why h(...) should be very well defined in itself, so it is easy to swap out whole trees, because the libraries rely on the same h function usage.

How would a VDOM or JSON abstraction of this look?

Since the elements are only tied together through tag, data, and children, you could just plop those into objects or arrays:

{
  tag: 'div',
  data: { class: 'foo' },
  children: [
    { tag: 'div', data: null, children: [ 'foo' ] },
    { tag: 'span', data: null, children: [ 'bar' ] },
    // ...
  ]
}

or more compact

[ 'div', { class: 'foo' }, [
  [ 'div', null, [ 'foo' ] ],
  [ 'span', null, [ 'bar' ] ]
]]

which could then map directly to h() calls:

h('div', { class: 'foo' }, [
  h('div', null, [ 'foo' ]),
  h('span', null, [ 'bar' ])
])

This is possible because the spec limits trees to a single node type, so you can guarantee the h(...) function will be the same for every node.

How strict is the spec?

Some conditions are critical, such as parameter precedence, but others are simple assertions that can be "reasonably ignored" for now to create smaller implementation sizes. For example, checking primitive types and array contents every time can be costly, so they can be assumed. But, an implementation should never support something outside of what the spec allows.

We may create fuzztesters to ensure compatbility as the spec gets more mature.

h2spec's People

Contributors

jamen avatar semibran avatar whaaaley 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

h2spec's Issues

Specify `data` object further

The data object is open-ended right now and this leaves room for incompatibilities between the modules to manifest.

Luckily everything is funneled in this single object, so when you need to make compromises, you can still follow the same call signature spec, but just specify a new data object.

That being said, we should brainstorm things to specify, and how we should go about doing this to satisfy several environments (VDOM, SSR, DOM, etc.) but with-in reason, as things can still deviate from this data object if they choose.

Parse HTML into h() calls

So you can creates different return types directly from HTML strings. For example:

var h = require('h2json')

parse(h, '<div class="foo">Hello world</div>')
// ['div', { class: 'foo' }, 'Hello world']

Classlist

Classes are easily one of the most common updates made to the DOM. Since it's so common I think there should be some sugar around classes. (This could potentially improve performance as well?)

I propose adding classlist, a synthetic attribute, to the spec.

h('div', { classlist: { '-is-active': true } }, 'foobar')

Functions as children?

Hey, this repo seems a really nice idea to build since we've got a lot of libraries building virtual dom's in their way and establish a spec around this would make the ecosystem more compatible and less error prone when switching virtual dom engines. Thanks for starting this.

I've saw in the readme that:

  1. children must be a node, primitive value, or an array of either.
  • primitive value is a Boolean, Number, String, null, or undefined (specified by ECMAScript)

But actually, when working with React, Preact or Inferno, or any other Virtual DOMs more established, we can see that there is an existing pattern to run a function as a children.

http://reactpatterns.com/#function-as-children

And, as most of pattern, we have people with their point of view saying that this is an anti-pattern:

http://americanexpress.io/faccs-are-an-antipattern/

Well, knowing this, I thought it was a good idea to start this issue to discuss whether children could be a function as well, or if a function can be considered as a primitive value
.

VDOM

We should brainstorm a VDOM. So far we just have a simple idea of { tag, data, children }, but how do you think we should implement this?

Could take an approach like hyperapp, but I would have to look at their code again. They have the element that is bound to the nodes detached from the node structure.

On the other hand there is something like snabbdom which mutates the node structure and adds node.el.

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.