W3C home > Mailing lists > Public > whatwg@whatwg.org > August 2013

Re: [whatwg] Styling <details>

From: Ian Hickson <ian@hixie.ch>
Date: Tue, 20 Aug 2013 23:51:42 +0000 (UTC)
To: Brett Zamir <brettz9@yahoo.com>
Message-ID: <alpine.DEB.2.00.1308202337160.27209@ps20323.dreamhostps.com>
Cc: Cameron McCormack <cam@mcc.id.au>, whatwg <whatwg@whatwg.org>
On Thu, 3 Jan 2013, Brett Zamir wrote:
> 
> In my ideal world, with HTML deprived of XML or XML-like extensibility 
> (no entities or namespaces), and even with what Web Components or the 
> like could do, and with JavaScript already being able to encompass this 
> functionality, there appears to me to be a far greater need for making a 
> standard and familiar/friendly JSON/JavaScript way to represent HTML 
> than an HTML way to represent JavaScript.

There've been proposals to do this at the language level, e.g.:

   http://www.hixie.ch/specs/e4h/strawman

However, in practice I've found that you can pretty easily define two 
functions in JS that make this work more or less sufficiently well.

The first function is E(), which returns an element. It's signature:

   E(name, [attrs,] [children...])

...where attrs is an optional dictionary where:

 - entries whose value is a string are added as content attributes with 
   the given value
 - entries whose value is a number are added as content attributes with
   the given value as a string
 - entries whose value is "true" are added as content attributes with
   the empty vlaue
 - entries whose value is "false" are ignored
 - entries whose value is a function are assumed to be IDL attributes that 
   are to be set to that function
 - other entries throw an exception

...and where children is zero or more arguments where:

 - values that are Element, Comment, and Text nodes are appended to the 
   element as children
 - values that are DocumentFragments have their children appended to the
   element in the same way
 - values that are strings are appended as text nodes with the given value
 - values that are numbers are appended as text nodes with the given value 
   converted to a string
 - values that are arrays are recursively processed in the same way
 - other values throw an exception

The second function is F(children...) which takes just the varargs like 
the previous function, but returns a DocumentFragment instead.

So e.g.:

   document.body.appendChild(F(
     E('p', E('input', { type: 'button', 
                         value: 'Demo',
                         onclick: function (event) { alert('Hello!') }, 
                       }),
            ' Press the button, ', name, '! ', // name is a string var
            E('em', { class: 'beg' }, 'Please!'))));

It's not as pretty as E4H, but it's functional and way better than 
constructing it using raw DOM calls.

For the record, the E4H equivalent would be:

   document.body.appendChild(<><p><input type="button"
                                         value="Demo" 
                                         onclick="alert('Hello!')"/>\
                                  Press the button, {name}!\
                                  <em class="beg">Please!</em></p></>);

(If we did go down the E4H route, we'd have to find a better solution for 
event handlers, though.)


> [ // Optional document meta-attributes could come here
> ['html', [
>     ['head', [
>         ['script', [
>             // A JSON format sans functions could be possible, but allowable
> for convenience in templating
>             {$script: function (onReady) {
>                 require(['depend1'], function (depend1) {
>                     onReady(function () {
>                         document.body.appendChild(['p', ['World']]);
>                         depend1('no additional script tags needed for
> modularity');
> 
>                         // Ready and easy conversion
>                         var jml = ['b', ['Hello']], html = '<b>Hello</b>', dom
> = document.createElement(jml);
>                         jml === html.toJML() &&
>                             jml === dom.toJML() &&
>                                 html === jml.toHTML() &&
>                                     html === dom.toHTML() &&
>                                         dom === html.toDOM() &&
>                                             dom === jml.toDOM(); // true
>                     });
>                 });
>             }}
>         ]],
>         ['style', [
>             // Non-array objects would normally represent attributes, but when
> prefixed with the
>             //   reserved '$', other features become possible for HTML (or
> XML)
>             {$css: [
>                 ['p[greeting]', ['color', 'blue']]
>             ]
>         ]]
>     ]],
>     ['body', [
>         'text',
>         ['p', {'class':'greeting'}, ['Hello!']],
>         {'$#x': '263A'},
>         {$comment: 'Finished file!'}
>     ]]
> ]]
> ]

I don't really see the advantage of such a format. What problem are you 
solving here?

-- 
Ian Hickson               U+1047E                )\._.,--....,'``.    fL
http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'
Received on Tuesday, 20 August 2013 23:52:12 UTC

This archive was generated by hypermail 2.3.1 : Monday, 13 April 2015 23:09:23 UTC