mobiledoc-text-renderer
Advanced tools
Comparing version 0.2.1 to 0.3.0-beta1
@@ -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-beta1", | ||
"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
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
318759
30
7258
56
1