Skip to content

bustle/mobiledoc-dom-renderer

Repository files navigation

Mobiledoc DOM Renderer

This is a DOM renderer for the Mobiledoc format used by Mobiledoc-Kit.

To learn more about Mobiledoc cards and renderers, see the Mobiledoc Cards docs.

The renderer is a small library intended for use in browser clients.

Usage

var mobiledoc = {
  version: "0.3.0",
  markups: ["B"],
  atoms: [],
  cards: [],
  sections: [
    [1, 'P', [ // array of markers
      // marker
      [ 0,            // marker type 0 (standard text)
        [0],          // open markups (by index)
        0,            // close count
        'hello world'
      ]
    ]
  ]
};
var renderer = new MobiledocDOMRenderer({cards: []});
var rendered = renderer.render(mobiledoc);
var result = rendered.result;
document.getElementById('output').appendChild(result);
// renders <div><p><b>hello world</b></b></div>
// into 'output' element

The Renderer constructor accepts a single object with the following optional properties:

  • cards [array] - The list of card objects that the renderer may encounter in the mobiledoc
  • atoms [array] - The list of atom objects that the renderer may encounter in the mobiledoc
  • cardOptions [object] - Options to pass to cards and atoms when they are rendered
  • unknownCardHandler [function] - Will be called when any unknown card is enountered
  • unknownAtomHandler [function] - Will be called when any unknown atom is enountered
  • sectionElementRenderer [object] - A map of hooks for section element rendering.
    • Valid keys are P, H1, H2, H3, H4, H5, H6, BLOCKQUOTE, ASIDE
    • Arguments are tagName, dom
    • A valid value is a function that returns an element
  • markupElementRenderer [object] - A map of hooks for inline element rendering.
    • Valid keys are B, I, STRONG, EM, A, U, SUB, SUP, S, CODE
    • Arguments are tagName, dom, attributes={}
    • A valid value is a function that returns an element
  • dom [object] - A native or SimpleDOM implementation of the DOM.

The return value from renderer.render(mobiledoc) is an object with two properties:

  • result [DOM Node] - The rendered result
  • teardown [function] - When called, this function will tear down the rendered mobiledoc and call any teardown handlers that were registered by cards when they were rendered

Rendering HTML

In a browser, rendering to HTML is simple:

var renderer = new MobiledocDOMRenderer();
var rendered = renderer.render(mobiledoc);
var html = rendered.result.outerHTML;

However on the server in Node.js, native DOM APIs are not available. To make server-rendering easy, this DOM renderer is SimpleDOM compatible. You may pass an instance of a SimpleDOM document and serialize its output. For example:

var renderer = new MobiledocDOMRenderer({
  dom: new SimpleDOM.Document()
});
var rendered = renderer.render(mobiledoc);
var serializer = new SimpleDOM.HTMLSerializer([]);
var html = serializer.serializeChildren(rendered.result);

This usage of the DOM renderer for rendering HTML has the advantage of allowing developers to easily implement cards that work in a server and client context.

sectionElementRenderer

Use this renderer option to customize what element is used when rendering a section.

var renderer = new MobiledocDOMRenderer({
  sectionElementRenderer: {
    P: function(_, dom) { return dom.createElement('span'); },
    H1: function(_, dom) { return dom.createElement('h2'); },
    H2: function(tagName, dom) {
      var element = dom.createElement(tagName);
      element.setAttribute('class', 'subheadline');
      return element;
    }
    /* Valid keys are P, H1, H2, H3, H4, H5, H6, BLOCKQUOTE, ASIDE */
  }
});
var rendered = renderer.render(mobiledoc);

markupElementRenderer

Use this renderer option to customize what inline tags are used when rendering a section's content.

var renderer = new MobiledocDOMRenderer({
  markupElementRenderer: {
    B: function(_, dom) { return dom.createElement('strong'); },
    A: function(tagName, dom, attrs={}) {
      let element = dom.createElement(tagName);

      for (let attr in attrs) {
        element.setAttribute(attr, attrs[attr]);
      }

      element.setAttribute('rel', 'nofollow');
      return element;
    }
  }
});
var rendered = renderer.render(mobiledoc);

Attribute Sanitization (XSS Protection)

Mobiledoc DOM Renderer sanitizes the href attribute of 'A' markups, prefixing the string unsafe: on potentially unsafe urls. It determines an environment- appropriate URL protocol parser. In rare cases it may be unable to determine one (this can happen when running the renderer in a Node VM Sandbox, like ember-cli- fastboot does), and will throw in that case. To fix this, you can provide a custom markupElementRenderer for the 'A' tag that will be used instead of the default.

Tests

Releasing

  • Use np (install with npm install -g np)
  • np <version> (e.g. np 0.5.2)
  • git push --tags