-
Notifications
You must be signed in to change notification settings - Fork 50
JavaScript DOM Syntax
The HTML DOM is a very old API, but it is hard to get away from it, because it is basically the foundation of everything in a webpage. The DOM API has long and verbose method names like e.appendChild
, e.setAttribute
and document.createTextNode
, it quickly becomes tiring typing these over and over.
To make working with the DOM API simple and clean, the JavaScript backend transpiles the right arrow ->
to call a hidden method attached to the prototype of HTMLElement. The method takes any number of arguments, and returns this
so you can chain multiple calls together.
Append multiple children at once to HTMLElement elt
, note this is just calling elt.appendChild
under the hood. The arguments can be other HTML Elements, or TextNodes.
elt->( a, b, c )
Passing a string as one of the arguments will automatically call document.createTextNode
and append the node to elt
.
elt->( "mystring" )
Named keyword arguments will set those attributes on elt
by calling setAttribute
.
elt->( id="foo", bar="helloworld" )
HTMLDocument prototype type is overloaded so that you can use ->
to create new elements and get elements by id. The example below creates a new div
element.
document->('div')
A string prefixed with #
is considered to be an ID, and will document.getElementById
will be used to return the element.
document->('#myid')
If you want to see how this is actually defined and attached to the prototype of HTMLElement,
this is the code from builtins_core.py. You can do the same on your own classes, or prototypes from external JavaScript API's, you just need to attach a function to the prototype named __right_arrow__
.
if HTMLElement is not undefined:
@bind(HTMLElement.prototype.__right_arrow__)
def __auto_dom__():
for item in arguments:
T = typeof(item)
if instanceof(item, HTMLElement):
this.appendChild( item )
elif instanceof(item, Text): ## a text node create by `document.createTextNode`
this.appendChild( item )
elif T=='string':
this.appendChild( document.createTextNode(item) )
elif T=='function':
raise RuntimeError('HTMLElement->(lambda function) is invalid')
elif T=='object':
for key in item.keys():
this.setAttribute(key, item[key])
else:
raise RuntimeError('HTMLElement->(invalid type): '+ item)
return this