Skip to content

JavaScript DOM Syntax

brett hartshorn edited this page Sep 10, 2015 · 2 revisions

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 Children

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 )

Create and Append TextNode

Passing a string as one of the arguments will automatically call document.createTextNode and append the node to elt.

elt->( "mystring" )

Setting Attributes

Named keyword arguments will set those attributes on elt by calling setAttribute.

elt->( id="foo", bar="helloworld" )

Create New Element

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')

Get Element By ID

A string prefixed with # is considered to be an ID, and will document.getElementById will be used to return the element.

document->('#myid')

Examples

Implementation

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__.

commit

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