DOMBuilder Core¶
This page documents the DOMBuilder
object implemented in the core
DOMBuilder.js script.
Note
For brevity, some further examples will assume that element functions are available in the global scope.
Element Functions¶
Element functions accept flexible combinations of input arguments,
creating a declarative layer on top of DOMBuilder.createElement()
.
DOMBuilder.elements
is an Object
containing a function for
each valid tag name declared in the HTML 4.01 Strict DTD,
Frameset DTD and HTML5 differences from HTML4 W3C Working Draft,
referenced by the corresponding tag name in uppercase.
-
DOMBuilder.
elements
¶ Element functions which create contents based on the current value of
DOMBuilder.mode
An exhaustive list is available below in Element Function Names.
When called, these functions will create an element with the corresponding
tag name, giving it any attributes which are specified as properties of an
optional Object
argument and appending any child content passed in.
Element functions accept the following variations of arguments:
Element Creation Function Arguments | |
---|---|
(attributes, child1, ...) |
an attributes Object followed by an
arbitrary number of children. |
(attributes, [child1, ...]) |
an attributes Object and an Array of
children. |
(child1, ...) |
an arbitrary number of children. |
([child1, ...]) |
an Array of children. |
Example:
The following function creates a <table>
representation of a list of
objects, taking advantage of the flexible combinations of arguments
accepted by element functions:
/**
* @param headers a list of column headings.
* @param objects the objects to be displayed.
* @param properties names of object properties which map to the
* corresponding columns.
*/
function createTable(headers, objects, properties) {
return TABLE({cellSpacing: 1, 'class': 'data sortable'}
, THEAD(TR(TH.map(headers)))
, TBODY(
TR.map(objects, function(obj) {
return TD.map(properties, function(prop) {
if (typeof obj[prop] == 'boolean') {
return obj[prop] ? 'Yes' : 'No'
}
return obj[prop]
})
})
)
)
}
Given this function, the following code...
createTable(
['Name', 'Table #', 'Vegetarian'],
[{name: 'Steve McMeat', table: 3, veggie: false},
{name: 'Omar Omni', table: 5, veggie: false},
{name: 'Ivana Huggacow', table: 1, veggie: True}],
['name', 'table', 'veggie']
)
...would produce output corresponding to the following HTML:
<table class="data sortable" cellspacing="1">
<thead>
<tr>
<th>Name</th>
<th>Table #</th>
<th>Vegetarian</th>
</tr>
</thead>
<tbody>
<tr>
<td>Steve McMeat</td>
<td>3</td>
<td>No</td>
</tr>
<tr>
<td>Omar Omni</td>
<td>5</td>
<td>No</td>
</tr>
<tr>
<td>Ivana Huggacow</td>
<td>1</td>
<td>Yes</td>
</tr>
</tbody>
</table>
Map Functions¶
New in version 1.3.
Map functions provide a shorthand for:
- creating elements for each item in a list, via
DOMBuilder.map()
- wrapping elements created for each item in a list with a fragment, via
DOMBuilder.fragment.map()
-
DOMBuilder.
map
(tagName, defaultAttributes, items[, mappingFunction[, mode]])¶ Creates an element for (potentially) every item in a list.
Arguments: - tagName (String) – the name of the element to create for each item in the list.
- defaultAttributes (Object) – default attributes for the element.
- items (Array) – the list of items to use as the basis for creating elements.
- mappingFunction (Function) – a function to be called with each item in the list, to provide contents for the element which will be created for that item.
- mode (String) – the DOMBuilder mode to be used when creating elements.
If provided, the mapping function will be called with the following arguments:
mappingFunction(item, attributes, loopStatus)
Contents returned by the mapping function can consist of a single value or a mixed
Array
.Attributes for the created element can be altered per-item by modifying the
attributes
argument, which will initially contain the contents ofdefaultAttributes
, if it was provided.The
loopStatus
argument is anObject
with the following properties:index
- 0-based index of the current item in the list.
first
true
if the current item is the first in the list.last
true
if the current item is the last in the list.
The mapping function can prevent an element from being created for a given item altogether by returning
null
.If a mapping function is not provided, a new element will be created for each item in the list and the item itself will be used as the contents.
Changed in version 2.0:
defaultAttributes
is now required - flexible arguments are now handled by themap
functions exposed on element creation functions; themode
argument was added; a loop status object is now passed when calling the mapping function.
This function is also exposed via element creation functions. Each
element creation function has its own map
function, which allows more
flexible arguments to be passed in.
Element Creation Function .map() Arguments |
|
---|---|
(defaultAttributes, [item1, ...], mappingFunction) |
a default attributes attributes object, a list of items and a mapping Function. |
([item1, ...], mappingFunction) |
a list of items and a mapping Function. |
([item1, ...]) |
a list of items, to be used as element content as-is. |
This example shows how you could make use of the attributes
and
itemIndex
arguments to the mapping function to implement table
striping:
TR.map(rows, function(row, attributes, loop) {
attributes['class'] = (loop.index % 2 == 0 ? 'stripe1' : 'stripe2')
return TD.map(row)
})
Core API¶
These are the core functions whose output can be controlled using Output Modes.
-
DOMBuilder.
createElement
(tagName[, attributes], children], mode])¶ Creates an HTML element with the given tag name, attributes and children, optionally with a forced output mode.
Arguments: - tagName (String) – the name of the element to be created.
- attributes (Object) – attributes to be applied to the new element.
- children (Array) – childen to be appended to the new element.
- mode (String) – the mode to be used to create the element.
If children are provided, they will be appended to the new element. Any children which are not elements or fragments will be coerced to
String
and appended as text nodes.Changed in version 2.0: Now delegates to the configured mode to do all the real work.
-
DOMBuilder.
fragment
()¶ Creates a container grouping any given elements together without the need to wrap them in a redundant element. This functionality was for DOM Mode - see Document Fragments - but is supported by all output modes for the same grouping purposes.
Supported argument formats are:
Fragment Creation Arguments (child1, ...)
an arbitrary number of children. ([child1, ...])
an Array
of children.
Output Modes¶
Changed in version 2.0: Output modes now sit independent of DOMBuilder core and are pluggable.
DOMBuilder provides the ability to register new modes, which make use of the arguments given when elements and fragments are created.
-
DOMBuilder.
addMode
(mode)¶ Adds a new mode and exposes an API for it in the DOMBuilder object under a property corresponding to the mode’s name.
The first mode to be added will have its name stored in
DOMBuilder.mode
, making it the default output mode.Arguments: - mode (Object) –
Modes are defined as an
Object
with the following properties.name
- the mode’s name.
createElement(tagName, attributes, children)
- a Function which takes a tag name, attributes object and list of children and returns a content object.
fragment(children)
- a Function which takes a list of children and returns a content fragment.
isModeObject(object)
(optional)- a Function which can be used to eliminate false positives when
DOMBuilder is trying to determine whether or not an attributes
object was given - it should return
true
if given a mode-created content object. api
(optional)- an Object defining a public API for the mode’s implementation, exposing variables, functions and constructors used in implementation which may be of interest to anyone who wants to make use of the mode’s internals.
apply
(optional)- an Object defining additional properties to be added to the object
DOMBuilder creates for easy access to mode-specific element functions
(see below). Just as element functions are a convenience layer over
DOMBuilder.createElement()
, the purpose of theapply
property is to allow modes to provde a convenient way to access mode-specific functionality.Any properties specified with
apply
will also be added to objects passed intoDOMBuilder.apply()
when a mode is specified.
When a mode is added, a
DOMBuilder.<mode name>
Object is also created, containing element functions which will always create content using the given mode and any additional properties which were defined via the mode’sapply
properties.New in version 2.0.
- mode (Object) –
Example: a mode which prints out the arguments it was given:
DOMBuilder.addMode({
name: 'log'
, createElement: function(tagName, attributes, children) {
console.log(tagName, attributes, children)
return tagName
}
})
>>> DOMBuilder.build(article, 'log')
h2 Object {} ["Article title"]
p Object {} ["Paragraph one"]
p Object {} ["Paragraph two"]
div Object { class="article"} ["h2", "p", "p"]
Setting a mode’s name as DOMBuilder.mode
makes it the default
output format.
-
DOMBuilder.
mode
¶ Determines which mode
DOMBuilder.createElement()
andDOMBuilder.fragment()
will use by default.
Provided Modes¶
Implementations of the following default modes are provided for use:
Output modes:
Name | Outputs | Documentation |
---|---|---|
'dom' |
DOM Elements | DOM Mode |
'html' |
MockElement() objects which toString() to HTML4 |
HTML Mode |
Temporarily Switching Mode¶
If you’re going to be working with mixed output types, forgetting to reset
DOMBuilder.mode
would be catastrophic, so DOMBuilder provides
DOMBuilder.withMode()
to manage it for you.
-
DOMBuilder.
withMode
(mode, func[, args...])¶ Calls a function, with
DOMBuilder.mode
set to the given value for the duration of the function call, and returns its output.Any additional arguments passed after the
func
argument will be passed to the function when it is called.>>> function createParagraph() { return P('Bed and', BR(), 'BReakfast') } >>> DOMBuilder.mode = 'dom' >>> createParagraph().toString() // DOM mode by default "[object HTMLParagraphElement]" >>> DOMBuilder.withMode('HTML', createParagraph).toString() "<p>Bed and<br>BReakfast</p>"
Referencing Element Functions¶
Some options for convenient ways to reference element functions.
Create a local variable referencing the element functions you want to use:
var el = DOMBuilder.dom el.DIV('Hello')
Use the with statement to put the element functions of your choice in the scope chain for variable resolution:
with (DOMBuilder.dom) { DIV('Hello') }You could consider the with statement misunderstood; some consider with Statement Considered Harmful the final word on using the
with
statement at all, but to quote The Dude - yeah, well, y’know, that’s just, like, your opinion, man. It’s actually a pretty nice fit for builder and templating code in which properties are only ever read from the scoped object and it accounts for a significant proportion of property lookups.Just be aware that the
with
statement will be considered a syntax error if you wish to opt-in to ECMAScript 5’s strict mode in the future, but there are ways are ways to mix strict and non-stict code, as it can be toggled at the function level.
Add element functions to the global scope using DOMBuilder.apply()
:
DOMBuilder.apply(window, 'dom') DIV('Hello')Filling the global scope full of properties isn’t something which should be done lightly, but you might be ok with it for quick scripts or for utilities which you’ll be using often and which are named in ways which are unlikely to conflict with your other code, such as DOMBuilder’s upper-cased element functions.
This particular piece of documentation won’t judge you - it’s your call.
-
DOMBuilder.
apply
(context[, mode])¶ Adds element functions to the given object, optionally for a specific mode.
Arguments: - context (Object) – An object which element functions will be added to.
- mode (String) –
The name of a mode for which mode-specific element functions and convenience API should be added.
If not given, element functions from
DOMBuilder.elements
will be used.
Changed in version 2.0: The
context
argument is now required; added themode
argument.
Element Function Names¶
An exhaustive list of the available element function names.
Element Function Names | |||||||||
---|---|---|---|---|---|---|---|---|---|
A | ABBR | ACRONYM | ADDRESS | AREA | ARTICLE | ASIDE | AUDIO | B | BDI |
BDO | BIG | BLOCKQUOTE | BODY | BR | BUTTON | CANVAS | CAPTION | CITE | CODE |
COL | COLGROUP | COMMAND | DATALIST | DD | DEL | DETAILS | DFN | DIV | DL |
DT | EM | EMBED | FIELDSET | FIGCAPTION | FIGURE | FOOTER | FORM | FRAME | FRAMESET |
H1 | H2 | H3 | H4 | H5 | H6 | HR | HEAD | HEADER | HGROUP |
HTML | I | IFRAME | IMG | INPUT | INS | KBD | KEYGEN | LABEL | LEGEND |
LI | LINK | MAP | MARK | META | METER | NAV | NOSCRIPT | OBJECT | OL |
OPTGROUP | OPTION | OUTPUT | P | PARAM | PRE | PROGRESS | Q | RP | RT |
RUBY | SAMP | SCRIPT | SECTION | SELECT | SMALL | SOURCE | SPAN | STRONG | STYLE |
SUB | SUMMARY | SUP | TABLE | TBODY | TD | TEXTAREA | TFOOT | TH | THEAD |
TIME | TITLE | TR | TRACK | TT | UL | VAR | VIDEO | WBR |
Building from Arrays¶
New in version 2.0.
To make use of DOMBuilder’s Output Modes without using the rest of its
API, you can define HTML elements as nested Arrays, where each array represents
an element and each element can consist of a tag name, an optional Object
defining element attributes and an arbitrary number of content items.
For example:
Input | Sample HTML Output |
---|---|
['div'] |
<div></div> |
['div', {id: 'test'}] |
<div id="test"></div> |
['div', 'content'] |
<div>content</div> |
['div', {id: 'test'}, 'content'] |
<div id="test">content</div> |
['div', 'oh, ', ['span', 'hi!']] |
<div>oh, <span>hi!</span></div> |
To create content from a nested Array in this format, use:
-
DOMBuilder.
build
(contents[, mode])¶ Builds the specified type of output from a nested Array representation of HTML elements.
Arguments: - contents (Array) – Content defined as a nested Array
- mode (String) – Name of the output mode to use. If not given, defaults to
DOMBuilder.mode
var article =
['div', {'class': 'article'}
, ['h2', 'Article title']
, ['p', 'Paragraph one']
, ['p', 'Paragraph two']
]
>>> DOMBuilder.build(article, 'html').toString()
<div class="article"><h2>Article title</h2><p>Paragraph one</p><p>Paragraph two</p></div>
You can also use the element function and core API to create array
representations of HTML elements, by setting DOMBuilder.mode
to null
and using DOMBuilder.elements
, or directly by using
the element functions defined in DOMBuilder.array
:
-
DOMBuilder.
array
¶ Element functions which will always create nested element Array output.
This is the default output format if
DOMBuilder.mode
isnull
, effectively making it anull
mode.