Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

mobiledoc-dom-renderer

Package Overview
Dependencies
Maintainers
2
Versions
52
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mobiledoc-dom-renderer - npm Package Compare versions

Comparing version 0.1.18 to 0.2.0

dist/commonjs/mobiledoc-dom-renderer/renderer-factory.js

460

dist/amd/mobiledoc-dom-renderer.js

@@ -1,35 +0,31 @@

define('mobiledoc-dom-renderer/cards/image', ['exports', 'mobiledoc-dom-renderer/utils/dom'], function (exports, _mobiledocDomRendererUtilsDom) {
define('mobiledoc-dom-renderer/cards/image', ['exports', 'mobiledoc-dom-renderer/utils/dom', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererUtilsDom, _mobiledocDomRendererUtilsRenderType) {
'use strict';
var ImageCard = {
exports['default'] = {
name: 'image',
display: {
setup: function setup(element, options, env, payload) {
if (payload.src) {
var img = (0, _mobiledocDomRendererUtilsDom.createElement)('img');
img.src = payload.src;
(0, _mobiledocDomRendererUtilsDom.appendChild)(element, img);
}
}
type: _mobiledocDomRendererUtilsRenderType['default'],
render: function render(_ref) {
var payload = _ref.payload;
var img = (0, _mobiledocDomRendererUtilsDom.createElement)('img');
img.src = payload.src;
return img;
}
};
exports['default'] = ImageCard;
});
define('mobiledoc-dom-renderer', ['exports', 'mobiledoc-dom-renderer/renderer'], function (exports, _mobiledocDomRendererRenderer) {
define('mobiledoc-dom-renderer', ['exports', 'mobiledoc-dom-renderer/renderer-factory', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererRendererFactory, _mobiledocDomRendererUtilsRenderType) {
'use strict';
exports.registerGlobal = registerGlobal;
exports.RENDER_TYPE = _mobiledocDomRendererUtilsRenderType['default'];
function registerGlobal(window) {
window.MobiledocDOMRenderer = _mobiledocDomRendererRenderer['default'];
window.MobiledocDOMRenderer = _mobiledocDomRendererRendererFactory['default'];
}
exports['default'] = _mobiledocDomRendererRenderer['default'];
exports['default'] = _mobiledocDomRendererRendererFactory['default'];
});
define('mobiledoc-dom-renderer/renderer', ['exports', 'mobiledoc-dom-renderer/utils/dom', 'mobiledoc-dom-renderer/cards/image'], function (exports, _mobiledocDomRendererUtilsDom, _mobiledocDomRendererCardsImage) {
define('mobiledoc-dom-renderer/renderer-factory', ['exports', 'mobiledoc-dom-renderer/renderer', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererRenderer, _mobiledocDomRendererUtilsRenderType) {
'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; }; })();

@@ -39,7 +35,2 @@

var MARKUP_SECTION_TYPE = 1;
var IMAGE_SECTION_TYPE = 2;
var LIST_SECTION_TYPE = 3;
var CARD_SECTION_TYPE = 10;
/**

@@ -53,2 +44,63 @@ * runtime DOM renderer

function validateCards(cards) {
if (!Array.isArray(cards)) {
throw new Error('`cards` must be passed as an array, not an object.');
}
for (var i = 0; i < cards.length; i++) {
var card = cards[i];
if (card.type !== _mobiledocDomRendererUtilsRenderType['default']) {
throw new Error('Card "' + card.name + '" must be of type "' + _mobiledocDomRendererUtilsRenderType['default'] + '", is type "' + card.type + '"');
}
if (!card.render) {
throw new Error('Card "' + card.name + '" must define `render`');
}
}
}
var RendererFactory = (function () {
function RendererFactory() {
var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var cards = _ref.cards;
var atoms = _ref.atoms;
var cardOptions = _ref.cardOptions;
var unknownCardHandler = _ref.unknownCardHandler;
_classCallCheck(this, RendererFactory);
cards = cards || [];
validateCards(cards);
atoms = atoms || [];
cardOptions = cardOptions || {};
this.state = { cards: cards, atoms: atoms, cardOptions: cardOptions, unknownCardHandler: unknownCardHandler };
}
_createClass(RendererFactory, [{
key: 'render',
value: function render(mobiledoc) {
return new _mobiledocDomRendererRenderer['default'](mobiledoc, this.state).render();
}
}]);
return RendererFactory;
})();
exports['default'] = RendererFactory;
});
define('mobiledoc-dom-renderer/renderer', ['exports', 'mobiledoc-dom-renderer/utils/dom', 'mobiledoc-dom-renderer/cards/image', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererUtilsDom, _mobiledocDomRendererCardsImage, _mobiledocDomRendererUtilsRenderType) {
'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 MARKUP_SECTION_TYPE = 1;
var IMAGE_SECTION_TYPE = 2;
var LIST_SECTION_TYPE = 3;
var CARD_SECTION_TYPE = 10;
function createElementFromMarkerType() {

@@ -73,165 +125,258 @@ var _ref = arguments.length <= 0 || arguments[0] === undefined ? ['', []] : arguments[0];

function renderMarkersOnElement(element, markers, renderState) {
var elements = [element];
var currentElement = element;
function validateVersion(version) {
if (version !== '0.2.0') {
throw new Error('Unexpected Mobiledoc version "' + version + '"');
}
}
for (var i = 0, l = markers.length; i < l; i++) {
var marker = markers[i];
var Renderer = (function () {
function Renderer(mobiledoc, state) {
_classCallCheck(this, Renderer);
var _marker = _slicedToArray(marker, 3);
var cards = state.cards;
var cardOptions = state.cardOptions;
var atoms = state.atoms;
var unknownCardHandler = state.unknownCardHandler;
var version = mobiledoc.version;
var sectionData = mobiledoc.sections;
var openTypes = _marker[0];
var closeTypes = _marker[1];
var text = _marker[2];
validateVersion(version);
for (var j = 0, m = openTypes.length; j < m; j++) {
var markerType = renderState.markerTypes[openTypes[j]];
var openedElement = createElementFromMarkerType(markerType);
(0, _mobiledocDomRendererUtilsDom.appendChild)(currentElement, openedElement);
elements.push(openedElement);
currentElement = openedElement;
}
var _sectionData = _slicedToArray(sectionData, 2);
(0, _mobiledocDomRendererUtilsDom.appendChild)(currentElement, (0, _mobiledocDomRendererUtilsDom.createTextNode)(text));
var markerTypes = _sectionData[0];
var sections = _sectionData[1];
for (var j = 0, m = closeTypes; j < m; j++) {
elements.pop();
currentElement = elements[elements.length - 1];
}
this.root = (0, _mobiledocDomRendererUtilsDom.createDocumentFragment)();
this.markerTypes = markerTypes;
this.sections = sections;
this.cards = cards;
this.atoms = atoms;
this.cardOptions = cardOptions;
this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;
this._teardownCallbacks = [];
this._renderedChildNodes = [];
}
}
function renderListItem(markers, renderState) {
var element = (0, _mobiledocDomRendererUtilsDom.createElement)('li');
renderMarkersOnElement(element, markers, renderState);
return element;
}
_createClass(Renderer, [{
key: 'render',
value: function render() {
var _this = this;
function renderListSection(_ref3, renderState) {
var _ref32 = _slicedToArray(_ref3, 3);
this.sections.forEach(function (section) {
(0, _mobiledocDomRendererUtilsDom.appendChild)(_this.root, _this.renderSection(section));
});
// maintain a reference to child nodes so they can be cleaned up later by teardown
this._renderedChildNodes = Array.prototype.slice.call(this.root.childNodes);
return { result: this.root, teardown: function teardown() {
return _this.teardown();
} };
}
}, {
key: 'teardown',
value: function teardown() {
for (var i = 0; i < this._teardownCallbacks.length; i++) {
this._teardownCallbacks[i]();
}
for (var i = 0; i < this._renderedChildNodes.length; i++) {
var node = this._renderedChildNodes[i];
if (node.parentNode) {
(0, _mobiledocDomRendererUtilsDom.removeChild)(node.parentNode, node);
}
}
}
}, {
key: 'renderSection',
value: function renderSection(section) {
var _section = _slicedToArray(section, 1);
var type = _ref32[0];
var tagName = _ref32[1];
var listItems = _ref32[2];
var type = _section[0];
var element = (0, _mobiledocDomRendererUtilsDom.createElement)(tagName);
listItems.forEach(function (li) {
(0, _mobiledocDomRendererUtilsDom.appendChild)(element, renderListItem(li, renderState));
});
return element;
}
switch (type) {
case MARKUP_SECTION_TYPE:
return this.renderMarkupSection(section);
case IMAGE_SECTION_TYPE:
return this.renderImageSection(section);
case LIST_SECTION_TYPE:
return this.renderListSection(section);
case CARD_SECTION_TYPE:
return this.renderCardSection(section);
default:
throw new Error('Cannot render mobiledoc section of type "' + type + '"');
}
}
}, {
key: 'renderMarkersOnElement',
value: function renderMarkersOnElement(element, markers) {
var elements = [element];
var currentElement = element;
function renderImageSection(_ref4) {
var _ref42 = _slicedToArray(_ref4, 2);
for (var i = 0, l = markers.length; i < l; i++) {
var marker = markers[i];
var type = _ref42[0];
var src = _ref42[1];
var _marker = _slicedToArray(marker, 3);
var element = (0, _mobiledocDomRendererUtilsDom.createElement)('img');
element.src = src;
return element;
}
var openTypes = _marker[0];
var closeTypes = _marker[1];
var text = _marker[2];
function renderCardSection(_ref5, renderState) {
var _ref52 = _slicedToArray(_ref5, 3);
for (var j = 0, m = openTypes.length; j < m; j++) {
var markerType = this.markerTypes[openTypes[j]];
var openedElement = createElementFromMarkerType(markerType);
(0, _mobiledocDomRendererUtilsDom.appendChild)(currentElement, openedElement);
elements.push(openedElement);
currentElement = openedElement;
}
var type = _ref52[0];
var name = _ref52[1];
var payload = _ref52[2];
var cards = renderState.cards;
(0, _mobiledocDomRendererUtilsDom.appendChild)(currentElement, (0, _mobiledocDomRendererUtilsDom.createTextNode)(text));
var card = cards[name];
if (!card) {
throw new Error('Cannot render unknown card named ' + name);
}
if (!payload) {
payload = {};
}
var element = (0, _mobiledocDomRendererUtilsDom.createElement)('div');
var cardOptions = renderState.options.cardOptions || {};
card.display.setup(element, cardOptions, { name: name }, payload);
return element;
}
for (var j = 0, m = closeTypes; j < m; j++) {
elements.pop();
currentElement = elements[elements.length - 1];
}
}
}
}, {
key: 'renderListItem',
value: function renderListItem(markers) {
var element = (0, _mobiledocDomRendererUtilsDom.createElement)('li');
this.renderMarkersOnElement(element, markers);
return element;
}
}, {
key: 'renderListSection',
value: function renderListSection(_ref3) {
var _this2 = this;
function renderMarkupSection(_ref6, renderState) {
var _ref62 = _slicedToArray(_ref6, 3);
var _ref32 = _slicedToArray(_ref3, 3);
var type = _ref62[0];
var tagName = _ref62[1];
var markers = _ref62[2];
var type = _ref32[0];
var tagName = _ref32[1];
var listItems = _ref32[2];
var element = (0, _mobiledocDomRendererUtilsDom.createElement)(tagName);
renderMarkersOnElement(element, markers, renderState);
return element;
}
var element = (0, _mobiledocDomRendererUtilsDom.createElement)(tagName);
listItems.forEach(function (li) {
(0, _mobiledocDomRendererUtilsDom.appendChild)(element, _this2.renderListItem(li));
});
return element;
}
}, {
key: 'renderImageSection',
value: function renderImageSection(_ref4) {
var _ref42 = _slicedToArray(_ref4, 2);
function renderSection(section, renderState) {
var _section = _slicedToArray(section, 1);
var type = _ref42[0];
var src = _ref42[1];
var type = _section[0];
var element = (0, _mobiledocDomRendererUtilsDom.createElement)('img');
element.src = src;
return element;
}
}, {
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 === _mobiledocDomRendererCardsImage['default'].name) {
return _mobiledocDomRendererCardsImage['default'];
}
return this._createUnknownCard(name);
}
}, {
key: '_createUnknownCard',
value: function _createUnknownCard(name) {
return {
name: name,
type: _mobiledocDomRendererUtilsRenderType['default'],
render: this.unknownCardHandler
};
}
}, {
key: '_createCardArgument',
value: function _createCardArgument(card) {
var _this3 = this;
switch (type) {
case MARKUP_SECTION_TYPE:
return renderMarkupSection(section, renderState);
case IMAGE_SECTION_TYPE:
return renderImageSection(section, renderState);
case LIST_SECTION_TYPE:
return renderListSection(section, renderState);
case CARD_SECTION_TYPE:
return renderCardSection(section, renderState);
default:
throw new Error('Unimplement renderer for type ' + type);
}
}
var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
function validateVersion(version) {
if (version !== '0.2.0') {
throw new Error('Unexpected Mobiledoc version "' + version + '"');
}
}
var env = {
name: card.name,
isInEditor: false,
onTeardown: function onTeardown(callback) {
return _this3._registerTeardownCallback(callback);
}
};
var Renderer = (function () {
function Renderer() {
_classCallCheck(this, Renderer);
}
var options = this.cardOptions;
_createClass(Renderer, [{
key: 'render',
return { env: env, options: options, payload: payload };
}
}, {
key: '_registerTeardownCallback',
value: function _registerTeardownCallback(callback) {
this._teardownCallbacks.push(callback);
}
}, {
key: 'renderCardSection',
value: function renderCardSection(_ref5) {
var _ref52 = _slicedToArray(_ref5, 3);
/**
* @param {Mobiledoc} mobiledoc
* @param {DOMNode} [rootElement] defaults to an empty div
* @param {Object} [cards] Each top-level property on the object is considered
* to be a card's name, its value is an object with `setup` and (optional) `teardown`
* properties
* @return DOMNode
*/
value: function render(_ref7) {
var root = arguments.length <= 1 || arguments[1] === undefined ? (0, _mobiledocDomRendererUtilsDom.createElement)('div') : arguments[1];
var cards = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
var version = _ref7.version;
var sectionData = _ref7.sections;
var options = arguments.length <= 3 || arguments[3] === undefined ? {} : arguments[3];
var type = _ref52[0];
var name = _ref52[1];
var payload = _ref52[2];
validateVersion(version);
var card = this.findCard(name);
var _sectionData = _slicedToArray(sectionData, 2);
var cardWrapper = this._createCardElement();
var cardArg = this._createCardArgument(card, payload);
var rendered = card.render(cardArg);
var markerTypes = _sectionData[0];
var sections = _sectionData[1];
this._validateCardRender(rendered, card.name);
cards.image = cards.image || _mobiledocDomRendererCardsImage['default'];
var renderState = { root: root, markerTypes: markerTypes, cards: cards, options: options };
if (rendered) {
(0, _mobiledocDomRendererUtilsDom.appendChild)(cardWrapper, rendered);
}
return cardWrapper;
}
}, {
key: '_createCardElement',
value: function _createCardElement() {
return (0, _mobiledocDomRendererUtilsDom.createElement)('div');
}
}, {
key: '_validateCardRender',
value: function _validateCardRender(rendered, cardName) {
if (!rendered) {
return;
}
if (Array.isArray(cards)) {
throw new Error('`cards` must be passed as an object, not an array.');
if (typeof rendered !== 'object') {
throw new Error('Card "' + cardName + '" must render ' + _mobiledocDomRendererUtilsRenderType['default'] + ', but result was "' + rendered + '"');
}
}
}, {
key: 'renderMarkupSection',
value: function renderMarkupSection(_ref6) {
var _ref62 = _slicedToArray(_ref6, 3);
sections.forEach(function (section) {
var rendered = renderSection(section, renderState);
(0, _mobiledocDomRendererUtilsDom.appendChild)(renderState.root, rendered);
});
var type = _ref62[0];
var tagName = _ref62[1];
var markers = _ref62[2];
return root;
var element = (0, _mobiledocDomRendererUtilsDom.createElement)(tagName);
this.renderMarkersOnElement(element, markers);
return element;
}
}, {
key: '_defaultUnknownCardHandler',
get: function get() {
return function (_ref7) {
var name = _ref7.env.name;
throw new Error('Card "' + name + '" not found but no unknownCardHandler was registered');
};
}
}]);

@@ -249,4 +394,6 @@

exports.appendChild = appendChild;
exports.removeChild = removeChild;
exports.createTextNode = createTextNode;
exports.setAttribute = setAttribute;
exports.createDocumentFragment = createDocumentFragment;

@@ -261,2 +408,6 @@ function createElement(tagName) {

function removeChild(target, child) {
target.removeChild(child);
}
function addHTMLSpaces(text) {

@@ -274,2 +425,11 @@ var nbsp = ' ';

}
function createDocumentFragment() {
return document.createDocumentFragment();
}
});
define('mobiledoc-dom-renderer/utils/render-type', ['exports'], function (exports) {
'use strict';
exports['default'] = 'dom';
});//# sourceMappingURL=mobiledoc-dom-renderer.map

@@ -5,15 +5,14 @@ 'use strict';

var ImageCard = {
var _utilsRenderType = require('../utils/render-type');
exports['default'] = {
name: 'image',
display: {
setup: function setup(element, options, env, payload) {
if (payload.src) {
var img = (0, _utilsDom.createElement)('img');
img.src = payload.src;
(0, _utilsDom.appendChild)(element, img);
}
}
type: _utilsRenderType['default'],
render: function render(_ref) {
var payload = _ref.payload;
var img = (0, _utilsDom.createElement)('img');
img.src = payload.src;
return img;
}
};
exports['default'] = ImageCard;
};

@@ -5,8 +5,12 @@ 'use strict';

var _renderer = require('./renderer');
var _rendererFactory = require('./renderer-factory');
var _utilsRenderType = require('./utils/render-type');
exports.RENDER_TYPE = _utilsRenderType['default'];
function registerGlobal(window) {
window.MobiledocDOMRenderer = _renderer['default'];
window.MobiledocDOMRenderer = _rendererFactory['default'];
}
exports['default'] = _renderer['default'];
exports['default'] = _rendererFactory['default'];

@@ -13,2 +13,4 @@ 'use strict';

var _utilsRenderType = require('./utils/render-type');
var MARKUP_SECTION_TYPE = 1;

@@ -19,10 +21,2 @@ var IMAGE_SECTION_TYPE = 2;

/**
* runtime DOM renderer
* renders a mobiledoc to DOM
*
* input: mobiledoc
* output: DOM
*/
function createElementFromMarkerType() {

@@ -47,165 +41,258 @@ var _ref = arguments.length <= 0 || arguments[0] === undefined ? ['', []] : arguments[0];

function renderMarkersOnElement(element, markers, renderState) {
var elements = [element];
var currentElement = element;
function validateVersion(version) {
if (version !== '0.2.0') {
throw new Error('Unexpected Mobiledoc version "' + version + '"');
}
}
for (var i = 0, l = markers.length; i < l; i++) {
var marker = markers[i];
var Renderer = (function () {
function Renderer(mobiledoc, state) {
_classCallCheck(this, Renderer);
var _marker = _slicedToArray(marker, 3);
var cards = state.cards;
var cardOptions = state.cardOptions;
var atoms = state.atoms;
var unknownCardHandler = state.unknownCardHandler;
var version = mobiledoc.version;
var sectionData = mobiledoc.sections;
var openTypes = _marker[0];
var closeTypes = _marker[1];
var text = _marker[2];
validateVersion(version);
for (var j = 0, m = openTypes.length; j < m; j++) {
var markerType = renderState.markerTypes[openTypes[j]];
var openedElement = createElementFromMarkerType(markerType);
(0, _utilsDom.appendChild)(currentElement, openedElement);
elements.push(openedElement);
currentElement = openedElement;
}
var _sectionData = _slicedToArray(sectionData, 2);
(0, _utilsDom.appendChild)(currentElement, (0, _utilsDom.createTextNode)(text));
var markerTypes = _sectionData[0];
var sections = _sectionData[1];
for (var j = 0, m = closeTypes; j < m; j++) {
elements.pop();
currentElement = elements[elements.length - 1];
}
this.root = (0, _utilsDom.createDocumentFragment)();
this.markerTypes = markerTypes;
this.sections = sections;
this.cards = cards;
this.atoms = atoms;
this.cardOptions = cardOptions;
this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;
this._teardownCallbacks = [];
this._renderedChildNodes = [];
}
}
function renderListItem(markers, renderState) {
var element = (0, _utilsDom.createElement)('li');
renderMarkersOnElement(element, markers, renderState);
return element;
}
_createClass(Renderer, [{
key: 'render',
value: function render() {
var _this = this;
function renderListSection(_ref3, renderState) {
var _ref32 = _slicedToArray(_ref3, 3);
this.sections.forEach(function (section) {
(0, _utilsDom.appendChild)(_this.root, _this.renderSection(section));
});
// maintain a reference to child nodes so they can be cleaned up later by teardown
this._renderedChildNodes = Array.prototype.slice.call(this.root.childNodes);
return { result: this.root, teardown: function teardown() {
return _this.teardown();
} };
}
}, {
key: 'teardown',
value: function teardown() {
for (var i = 0; i < this._teardownCallbacks.length; i++) {
this._teardownCallbacks[i]();
}
for (var i = 0; i < this._renderedChildNodes.length; i++) {
var node = this._renderedChildNodes[i];
if (node.parentNode) {
(0, _utilsDom.removeChild)(node.parentNode, node);
}
}
}
}, {
key: 'renderSection',
value: function renderSection(section) {
var _section = _slicedToArray(section, 1);
var type = _ref32[0];
var tagName = _ref32[1];
var listItems = _ref32[2];
var type = _section[0];
var element = (0, _utilsDom.createElement)(tagName);
listItems.forEach(function (li) {
(0, _utilsDom.appendChild)(element, renderListItem(li, renderState));
});
return element;
}
switch (type) {
case MARKUP_SECTION_TYPE:
return this.renderMarkupSection(section);
case IMAGE_SECTION_TYPE:
return this.renderImageSection(section);
case LIST_SECTION_TYPE:
return this.renderListSection(section);
case CARD_SECTION_TYPE:
return this.renderCardSection(section);
default:
throw new Error('Cannot render mobiledoc section of type "' + type + '"');
}
}
}, {
key: 'renderMarkersOnElement',
value: function renderMarkersOnElement(element, markers) {
var elements = [element];
var currentElement = element;
function renderImageSection(_ref4) {
var _ref42 = _slicedToArray(_ref4, 2);
for (var i = 0, l = markers.length; i < l; i++) {
var marker = markers[i];
var type = _ref42[0];
var src = _ref42[1];
var _marker = _slicedToArray(marker, 3);
var element = (0, _utilsDom.createElement)('img');
element.src = src;
return element;
}
var openTypes = _marker[0];
var closeTypes = _marker[1];
var text = _marker[2];
function renderCardSection(_ref5, renderState) {
var _ref52 = _slicedToArray(_ref5, 3);
for (var j = 0, m = openTypes.length; j < m; j++) {
var markerType = this.markerTypes[openTypes[j]];
var openedElement = createElementFromMarkerType(markerType);
(0, _utilsDom.appendChild)(currentElement, openedElement);
elements.push(openedElement);
currentElement = openedElement;
}
var type = _ref52[0];
var name = _ref52[1];
var payload = _ref52[2];
var cards = renderState.cards;
(0, _utilsDom.appendChild)(currentElement, (0, _utilsDom.createTextNode)(text));
var card = cards[name];
if (!card) {
throw new Error('Cannot render unknown card named ' + name);
}
if (!payload) {
payload = {};
}
var element = (0, _utilsDom.createElement)('div');
var cardOptions = renderState.options.cardOptions || {};
card.display.setup(element, cardOptions, { name: name }, payload);
return element;
}
for (var j = 0, m = closeTypes; j < m; j++) {
elements.pop();
currentElement = elements[elements.length - 1];
}
}
}
}, {
key: 'renderListItem',
value: function renderListItem(markers) {
var element = (0, _utilsDom.createElement)('li');
this.renderMarkersOnElement(element, markers);
return element;
}
}, {
key: 'renderListSection',
value: function renderListSection(_ref3) {
var _this2 = this;
function renderMarkupSection(_ref6, renderState) {
var _ref62 = _slicedToArray(_ref6, 3);
var _ref32 = _slicedToArray(_ref3, 3);
var type = _ref62[0];
var tagName = _ref62[1];
var markers = _ref62[2];
var type = _ref32[0];
var tagName = _ref32[1];
var listItems = _ref32[2];
var element = (0, _utilsDom.createElement)(tagName);
renderMarkersOnElement(element, markers, renderState);
return element;
}
var element = (0, _utilsDom.createElement)(tagName);
listItems.forEach(function (li) {
(0, _utilsDom.appendChild)(element, _this2.renderListItem(li));
});
return element;
}
}, {
key: 'renderImageSection',
value: function renderImageSection(_ref4) {
var _ref42 = _slicedToArray(_ref4, 2);
function renderSection(section, renderState) {
var _section = _slicedToArray(section, 1);
var type = _ref42[0];
var src = _ref42[1];
var type = _section[0];
var element = (0, _utilsDom.createElement)('img');
element.src = src;
return element;
}
}, {
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 === _cardsImage['default'].name) {
return _cardsImage['default'];
}
return this._createUnknownCard(name);
}
}, {
key: '_createUnknownCard',
value: function _createUnknownCard(name) {
return {
name: name,
type: _utilsRenderType['default'],
render: this.unknownCardHandler
};
}
}, {
key: '_createCardArgument',
value: function _createCardArgument(card) {
var _this3 = this;
switch (type) {
case MARKUP_SECTION_TYPE:
return renderMarkupSection(section, renderState);
case IMAGE_SECTION_TYPE:
return renderImageSection(section, renderState);
case LIST_SECTION_TYPE:
return renderListSection(section, renderState);
case CARD_SECTION_TYPE:
return renderCardSection(section, renderState);
default:
throw new Error('Unimplement renderer for type ' + type);
}
}
var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
function validateVersion(version) {
if (version !== '0.2.0') {
throw new Error('Unexpected Mobiledoc version "' + version + '"');
}
}
var env = {
name: card.name,
isInEditor: false,
onTeardown: function onTeardown(callback) {
return _this3._registerTeardownCallback(callback);
}
};
var Renderer = (function () {
function Renderer() {
_classCallCheck(this, Renderer);
}
var options = this.cardOptions;
_createClass(Renderer, [{
key: 'render',
return { env: env, options: options, payload: payload };
}
}, {
key: '_registerTeardownCallback',
value: function _registerTeardownCallback(callback) {
this._teardownCallbacks.push(callback);
}
}, {
key: 'renderCardSection',
value: function renderCardSection(_ref5) {
var _ref52 = _slicedToArray(_ref5, 3);
/**
* @param {Mobiledoc} mobiledoc
* @param {DOMNode} [rootElement] defaults to an empty div
* @param {Object} [cards] Each top-level property on the object is considered
* to be a card's name, its value is an object with `setup` and (optional) `teardown`
* properties
* @return DOMNode
*/
value: function render(_ref7) {
var root = arguments.length <= 1 || arguments[1] === undefined ? (0, _utilsDom.createElement)('div') : arguments[1];
var cards = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
var version = _ref7.version;
var sectionData = _ref7.sections;
var options = arguments.length <= 3 || arguments[3] === undefined ? {} : arguments[3];
var type = _ref52[0];
var name = _ref52[1];
var payload = _ref52[2];
validateVersion(version);
var card = this.findCard(name);
var _sectionData = _slicedToArray(sectionData, 2);
var cardWrapper = this._createCardElement();
var cardArg = this._createCardArgument(card, payload);
var rendered = card.render(cardArg);
var markerTypes = _sectionData[0];
var sections = _sectionData[1];
this._validateCardRender(rendered, card.name);
cards.image = cards.image || _cardsImage['default'];
var renderState = { root: root, markerTypes: markerTypes, cards: cards, options: options };
if (rendered) {
(0, _utilsDom.appendChild)(cardWrapper, rendered);
}
return cardWrapper;
}
}, {
key: '_createCardElement',
value: function _createCardElement() {
return (0, _utilsDom.createElement)('div');
}
}, {
key: '_validateCardRender',
value: function _validateCardRender(rendered, cardName) {
if (!rendered) {
return;
}
if (Array.isArray(cards)) {
throw new Error('`cards` must be passed as an object, not an array.');
if (typeof rendered !== 'object') {
throw new Error('Card "' + cardName + '" must render ' + _utilsRenderType['default'] + ', but result was "' + rendered + '"');
}
}
}, {
key: 'renderMarkupSection',
value: function renderMarkupSection(_ref6) {
var _ref62 = _slicedToArray(_ref6, 3);
sections.forEach(function (section) {
var rendered = renderSection(section, renderState);
(0, _utilsDom.appendChild)(renderState.root, rendered);
});
var type = _ref62[0];
var tagName = _ref62[1];
var markers = _ref62[2];
return root;
var element = (0, _utilsDom.createElement)(tagName);
this.renderMarkersOnElement(element, markers);
return element;
}
}, {
key: '_defaultUnknownCardHandler',
get: function get() {
return function (_ref7) {
var name = _ref7.env.name;
throw new Error('Card "' + name + '" not found but no unknownCardHandler was registered');
};
}
}]);

@@ -212,0 +299,0 @@

@@ -5,4 +5,6 @@ 'use strict';

exports.appendChild = appendChild;
exports.removeChild = removeChild;
exports.createTextNode = createTextNode;
exports.setAttribute = setAttribute;
exports.createDocumentFragment = createDocumentFragment;

@@ -17,2 +19,6 @@ function createElement(tagName) {

function removeChild(target, child) {
target.removeChild(child);
}
function addHTMLSpaces(text) {

@@ -29,2 +35,6 @@ var nbsp = ' ';

node.setAttribute(propName, value);
}
function createDocumentFragment() {
return document.createDocumentFragment();
}

@@ -191,36 +191,32 @@ ;(function() {

define('mobiledoc-dom-renderer/cards/image', ['exports', 'mobiledoc-dom-renderer/utils/dom'], function (exports, _mobiledocDomRendererUtilsDom) {
define('mobiledoc-dom-renderer/cards/image', ['exports', 'mobiledoc-dom-renderer/utils/dom', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererUtilsDom, _mobiledocDomRendererUtilsRenderType) {
'use strict';
var ImageCard = {
exports['default'] = {
name: 'image',
display: {
setup: function setup(element, options, env, payload) {
if (payload.src) {
var img = (0, _mobiledocDomRendererUtilsDom.createElement)('img');
img.src = payload.src;
(0, _mobiledocDomRendererUtilsDom.appendChild)(element, img);
}
}
type: _mobiledocDomRendererUtilsRenderType['default'],
render: function render(_ref) {
var payload = _ref.payload;
var img = (0, _mobiledocDomRendererUtilsDom.createElement)('img');
img.src = payload.src;
return img;
}
};
exports['default'] = ImageCard;
});
define('mobiledoc-dom-renderer', ['exports', 'mobiledoc-dom-renderer/renderer'], function (exports, _mobiledocDomRendererRenderer) {
define('mobiledoc-dom-renderer', ['exports', 'mobiledoc-dom-renderer/renderer-factory', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererRendererFactory, _mobiledocDomRendererUtilsRenderType) {
'use strict';
exports.registerGlobal = registerGlobal;
exports.RENDER_TYPE = _mobiledocDomRendererUtilsRenderType['default'];
function registerGlobal(window) {
window.MobiledocDOMRenderer = _mobiledocDomRendererRenderer['default'];
window.MobiledocDOMRenderer = _mobiledocDomRendererRendererFactory['default'];
}
exports['default'] = _mobiledocDomRendererRenderer['default'];
exports['default'] = _mobiledocDomRendererRendererFactory['default'];
});
define('mobiledoc-dom-renderer/renderer', ['exports', 'mobiledoc-dom-renderer/utils/dom', 'mobiledoc-dom-renderer/cards/image'], function (exports, _mobiledocDomRendererUtilsDom, _mobiledocDomRendererCardsImage) {
define('mobiledoc-dom-renderer/renderer-factory', ['exports', 'mobiledoc-dom-renderer/renderer', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererRenderer, _mobiledocDomRendererUtilsRenderType) {
'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; }; })();

@@ -230,7 +226,2 @@

var MARKUP_SECTION_TYPE = 1;
var IMAGE_SECTION_TYPE = 2;
var LIST_SECTION_TYPE = 3;
var CARD_SECTION_TYPE = 10;
/**

@@ -244,2 +235,63 @@ * runtime DOM renderer

function validateCards(cards) {
if (!Array.isArray(cards)) {
throw new Error('`cards` must be passed as an array, not an object.');
}
for (var i = 0; i < cards.length; i++) {
var card = cards[i];
if (card.type !== _mobiledocDomRendererUtilsRenderType['default']) {
throw new Error('Card "' + card.name + '" must be of type "' + _mobiledocDomRendererUtilsRenderType['default'] + '", is type "' + card.type + '"');
}
if (!card.render) {
throw new Error('Card "' + card.name + '" must define `render`');
}
}
}
var RendererFactory = (function () {
function RendererFactory() {
var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var cards = _ref.cards;
var atoms = _ref.atoms;
var cardOptions = _ref.cardOptions;
var unknownCardHandler = _ref.unknownCardHandler;
_classCallCheck(this, RendererFactory);
cards = cards || [];
validateCards(cards);
atoms = atoms || [];
cardOptions = cardOptions || {};
this.state = { cards: cards, atoms: atoms, cardOptions: cardOptions, unknownCardHandler: unknownCardHandler };
}
_createClass(RendererFactory, [{
key: 'render',
value: function render(mobiledoc) {
return new _mobiledocDomRendererRenderer['default'](mobiledoc, this.state).render();
}
}]);
return RendererFactory;
})();
exports['default'] = RendererFactory;
});
define('mobiledoc-dom-renderer/renderer', ['exports', 'mobiledoc-dom-renderer/utils/dom', 'mobiledoc-dom-renderer/cards/image', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererUtilsDom, _mobiledocDomRendererCardsImage, _mobiledocDomRendererUtilsRenderType) {
'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 MARKUP_SECTION_TYPE = 1;
var IMAGE_SECTION_TYPE = 2;
var LIST_SECTION_TYPE = 3;
var CARD_SECTION_TYPE = 10;
function createElementFromMarkerType() {

@@ -264,165 +316,258 @@ var _ref = arguments.length <= 0 || arguments[0] === undefined ? ['', []] : arguments[0];

function renderMarkersOnElement(element, markers, renderState) {
var elements = [element];
var currentElement = element;
function validateVersion(version) {
if (version !== '0.2.0') {
throw new Error('Unexpected Mobiledoc version "' + version + '"');
}
}
for (var i = 0, l = markers.length; i < l; i++) {
var marker = markers[i];
var Renderer = (function () {
function Renderer(mobiledoc, state) {
_classCallCheck(this, Renderer);
var _marker = _slicedToArray(marker, 3);
var cards = state.cards;
var cardOptions = state.cardOptions;
var atoms = state.atoms;
var unknownCardHandler = state.unknownCardHandler;
var version = mobiledoc.version;
var sectionData = mobiledoc.sections;
var openTypes = _marker[0];
var closeTypes = _marker[1];
var text = _marker[2];
validateVersion(version);
for (var j = 0, m = openTypes.length; j < m; j++) {
var markerType = renderState.markerTypes[openTypes[j]];
var openedElement = createElementFromMarkerType(markerType);
(0, _mobiledocDomRendererUtilsDom.appendChild)(currentElement, openedElement);
elements.push(openedElement);
currentElement = openedElement;
}
var _sectionData = _slicedToArray(sectionData, 2);
(0, _mobiledocDomRendererUtilsDom.appendChild)(currentElement, (0, _mobiledocDomRendererUtilsDom.createTextNode)(text));
var markerTypes = _sectionData[0];
var sections = _sectionData[1];
for (var j = 0, m = closeTypes; j < m; j++) {
elements.pop();
currentElement = elements[elements.length - 1];
}
this.root = (0, _mobiledocDomRendererUtilsDom.createDocumentFragment)();
this.markerTypes = markerTypes;
this.sections = sections;
this.cards = cards;
this.atoms = atoms;
this.cardOptions = cardOptions;
this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;
this._teardownCallbacks = [];
this._renderedChildNodes = [];
}
}
function renderListItem(markers, renderState) {
var element = (0, _mobiledocDomRendererUtilsDom.createElement)('li');
renderMarkersOnElement(element, markers, renderState);
return element;
}
_createClass(Renderer, [{
key: 'render',
value: function render() {
var _this = this;
function renderListSection(_ref3, renderState) {
var _ref32 = _slicedToArray(_ref3, 3);
this.sections.forEach(function (section) {
(0, _mobiledocDomRendererUtilsDom.appendChild)(_this.root, _this.renderSection(section));
});
// maintain a reference to child nodes so they can be cleaned up later by teardown
this._renderedChildNodes = Array.prototype.slice.call(this.root.childNodes);
return { result: this.root, teardown: function teardown() {
return _this.teardown();
} };
}
}, {
key: 'teardown',
value: function teardown() {
for (var i = 0; i < this._teardownCallbacks.length; i++) {
this._teardownCallbacks[i]();
}
for (var i = 0; i < this._renderedChildNodes.length; i++) {
var node = this._renderedChildNodes[i];
if (node.parentNode) {
(0, _mobiledocDomRendererUtilsDom.removeChild)(node.parentNode, node);
}
}
}
}, {
key: 'renderSection',
value: function renderSection(section) {
var _section = _slicedToArray(section, 1);
var type = _ref32[0];
var tagName = _ref32[1];
var listItems = _ref32[2];
var type = _section[0];
var element = (0, _mobiledocDomRendererUtilsDom.createElement)(tagName);
listItems.forEach(function (li) {
(0, _mobiledocDomRendererUtilsDom.appendChild)(element, renderListItem(li, renderState));
});
return element;
}
switch (type) {
case MARKUP_SECTION_TYPE:
return this.renderMarkupSection(section);
case IMAGE_SECTION_TYPE:
return this.renderImageSection(section);
case LIST_SECTION_TYPE:
return this.renderListSection(section);
case CARD_SECTION_TYPE:
return this.renderCardSection(section);
default:
throw new Error('Cannot render mobiledoc section of type "' + type + '"');
}
}
}, {
key: 'renderMarkersOnElement',
value: function renderMarkersOnElement(element, markers) {
var elements = [element];
var currentElement = element;
function renderImageSection(_ref4) {
var _ref42 = _slicedToArray(_ref4, 2);
for (var i = 0, l = markers.length; i < l; i++) {
var marker = markers[i];
var type = _ref42[0];
var src = _ref42[1];
var _marker = _slicedToArray(marker, 3);
var element = (0, _mobiledocDomRendererUtilsDom.createElement)('img');
element.src = src;
return element;
}
var openTypes = _marker[0];
var closeTypes = _marker[1];
var text = _marker[2];
function renderCardSection(_ref5, renderState) {
var _ref52 = _slicedToArray(_ref5, 3);
for (var j = 0, m = openTypes.length; j < m; j++) {
var markerType = this.markerTypes[openTypes[j]];
var openedElement = createElementFromMarkerType(markerType);
(0, _mobiledocDomRendererUtilsDom.appendChild)(currentElement, openedElement);
elements.push(openedElement);
currentElement = openedElement;
}
var type = _ref52[0];
var name = _ref52[1];
var payload = _ref52[2];
var cards = renderState.cards;
(0, _mobiledocDomRendererUtilsDom.appendChild)(currentElement, (0, _mobiledocDomRendererUtilsDom.createTextNode)(text));
var card = cards[name];
if (!card) {
throw new Error('Cannot render unknown card named ' + name);
}
if (!payload) {
payload = {};
}
var element = (0, _mobiledocDomRendererUtilsDom.createElement)('div');
var cardOptions = renderState.options.cardOptions || {};
card.display.setup(element, cardOptions, { name: name }, payload);
return element;
}
for (var j = 0, m = closeTypes; j < m; j++) {
elements.pop();
currentElement = elements[elements.length - 1];
}
}
}
}, {
key: 'renderListItem',
value: function renderListItem(markers) {
var element = (0, _mobiledocDomRendererUtilsDom.createElement)('li');
this.renderMarkersOnElement(element, markers);
return element;
}
}, {
key: 'renderListSection',
value: function renderListSection(_ref3) {
var _this2 = this;
function renderMarkupSection(_ref6, renderState) {
var _ref62 = _slicedToArray(_ref6, 3);
var _ref32 = _slicedToArray(_ref3, 3);
var type = _ref62[0];
var tagName = _ref62[1];
var markers = _ref62[2];
var type = _ref32[0];
var tagName = _ref32[1];
var listItems = _ref32[2];
var element = (0, _mobiledocDomRendererUtilsDom.createElement)(tagName);
renderMarkersOnElement(element, markers, renderState);
return element;
}
var element = (0, _mobiledocDomRendererUtilsDom.createElement)(tagName);
listItems.forEach(function (li) {
(0, _mobiledocDomRendererUtilsDom.appendChild)(element, _this2.renderListItem(li));
});
return element;
}
}, {
key: 'renderImageSection',
value: function renderImageSection(_ref4) {
var _ref42 = _slicedToArray(_ref4, 2);
function renderSection(section, renderState) {
var _section = _slicedToArray(section, 1);
var type = _ref42[0];
var src = _ref42[1];
var type = _section[0];
var element = (0, _mobiledocDomRendererUtilsDom.createElement)('img');
element.src = src;
return element;
}
}, {
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 === _mobiledocDomRendererCardsImage['default'].name) {
return _mobiledocDomRendererCardsImage['default'];
}
return this._createUnknownCard(name);
}
}, {
key: '_createUnknownCard',
value: function _createUnknownCard(name) {
return {
name: name,
type: _mobiledocDomRendererUtilsRenderType['default'],
render: this.unknownCardHandler
};
}
}, {
key: '_createCardArgument',
value: function _createCardArgument(card) {
var _this3 = this;
switch (type) {
case MARKUP_SECTION_TYPE:
return renderMarkupSection(section, renderState);
case IMAGE_SECTION_TYPE:
return renderImageSection(section, renderState);
case LIST_SECTION_TYPE:
return renderListSection(section, renderState);
case CARD_SECTION_TYPE:
return renderCardSection(section, renderState);
default:
throw new Error('Unimplement renderer for type ' + type);
}
}
var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
function validateVersion(version) {
if (version !== '0.2.0') {
throw new Error('Unexpected Mobiledoc version "' + version + '"');
}
}
var env = {
name: card.name,
isInEditor: false,
onTeardown: function onTeardown(callback) {
return _this3._registerTeardownCallback(callback);
}
};
var Renderer = (function () {
function Renderer() {
_classCallCheck(this, Renderer);
}
var options = this.cardOptions;
_createClass(Renderer, [{
key: 'render',
return { env: env, options: options, payload: payload };
}
}, {
key: '_registerTeardownCallback',
value: function _registerTeardownCallback(callback) {
this._teardownCallbacks.push(callback);
}
}, {
key: 'renderCardSection',
value: function renderCardSection(_ref5) {
var _ref52 = _slicedToArray(_ref5, 3);
/**
* @param {Mobiledoc} mobiledoc
* @param {DOMNode} [rootElement] defaults to an empty div
* @param {Object} [cards] Each top-level property on the object is considered
* to be a card's name, its value is an object with `setup` and (optional) `teardown`
* properties
* @return DOMNode
*/
value: function render(_ref7) {
var root = arguments.length <= 1 || arguments[1] === undefined ? (0, _mobiledocDomRendererUtilsDom.createElement)('div') : arguments[1];
var cards = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
var version = _ref7.version;
var sectionData = _ref7.sections;
var options = arguments.length <= 3 || arguments[3] === undefined ? {} : arguments[3];
var type = _ref52[0];
var name = _ref52[1];
var payload = _ref52[2];
validateVersion(version);
var card = this.findCard(name);
var _sectionData = _slicedToArray(sectionData, 2);
var cardWrapper = this._createCardElement();
var cardArg = this._createCardArgument(card, payload);
var rendered = card.render(cardArg);
var markerTypes = _sectionData[0];
var sections = _sectionData[1];
this._validateCardRender(rendered, card.name);
cards.image = cards.image || _mobiledocDomRendererCardsImage['default'];
var renderState = { root: root, markerTypes: markerTypes, cards: cards, options: options };
if (rendered) {
(0, _mobiledocDomRendererUtilsDom.appendChild)(cardWrapper, rendered);
}
return cardWrapper;
}
}, {
key: '_createCardElement',
value: function _createCardElement() {
return (0, _mobiledocDomRendererUtilsDom.createElement)('div');
}
}, {
key: '_validateCardRender',
value: function _validateCardRender(rendered, cardName) {
if (!rendered) {
return;
}
if (Array.isArray(cards)) {
throw new Error('`cards` must be passed as an object, not an array.');
if (typeof rendered !== 'object') {
throw new Error('Card "' + cardName + '" must render ' + _mobiledocDomRendererUtilsRenderType['default'] + ', but result was "' + rendered + '"');
}
}
}, {
key: 'renderMarkupSection',
value: function renderMarkupSection(_ref6) {
var _ref62 = _slicedToArray(_ref6, 3);
sections.forEach(function (section) {
var rendered = renderSection(section, renderState);
(0, _mobiledocDomRendererUtilsDom.appendChild)(renderState.root, rendered);
});
var type = _ref62[0];
var tagName = _ref62[1];
var markers = _ref62[2];
return root;
var element = (0, _mobiledocDomRendererUtilsDom.createElement)(tagName);
this.renderMarkersOnElement(element, markers);
return element;
}
}, {
key: '_defaultUnknownCardHandler',
get: function get() {
return function (_ref7) {
var name = _ref7.env.name;
throw new Error('Card "' + name + '" not found but no unknownCardHandler was registered');
};
}
}]);

@@ -440,4 +585,6 @@

exports.appendChild = appendChild;
exports.removeChild = removeChild;
exports.createTextNode = createTextNode;
exports.setAttribute = setAttribute;
exports.createDocumentFragment = createDocumentFragment;

@@ -452,2 +599,6 @@ function createElement(tagName) {

function removeChild(target, child) {
target.removeChild(child);
}
function addHTMLSpaces(text) {

@@ -465,5 +616,14 @@ var nbsp = ' ';

}
function createDocumentFragment() {
return document.createDocumentFragment();
}
});
define('mobiledoc-dom-renderer/utils/render-type', ['exports'], function (exports) {
'use strict';
exports['default'] = 'dom';
});
require("mobiledoc-dom-renderer")["registerGlobal"](window, document);
})();
//# sourceMappingURL=mobiledoc-dom-renderer.map

@@ -12,2 +12,7 @@ QUnit.module('JSHint - tests/jshint/cards');

QUnit.module('JSHint - tests/jshint');
QUnit.test('tests/jshint/renderer-factory.js should pass jshint', function(assert) {
assert.ok(true, 'tests/jshint/renderer-factory.js should pass jshint.');
});
QUnit.module('JSHint - tests/jshint');
QUnit.test('tests/jshint/renderer.js should pass jshint', function(assert) {

@@ -27,2 +32,7 @@ assert.ok(true, 'tests/jshint/renderer.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.');
});
define('tests/unit/renderer-test', ['exports', 'mobiledoc-dom-renderer'], function (exports, _mobiledocDomRenderer) {

@@ -33,16 +43,100 @@ /* global QUnit */

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var _QUnit = QUnit;
var test = _QUnit.test;
var _module = _QUnit.module;
var MOBILEDOC_VERSION = '0.2.0';
var dataUri = "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=";
var renderer = undefined;
QUnit.module('Unit: Mobiledoc DOM Renderer', {
_module('Unit: Mobiledoc DOM Renderer', {
beforeEach: function beforeEach() {
renderer = new _mobiledocDomRenderer['default']();
},
afterEach: function afterEach() {
if (renderer) {
renderer = null;
}
}
});
test('rendering unknown card without unknownCardHandler throws', function (assert) {
var cardName = 'not-known';
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], [[10, cardName]]]
};
renderer = new _mobiledocDomRenderer['default']({ cards: [], unknownCardHandler: undefined });
assert.throws(function () {
return renderer.render(mobiledoc);
}, new RegExp('Card "' + cardName + '" not found.*no unknownCardHandler'));
});
test('rendering unknown card uses unknownCardHandler', function (assert) {
assert.expect(5);
var cardName = 'my-card';
var expectedOptions = {};
var expectedPayload = {};
var unknownCardHandler = function unknownCardHandler(_ref) {
var env = _ref.env;
var options = _ref.options;
var payload = _ref.payload;
assert.equal(env.name, cardName, 'name is correct');
assert.ok(!env.isInEditor, 'not in editor');
assert.ok(!!env.onTeardown, 'has onTeardown');
assert.deepEqual(options, expectedOptions, 'correct options');
assert.deepEqual(payload, expectedPayload, 'correct payload');
};
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], [[10, cardName, expectedPayload]]]
};
renderer = new _mobiledocDomRenderer['default']({
cards: [], cardOptions: expectedOptions, unknownCardHandler: unknownCardHandler
});
renderer.render(mobiledoc);
});
test('throws if card render returns invalid result', function (assert) {
var card = {
name: 'bad',
type: 'dom',
render: function render() {
return 'string';
}
};
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], [[10, card.name]]]
};
renderer = new _mobiledocDomRenderer['default']({ cards: [card] });
assert.throws(function () {
return renderer.render(mobiledoc);
}, /Card "bad" must render dom/);
});
test('card may render nothing', function (assert) {
var card = {
name: 'ok',
type: 'dom',
render: function render() {}
};
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], [[10, card.name]]]
};
renderer = new _mobiledocDomRenderer['default']({ cards: [card] });
renderer.render(mobiledoc);
assert.ok(true, 'No error thrown');
});
test('it exists', function (assert) {

@@ -53,2 +147,38 @@ assert.ok(_mobiledocDomRenderer['default'], 'class exists');

test('throws if given a card with an invalid type', function (assert) {
var cardName = 'bad';
var card = {
name: cardName,
type: 'text',
render: function render() {}
};
var cards = [card];
assert.throws(function () {
new _mobiledocDomRenderer['default']({ cards: cards });
}, // jshint ignore: line
new RegExp('Card "' + cardName + '" must be of type "' + _mobiledocDomRenderer.RENDER_TYPE + '"'));
});
test('throws if given a card without a render method', function (assert) {
var cardName = 'bad';
var card = {
name: cardName,
type: _mobiledocDomRenderer.RENDER_TYPE,
render: undefined
};
var cards = [card];
assert.throws(function () {
new _mobiledocDomRenderer['default']({ cards: cards });
}, // jshint ignore: line
new RegExp('Card "' + cardName + '" must define `render`'));
});
test('throws if given an object of cards', function (assert) {
var cards = {};
assert.throws(function () {
new _mobiledocDomRenderer['default']({ cards: cards });
}, // jshint ignore: line
new RegExp('`cards` must be passed as an array'));
});
test('renders an empty mobiledoc', function (assert) {

@@ -61,5 +191,8 @@ var mobiledoc = {

};
var rendered = renderer.render(mobiledoc);
assert.ok(rendered, 'renders output');
var _renderer$render = renderer.render(mobiledoc);
var rendered = _renderer$render.result;
assert.ok(!!rendered, 'renders result');
assert.equal(rendered.childNodes.length, 0, 'has no sections');

@@ -75,3 +208,5 @@ });

};
var rendered = renderer.render(mobiledoc);
var renderResult = renderer.render(mobiledoc);
var rendered = renderResult.result;
assert.equal(rendered.childNodes.length, 1, 'renders 1 section');

@@ -89,3 +224,7 @@ assert.equal(rendered.childNodes[0].tagName, 'P', 'renders a P');

};
var rendered = renderer.render(mobiledoc);
var _renderer$render2 = renderer.render(mobiledoc);
var rendered = _renderer$render2.result;
assert.equal(rendered.childNodes.length, 1, 'renders 1 section');

@@ -104,3 +243,7 @@ var sectionEl = rendered.childNodes[0];

};
var rendered = renderer.render(mobiledoc);
var _renderer$render3 = renderer.render(mobiledoc);
var rendered = _renderer$render3.result;
assert.equal(rendered.childNodes.length, 1, 'renders 1 section');

@@ -123,3 +266,7 @@ var sectionEl = rendered.childNodes[0];

};
var rendered = renderer.render(mobiledoc);
var _renderer$render4 = renderer.render(mobiledoc);
var rendered = _renderer$render4.result;
assert.equal(rendered.childNodes.length, 1, 'renders 1 section');

@@ -132,3 +279,2 @@ var sectionEl = rendered.childNodes[0];

test('renders a mobiledoc with image section', function (assert) {
var url = "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=";
var mobiledoc = {

@@ -138,29 +284,39 @@ version: MOBILEDOC_VERSION,

[// sections
[2, url]]]
[2, dataUri]]]
};
var rendered = renderer.render(mobiledoc);
var _renderer$render5 = renderer.render(mobiledoc);
var rendered = _renderer$render5.result;
assert.equal(rendered.childNodes.length, 1, 'renders 1 section');
var sectionEl = rendered.childNodes[0];
assert.equal(sectionEl.src, url);
assert.equal(sectionEl.src, dataUri);
});
test('renders a mobiledoc with card section', function (assert) {
assert.expect(4);
assert.expect(7);
var cardName = 'title-card';
var payload = {
name: 'bob'
};
var options = {
cardOptions: { foo: 'bar' }
};
var expectedOptions = options.cardOptions;
var expectedPayload = { name: 'bob' };
var expectedOptions = { foo: 'bar' };
var TitleCard = {
name: cardName,
display: {
setup: function setup(element, options, env, setupPayload) {
assert.deepEqual(payload, setupPayload);
assert.deepEqual(options, expectedOptions);
element.innerHTML = setupPayload.name;
}
type: 'dom',
render: function render(_ref2) {
var env = _ref2.env;
var options = _ref2.options;
var payload = _ref2.payload;
var name = env.name;
var isInEditor = env.isInEditor;
var onTeardown = env.onTeardown;
assert.equal(name, cardName, 'has name');
assert.ok(!isInEditor, 'not isInEditor');
assert.ok(!!onTeardown, 'has onTeardown');
assert.deepEqual(options, expectedOptions);
assert.deepEqual(payload, expectedPayload);
return document.createTextNode(payload.name);
}

@@ -172,56 +328,78 @@ };

[// sections
[10, cardName, payload]]]
[10, cardName, expectedPayload]]]
};
var cards = _defineProperty({}, cardName, TitleCard);
var element = document.createElement('div');
var rendered = renderer.render(mobiledoc, element, cards, options);
renderer = new _mobiledocDomRenderer['default']({ cards: [TitleCard], cardOptions: expectedOptions });
var _renderer$render6 = renderer.render(mobiledoc);
var rendered = _renderer$render6.result;
assert.equal(rendered.childNodes.length, 1, 'renders 1 section');
var sectionEl = rendered.childNodes[0];
assert.equal(sectionEl.innerHTML, payload.name);
assert.equal(sectionEl.innerHTML, expectedPayload.name);
});
test('renders a mobiledoc with card section and no payload', function (assert) {
assert.expect(3);
var cardName = 'title-card';
var TitleCard = {
name: cardName,
display: {
setup: function setup(element, options, env, setupPayload) {
assert.deepEqual({}, setupPayload);
element.innerHTML = '';
}
}
};
test('renderResult.teardown removes rendered sections from dom', function (assert) {
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], // markers
[// sections
[10, cardName]]]
sections: [[], [[1, 'p', [[[], 0, 'Hello world']]]]]
};
var rendered = renderer.render(mobiledoc, document.createElement('div'), _defineProperty({}, cardName, TitleCard));
var _renderer$render7 = renderer.render(mobiledoc);
var rendered = _renderer$render7.result;
var teardown = _renderer$render7.teardown;
assert.equal(rendered.childNodes.length, 1, 'renders 1 section');
var sectionEl = rendered.childNodes[0];
assert.equal(sectionEl.innerHTML, '');
var fixture = document.getElementById('qunit-fixture');
fixture.appendChild(rendered);
assert.ok(fixture.childNodes.length === 1, 'precond - result is appended');
teardown();
assert.ok(fixture.childNodes.length === 0, 'rendered result removed after teardown');
});
test('when passed an array of cards, throws', function (assert) {
test('card can register teardown hook', function (assert) {
var cardName = 'title-card';
var didTeardown = false;
var card = {
name: cardName,
type: 'dom',
render: function render(_ref3) {
var env = _ref3.env;
env.onTeardown(function () {
return didTeardown = true;
});
}
};
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], []]
sections: [[], [[10, cardName]]]
};
var cards = [{ name: 'test-card' }];
var element = document.createElement('div');
assert.throws(function () {
renderer.render(mobiledoc, element, cards);
}, /cards.*must be passed as an object/);
renderer = new _mobiledocDomRenderer['default']({ cards: [card] });
var _renderer$render8 = renderer.render(mobiledoc);
var teardown = _renderer$render8.teardown;
assert.ok(!didTeardown, 'teardown not called');
teardown();
assert.ok(didTeardown, 'teardown called');
});
test('renders a mobiledoc with default image section', function (assert) {
test('renders a mobiledoc with default image card', function (assert) {
assert.expect(3);
var cardName = 'image';
var payload = {
src: 'http://example.org/foo.jpg'
src: dataUri
};

@@ -234,3 +412,7 @@ var mobiledoc = {

};
var rendered = renderer.render(mobiledoc, document.createElement('div'));
var _renderer$render9 = renderer.render(mobiledoc);
var rendered = _renderer$render9.result;
assert.equal(rendered.childNodes.length, 1, 'renders 1 section');

@@ -240,3 +422,3 @@ var sectionEl = rendered.childNodes[0];

assert.equal(sectionEl.firstChild.tagName, 'IMG');
assert.equal(sectionEl.firstChild.src, 'http://example.org/foo.jpg');
assert.equal(sectionEl.firstChild.src, dataUri);
});

@@ -249,3 +431,7 @@

};
var rendered = renderer.render(mobiledoc, document.createElement('div'));
var _renderer$render10 = renderer.render(mobiledoc, document.createElement('div'));
var rendered = _renderer$render10.result;
assert.equal(rendered.childNodes.length, 1, 'renders 1 section');

@@ -284,5 +470,9 @@

var nbsp = ' ';
var sn = ' ' + nbsp;
var expectedText = [repeat(sn, 2), 'some', repeat(sn, 2), ' ', 'text', repeat(sn, 3)].join('');
var rendered = renderer.render(mobiledoc);
var sn = space + nbsp;
var expectedText = [repeat(sn, 2), 'some', repeat(sn, 2), space, 'text', repeat(sn, 3)].join('');
var _renderer$render11 = renderer.render(mobiledoc);
var rendered = _renderer$render11.result;
var textNode = rendered.firstChild.firstChild;

@@ -293,13 +483,15 @@ assert.equal(textNode.textContent, expectedText, 'renders the text');

test('rendering nested mobiledocs in cards', function (assert) {
var renderer = new _mobiledocDomRenderer['default']();
var cards = [{
name: 'nested-card',
type: 'dom',
render: function render(_ref4) {
var payload = _ref4.payload;
var cards = {
'nested-card': {
display: {
setup: function setup(element, options, env, payload) {
renderer.render(payload.mobiledoc, element, cards);
}
}
var _renderer$render12 = renderer.render(payload.mobiledoc);
var rendered = _renderer$render12.result;
return rendered;
}
};
}];

@@ -320,3 +512,8 @@ var innerMobiledoc = {

var rendered = renderer.render(mobiledoc, document.createElement('div'), cards);
var renderer = new _mobiledocDomRenderer['default']({ cards: cards });
var _renderer$render13 = renderer.render(mobiledoc);
var rendered = _renderer$render13.result;
assert.equal(rendered.childNodes.length, 1, 'renders 1 section');

@@ -323,0 +520,0 @@ var card = rendered.childNodes[0];

@@ -1,19 +0,12 @@

import {
createElement,
appendChild
} from '../utils/dom';
import { createElement } from '../utils/dom';
import RENDER_TYPE from '../utils/render-type';
const ImageCard = {
export default {
name: 'image',
display: {
setup(element, options, env, payload) {
if (payload.src) {
let img = createElement('img');
img.src = payload.src;
appendChild(element, img);
}
}
type: RENDER_TYPE,
render({payload}) {
let img = createElement('img');
img.src = payload.src;
return img;
}
};
export default ImageCard;

@@ -1,7 +0,10 @@

import Renderer from './renderer';
import RendererFactory from './renderer-factory';
import RENDER_TYPE from './utils/render-type';
export { RENDER_TYPE };
export function registerGlobal(window) {
window.MobiledocDOMRenderer = Renderer;
window.MobiledocDOMRenderer = RendererFactory;
}
export default Renderer;
export default RendererFactory;
import {
createElement,
appendChild,
removeChild,
createTextNode,
setAttribute
setAttribute,
createDocumentFragment
} from './utils/dom';
import ImageCard from './cards/image';
import RENDER_TYPE from './utils/render-type';

@@ -14,10 +17,2 @@ const MARKUP_SECTION_TYPE = 1;

/**
* runtime DOM renderer
* renders a mobiledoc to DOM
*
* input: mobiledoc
* output: DOM
*/
function createElementFromMarkerType([tagName, attributes]=['', []]){

@@ -35,116 +30,187 @@ let element = createElement(tagName);

function renderMarkersOnElement(element, markers, renderState) {
let elements = [element];
let currentElement = element;
function validateVersion(version) {
if (version !== '0.2.0') {
throw new Error(`Unexpected Mobiledoc version "${version}"`);
}
}
for (let i=0, l=markers.length; i<l; i++) {
let marker = markers[i];
let [openTypes, closeTypes, text] = marker;
export default class Renderer {
constructor(mobiledoc, state) {
let { cards, cardOptions, atoms, unknownCardHandler } = state;
let { version, sections: sectionData } = mobiledoc;
validateVersion(version);
for (let j=0, m=openTypes.length; j<m; j++) {
let markerType = renderState.markerTypes[openTypes[j]];
let openedElement = createElementFromMarkerType(markerType);
appendChild(currentElement, openedElement);
elements.push(openedElement);
currentElement = openedElement;
const [markerTypes, sections] = sectionData;
this.root = createDocumentFragment();
this.markerTypes = markerTypes;
this.sections = sections;
this.cards = cards;
this.atoms = atoms;
this.cardOptions = cardOptions;
this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;
this._teardownCallbacks = [];
this._renderedChildNodes = [];
}
get _defaultUnknownCardHandler() {
return ({env: {name}}) => {
throw new Error(`Card "${name}" not found but no unknownCardHandler was registered`);
};
}
render() {
this.sections.forEach(section => {
appendChild(this.root, this.renderSection(section));
});
// maintain a reference to child nodes so they can be cleaned up later by teardown
this._renderedChildNodes = Array.prototype.slice.call(this.root.childNodes);
return { result: this.root, teardown: () => this.teardown() };
}
teardown() {
for (let i=0; i < this._teardownCallbacks.length; i++) {
this._teardownCallbacks[i]();
}
for (let i=0; i < this._renderedChildNodes.length; i++) {
let node = this._renderedChildNodes[i];
if (node.parentNode) {
removeChild(node.parentNode, node);
}
}
}
appendChild(currentElement, createTextNode(text));
renderSection(section) {
const [type] = section;
switch (type) {
case MARKUP_SECTION_TYPE:
return this.renderMarkupSection(section);
case IMAGE_SECTION_TYPE:
return this.renderImageSection(section);
case LIST_SECTION_TYPE:
return this.renderListSection(section);
case CARD_SECTION_TYPE:
return this.renderCardSection(section);
default:
throw new Error(`Cannot render mobiledoc section of type "${type}"`);
}
}
for (let j=0, m=closeTypes; j<m; j++) {
elements.pop();
currentElement = elements[elements.length - 1];
renderMarkersOnElement(element, markers) {
let elements = [element];
let currentElement = element;
for (let i=0, l=markers.length; i<l; i++) {
let marker = markers[i];
let [openTypes, closeTypes, text] = marker;
for (let j=0, m=openTypes.length; j<m; j++) {
let markerType = this.markerTypes[openTypes[j]];
let openedElement = createElementFromMarkerType(markerType);
appendChild(currentElement, openedElement);
elements.push(openedElement);
currentElement = openedElement;
}
appendChild(currentElement, createTextNode(text));
for (let j=0, m=closeTypes; j<m; j++) {
elements.pop();
currentElement = elements[elements.length - 1];
}
}
}
}
function renderListItem(markers, renderState) {
const element = createElement('li');
renderMarkersOnElement(element, markers, renderState);
return element;
}
renderListItem(markers) {
const element = createElement('li');
this.renderMarkersOnElement(element, markers);
return element;
}
function renderListSection([type, tagName, listItems], renderState) {
const element = createElement(tagName);
listItems.forEach(li => {
appendChild(element, (renderListItem(li, renderState)));
});
return element;
}
renderListSection([type, tagName, listItems]) {
const element = createElement(tagName);
listItems.forEach(li => {
appendChild(element, (this.renderListItem(li)));
});
return element;
}
function renderImageSection([type, src]) {
let element = createElement('img');
element.src = src;
return element;
}
renderImageSection([type, src]) {
let element = createElement('img');
element.src = src;
return element;
}
function renderCardSection([type, name, payload], renderState) {
let { cards } = renderState;
let card = cards[name];
if (!card) {
throw new Error(`Cannot render unknown card named ${name}`);
findCard(name) {
for (let i=0; i < this.cards.length; i++) {
if (this.cards[i].name === name) {
return this.cards[i];
}
}
if (name === ImageCard.name) {
return ImageCard;
}
return this._createUnknownCard(name);
}
if (!payload) {
payload = {};
_createUnknownCard(name) {
return {
name,
type: RENDER_TYPE,
render: this.unknownCardHandler
};
}
let element = createElement('div');
let cardOptions = renderState.options.cardOptions || {};
card.display.setup(element, cardOptions, {name}, payload);
return element;
}
function renderMarkupSection([type, tagName, markers], renderState) {
const element = createElement(tagName);
renderMarkersOnElement(element, markers, renderState);
return element;
}
_createCardArgument(card, payload={}) {
let env = {
name: card.name,
isInEditor: false,
onTeardown: (callback) => this._registerTeardownCallback(callback)
};
function renderSection(section, renderState) {
const [type] = section;
switch (type) {
case MARKUP_SECTION_TYPE:
return renderMarkupSection(section, renderState);
case IMAGE_SECTION_TYPE:
return renderImageSection(section, renderState);
case LIST_SECTION_TYPE:
return renderListSection(section, renderState);
case CARD_SECTION_TYPE:
return renderCardSection(section, renderState);
default:
throw new Error('Unimplement renderer for type ' + type);
let options = this.cardOptions;
return { env, options, payload };
}
}
function validateVersion(version) {
if (version !== '0.2.0') {
throw new Error(`Unexpected Mobiledoc version "${version}"`);
_registerTeardownCallback(callback) {
this._teardownCallbacks.push(callback);
}
}
export default class Renderer {
/**
* @param {Mobiledoc} mobiledoc
* @param {DOMNode} [rootElement] defaults to an empty div
* @param {Object} [cards] Each top-level property on the object is considered
* to be a card's name, its value is an object with `setup` and (optional) `teardown`
* properties
* @return DOMNode
*/
render({version, sections: sectionData}, root=createElement('div'), cards={}, options={}) {
validateVersion(version);
const [markerTypes, sections] = sectionData;
cards.image = cards.image || ImageCard;
const renderState = {root, markerTypes, cards, options};
renderCardSection([type, name, payload]) {
let card = this.findCard(name);
if (Array.isArray(cards)) {
throw new Error('`cards` must be passed as an object, not an array.');
let cardWrapper = this._createCardElement();
let cardArg = this._createCardArgument(card, payload);
let rendered = card.render(cardArg);
this._validateCardRender(rendered, card.name);
if (rendered) {
appendChild(cardWrapper, rendered);
}
return cardWrapper;
}
sections.forEach(section => {
let rendered = renderSection(section, renderState);
appendChild(renderState.root, rendered);
});
_createCardElement() {
return createElement('div');
}
return root;
_validateCardRender(rendered, cardName) {
if (!rendered) {
return;
}
if (typeof rendered !== 'object') {
throw new Error(`Card "${cardName}" must render ${RENDER_TYPE}, but result was "${rendered}"`);
}
}
renderMarkupSection([type, tagName, markers]) {
const element = createElement(tagName);
this.renderMarkersOnElement(element, markers);
return element;
}
}

@@ -9,2 +9,6 @@ export function createElement(tagName) {

export function removeChild(target, child) {
target.removeChild(child);
}
function addHTMLSpaces(text) {

@@ -22,1 +26,5 @@ let nbsp = '\u00A0';

}
export function createDocumentFragment() {
return document.createDocumentFragment();
}
{
"name": "mobiledoc-dom-renderer",
"version": "0.1.18",
"version": "0.2.0",
"description": "Renders Mobiledoc input to DOM output",

@@ -5,0 +5,0 @@ "scripts": {

## Mobiledoc DOM Renderer [![Build Status](https://travis-ci.org/bustlelabs/mobiledoc-dom-renderer.svg?branch=master)](https://travis-ci.org/bustlelabs/mobiledoc-dom-renderer)
This is a DOM renderer for the [Mobiledoc](https://github.com/bustlelabs/content-kit-editor/blob/master/MOBILEDOC.md) format used
This is a DOM renderer for the [Mobiledoc](https://github.com/bustlelabs/mobiledoc-kit/blob/master/MOBILEDOC.md) format used
by [Mobiledoc-Kit](https://github.com/bustlelabs/mobiledoc-kit).

@@ -12,3 +12,3 @@

var mobiledoc = {
version: "0.1",
version: "0.2.0",
sections: [

@@ -30,6 +30,6 @@ [ // markers

};
var renderer = new MobiledocDOMRenderer();
var cards = {};
var rendered = renderer.render(mobiledoc, document.createElement('div'), cards);
document.getElementById('output').appendChild(rendered);
var renderer = new MobiledocDOMRenderer({cards: []});
var rendered = renderer.render(mobiledoc);
var result = rendered.result;
document.getElementById('output').appendChild(result);
// renders <div><p><b>hello world</b></b></div>

@@ -39,2 +39,11 @@ // into 'output' element

The Renderer constructor accepts a single object with the following optional properties:
* `cards`: An array of card objects
* `cardOptions`: Options to pass to cards when they are rendered
* `unknownCardHandler`: A method that will be called when any unknown card is enountered
The return value from `renderer.render(mobiledoc)` is an object with two properties:
* `result` The rendered result. A DOMNode
* `teardown` A teardown method that, when called, will tear down the rendered mobiledoc and call any teardown handlers that were registered by cards in the mobiledoc.
### Tests

@@ -41,0 +50,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc