mobiledoc-text-renderer
Advanced tools
Comparing version 0.2.1 to 0.3.0-beta.1
@@ -10,3 +10,3 @@ define('mobiledoc-text-renderer/cards/image', ['exports'], function (exports) { | ||
}); | ||
define('mobiledoc-text-renderer', ['exports', 'mobiledoc-text-renderer/renderer-factory'], function (exports, _mobiledocTextRendererRendererFactory) { | ||
define('mobiledoc-text-renderer', ['exports', 'mobiledoc-text-renderer/renderer-factory', 'mobiledoc-text-renderer/utils/render-type'], function (exports, _mobiledocTextRendererRendererFactory, _mobiledocTextRendererUtilsRenderType) { | ||
'use strict'; | ||
@@ -20,5 +20,6 @@ | ||
exports.RENDER_TYPE = _mobiledocTextRendererUtilsRenderType['default']; | ||
exports['default'] = _mobiledocTextRendererRendererFactory['default']; | ||
}); | ||
define('mobiledoc-text-renderer/renderer-factory', ['exports', 'mobiledoc-text-renderer/renderer'], function (exports, _mobiledocTextRendererRenderer) { | ||
define('mobiledoc-text-renderer/renderer-factory', ['exports', 'mobiledoc-text-renderer/renderers/0-2', 'mobiledoc-text-renderer/renderers/0-3', 'mobiledoc-text-renderer/utils/render-type'], function (exports, _mobiledocTextRendererRenderers02, _mobiledocTextRendererRenderers03, _mobiledocTextRendererUtilsRenderType) { | ||
'use strict'; | ||
@@ -30,3 +31,2 @@ | ||
var RENDER_TYPE = 'text'; | ||
/** | ||
@@ -41,9 +41,9 @@ * runtime Text renderer | ||
function validateCards(cards) { | ||
if (!Array.isArray) { | ||
throw new Error('`cards` must be an array'); | ||
if (!Array.isArray(cards)) { | ||
throw new Error('`cards` must be passed as an array'); | ||
} | ||
for (var i = 0; i < cards.length; i++) { | ||
var card = cards[i]; | ||
if (card.type !== RENDER_TYPE) { | ||
throw new Error('Card "' + card.name + '" must be type "' + RENDER_TYPE + '", was "' + card.type + '"'); | ||
if (card.type !== _mobiledocTextRendererUtilsRenderType['default']) { | ||
throw new Error('Card "' + card.name + '" must be type "' + _mobiledocTextRendererUtilsRenderType['default'] + '", was "' + card.type + '"'); | ||
} | ||
@@ -56,2 +56,17 @@ if (!card.render) { | ||
function validateAtoms(atoms) { | ||
if (!Array.isArray(atoms)) { | ||
throw new Error('`atoms` must be passed as an array'); | ||
} | ||
for (var i = 0; i < atoms.length; i++) { | ||
var atom = atoms[i]; | ||
if (atom.type !== _mobiledocTextRendererUtilsRenderType['default']) { | ||
throw new Error('Atom "' + atom.name + '" must be type "' + _mobiledocTextRendererUtilsRenderType['default'] + '", was "' + atom.type + '"'); | ||
} | ||
if (!atom.render) { | ||
throw new Error('Atom "' + atom.name + '" must define `render`'); | ||
} | ||
} | ||
} | ||
var RendererFactory = (function () { | ||
@@ -65,2 +80,3 @@ function RendererFactory() { | ||
var unknownCardHandler = _ref.unknownCardHandler; | ||
var unknownAtomHandler = _ref.unknownAtomHandler; | ||
@@ -72,5 +88,6 @@ _classCallCheck(this, RendererFactory); | ||
atoms = atoms || []; | ||
validateAtoms(atoms); | ||
cardOptions = cardOptions || {}; | ||
this.state = { cards: cards, atoms: atoms, cardOptions: cardOptions, unknownCardHandler: unknownCardHandler }; | ||
this.state = { cards: cards, atoms: atoms, cardOptions: cardOptions, unknownCardHandler: unknownCardHandler, unknownAtomHandler: unknownAtomHandler }; | ||
} | ||
@@ -81,3 +98,14 @@ | ||
value: function render(mobiledoc) { | ||
return new _mobiledocTextRendererRenderer['default'](mobiledoc, this.state).render(); | ||
var version = mobiledoc.version; | ||
switch (version) { | ||
case _mobiledocTextRendererRenderers02.MOBILEDOC_VERSION: | ||
case undefined: | ||
case null: | ||
return new _mobiledocTextRendererRenderers02['default'](mobiledoc, this.state).render(); | ||
case _mobiledocTextRendererRenderers03.MOBILEDOC_VERSION: | ||
return new _mobiledocTextRendererRenderers03['default'](mobiledoc, this.state).render(); | ||
default: | ||
throw new Error('Unexpected Mobiledoc version "' + version + '"'); | ||
} | ||
} | ||
@@ -91,3 +119,3 @@ }]); | ||
}); | ||
define('mobiledoc-text-renderer/renderer', ['exports', 'mobiledoc-text-renderer/cards/image'], function (exports, _mobiledocTextRendererCardsImage) { | ||
define('mobiledoc-text-renderer/renderers/0-2', ['exports', 'mobiledoc-text-renderer/cards/image', 'mobiledoc-text-renderer/utils/render-type', 'mobiledoc-text-renderer/utils/section-types'], function (exports, _mobiledocTextRendererCardsImage, _mobiledocTextRendererUtilsRenderType, _mobiledocTextRendererUtilsSectionTypes) { | ||
/** | ||
@@ -109,12 +137,9 @@ * runtime Text renderer | ||
var LINE_BREAK = '\n'; | ||
var RENDER_TYPE = 'text'; | ||
var MARKUP_SECTION_TYPE = 1; | ||
var IMAGE_SECTION_TYPE = 2; | ||
var LIST_SECTION_TYPE = 3; | ||
var CARD_SECTION_TYPE = 10; | ||
var MOBILEDOC_VERSION = '0.2.0'; | ||
exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION; | ||
function validateVersion(version) { | ||
if (version !== '0.2.0') { | ||
throw new Error('Unknown mobiledoc version "' + version + '"'); | ||
if (version !== MOBILEDOC_VERSION) { | ||
throw new Error('Unexpected Mobiledoc version "' + version + '"'); | ||
} | ||
@@ -181,9 +206,9 @@ } | ||
switch (type) { | ||
case MARKUP_SECTION_TYPE: | ||
case _mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE: | ||
return this.renderMarkupSection(section); | ||
case IMAGE_SECTION_TYPE: | ||
case _mobiledocTextRendererUtilsSectionTypes.IMAGE_SECTION_TYPE: | ||
return this.renderImageSection(section); | ||
case LIST_SECTION_TYPE: | ||
case _mobiledocTextRendererUtilsSectionTypes.LIST_SECTION_TYPE: | ||
return this.renderListSection(section); | ||
case CARD_SECTION_TYPE: | ||
case _mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE: | ||
return this.renderCardSection(section); | ||
@@ -237,3 +262,3 @@ default: | ||
name: name, | ||
type: RENDER_TYPE, | ||
type: _mobiledocTextRendererUtilsRenderType['default'], | ||
render: this.unknownCardHandler | ||
@@ -256,5 +281,18 @@ }; | ||
this._validateCardRender(rendered, card.name); | ||
return rendered || ''; | ||
} | ||
}, { | ||
key: '_validateCardRender', | ||
value: function _validateCardRender(rendered, cardName) { | ||
if (!rendered) { | ||
return; | ||
} | ||
if (typeof rendered !== 'string') { | ||
throw new Error('Card "' + cardName + '" must render ' + _mobiledocTextRendererUtilsRenderType['default'] + ', but result was ' + typeof rendered + '"'); | ||
} | ||
} | ||
}, { | ||
key: '_registerTeardownCallback', | ||
@@ -318,2 +356,389 @@ value: function _registerTeardownCallback(callback) { | ||
exports['default'] = Renderer; | ||
}); | ||
define('mobiledoc-text-renderer/renderers/0-3', ['exports', 'mobiledoc-text-renderer/cards/image', 'mobiledoc-text-renderer/utils/render-type', 'mobiledoc-text-renderer/utils/section-types', 'mobiledoc-text-renderer/utils/marker-types'], function (exports, _mobiledocTextRendererCardsImage, _mobiledocTextRendererUtilsRenderType, _mobiledocTextRendererUtilsSectionTypes, _mobiledocTextRendererUtilsMarkerTypes) { | ||
/** | ||
* runtime Text renderer | ||
* renders a mobiledoc to Text | ||
* | ||
* input: mobiledoc | ||
* output: Text (string) | ||
*/ | ||
'use strict'; | ||
var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); | ||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | ||
var LINE_BREAK = '\n'; | ||
var MOBILEDOC_VERSION = '0.3.0'; | ||
exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION; | ||
function validateVersion(version) { | ||
if (version !== MOBILEDOC_VERSION) { | ||
throw new Error('Unexpected Mobiledoc version "' + version + '"'); | ||
} | ||
} | ||
var Renderer = (function () { | ||
function Renderer(mobiledoc, state) { | ||
_classCallCheck(this, Renderer); | ||
var cards = state.cards; | ||
var cardOptions = state.cardOptions; | ||
var atoms = state.atoms; | ||
var unknownCardHandler = state.unknownCardHandler; | ||
var unknownAtomHandler = state.unknownAtomHandler; | ||
var version = mobiledoc.version; | ||
var sections = mobiledoc.sections; | ||
var atomTypes = mobiledoc.atoms; | ||
var cardTypes = mobiledoc.cards; | ||
validateVersion(version); | ||
this.root = []; | ||
this.sections = sections; | ||
this.atomTypes = atomTypes; | ||
this.cardTypes = cardTypes; | ||
this.cards = cards; | ||
this.atoms = atoms; | ||
this.cardOptions = cardOptions; | ||
this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler; | ||
this.unknownAtomHandler = unknownAtomHandler || this._defaultUnknownAtomHandler; | ||
this._teardownCallbacks = []; | ||
} | ||
_createClass(Renderer, [{ | ||
key: 'render', | ||
value: function render() { | ||
var _this = this; | ||
this.sections.forEach(function (section) { | ||
_this.root.push(_this.renderSection(section)); | ||
}); | ||
var result = this.root.join(LINE_BREAK); | ||
return { result: result, teardown: function teardown() { | ||
return _this.teardown(); | ||
} }; | ||
} | ||
}, { | ||
key: 'teardown', | ||
value: function teardown() { | ||
for (var i = 0; i < this._teardownCallbacks.length; i++) { | ||
this._teardownCallbacks[i](); | ||
} | ||
} | ||
}, { | ||
key: 'renderSection', | ||
value: function renderSection(section) { | ||
var _section = _slicedToArray(section, 1); | ||
var type = _section[0]; | ||
switch (type) { | ||
case _mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE: | ||
return this.renderMarkupSection(section); | ||
case _mobiledocTextRendererUtilsSectionTypes.IMAGE_SECTION_TYPE: | ||
return this.renderImageSection(section); | ||
case _mobiledocTextRendererUtilsSectionTypes.LIST_SECTION_TYPE: | ||
return this.renderListSection(section); | ||
case _mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE: | ||
return this.renderCardSection(section); | ||
default: | ||
throw new Error('Unimplemented renderer for type ' + type); | ||
} | ||
} | ||
}, { | ||
key: 'renderImageSection', | ||
value: function renderImageSection() { | ||
return ''; | ||
} | ||
}, { | ||
key: 'renderListSection', | ||
value: function renderListSection(_ref) { | ||
var _this2 = this; | ||
var _ref2 = _slicedToArray(_ref, 3); | ||
var type = _ref2[0]; | ||
var tagName = _ref2[1]; | ||
var items = _ref2[2]; | ||
return items.map(function (li) { | ||
return _this2.renderListItem(li); | ||
}).join(LINE_BREAK); | ||
} | ||
}, { | ||
key: 'renderListItem', | ||
value: function renderListItem(markers) { | ||
return this.renderMarkers(markers); | ||
} | ||
}, { | ||
key: 'findCard', | ||
value: function findCard(name) { | ||
for (var i = 0; i < this.cards.length; i++) { | ||
if (this.cards[i].name === name) { | ||
return this.cards[i]; | ||
} | ||
} | ||
if (name === _mobiledocTextRendererCardsImage['default'].name) { | ||
return _mobiledocTextRendererCardsImage['default']; | ||
} | ||
return this._createUnknownCard(name); | ||
} | ||
}, { | ||
key: '_findCardByIndex', | ||
value: function _findCardByIndex(index) { | ||
var cardType = this.cardTypes[index]; | ||
if (!cardType) { | ||
throw new Error('No card definition found at index ' + index); | ||
} | ||
var _cardType = _slicedToArray(cardType, 2); | ||
var name = _cardType[0]; | ||
var payload = _cardType[1]; | ||
var card = this.findCard(name); | ||
return { | ||
card: card, | ||
payload: payload | ||
}; | ||
} | ||
}, { | ||
key: '_createUnknownCard', | ||
value: function _createUnknownCard(name) { | ||
return { | ||
name: name, | ||
type: _mobiledocTextRendererUtilsRenderType['default'], | ||
render: this.unknownCardHandler | ||
}; | ||
} | ||
}, { | ||
key: 'renderCardSection', | ||
value: function renderCardSection(_ref3) { | ||
var _ref32 = _slicedToArray(_ref3, 2); | ||
var type = _ref32[0]; | ||
var index = _ref32[1]; | ||
var _findCardByIndex2 = this._findCardByIndex(index); | ||
var card = _findCardByIndex2.card; | ||
var payload = _findCardByIndex2.payload; | ||
var cardArg = this._createCardArgument(card, payload); | ||
var rendered = card.render(cardArg); | ||
this._validateCardRender(rendered, card.name); | ||
return rendered || ''; | ||
} | ||
}, { | ||
key: '_validateCardRender', | ||
value: function _validateCardRender(rendered, cardName) { | ||
if (!rendered) { | ||
return; | ||
} | ||
if (typeof rendered !== 'string') { | ||
throw new Error('Card "' + cardName + '" must render ' + _mobiledocTextRendererUtilsRenderType['default'] + ', but result was ' + typeof rendered + '"'); | ||
} | ||
} | ||
}, { | ||
key: '_registerTeardownCallback', | ||
value: function _registerTeardownCallback(callback) { | ||
this._teardownCallbacks.push(callback); | ||
} | ||
}, { | ||
key: '_createCardArgument', | ||
value: function _createCardArgument(card) { | ||
var _this3 = this; | ||
var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
var env = { | ||
name: card.name, | ||
isInEditor: false, | ||
onTeardown: function onTeardown(callback) { | ||
return _this3._registerTeardownCallback(callback); | ||
} | ||
}; | ||
var options = this.cardOptions; | ||
return { env: env, options: options, payload: payload }; | ||
} | ||
}, { | ||
key: 'renderMarkupSection', | ||
value: function renderMarkupSection(_ref4) { | ||
var _ref42 = _slicedToArray(_ref4, 3); | ||
var type = _ref42[0]; | ||
var tagName = _ref42[1]; | ||
var markers = _ref42[2]; | ||
return this.renderMarkers(markers); | ||
} | ||
}, { | ||
key: 'findAtom', | ||
value: function findAtom(name) { | ||
for (var i = 0; i < this.atoms.length; i++) { | ||
if (this.atoms[i].name === name) { | ||
return this.atoms[i]; | ||
} | ||
} | ||
return this._createUnknownAtom(name); | ||
} | ||
}, { | ||
key: '_createUnknownAtom', | ||
value: function _createUnknownAtom(name) { | ||
return { | ||
name: name, | ||
type: _mobiledocTextRendererUtilsRenderType['default'], | ||
render: this.unknownAtomHandler | ||
}; | ||
} | ||
}, { | ||
key: '_createAtomArgument', | ||
value: function _createAtomArgument(atom, value, payload) { | ||
var _this4 = this; | ||
var env = { | ||
name: atom.name, | ||
onTeardown: function onTeardown(callback) { | ||
return _this4._registerTeardownCallback(callback); | ||
} | ||
}; | ||
var options = this.cardOptions; | ||
return { env: env, options: options, value: value, payload: payload }; | ||
} | ||
}, { | ||
key: '_validateAtomRender', | ||
value: function _validateAtomRender(rendered, atomName) { | ||
if (!rendered) { | ||
return; | ||
} | ||
if (typeof rendered !== 'string') { | ||
throw new Error('Atom "' + atomName + '" must render ' + _mobiledocTextRendererUtilsRenderType['default'] + ', but result was ' + typeof rendered + '"'); | ||
} | ||
} | ||
}, { | ||
key: '_findAtomByIndex', | ||
value: function _findAtomByIndex(index) { | ||
var atomType = this.atomTypes[index]; | ||
if (!atomType) { | ||
throw new Error('No atom definition found at index ' + index); | ||
} | ||
var _atomType = _slicedToArray(atomType, 3); | ||
var name = _atomType[0]; | ||
var value = _atomType[1]; | ||
var payload = _atomType[2]; | ||
var atom = this.findAtom(name); | ||
return { | ||
atom: atom, | ||
value: value, | ||
payload: payload | ||
}; | ||
} | ||
}, { | ||
key: '_renderAtom', | ||
value: function _renderAtom(index) { | ||
var _findAtomByIndex2 = this._findAtomByIndex(index); | ||
var atom = _findAtomByIndex2.atom; | ||
var value = _findAtomByIndex2.value; | ||
var payload = _findAtomByIndex2.payload; | ||
var atomArg = this._createAtomArgument(atom, value, payload); | ||
var rendered = atom.render(atomArg); | ||
this._validateAtomRender(rendered, atom.name); | ||
return rendered || ''; | ||
} | ||
}, { | ||
key: 'renderMarkers', | ||
value: function renderMarkers(markers) { | ||
var _this5 = this; | ||
var str = ''; | ||
markers.forEach(function (m) { | ||
var _m = _slicedToArray(m, 4); | ||
var type = _m[0]; | ||
var value = _m[3]; | ||
switch (type) { | ||
case _mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE: | ||
str += value; | ||
break; | ||
case _mobiledocTextRendererUtilsMarkerTypes.ATOM_MARKER_TYPE: | ||
str += _this5._renderAtom(value); | ||
break; | ||
default: | ||
throw new Error('Unknown markup type (' + type + ')'); | ||
} | ||
}); | ||
return str; | ||
} | ||
}, { | ||
key: '_defaultUnknownCardHandler', | ||
get: function get() { | ||
return function () { | ||
// for the text renderer, a missing card is a no-op | ||
}; | ||
} | ||
}, { | ||
key: '_defaultUnknownAtomHandler', | ||
get: function get() { | ||
return function (_ref5) { | ||
var value = _ref5.value; | ||
return value || ''; | ||
}; | ||
} | ||
}]); | ||
return Renderer; | ||
})(); | ||
exports['default'] = Renderer; | ||
}); | ||
define("mobiledoc-text-renderer/utils/marker-types", ["exports"], function (exports) { | ||
"use strict"; | ||
var MARKUP_MARKER_TYPE = 0; | ||
exports.MARKUP_MARKER_TYPE = MARKUP_MARKER_TYPE; | ||
var ATOM_MARKER_TYPE = 1; | ||
exports.ATOM_MARKER_TYPE = ATOM_MARKER_TYPE; | ||
}); | ||
define('mobiledoc-text-renderer/utils/render-type', ['exports'], function (exports) { | ||
'use strict'; | ||
exports['default'] = 'text'; | ||
}); | ||
define("mobiledoc-text-renderer/utils/section-types", ["exports"], function (exports) { | ||
"use strict"; | ||
var MARKUP_SECTION_TYPE = 1; | ||
exports.MARKUP_SECTION_TYPE = MARKUP_SECTION_TYPE; | ||
var IMAGE_SECTION_TYPE = 2; | ||
exports.IMAGE_SECTION_TYPE = IMAGE_SECTION_TYPE; | ||
var LIST_SECTION_TYPE = 3; | ||
exports.LIST_SECTION_TYPE = LIST_SECTION_TYPE; | ||
var CARD_SECTION_TYPE = 10; | ||
exports.CARD_SECTION_TYPE = CARD_SECTION_TYPE; | ||
});//# sourceMappingURL=mobiledoc-text-renderer.map |
@@ -7,2 +7,4 @@ 'use strict'; | ||
var _utilsRenderType = require('./utils/render-type'); | ||
function registerGlobal(window) { | ||
@@ -12,2 +14,3 @@ window.MobiledocTextRenderer = _rendererFactory['default']; | ||
exports.RENDER_TYPE = _utilsRenderType['default']; | ||
exports['default'] = _rendererFactory['default']; |
@@ -7,5 +7,8 @@ 'use strict'; | ||
var _renderer = require('./renderer'); | ||
var _renderers02 = require('./renderers/0-2'); | ||
var RENDER_TYPE = 'text'; | ||
var _renderers03 = require('./renderers/0-3'); | ||
var _utilsRenderType = require('./utils/render-type'); | ||
/** | ||
@@ -20,9 +23,9 @@ * runtime Text renderer | ||
function validateCards(cards) { | ||
if (!Array.isArray) { | ||
throw new Error('`cards` must be an array'); | ||
if (!Array.isArray(cards)) { | ||
throw new Error('`cards` must be passed as an array'); | ||
} | ||
for (var i = 0; i < cards.length; i++) { | ||
var card = cards[i]; | ||
if (card.type !== RENDER_TYPE) { | ||
throw new Error('Card "' + card.name + '" must be type "' + RENDER_TYPE + '", was "' + card.type + '"'); | ||
if (card.type !== _utilsRenderType['default']) { | ||
throw new Error('Card "' + card.name + '" must be type "' + _utilsRenderType['default'] + '", was "' + card.type + '"'); | ||
} | ||
@@ -35,2 +38,17 @@ if (!card.render) { | ||
function validateAtoms(atoms) { | ||
if (!Array.isArray(atoms)) { | ||
throw new Error('`atoms` must be passed as an array'); | ||
} | ||
for (var i = 0; i < atoms.length; i++) { | ||
var atom = atoms[i]; | ||
if (atom.type !== _utilsRenderType['default']) { | ||
throw new Error('Atom "' + atom.name + '" must be type "' + _utilsRenderType['default'] + '", was "' + atom.type + '"'); | ||
} | ||
if (!atom.render) { | ||
throw new Error('Atom "' + atom.name + '" must define `render`'); | ||
} | ||
} | ||
} | ||
var RendererFactory = (function () { | ||
@@ -44,2 +62,3 @@ function RendererFactory() { | ||
var unknownCardHandler = _ref.unknownCardHandler; | ||
var unknownAtomHandler = _ref.unknownAtomHandler; | ||
@@ -51,5 +70,6 @@ _classCallCheck(this, RendererFactory); | ||
atoms = atoms || []; | ||
validateAtoms(atoms); | ||
cardOptions = cardOptions || {}; | ||
this.state = { cards: cards, atoms: atoms, cardOptions: cardOptions, unknownCardHandler: unknownCardHandler }; | ||
this.state = { cards: cards, atoms: atoms, cardOptions: cardOptions, unknownCardHandler: unknownCardHandler, unknownAtomHandler: unknownAtomHandler }; | ||
} | ||
@@ -60,3 +80,14 @@ | ||
value: function render(mobiledoc) { | ||
return new _renderer['default'](mobiledoc, this.state).render(); | ||
var version = mobiledoc.version; | ||
switch (version) { | ||
case _renderers02.MOBILEDOC_VERSION: | ||
case undefined: | ||
case null: | ||
return new _renderers02['default'](mobiledoc, this.state).render(); | ||
case _renderers03.MOBILEDOC_VERSION: | ||
return new _renderers03['default'](mobiledoc, this.state).render(); | ||
default: | ||
throw new Error('Unexpected Mobiledoc version "' + version + '"'); | ||
} | ||
} | ||
@@ -63,0 +94,0 @@ }]); |
@@ -200,3 +200,3 @@ ;(function() { | ||
}); | ||
define('mobiledoc-text-renderer', ['exports', 'mobiledoc-text-renderer/renderer-factory'], function (exports, _mobiledocTextRendererRendererFactory) { | ||
define('mobiledoc-text-renderer', ['exports', 'mobiledoc-text-renderer/renderer-factory', 'mobiledoc-text-renderer/utils/render-type'], function (exports, _mobiledocTextRendererRendererFactory, _mobiledocTextRendererUtilsRenderType) { | ||
'use strict'; | ||
@@ -210,5 +210,6 @@ | ||
exports.RENDER_TYPE = _mobiledocTextRendererUtilsRenderType['default']; | ||
exports['default'] = _mobiledocTextRendererRendererFactory['default']; | ||
}); | ||
define('mobiledoc-text-renderer/renderer-factory', ['exports', 'mobiledoc-text-renderer/renderer'], function (exports, _mobiledocTextRendererRenderer) { | ||
define('mobiledoc-text-renderer/renderer-factory', ['exports', 'mobiledoc-text-renderer/renderers/0-2', 'mobiledoc-text-renderer/renderers/0-3', 'mobiledoc-text-renderer/utils/render-type'], function (exports, _mobiledocTextRendererRenderers02, _mobiledocTextRendererRenderers03, _mobiledocTextRendererUtilsRenderType) { | ||
'use strict'; | ||
@@ -220,3 +221,2 @@ | ||
var RENDER_TYPE = 'text'; | ||
/** | ||
@@ -231,9 +231,9 @@ * runtime Text renderer | ||
function validateCards(cards) { | ||
if (!Array.isArray) { | ||
throw new Error('`cards` must be an array'); | ||
if (!Array.isArray(cards)) { | ||
throw new Error('`cards` must be passed as an array'); | ||
} | ||
for (var i = 0; i < cards.length; i++) { | ||
var card = cards[i]; | ||
if (card.type !== RENDER_TYPE) { | ||
throw new Error('Card "' + card.name + '" must be type "' + RENDER_TYPE + '", was "' + card.type + '"'); | ||
if (card.type !== _mobiledocTextRendererUtilsRenderType['default']) { | ||
throw new Error('Card "' + card.name + '" must be type "' + _mobiledocTextRendererUtilsRenderType['default'] + '", was "' + card.type + '"'); | ||
} | ||
@@ -246,2 +246,17 @@ if (!card.render) { | ||
function validateAtoms(atoms) { | ||
if (!Array.isArray(atoms)) { | ||
throw new Error('`atoms` must be passed as an array'); | ||
} | ||
for (var i = 0; i < atoms.length; i++) { | ||
var atom = atoms[i]; | ||
if (atom.type !== _mobiledocTextRendererUtilsRenderType['default']) { | ||
throw new Error('Atom "' + atom.name + '" must be type "' + _mobiledocTextRendererUtilsRenderType['default'] + '", was "' + atom.type + '"'); | ||
} | ||
if (!atom.render) { | ||
throw new Error('Atom "' + atom.name + '" must define `render`'); | ||
} | ||
} | ||
} | ||
var RendererFactory = (function () { | ||
@@ -255,2 +270,3 @@ function RendererFactory() { | ||
var unknownCardHandler = _ref.unknownCardHandler; | ||
var unknownAtomHandler = _ref.unknownAtomHandler; | ||
@@ -262,5 +278,6 @@ _classCallCheck(this, RendererFactory); | ||
atoms = atoms || []; | ||
validateAtoms(atoms); | ||
cardOptions = cardOptions || {}; | ||
this.state = { cards: cards, atoms: atoms, cardOptions: cardOptions, unknownCardHandler: unknownCardHandler }; | ||
this.state = { cards: cards, atoms: atoms, cardOptions: cardOptions, unknownCardHandler: unknownCardHandler, unknownAtomHandler: unknownAtomHandler }; | ||
} | ||
@@ -271,3 +288,14 @@ | ||
value: function render(mobiledoc) { | ||
return new _mobiledocTextRendererRenderer['default'](mobiledoc, this.state).render(); | ||
var version = mobiledoc.version; | ||
switch (version) { | ||
case _mobiledocTextRendererRenderers02.MOBILEDOC_VERSION: | ||
case undefined: | ||
case null: | ||
return new _mobiledocTextRendererRenderers02['default'](mobiledoc, this.state).render(); | ||
case _mobiledocTextRendererRenderers03.MOBILEDOC_VERSION: | ||
return new _mobiledocTextRendererRenderers03['default'](mobiledoc, this.state).render(); | ||
default: | ||
throw new Error('Unexpected Mobiledoc version "' + version + '"'); | ||
} | ||
} | ||
@@ -281,3 +309,3 @@ }]); | ||
}); | ||
define('mobiledoc-text-renderer/renderer', ['exports', 'mobiledoc-text-renderer/cards/image'], function (exports, _mobiledocTextRendererCardsImage) { | ||
define('mobiledoc-text-renderer/renderers/0-2', ['exports', 'mobiledoc-text-renderer/cards/image', 'mobiledoc-text-renderer/utils/render-type', 'mobiledoc-text-renderer/utils/section-types'], function (exports, _mobiledocTextRendererCardsImage, _mobiledocTextRendererUtilsRenderType, _mobiledocTextRendererUtilsSectionTypes) { | ||
/** | ||
@@ -299,12 +327,9 @@ * runtime Text renderer | ||
var LINE_BREAK = '\n'; | ||
var RENDER_TYPE = 'text'; | ||
var MARKUP_SECTION_TYPE = 1; | ||
var IMAGE_SECTION_TYPE = 2; | ||
var LIST_SECTION_TYPE = 3; | ||
var CARD_SECTION_TYPE = 10; | ||
var MOBILEDOC_VERSION = '0.2.0'; | ||
exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION; | ||
function validateVersion(version) { | ||
if (version !== '0.2.0') { | ||
throw new Error('Unknown mobiledoc version "' + version + '"'); | ||
if (version !== MOBILEDOC_VERSION) { | ||
throw new Error('Unexpected Mobiledoc version "' + version + '"'); | ||
} | ||
@@ -371,9 +396,9 @@ } | ||
switch (type) { | ||
case MARKUP_SECTION_TYPE: | ||
case _mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE: | ||
return this.renderMarkupSection(section); | ||
case IMAGE_SECTION_TYPE: | ||
case _mobiledocTextRendererUtilsSectionTypes.IMAGE_SECTION_TYPE: | ||
return this.renderImageSection(section); | ||
case LIST_SECTION_TYPE: | ||
case _mobiledocTextRendererUtilsSectionTypes.LIST_SECTION_TYPE: | ||
return this.renderListSection(section); | ||
case CARD_SECTION_TYPE: | ||
case _mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE: | ||
return this.renderCardSection(section); | ||
@@ -427,3 +452,3 @@ default: | ||
name: name, | ||
type: RENDER_TYPE, | ||
type: _mobiledocTextRendererUtilsRenderType['default'], | ||
render: this.unknownCardHandler | ||
@@ -446,5 +471,18 @@ }; | ||
this._validateCardRender(rendered, card.name); | ||
return rendered || ''; | ||
} | ||
}, { | ||
key: '_validateCardRender', | ||
value: function _validateCardRender(rendered, cardName) { | ||
if (!rendered) { | ||
return; | ||
} | ||
if (typeof rendered !== 'string') { | ||
throw new Error('Card "' + cardName + '" must render ' + _mobiledocTextRendererUtilsRenderType['default'] + ', but result was ' + typeof rendered + '"'); | ||
} | ||
} | ||
}, { | ||
key: '_registerTeardownCallback', | ||
@@ -509,4 +547,391 @@ value: function _registerTeardownCallback(callback) { | ||
}); | ||
define('mobiledoc-text-renderer/renderers/0-3', ['exports', 'mobiledoc-text-renderer/cards/image', 'mobiledoc-text-renderer/utils/render-type', 'mobiledoc-text-renderer/utils/section-types', 'mobiledoc-text-renderer/utils/marker-types'], function (exports, _mobiledocTextRendererCardsImage, _mobiledocTextRendererUtilsRenderType, _mobiledocTextRendererUtilsSectionTypes, _mobiledocTextRendererUtilsMarkerTypes) { | ||
/** | ||
* runtime Text renderer | ||
* renders a mobiledoc to Text | ||
* | ||
* input: mobiledoc | ||
* output: Text (string) | ||
*/ | ||
'use strict'; | ||
var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); | ||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | ||
var LINE_BREAK = '\n'; | ||
var MOBILEDOC_VERSION = '0.3.0'; | ||
exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION; | ||
function validateVersion(version) { | ||
if (version !== MOBILEDOC_VERSION) { | ||
throw new Error('Unexpected Mobiledoc version "' + version + '"'); | ||
} | ||
} | ||
var Renderer = (function () { | ||
function Renderer(mobiledoc, state) { | ||
_classCallCheck(this, Renderer); | ||
var cards = state.cards; | ||
var cardOptions = state.cardOptions; | ||
var atoms = state.atoms; | ||
var unknownCardHandler = state.unknownCardHandler; | ||
var unknownAtomHandler = state.unknownAtomHandler; | ||
var version = mobiledoc.version; | ||
var sections = mobiledoc.sections; | ||
var atomTypes = mobiledoc.atoms; | ||
var cardTypes = mobiledoc.cards; | ||
validateVersion(version); | ||
this.root = []; | ||
this.sections = sections; | ||
this.atomTypes = atomTypes; | ||
this.cardTypes = cardTypes; | ||
this.cards = cards; | ||
this.atoms = atoms; | ||
this.cardOptions = cardOptions; | ||
this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler; | ||
this.unknownAtomHandler = unknownAtomHandler || this._defaultUnknownAtomHandler; | ||
this._teardownCallbacks = []; | ||
} | ||
_createClass(Renderer, [{ | ||
key: 'render', | ||
value: function render() { | ||
var _this = this; | ||
this.sections.forEach(function (section) { | ||
_this.root.push(_this.renderSection(section)); | ||
}); | ||
var result = this.root.join(LINE_BREAK); | ||
return { result: result, teardown: function teardown() { | ||
return _this.teardown(); | ||
} }; | ||
} | ||
}, { | ||
key: 'teardown', | ||
value: function teardown() { | ||
for (var i = 0; i < this._teardownCallbacks.length; i++) { | ||
this._teardownCallbacks[i](); | ||
} | ||
} | ||
}, { | ||
key: 'renderSection', | ||
value: function renderSection(section) { | ||
var _section = _slicedToArray(section, 1); | ||
var type = _section[0]; | ||
switch (type) { | ||
case _mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE: | ||
return this.renderMarkupSection(section); | ||
case _mobiledocTextRendererUtilsSectionTypes.IMAGE_SECTION_TYPE: | ||
return this.renderImageSection(section); | ||
case _mobiledocTextRendererUtilsSectionTypes.LIST_SECTION_TYPE: | ||
return this.renderListSection(section); | ||
case _mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE: | ||
return this.renderCardSection(section); | ||
default: | ||
throw new Error('Unimplemented renderer for type ' + type); | ||
} | ||
} | ||
}, { | ||
key: 'renderImageSection', | ||
value: function renderImageSection() { | ||
return ''; | ||
} | ||
}, { | ||
key: 'renderListSection', | ||
value: function renderListSection(_ref) { | ||
var _this2 = this; | ||
var _ref2 = _slicedToArray(_ref, 3); | ||
var type = _ref2[0]; | ||
var tagName = _ref2[1]; | ||
var items = _ref2[2]; | ||
return items.map(function (li) { | ||
return _this2.renderListItem(li); | ||
}).join(LINE_BREAK); | ||
} | ||
}, { | ||
key: 'renderListItem', | ||
value: function renderListItem(markers) { | ||
return this.renderMarkers(markers); | ||
} | ||
}, { | ||
key: 'findCard', | ||
value: function findCard(name) { | ||
for (var i = 0; i < this.cards.length; i++) { | ||
if (this.cards[i].name === name) { | ||
return this.cards[i]; | ||
} | ||
} | ||
if (name === _mobiledocTextRendererCardsImage['default'].name) { | ||
return _mobiledocTextRendererCardsImage['default']; | ||
} | ||
return this._createUnknownCard(name); | ||
} | ||
}, { | ||
key: '_findCardByIndex', | ||
value: function _findCardByIndex(index) { | ||
var cardType = this.cardTypes[index]; | ||
if (!cardType) { | ||
throw new Error('No card definition found at index ' + index); | ||
} | ||
var _cardType = _slicedToArray(cardType, 2); | ||
var name = _cardType[0]; | ||
var payload = _cardType[1]; | ||
var card = this.findCard(name); | ||
return { | ||
card: card, | ||
payload: payload | ||
}; | ||
} | ||
}, { | ||
key: '_createUnknownCard', | ||
value: function _createUnknownCard(name) { | ||
return { | ||
name: name, | ||
type: _mobiledocTextRendererUtilsRenderType['default'], | ||
render: this.unknownCardHandler | ||
}; | ||
} | ||
}, { | ||
key: 'renderCardSection', | ||
value: function renderCardSection(_ref3) { | ||
var _ref32 = _slicedToArray(_ref3, 2); | ||
var type = _ref32[0]; | ||
var index = _ref32[1]; | ||
var _findCardByIndex2 = this._findCardByIndex(index); | ||
var card = _findCardByIndex2.card; | ||
var payload = _findCardByIndex2.payload; | ||
var cardArg = this._createCardArgument(card, payload); | ||
var rendered = card.render(cardArg); | ||
this._validateCardRender(rendered, card.name); | ||
return rendered || ''; | ||
} | ||
}, { | ||
key: '_validateCardRender', | ||
value: function _validateCardRender(rendered, cardName) { | ||
if (!rendered) { | ||
return; | ||
} | ||
if (typeof rendered !== 'string') { | ||
throw new Error('Card "' + cardName + '" must render ' + _mobiledocTextRendererUtilsRenderType['default'] + ', but result was ' + typeof rendered + '"'); | ||
} | ||
} | ||
}, { | ||
key: '_registerTeardownCallback', | ||
value: function _registerTeardownCallback(callback) { | ||
this._teardownCallbacks.push(callback); | ||
} | ||
}, { | ||
key: '_createCardArgument', | ||
value: function _createCardArgument(card) { | ||
var _this3 = this; | ||
var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
var env = { | ||
name: card.name, | ||
isInEditor: false, | ||
onTeardown: function onTeardown(callback) { | ||
return _this3._registerTeardownCallback(callback); | ||
} | ||
}; | ||
var options = this.cardOptions; | ||
return { env: env, options: options, payload: payload }; | ||
} | ||
}, { | ||
key: 'renderMarkupSection', | ||
value: function renderMarkupSection(_ref4) { | ||
var _ref42 = _slicedToArray(_ref4, 3); | ||
var type = _ref42[0]; | ||
var tagName = _ref42[1]; | ||
var markers = _ref42[2]; | ||
return this.renderMarkers(markers); | ||
} | ||
}, { | ||
key: 'findAtom', | ||
value: function findAtom(name) { | ||
for (var i = 0; i < this.atoms.length; i++) { | ||
if (this.atoms[i].name === name) { | ||
return this.atoms[i]; | ||
} | ||
} | ||
return this._createUnknownAtom(name); | ||
} | ||
}, { | ||
key: '_createUnknownAtom', | ||
value: function _createUnknownAtom(name) { | ||
return { | ||
name: name, | ||
type: _mobiledocTextRendererUtilsRenderType['default'], | ||
render: this.unknownAtomHandler | ||
}; | ||
} | ||
}, { | ||
key: '_createAtomArgument', | ||
value: function _createAtomArgument(atom, value, payload) { | ||
var _this4 = this; | ||
var env = { | ||
name: atom.name, | ||
onTeardown: function onTeardown(callback) { | ||
return _this4._registerTeardownCallback(callback); | ||
} | ||
}; | ||
var options = this.cardOptions; | ||
return { env: env, options: options, value: value, payload: payload }; | ||
} | ||
}, { | ||
key: '_validateAtomRender', | ||
value: function _validateAtomRender(rendered, atomName) { | ||
if (!rendered) { | ||
return; | ||
} | ||
if (typeof rendered !== 'string') { | ||
throw new Error('Atom "' + atomName + '" must render ' + _mobiledocTextRendererUtilsRenderType['default'] + ', but result was ' + typeof rendered + '"'); | ||
} | ||
} | ||
}, { | ||
key: '_findAtomByIndex', | ||
value: function _findAtomByIndex(index) { | ||
var atomType = this.atomTypes[index]; | ||
if (!atomType) { | ||
throw new Error('No atom definition found at index ' + index); | ||
} | ||
var _atomType = _slicedToArray(atomType, 3); | ||
var name = _atomType[0]; | ||
var value = _atomType[1]; | ||
var payload = _atomType[2]; | ||
var atom = this.findAtom(name); | ||
return { | ||
atom: atom, | ||
value: value, | ||
payload: payload | ||
}; | ||
} | ||
}, { | ||
key: '_renderAtom', | ||
value: function _renderAtom(index) { | ||
var _findAtomByIndex2 = this._findAtomByIndex(index); | ||
var atom = _findAtomByIndex2.atom; | ||
var value = _findAtomByIndex2.value; | ||
var payload = _findAtomByIndex2.payload; | ||
var atomArg = this._createAtomArgument(atom, value, payload); | ||
var rendered = atom.render(atomArg); | ||
this._validateAtomRender(rendered, atom.name); | ||
return rendered || ''; | ||
} | ||
}, { | ||
key: 'renderMarkers', | ||
value: function renderMarkers(markers) { | ||
var _this5 = this; | ||
var str = ''; | ||
markers.forEach(function (m) { | ||
var _m = _slicedToArray(m, 4); | ||
var type = _m[0]; | ||
var value = _m[3]; | ||
switch (type) { | ||
case _mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE: | ||
str += value; | ||
break; | ||
case _mobiledocTextRendererUtilsMarkerTypes.ATOM_MARKER_TYPE: | ||
str += _this5._renderAtom(value); | ||
break; | ||
default: | ||
throw new Error('Unknown markup type (' + type + ')'); | ||
} | ||
}); | ||
return str; | ||
} | ||
}, { | ||
key: '_defaultUnknownCardHandler', | ||
get: function get() { | ||
return function () { | ||
// for the text renderer, a missing card is a no-op | ||
}; | ||
} | ||
}, { | ||
key: '_defaultUnknownAtomHandler', | ||
get: function get() { | ||
return function (_ref5) { | ||
var value = _ref5.value; | ||
return value || ''; | ||
}; | ||
} | ||
}]); | ||
return Renderer; | ||
})(); | ||
exports['default'] = Renderer; | ||
}); | ||
define("mobiledoc-text-renderer/utils/marker-types", ["exports"], function (exports) { | ||
"use strict"; | ||
var MARKUP_MARKER_TYPE = 0; | ||
exports.MARKUP_MARKER_TYPE = MARKUP_MARKER_TYPE; | ||
var ATOM_MARKER_TYPE = 1; | ||
exports.ATOM_MARKER_TYPE = ATOM_MARKER_TYPE; | ||
}); | ||
define('mobiledoc-text-renderer/utils/render-type', ['exports'], function (exports) { | ||
'use strict'; | ||
exports['default'] = 'text'; | ||
}); | ||
define("mobiledoc-text-renderer/utils/section-types", ["exports"], function (exports) { | ||
"use strict"; | ||
var MARKUP_SECTION_TYPE = 1; | ||
exports.MARKUP_SECTION_TYPE = MARKUP_SECTION_TYPE; | ||
var IMAGE_SECTION_TYPE = 2; | ||
exports.IMAGE_SECTION_TYPE = IMAGE_SECTION_TYPE; | ||
var LIST_SECTION_TYPE = 3; | ||
exports.LIST_SECTION_TYPE = LIST_SECTION_TYPE; | ||
var CARD_SECTION_TYPE = 10; | ||
exports.CARD_SECTION_TYPE = CARD_SECTION_TYPE; | ||
}); | ||
require("mobiledoc-text-renderer")["registerGlobal"](window, document); | ||
})(); | ||
//# sourceMappingURL=mobiledoc-text-renderer.map |
@@ -16,13 +16,38 @@ QUnit.module('JSHint - tests/jshint/cards'); | ||
QUnit.module('JSHint - tests/jshint'); | ||
QUnit.test('tests/jshint/renderer.js should pass jshint', function(assert) { | ||
assert.ok(true, 'tests/jshint/renderer.js should pass jshint.'); | ||
QUnit.module('JSHint - tests/jshint/renderers'); | ||
QUnit.test('tests/jshint/renderers/0-2.js should pass jshint', function(assert) { | ||
assert.ok(true, 'tests/jshint/renderers/0-2.js should pass jshint.'); | ||
}); | ||
QUnit.module('JSHint - tests/jshint/unit'); | ||
QUnit.test('tests/jshint/unit/text-renderer-test.js should pass jshint', function(assert) { | ||
assert.ok(true, 'tests/jshint/unit/text-renderer-test.js should pass jshint.'); | ||
QUnit.module('JSHint - tests/jshint/renderers'); | ||
QUnit.test('tests/jshint/renderers/0-3.js should pass jshint', function(assert) { | ||
assert.ok(true, 'tests/jshint/renderers/0-3.js should pass jshint.'); | ||
}); | ||
define('tests/unit/text-renderer-test', ['exports', 'mobiledoc-text-renderer'], function (exports, _mobiledocTextRenderer) { | ||
QUnit.module('JSHint - tests/jshint/unit/renderers'); | ||
QUnit.test('tests/jshint/unit/renderers/0-2-test.js should pass jshint', function(assert) { | ||
assert.ok(true, 'tests/jshint/unit/renderers/0-2-test.js should pass jshint.'); | ||
}); | ||
QUnit.module('JSHint - tests/jshint/unit/renderers'); | ||
QUnit.test('tests/jshint/unit/renderers/0-3-test.js should pass jshint', function(assert) { | ||
assert.ok(true, 'tests/jshint/unit/renderers/0-3-test.js should pass jshint.'); | ||
}); | ||
QUnit.module('JSHint - tests/jshint/utils'); | ||
QUnit.test('tests/jshint/utils/marker-types.js should pass jshint', function(assert) { | ||
assert.ok(true, 'tests/jshint/utils/marker-types.js should pass jshint.'); | ||
}); | ||
QUnit.module('JSHint - tests/jshint/utils'); | ||
QUnit.test('tests/jshint/utils/render-type.js should pass jshint', function(assert) { | ||
assert.ok(true, 'tests/jshint/utils/render-type.js should pass jshint.'); | ||
}); | ||
QUnit.module('JSHint - tests/jshint/utils'); | ||
QUnit.test('tests/jshint/utils/section-types.js should pass jshint', function(assert) { | ||
assert.ok(true, 'tests/jshint/utils/section-types.js should pass jshint.'); | ||
}); | ||
define('tests/unit/renderers/0-2-test', ['exports', 'mobiledoc-text-renderer', 'mobiledoc-text-renderer/utils/section-types'], function (exports, _mobiledocTextRenderer, _mobiledocTextRendererUtilsSectionTypes) { | ||
/* global QUnit */ | ||
@@ -34,2 +59,3 @@ | ||
var test = _QUnit.test; | ||
var _module = _QUnit.module; | ||
@@ -39,3 +65,3 @@ var MOBILEDOC_VERSION = '0.2.0'; | ||
var renderer = undefined; | ||
QUnit.module('Unit: Mobiledoc Text Renderer', { | ||
_module('Unit: Mobiledoc Text Renderer - 0.2', { | ||
beforeEach: function beforeEach() { | ||
@@ -46,9 +72,153 @@ renderer = new _mobiledocTextRenderer['default'](); | ||
test('it exists', function (assert) { | ||
assert.ok(_mobiledocTextRenderer['default'], 'class exists'); | ||
assert.ok(renderer, 'instance exists'); | ||
test('renders an empty mobiledoc', function (assert) { | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
sections: [[], // markers | ||
[] // sections | ||
] | ||
}; | ||
var _renderer$render = renderer.render(mobiledoc); | ||
var rendered = _renderer$render.result; | ||
assert.equal(rendered, '', 'output is empty'); | ||
}); | ||
test('throws if given card with invalid type', function (assert) { | ||
test('renders a mobiledoc without markers', function (assert) { | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
sections: [[], // markers | ||
[// sections | ||
[_mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[[], 0, 'hello world']]]]] | ||
}; | ||
var _renderer$render2 = renderer.render(mobiledoc); | ||
var rendered = _renderer$render2.result; | ||
assert.equal(rendered, 'hello world'); | ||
}); | ||
test('renders a mobiledoc with simple (no attributes) marker', function (assert) { | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
sections: [[// markers | ||
['B']], [// sections | ||
[_mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[[0], 1, 'hello world']]]]] | ||
}; | ||
var _renderer$render3 = renderer.render(mobiledoc); | ||
var rendered = _renderer$render3.result; | ||
assert.equal(rendered, 'hello world'); | ||
}); | ||
test('renders a mobiledoc with complex (has attributes) marker', function (assert) { | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
sections: [[// markers | ||
['A', ['href', 'http://google.com']]], [// sections | ||
[_mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[[0], 1, 'hello world']]]]] | ||
}; | ||
var _renderer$render4 = renderer.render(mobiledoc); | ||
var rendered = _renderer$render4.result; | ||
assert.equal(rendered, 'hello world'); | ||
}); | ||
test('renders a mobiledoc with multiple markups in a section', function (assert) { | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
sections: [[// markers | ||
['B'], ['I']], [// sections | ||
[_mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[[0], 0, 'hello '], // b | ||
[[1], 0, 'brave '], // b+i | ||
[[], 1, 'new '], // close i | ||
[[], 1, 'world'] // close b | ||
]]]] | ||
}; | ||
var _renderer$render5 = renderer.render(mobiledoc); | ||
var rendered = _renderer$render5.result; | ||
assert.equal(rendered, 'hello brave new world'); | ||
}); | ||
test('renders a mobiledoc with image section', function (assert) { | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
sections: [[], // markers | ||
[// sections | ||
[_mobiledocTextRendererUtilsSectionTypes.IMAGE_SECTION_TYPE, 'imageUrl']]] | ||
}; | ||
var _renderer$render6 = renderer.render(mobiledoc); | ||
var rendered = _renderer$render6.result; | ||
assert.equal(rendered, '', 'image section is empty string'); | ||
}); | ||
test('renders a mobiledoc with built-in image card (as empty string)', function (assert) { | ||
assert.expect(1); | ||
var cardName = 'image-card'; | ||
var payload = { src: 'bob.gif' }; | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
sections: [[], // markers | ||
[// sections | ||
[_mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE, cardName, payload]]] | ||
}; | ||
var _renderer$render7 = renderer.render(mobiledoc); | ||
var rendered = _renderer$render7.result; | ||
assert.equal(rendered, '', 'card section is empty'); | ||
}); | ||
test('render mobiledoc with list section and list items', function (assert) { | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
sections: [[], [[_mobiledocTextRendererUtilsSectionTypes.LIST_SECTION_TYPE, 'ul', [[[[], 0, 'first item']], [[[], 0, 'second item']]]]]] | ||
}; | ||
var _renderer$render8 = renderer.render(mobiledoc); | ||
var rendered = _renderer$render8.result; | ||
assert.equal(rendered, ['first item', 'second item'].join('\n')); | ||
}); | ||
test('renders a mobiledoc with card section', function (assert) { | ||
var cardName = 'title-card'; | ||
var card = { | ||
name: cardName, | ||
type: 'text', | ||
render: function render() { | ||
return 'Hello'; | ||
} | ||
}; | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
sections: [[], // markers | ||
[// sections | ||
[_mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE, cardName]]] | ||
}; | ||
renderer = new _mobiledocTextRenderer['default']({ cards: [card] }); | ||
var _renderer$render9 = renderer.render(mobiledoc); | ||
var rendered = _renderer$render9.result; | ||
assert.equal(rendered, 'Hello'); | ||
}); | ||
test('throws when given card with invalid type', function (assert) { | ||
var card = { | ||
name: 'bad', | ||
@@ -64,3 +234,3 @@ type: 'other', | ||
test('throws if given card without render', function (assert) { | ||
test('throws when given card without `render`', function (assert) { | ||
var card = { | ||
@@ -77,10 +247,136 @@ name: 'bad', | ||
test('card can register teardown callback', function (assert) { | ||
var didTeardown = undefined; | ||
test('throws if card render returns invalid result', function (assert) { | ||
var card = { | ||
name: 'bad', | ||
type: 'text', | ||
render: function render() { | ||
return []; | ||
} | ||
}; | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
sections: [[], // markers | ||
[[_mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE, card.name]] // sections | ||
] | ||
}; | ||
renderer = new _mobiledocTextRenderer['default']({ cards: [card] }); | ||
assert.throws(function () { | ||
return renderer.render(mobiledoc); | ||
}, /Card "bad" must render text/); | ||
}); | ||
test('card may render nothing', function (assert) { | ||
var card = { | ||
name: 'ok', | ||
type: 'text', | ||
render: function render() {} | ||
}; | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
sections: [[], [[_mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE, card.name]]] | ||
}; | ||
renderer = new _mobiledocTextRenderer['default']({ cards: [card] }); | ||
renderer.render(mobiledoc); | ||
assert.ok(true, 'No error thrown'); | ||
}); | ||
test('rendering nested mobiledocs in cards', function (assert) { | ||
var cards = [{ | ||
name: 'nested-card', | ||
type: 'text', | ||
render: function render(_ref) { | ||
var env = _ref.env; | ||
var payload = _ref.payload; | ||
var _renderer$render10 = renderer.render(payload.mobiledoc); | ||
var rendered = _renderer$render10.result; | ||
return rendered; | ||
} | ||
}]; | ||
var innerMobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
sections: [[], // markers | ||
[// sections | ||
[_mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[[], 0, 'hello world']]]]] | ||
}; | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
sections: [[], // markers | ||
[// sections | ||
[_mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE, 'nested-card', { mobiledoc: innerMobiledoc }]]] | ||
}; | ||
var renderer = new _mobiledocTextRenderer['default']({ cards: cards }); | ||
var _renderer$render11 = renderer.render(mobiledoc); | ||
var rendered = _renderer$render11.result; | ||
assert.equal(rendered, 'hello world'); | ||
}); | ||
test('rendering unknown card without unknownCardHandler does nothing', function (assert) { | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
sections: [[], // markers | ||
[[_mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE, 'missing-card']]] | ||
}; | ||
renderer = new _mobiledocTextRenderer['default']({ cards: [], unknownCardHandler: undefined }); | ||
var _renderer$render12 = renderer.render(mobiledoc); | ||
var result = _renderer$render12.result; | ||
assert.equal(result, '', 'empty result'); | ||
}); | ||
test('rendering unknown card uses unknownCardHandler', function (assert) { | ||
assert.expect(5); | ||
var cardName = 'missing-card'; | ||
var expectedPayload = {}; | ||
var cardOptions = {}; | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
sections: [[], // markers | ||
[// sections | ||
[_mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE, cardName, expectedPayload]]] | ||
}; | ||
var unknownCardHandler = function unknownCardHandler(_ref2) { | ||
var env = _ref2.env; | ||
var payload = _ref2.payload; | ||
var options = _ref2.options; | ||
assert.equal(env.name, cardName, 'correct name'); | ||
assert.ok(!env.isInEditor, 'correct isInEditor'); | ||
assert.ok(!!env.onTeardown, 'onTeardown hook exists'); | ||
assert.deepEqual(payload, expectedPayload, 'correct payload'); | ||
assert.deepEqual(options, cardOptions, 'correct options'); | ||
}; | ||
renderer = new _mobiledocTextRenderer['default']({ cards: [], unknownCardHandler: unknownCardHandler, cardOptions: cardOptions }); | ||
renderer.render(mobiledoc); | ||
}); | ||
test('throws if given an object of cards', function (assert) { | ||
var cards = {}; | ||
assert.throws(function () { | ||
new _mobiledocTextRenderer['default']({ cards: cards }); | ||
}, // jshint ignore: line | ||
/`cards` must be passed as an array/); | ||
}); | ||
test('teardown hook calls registered teardown methods', function (assert) { | ||
var didTeardown = undefined; | ||
var card = { | ||
name: 'ok', | ||
type: 'text', | ||
render: function render(_ref3) { | ||
var env = _ref3.env; | ||
env.onTeardown(function () { | ||
@@ -94,9 +390,9 @@ return didTeardown = true; | ||
sections: [[], // markers | ||
[[10, card.name]]] | ||
[[_mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE, card.name]]] | ||
}; | ||
renderer = new _mobiledocTextRenderer['default']({ cards: [card] }); | ||
var _renderer$render = renderer.render(mobiledoc); | ||
var _renderer$render13 = renderer.render(mobiledoc); | ||
var teardown = _renderer$render.teardown; | ||
var teardown = _renderer$render13.teardown; | ||
@@ -110,28 +406,91 @@ assert.ok(!didTeardown, 'precond - no teardown'); | ||
test('rendering unknown card does nothing if no unknownCardHandler registered', function (assert) { | ||
test('throws when given an unexpected mobiledoc version', function (assert) { | ||
var mobiledoc = { | ||
version: '0.1.0', | ||
sections: [[], []] | ||
}; | ||
assert.throws(function () { | ||
return renderer.render(mobiledoc); | ||
}, /Unexpected Mobiledoc version.*0.1.0/); | ||
mobiledoc.version = '0.2.1'; | ||
assert.throws(function () { | ||
return renderer.render(mobiledoc); | ||
}, /Unexpected Mobiledoc version.*0.2.1/); | ||
}); | ||
test('renders a mobiledoc with multiple sections', function (assert) { | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
sections: [[], // markers | ||
[[10, 'missing-card']]] | ||
[// sections | ||
[_mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[[], 0, 'first section']]], [_mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[[], 0, 'second section']]]]] | ||
}; | ||
renderer = new _mobiledocTextRenderer['default']({ cards: [], unknownCardHandler: undefined }); | ||
var _renderer$render2 = renderer.render(mobiledoc); | ||
var _renderer$render14 = renderer.render(mobiledoc); | ||
var result = _renderer$render2.result; | ||
var rendered = _renderer$render14.result; | ||
assert.equal(result, '', 'empty result'); | ||
assert.equal(rendered, ['first section', 'second section'].join('\n')); | ||
}); | ||
test('XSS: unexpected markup and list section tag names are not renderered', function (assert) { | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
sections: [[], [[_mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'script', [[[], 0, 'alert("markup section XSS")']]], [_mobiledocTextRendererUtilsSectionTypes.LIST_SECTION_TYPE, 'script', [[[[], 0, 'alert("list section XSS")']]]]]] | ||
}; | ||
var _renderer$render15 = renderer.render(mobiledoc); | ||
var result = _renderer$render15.result; | ||
assert.ok(result.indexOf('script') === -1, 'no script tag rendered'); | ||
}); | ||
test('XSS: unexpected markup types are not rendered', function (assert) { | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
sections: [[['b'], // valid | ||
['em'], // valid | ||
['script'] // invalid | ||
], [[_mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'p', [[[0], 0, 'bold text'], [[1, 2], 3, 'alert("markup XSS")'], [[], 0, 'plain text']]]]] | ||
}; | ||
var _renderer$render16 = renderer.render(mobiledoc); | ||
var result = _renderer$render16.result; | ||
assert.ok(result.indexOf('script') === -1, 'no script tag rendered'); | ||
}); | ||
}); | ||
define('tests/unit/renderers/0-3-test', ['exports', 'mobiledoc-text-renderer', 'mobiledoc-text-renderer/utils/section-types', 'mobiledoc-text-renderer/utils/marker-types'], function (exports, _mobiledocTextRenderer, _mobiledocTextRendererUtilsSectionTypes, _mobiledocTextRendererUtilsMarkerTypes) { | ||
/* global QUnit */ | ||
'use strict'; | ||
var _QUnit = QUnit; | ||
var test = _QUnit.test; | ||
var _module = _QUnit.module; | ||
var MOBILEDOC_VERSION = '0.3.0'; | ||
var renderer = undefined; | ||
_module('Unit: Mobiledoc Text Renderer - 0.3', { | ||
beforeEach: function beforeEach() { | ||
renderer = new _mobiledocTextRenderer['default'](); | ||
} | ||
}); | ||
test('renders an empty mobiledoc', function (assert) { | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
sections: [[], // markers | ||
[] // sections | ||
] | ||
atoms: [], | ||
cards: [], | ||
markups: [], | ||
sections: [] | ||
}; | ||
var _renderer$render3 = renderer.render(mobiledoc); | ||
var _renderer$render = renderer.render(mobiledoc); | ||
var rendered = _renderer$render3.result; | ||
var rendered = _renderer$render.result; | ||
@@ -144,10 +503,11 @@ assert.equal(rendered, '', 'output is empty'); | ||
version: MOBILEDOC_VERSION, | ||
sections: [[], // markers | ||
[// sections | ||
[1, 'P', [[[], 0, 'hello world']]]]] | ||
atoms: [], | ||
cards: [], | ||
markups: [], | ||
sections: [[_mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[_mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 0, 'hello world']]]] | ||
}; | ||
var _renderer$render4 = renderer.render(mobiledoc); | ||
var _renderer$render2 = renderer.render(mobiledoc); | ||
var rendered = _renderer$render4.result; | ||
var rendered = _renderer$render2.result; | ||
@@ -160,10 +520,11 @@ assert.equal(rendered, 'hello world'); | ||
version: MOBILEDOC_VERSION, | ||
sections: [[// markers | ||
['B']], [// sections | ||
[1, 'P', [[[0], 1, 'hello world']]]]] | ||
atoms: [], | ||
cards: [], | ||
markups: [['B']], | ||
sections: [[_mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[_mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [0], 1, 'hello world']]]] | ||
}; | ||
var _renderer$render5 = renderer.render(mobiledoc); | ||
var _renderer$render3 = renderer.render(mobiledoc); | ||
var rendered = _renderer$render5.result; | ||
var rendered = _renderer$render3.result; | ||
@@ -176,10 +537,11 @@ assert.equal(rendered, 'hello world'); | ||
version: MOBILEDOC_VERSION, | ||
sections: [[// markers | ||
['A', ['href', 'http://google.com']]], [// sections | ||
[1, 'P', [[[0], 1, 'hello world']]]]] | ||
atoms: [], | ||
cards: [], | ||
markups: [['A', ['href', 'http://google.com']]], | ||
sections: [[_mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[_mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [0], 1, 'hello world']]]] | ||
}; | ||
var _renderer$render6 = renderer.render(mobiledoc); | ||
var _renderer$render4 = renderer.render(mobiledoc); | ||
var rendered = _renderer$render6.result; | ||
var rendered = _renderer$render4.result; | ||
@@ -192,14 +554,15 @@ assert.equal(rendered, 'hello world'); | ||
version: MOBILEDOC_VERSION, | ||
sections: [[// markers | ||
['B'], ['I']], [// sections | ||
[1, 'P', [[[0], 0, 'hello '], // b | ||
[[1], 0, 'brave '], // b+i | ||
[[], 1, 'new '], // close i | ||
[[], 1, 'world'] // close b | ||
]]]] | ||
atoms: [], | ||
cards: [], | ||
markups: [['B'], ['I']], | ||
sections: [[_mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[_mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [0], 0, 'hello '], // b | ||
[_mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [1], 0, 'brave '], // b+i | ||
[_mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 1, 'new '], // close i | ||
[_mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 1, 'world'] // close b | ||
]]] | ||
}; | ||
var _renderer$render7 = renderer.render(mobiledoc); | ||
var _renderer$render5 = renderer.render(mobiledoc); | ||
var rendered = _renderer$render7.result; | ||
var rendered = _renderer$render5.result; | ||
@@ -209,18 +572,19 @@ assert.equal(rendered, 'hello brave new world'); | ||
test('renders a mobiledoc with multiple sections', function (assert) { | ||
test('renders a mobiledoc with image section', function (assert) { | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
sections: [[], // markers | ||
[// sections | ||
[1, 'P', [[[], 0, 'first section']]], [1, 'P', [[[], 0, 'second section']]]]] | ||
atoms: [], | ||
cards: [], | ||
markups: [], | ||
sections: [[_mobiledocTextRendererUtilsSectionTypes.IMAGE_SECTION_TYPE, 'imageUrl']] | ||
}; | ||
var _renderer$render8 = renderer.render(mobiledoc); | ||
var _renderer$render6 = renderer.render(mobiledoc); | ||
var rendered = _renderer$render8.result; | ||
var rendered = _renderer$render6.result; | ||
assert.equal(rendered, ['first section', 'second section'].join('\n')); | ||
assert.equal(rendered, '', 'image section is empty string'); | ||
}); | ||
test('built-in image-card renders as empty string', function (assert) { | ||
test('renders a mobiledoc with built-in image card (as empty string)', function (assert) { | ||
assert.expect(1); | ||
@@ -231,10 +595,11 @@ var cardName = 'image-card'; | ||
version: MOBILEDOC_VERSION, | ||
sections: [[], // markers | ||
[// sections | ||
[10, cardName, payload]]] | ||
atoms: [], | ||
cards: [[cardName, payload]], | ||
markups: [], | ||
sections: [[_mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE, 0]] | ||
}; | ||
var _renderer$render9 = renderer.render(mobiledoc); | ||
var _renderer$render7 = renderer.render(mobiledoc); | ||
var rendered = _renderer$render9.result; | ||
var rendered = _renderer$render7.result; | ||
@@ -244,3 +609,19 @@ assert.equal(rendered, '', 'card section is empty'); | ||
test('renders a mobiledoc with card', function (assert) { | ||
test('render mobiledoc with list section and list items', function (assert) { | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
atoms: [], | ||
cards: [], | ||
markups: [], | ||
sections: [[_mobiledocTextRendererUtilsSectionTypes.LIST_SECTION_TYPE, 'ul', [[[_mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 0, 'first item']], [[_mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 0, 'second item']]]]] | ||
}; | ||
var _renderer$render8 = renderer.render(mobiledoc); | ||
var rendered = _renderer$render8.result; | ||
assert.equal(rendered, ['first item', 'second item'].join('\n')); | ||
}); | ||
test('renders a mobiledoc with card section', function (assert) { | ||
var cardName = 'title-card'; | ||
@@ -256,11 +637,12 @@ var card = { | ||
version: MOBILEDOC_VERSION, | ||
sections: [[], // markers | ||
[// sections | ||
[10, cardName]]] | ||
atoms: [], | ||
cards: [[cardName]], | ||
markups: [], | ||
sections: [[_mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE, 0]] | ||
}; | ||
renderer = new _mobiledocTextRenderer['default']({ cards: [card] }); | ||
var _renderer$render10 = renderer.render(mobiledoc); | ||
var _renderer$render9 = renderer.render(mobiledoc); | ||
var rendered = _renderer$render10.result; | ||
var rendered = _renderer$render9.result; | ||
@@ -270,8 +652,100 @@ assert.equal(rendered, 'Hello'); | ||
test('render mobiledoc with list section and list items', function (assert) { | ||
test('throws when given card with invalid type', function (assert) { | ||
var card = { | ||
name: 'bad', | ||
type: 'other', | ||
render: function render() {} | ||
}; | ||
assert.throws(function () { | ||
new _mobiledocTextRenderer['default']({ cards: [card] }); | ||
}, // jshint ignore:line | ||
/Card "bad" must be type "text"/); | ||
}); | ||
test('throws when given card without `render`', function (assert) { | ||
var card = { | ||
name: 'bad', | ||
type: 'text', | ||
render: undefined | ||
}; | ||
assert.throws(function () { | ||
new _mobiledocTextRenderer['default']({ cards: [card] }); | ||
}, // jshint ignore:line | ||
/Card "bad" must define.*render/); | ||
}); | ||
test('throws if card render returns invalid result', function (assert) { | ||
var card = { | ||
name: 'bad', | ||
type: 'text', | ||
render: function render() { | ||
return []; | ||
} | ||
}; | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
sections: [[], [[3, 'ul', [[[[], 0, 'first item']], [[[], 0, 'second item']]]]]] | ||
atoms: [], | ||
cards: [[card.name]], | ||
markups: [], | ||
sections: [[_mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE, 0]] | ||
}; | ||
renderer = new _mobiledocTextRenderer['default']({ cards: [card] }); | ||
assert.throws(function () { | ||
return renderer.render(mobiledoc); | ||
}, /Card "bad" must render text/); | ||
}); | ||
test('card may render nothing', function (assert) { | ||
var card = { | ||
name: 'ok', | ||
type: 'text', | ||
render: function render() {} | ||
}; | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
atoms: [], | ||
cards: [[card.name]], | ||
markups: [], | ||
sections: [[_mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE, 0]] | ||
}; | ||
renderer = new _mobiledocTextRenderer['default']({ cards: [card] }); | ||
renderer.render(mobiledoc); | ||
assert.ok(true, 'No error thrown'); | ||
}); | ||
test('rendering nested mobiledocs in cards', function (assert) { | ||
var cards = [{ | ||
name: 'nested-card', | ||
type: 'text', | ||
render: function render(_ref) { | ||
var payload = _ref.payload; | ||
var _renderer$render10 = renderer.render(payload.mobiledoc); | ||
var rendered = _renderer$render10.result; | ||
return rendered; | ||
} | ||
}]; | ||
var innerMobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
atoms: [], | ||
cards: [], | ||
markups: [], | ||
sections: [[_mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[_mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 0, 'hello world']]]] | ||
}; | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
atoms: [], | ||
cards: [['nested-card', { mobiledoc: innerMobiledoc }]], | ||
markups: [], | ||
sections: [[_mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE, 0]] | ||
}; | ||
var renderer = new _mobiledocTextRenderer['default']({ cards: cards }); | ||
var _renderer$render11 = renderer.render(mobiledoc); | ||
@@ -281,4 +755,298 @@ | ||
assert.equal(rendered, ['first item', 'second item'].join('\n')); | ||
assert.equal(rendered, 'hello world'); | ||
}); | ||
test('rendering unknown card without unknownCardHandler does nothing', function (assert) { | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
atoms: [], | ||
cards: [['missing-card']], | ||
markups: [], | ||
sections: [[_mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE, 0]] | ||
}; | ||
renderer = new _mobiledocTextRenderer['default']({ cards: [], unknownCardHandler: undefined }); | ||
var _renderer$render12 = renderer.render(mobiledoc); | ||
var result = _renderer$render12.result; | ||
assert.equal(result, '', 'empty result'); | ||
}); | ||
test('rendering unknown card uses unknownCardHandler', function (assert) { | ||
assert.expect(5); | ||
var cardName = 'missing-card'; | ||
var expectedPayload = {}; | ||
var cardOptions = {}; | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
atoms: [], | ||
cards: [[cardName, expectedPayload]], | ||
markups: [], | ||
sections: [[_mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE, 0]] | ||
}; | ||
var unknownCardHandler = function unknownCardHandler(_ref2) { | ||
var env = _ref2.env; | ||
var payload = _ref2.payload; | ||
var options = _ref2.options; | ||
assert.equal(env.name, cardName, 'correct name'); | ||
assert.ok(!env.isInEditor, 'correct isInEditor'); | ||
assert.ok(!!env.onTeardown, 'onTeardown hook exists'); | ||
assert.deepEqual(payload, expectedPayload, 'correct payload'); | ||
assert.deepEqual(options, cardOptions, 'correct options'); | ||
}; | ||
renderer = new _mobiledocTextRenderer['default']({ cards: [], unknownCardHandler: unknownCardHandler, cardOptions: cardOptions }); | ||
renderer.render(mobiledoc); | ||
}); | ||
test('throws if given an object of cards', function (assert) { | ||
var cards = {}; | ||
assert.throws(function () { | ||
new _mobiledocTextRenderer['default']({ cards: cards }); | ||
}, // jshint ignore: line | ||
/`cards` must be passed as an array/); | ||
}); | ||
test('teardown hook calls registered teardown methods', function (assert) { | ||
var didTeardown = undefined; | ||
var card = { | ||
name: 'ok', | ||
type: 'text', | ||
render: function render(_ref3) { | ||
var env = _ref3.env; | ||
env.onTeardown(function () { | ||
return didTeardown = true; | ||
}); | ||
} | ||
}; | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
atoms: [], | ||
cards: [[card.name]], | ||
markups: [], | ||
sections: [[_mobiledocTextRendererUtilsSectionTypes.CARD_SECTION_TYPE, 0]] | ||
}; | ||
renderer = new _mobiledocTextRenderer['default']({ cards: [card] }); | ||
var _renderer$render13 = renderer.render(mobiledoc); | ||
var teardown = _renderer$render13.teardown; | ||
assert.ok(!didTeardown, 'precond - no teardown'); | ||
teardown(); | ||
assert.ok(didTeardown, 'teardown callback called'); | ||
}); | ||
test('throws when given an unexpected mobiledoc version', function (assert) { | ||
var mobiledoc = { | ||
version: '0.1.0', | ||
atoms: [], | ||
cards: [], | ||
markups: [], | ||
sections: [] | ||
}; | ||
assert.throws(function () { | ||
return renderer.render(mobiledoc); | ||
}, /Unexpected Mobiledoc version.*0.1.0/); | ||
mobiledoc.version = '0.2.1'; | ||
assert.throws(function () { | ||
return renderer.render(mobiledoc); | ||
}, /Unexpected Mobiledoc version.*0.2.1/); | ||
}); | ||
test('renders a mobiledoc with multiple sections', function (assert) { | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
atoms: [], | ||
cards: [], | ||
markups: [], | ||
sections: [[_mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[_mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 0, 'first section']]], [_mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[_mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 0, 'second section']]]] | ||
}; | ||
var _renderer$render14 = renderer.render(mobiledoc); | ||
var rendered = _renderer$render14.result; | ||
assert.equal(rendered, ['first section', 'second section'].join('\n')); | ||
}); | ||
test('XSS: unexpected markup and list section tag names are not renderered', function (assert) { | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
atoms: [], | ||
cards: [], | ||
markups: [], | ||
sections: [[_mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'script', [[_mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 0, 'alert("markup section XSS")']]], [_mobiledocTextRendererUtilsSectionTypes.LIST_SECTION_TYPE, 'script', [[[_mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 0, 'alert("list section XSS")']]]]] | ||
}; | ||
var _renderer$render15 = renderer.render(mobiledoc); | ||
var result = _renderer$render15.result; | ||
assert.ok(result.indexOf('script') === -1, 'no script tag rendered'); | ||
}); | ||
test('XSS: unexpected markup types are not rendered', function (assert) { | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
atoms: [], | ||
cards: [], | ||
markups: [['b'], // valid | ||
['em'], // valid | ||
['script'] // invalid | ||
], | ||
sections: [[_mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'p', [[_mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [0], 0, 'bold text'], [_mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [1, 2], 3, 'alert("markup XSS")'], [_mobiledocTextRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 0, 'plain text']]]] | ||
}; | ||
var _renderer$render16 = renderer.render(mobiledoc); | ||
var result = _renderer$render16.result; | ||
assert.ok(result.indexOf('script') === -1, 'no script tag rendered'); | ||
}); | ||
test('renders a mobiledoc with atom', function (assert) { | ||
var atomName = 'hello-atom'; | ||
var atom = { | ||
name: atomName, | ||
type: 'text', | ||
render: function render(_ref4) { | ||
var value = _ref4.value; | ||
return 'Hello ' + value; | ||
} | ||
}; | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
atoms: [['hello-atom', 'Bob', { id: 42 }]], | ||
cards: [], | ||
markups: [], | ||
sections: [[_mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[_mobiledocTextRendererUtilsMarkerTypes.ATOM_MARKER_TYPE, [], 0, 0]]]] | ||
}; | ||
renderer = new _mobiledocTextRenderer['default']({ atoms: [atom] }); | ||
var _renderer$render17 = renderer.render(mobiledoc); | ||
var rendered = _renderer$render17.result; | ||
assert.equal(rendered, 'Hello Bob'); | ||
}); | ||
test('throws when given atom with invalid type', function (assert) { | ||
var atom = { | ||
name: 'bad', | ||
type: 'other', | ||
render: function render() {} | ||
}; | ||
assert.throws(function () { | ||
new _mobiledocTextRenderer['default']({ atoms: [atom] }); | ||
}, // jshint ignore:line | ||
/Atom "bad" must be type "text"/); | ||
}); | ||
test('throws when given atom without `render`', function (assert) { | ||
var atom = { | ||
name: 'bad', | ||
type: 'text', | ||
render: undefined | ||
}; | ||
assert.throws(function () { | ||
new _mobiledocTextRenderer['default']({ atoms: [atom] }); | ||
}, // jshint ignore:line | ||
/Atom "bad" must define.*render/); | ||
}); | ||
test('throws if atom render returns invalid result', function (assert) { | ||
var atom = { | ||
name: 'bad', | ||
type: 'text', | ||
render: function render() { | ||
return []; | ||
} | ||
}; | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
atoms: [['bad', 'Bob', { id: 42 }]], | ||
cards: [], | ||
markups: [], | ||
sections: [[_mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[_mobiledocTextRendererUtilsMarkerTypes.ATOM_MARKER_TYPE, [], 0, 0]]]] | ||
}; | ||
renderer = new _mobiledocTextRenderer['default']({ atoms: [atom] }); | ||
assert.throws(function () { | ||
return renderer.render(mobiledoc); | ||
}, /Atom "bad" must render text/); | ||
}); | ||
test('atom may render nothing', function (assert) { | ||
var atom = { | ||
name: 'ok', | ||
type: 'text', | ||
render: function render() {} | ||
}; | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
atoms: [['ok', 'Bob', { id: 42 }]], | ||
cards: [], | ||
markups: [], | ||
sections: [[_mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[_mobiledocTextRendererUtilsMarkerTypes.ATOM_MARKER_TYPE, [], 0, 0]]]] | ||
}; | ||
renderer = new _mobiledocTextRenderer['default']({ atoms: [atom] }); | ||
renderer.render(mobiledoc); | ||
assert.ok(true, 'No error thrown'); | ||
}); | ||
test('rendering unknown atom without unknownAtomHandler renders value', function (assert) { | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
atoms: [['missing-atom', 'Bob', { id: 42 }]], | ||
cards: [], | ||
markups: [], | ||
sections: [[_mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[_mobiledocTextRendererUtilsMarkerTypes.ATOM_MARKER_TYPE, [], 0, 0]]]] | ||
}; | ||
renderer = new _mobiledocTextRenderer['default']({ atoms: [], unknownAtomHandler: undefined }); | ||
var _renderer$render18 = renderer.render(mobiledoc); | ||
var result = _renderer$render18.result; | ||
assert.equal(result, 'Bob', 'uses value'); | ||
}); | ||
test('rendering unknown atom uses unknownAtomHandler', function (assert) { | ||
assert.expect(5); | ||
var atomName = 'missing-atom'; | ||
var expectedPayload = { id: 42 }; | ||
var cardOptions = {}; | ||
var mobiledoc = { | ||
version: MOBILEDOC_VERSION, | ||
atoms: [['missing-atom', 'Bob', { id: 42 }]], | ||
cards: [], | ||
markups: [], | ||
sections: [[_mobiledocTextRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[_mobiledocTextRendererUtilsMarkerTypes.ATOM_MARKER_TYPE, [], 0, 0]]]] | ||
}; | ||
var unknownAtomHandler = function unknownAtomHandler(_ref5) { | ||
var env = _ref5.env; | ||
var payload = _ref5.payload; | ||
var options = _ref5.options; | ||
assert.equal(env.name, atomName, 'correct name'); | ||
assert.ok(!env.isInEditor, 'correct isInEditor'); | ||
assert.ok(!!env.onTeardown, 'onTeardown hook exists'); | ||
assert.deepEqual(payload, expectedPayload, 'correct payload'); | ||
assert.deepEqual(options, cardOptions, 'correct options'); | ||
}; | ||
renderer = new _mobiledocTextRenderer['default']({ atoms: [], unknownAtomHandler: unknownAtomHandler, cardOptions: cardOptions }); | ||
renderer.render(mobiledoc); | ||
}); | ||
}); |
import RendererFactory from './renderer-factory'; | ||
import RENDER_TYPE from './utils/render-type'; | ||
@@ -6,3 +7,3 @@ export function registerGlobal(window) { | ||
} | ||
export { RENDER_TYPE }; | ||
export default RendererFactory; |
@@ -1,3 +0,4 @@ | ||
import Renderer from './renderer'; | ||
const RENDER_TYPE = 'text'; | ||
import Renderer_0_2, { MOBILEDOC_VERSION as MOBILEDOC_VERSION_0_2 } from './renderers/0-2'; | ||
import Renderer_0_3, { MOBILEDOC_VERSION as MOBILEDOC_VERSION_0_3 } from './renderers/0-3'; | ||
import RENDER_TYPE from './utils/render-type'; | ||
/** | ||
@@ -12,4 +13,4 @@ * runtime Text renderer | ||
function validateCards(cards) { | ||
if (!Array.isArray) { | ||
throw new Error('`cards` must be an array'); | ||
if (!Array.isArray(cards)) { | ||
throw new Error('`cards` must be passed as an array'); | ||
} | ||
@@ -27,15 +28,41 @@ for (let i=0; i < cards.length; i++) { | ||
function validateAtoms(atoms) { | ||
if (!Array.isArray(atoms)) { | ||
throw new Error('`atoms` must be passed as an array'); | ||
} | ||
for (let i=0; i < atoms.length; i++) { | ||
let atom = atoms[i]; | ||
if (atom.type !== RENDER_TYPE) { | ||
throw new Error(`Atom "${atom.name}" must be type "${RENDER_TYPE}", was "${atom.type}"`); | ||
} | ||
if (!atom.render) { | ||
throw new Error(`Atom "${atom.name}" must define \`render\``); | ||
} | ||
} | ||
} | ||
export default class RendererFactory { | ||
constructor({cards, atoms, cardOptions, unknownCardHandler}={}) { | ||
constructor({cards, atoms, cardOptions, unknownCardHandler, unknownAtomHandler}={}) { | ||
cards = cards || []; | ||
validateCards(cards); | ||
atoms = atoms || []; | ||
validateAtoms(atoms); | ||
cardOptions = cardOptions || {}; | ||
this.state = {cards, atoms, cardOptions, unknownCardHandler}; | ||
this.state = {cards, atoms, cardOptions, unknownCardHandler, unknownAtomHandler}; | ||
} | ||
render(mobiledoc) { | ||
return new Renderer(mobiledoc, this.state).render(); | ||
let { version } = mobiledoc; | ||
switch (version) { | ||
case MOBILEDOC_VERSION_0_2: | ||
case undefined: | ||
case null: | ||
return new Renderer_0_2(mobiledoc, this.state).render(); | ||
case MOBILEDOC_VERSION_0_3: | ||
return new Renderer_0_3(mobiledoc, this.state).render(); | ||
default: | ||
throw new Error(`Unexpected Mobiledoc version "${version}"`); | ||
} | ||
} | ||
} |
{ | ||
"name": "mobiledoc-text-renderer", | ||
"version": "0.2.1", | ||
"version": "0.3.0-beta.1", | ||
"description": "Renders mobiledoc input to text (string) output", | ||
@@ -5,0 +5,0 @@ "main": "dist/commonjs/mobiledoc-text-renderer/index.js", |
## Mobiledoc Text Renderer [![Build Status](https://travis-ci.org/bustlelabs/mobiledoc-text-renderer.svg?branch=master)](https://travis-ci.org/bustlelabs/mobiledoc-text-renderer) | ||
This is an Text renderer for the [Mobiledoc](https://github.com/bustlelabs/mobiledoc-kit/blob/master/MOBILEDOC.md) format used | ||
by the [Mobiledoc-kit](https://github.com/bustlelabs/mobiledoc-kit). | ||
This is a Text renderer for the [Mobiledoc format](https://github.com/bustlelabs/mobiledoc-kit/blob/master/MOBILEDOC.md) used | ||
by [Mobiledoc-kit](https://github.com/bustlelabs/mobiledoc-kit). | ||
To learn more about Mobiledoc cards and renderers, see the **[Mobiledoc Cards docs](https://github.com/bustlelabs/mobiledoc-kit/blob/master/CARDS.md)**. | ||
The renderer is a small library intended for use in servers that are building | ||
@@ -35,2 +37,11 @@ Text documents. It may be of limited use inside browsers as well. | ||
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 | ||
* `cardOptions` [object] - Options to pass to cards when they are rendered | ||
* `unknownCardHandler` [function] - Will be called when any unknown card is enountered | ||
The return value from `renderer.render(mobiledoc)` is an object with two properties: | ||
* `result` [string] - 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 | ||
### Tests | ||
@@ -37,0 +48,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
318760
30
7258
56