Elements

elements.js is the Raconteur module that defines an interface for generating HTML tags.

a('Click here!').class('external_link').url('http://example.com/')

Raconteur doesn't prevent you from writing html tags in either pure html or Markdown:

content: """
    <a href="example-situation">This is valid.</a>

    [This is too.](example-situation)
    """
content: `
    <a href="example-situation">This is valid.</a>

    [This is too.](example-situation)
    `

However, element helpers have some advantages that make them useful:

Each element helper is an object that can be reused, allowing you to define and reuse custom element classes:

blinky = (content) -> span(content).class('blink').class('pink')
sparkles = blinky(sparkles)
var blinky = (content) => span(content).class('blink').class('pink');
var sparkles = blinky(sparkles);

Element helpers allow adding class or id attributers to html elements, which Markdown syntax doesn't support. They provide a native (Javascript or Coffeescript) syntax, so that for (some users) they may be more readable than writing HTML elements by hand. And they come with shorthand for defining Raconteur-style action links:

a("foo").replacer("bar")
// Stringifies as <a class="replacer" href="./_replacer_bar">foo</a>

ElementHelper objects obey the following rules:

  • They are immutable (frozen).
  • All of the prototype's methods return a new, modified, frozen object the new object inherits from the old one, and so it supplies all of the same methods.
  • They supply a toString() method that generates the html tag itself, using all of their data.

Because toString() is the method that JavaScript itself uses to coerce Objects into Strings, for example during string interpolation/concatenation, you usually don't have to explicitly call it; merely placing an ElementHelper object inside a template string will generate the tag, and this is the most common usage when placing links inside content, writer, and action properties of situations.

"#{span('foo')}" # -> "<span>foo</span>"
`${span('foo')}`
'' + span('foo')
span('foo').toString() // All evaluate to "<span>foo</span>"

Because of this interface, it's easy to define a set of defaults which can then be modified:

elem = span('foo').class('glow').id('glowing_span')
# -> <span class="glow" id="glowing_span">foo</span>
elem.content('bar').id('bar_span')
# -> <span class="glow" id="bar_span">bar</span>

Setter Methods

Every ElementHelper object supplies the following methods. All of them return a new, modified ElementHelper which inherits from the ElementHelper that the method was called on. ElementHelpers are immutable to make this safe; otherwise, an ElementHelper could have its data changed by alterations to another ElementHelper further up its prototype chain.

alt(altText) -> ElementHelper

Returns a new ElementHelper with the given string as its _alt property. This property is used as the element's alt attribute.

class(className) -> ElementHelper

Returns a new ElementHelper with the given String as an additional class. This method is additive, so it adds new classes to the element. To completely change the element's classes, use ElementHelper#Classes

classes(classes) -> ElementHelper

Returns a new ElementHelper with the given Array as a list of classes. This shadows any previously defined classes. If you wanted to erase all of an element's classes, you could use element.classes([]).

content(content) -> ElementHelper

Returns a new ElementHelper with the given content. "Content" here means the element's inner html, which will be parsed as inline markdown.

id(idName) -> ElementHelper

Returns a new ElementHelper with the given id. This string is then used as the value of the element's id attribute.

ref(url) -> ElementHelper

Returns a new ElementHelper with the given string as its _ref property. This property is used as the value of the element's href attribute.

src(url) -> ElementHelper

Returns a new ElementHelper with the given string as its _src property. This property is used as the value of the element's src attribute.

url(url) -> ElementHelper, situation(url) -> ElementHelper

Aliases for ElementHelper#ref, for legibility.

once() -> ElementHelper

Returns a new ElementHelper with the once class added to it. This class has special meaning to Undum (once links stop being hyperlinks once clicked on). This method is shorthand for class('once').

type(linkType) -> ElementHelper

Returns a new ElementHelper with its _linkType property set to the given string. This property is used to integrate with Raconteur's special link types. When the ElementHelper is stringified, the _linkType property is added as a class to the link, and as a prefix to its href. So a link with a type of "writer" and a ref of "foo" will be written out with href="./_writer_foo"; when clicked, Raconteur will look for the current situation's writers.foo property.

If an ElementHelper's type is action, it will prefix the link's ref with ./ only.

It's possible to clear an element's _linkType_ property by setting it to null or an empty string: element.type(null).

writer(), replacer(), inserter(), action() -> ElementHelper

All of those methods are shorthand for defining an ElementHelper for an action link.

e.writer('foo')     // e.type('writer').ref('foo')
e.replacer('foo')   // e.type('replacer').ref('foo')
e.inserter('foo')   // e.type('inserter').ref('foo')
e.action('foo')     // e.type('action').ref('foo')

Exports

elements.js exports the following methods:

a(content) -> elementHelper

Returns a new <a> elementHelper object, with its content set to the argument.

span(content) -> elementHelper

Returns a new <span> elementHelper object, with its content set to the argument.

img(alt) -> elementHelper

Returns a new <img> elementHelper object, with its alt text set to the argument

element(tag) -> elementHelper

Returns a new elementHelper object for the given tag. Usually, this can be called once to define your own custom element helpers:

elements = require('raconteur/elements.js')
em = elements.element('em')
glow = (content) -> em.class('glow').content(content)
var elements = require('raconteur/elements.js');
var em = elements.element('em');
var glow = function (content) { return em.class('glow').content(content); };