{"version":3,"sources":["mobiledoc-dom-renderer/cards/image.js","mobiledoc-dom-renderer/index.js","mobiledoc-dom-renderer/renderer-factory.js","mobiledoc-dom-renderer/renderers/0-2.js","mobiledoc-dom-renderer/renderers/0-3.js","mobiledoc-dom-renderer/utils/array-utils.js","mobiledoc-dom-renderer/utils/dom.js","mobiledoc-dom-renderer/utils/marker-types.js","mobiledoc-dom-renderer/utils/render-type.js","mobiledoc-dom-renderer/utils/render-utils.js","mobiledoc-dom-renderer/utils/sanitization-utils.js","mobiledoc-dom-renderer/utils/section-types.js","mobiledoc-dom-renderer/utils/tag-names.js","mobiledoc-kit/cards/image.js","mobiledoc-kit/editor/edit-history.js","mobiledoc-kit/editor/edit-state.js","mobiledoc-kit/editor/editor.js","mobiledoc-kit/editor/event-manager.js","mobiledoc-kit/editor/key-commands.js","mobiledoc-kit/editor/mutation-handler.js","mobiledoc-kit/editor/post.js","mobiledoc-kit/editor/post/post-inserter.js","mobiledoc-kit/editor/selection-change-observer.js","mobiledoc-kit/editor/selection-manager.js","mobiledoc-kit/editor/text-input-handler.js","mobiledoc-kit/editor/text-input-handlers.js","mobiledoc-kit/editor/ui.js","mobiledoc-kit/index.js","mobiledoc-kit/models/_attributable.js","mobiledoc-kit/models/_markerable.js","mobiledoc-kit/models/_section.js","mobiledoc-kit/models/atom-node.js","mobiledoc-kit/models/atom.js","mobiledoc-kit/models/card-node.js","mobiledoc-kit/models/card.js","mobiledoc-kit/models/image.js","mobiledoc-kit/models/lifecycle-callbacks.js","mobiledoc-kit/models/list-item.js","mobiledoc-kit/models/list-section.js","mobiledoc-kit/models/marker.js","mobiledoc-kit/models/markup-section.js","mobiledoc-kit/models/markup.js","mobiledoc-kit/models/post-node-builder.js","mobiledoc-kit/models/post.js","mobiledoc-kit/models/render-node.js","mobiledoc-kit/models/render-tree.js","mobiledoc-kit/models/types.js","mobiledoc-kit/parsers/dom.js","mobiledoc-kit/parsers/html.js","mobiledoc-kit/parsers/mobiledoc/0-2.js","mobiledoc-kit/parsers/mobiledoc/0-3-1.js","mobiledoc-kit/parsers/mobiledoc/0-3-2.js","mobiledoc-kit/parsers/mobiledoc/0-3.js","mobiledoc-kit/parsers/mobiledoc/index.js","mobiledoc-kit/parsers/section.js","mobiledoc-kit/parsers/text.js","mobiledoc-kit/renderers/editor-dom.js","mobiledoc-kit/renderers/mobiledoc/0-2.js","mobiledoc-kit/renderers/mobiledoc/0-3-1.js","mobiledoc-kit/renderers/mobiledoc/0-3-2.js","mobiledoc-kit/renderers/mobiledoc/0-3.js","mobiledoc-kit/renderers/mobiledoc/index.js","mobiledoc-kit/utils/array-utils.js","mobiledoc-kit/utils/assert.js","mobiledoc-kit/utils/browser.js","mobiledoc-kit/utils/characters.js","mobiledoc-kit/utils/compiler.js","mobiledoc-kit/utils/copy.js","mobiledoc-kit/utils/cursor.js","mobiledoc-kit/utils/cursor/position.js","mobiledoc-kit/utils/cursor/range.js","mobiledoc-kit/utils/deprecate.js","mobiledoc-kit/utils/dom-utils.js","mobiledoc-kit/utils/element-map.js","mobiledoc-kit/utils/element-utils.js","mobiledoc-kit/utils/environment.js","mobiledoc-kit/utils/fixed-queue.js","mobiledoc-kit/utils/key.js","mobiledoc-kit/utils/keycodes.js","mobiledoc-kit/utils/keys.js","mobiledoc-kit/utils/linked-item.js","mobiledoc-kit/utils/linked-list.js","mobiledoc-kit/utils/log-manager.js","mobiledoc-kit/utils/markuperable.js","mobiledoc-kit/utils/merge.js","mobiledoc-kit/utils/mixin.js","mobiledoc-kit/utils/mobiledoc-error.js","mobiledoc-kit/utils/object-utils.js","mobiledoc-kit/utils/parse-utils.js","mobiledoc-kit/utils/placeholder-image-src.js","mobiledoc-kit/utils/selection-utils.js","mobiledoc-kit/utils/set.js","mobiledoc-kit/utils/string-utils.js","mobiledoc-kit/utils/to-range.js","mobiledoc-kit/version.js","mobiledoc-kit/views/tooltip.js","mobiledoc-kit/views/view.js","mobiledoc-text-renderer/cards/image.js","mobiledoc-text-renderer/index.js","mobiledoc-text-renderer/renderer-factory.js","mobiledoc-text-renderer/renderers/0-2.js","mobiledoc-text-renderer/renderers/0-3.js","mobiledoc-text-renderer/utils/marker-types.js","mobiledoc-text-renderer/utils/render-type.js","mobiledoc-text-renderer/utils/section-types.js"],"sourcesContent":["define('mobiledoc-dom-renderer/cards/image', ['exports', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererUtilsRenderType) {\n 'use strict';\n\n exports['default'] = {\n name: 'image',\n type: _mobiledocDomRendererUtilsRenderType['default'],\n render: function render(_ref) {\n var payload = _ref.payload;\n var dom = _ref.env.dom;\n\n var img = dom.createElement('img');\n img.src = payload.src;\n return img;\n }\n };\n});","define('mobiledoc-dom-renderer', ['exports', 'mobiledoc-dom-renderer/renderer-factory', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererRendererFactory, _mobiledocDomRendererUtilsRenderType) {\n 'use strict';\n\n exports.registerGlobal = registerGlobal;\n exports.RENDER_TYPE = _mobiledocDomRendererUtilsRenderType['default'];\n\n function registerGlobal(window) {\n window.MobiledocDOMRenderer = _mobiledocDomRendererRendererFactory['default'];\n }\n\n exports['default'] = _mobiledocDomRendererRendererFactory['default'];\n});","define('mobiledoc-dom-renderer/renderer-factory', ['exports', 'mobiledoc-dom-renderer/renderers/0-2', 'mobiledoc-dom-renderer/renderers/0-3', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererRenderers02, _mobiledocDomRendererRenderers03, _mobiledocDomRendererUtilsRenderType) {\n 'use strict';\n\n 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; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * runtime DOM renderer\n * renders a mobiledoc to DOM\n *\n * input: mobiledoc\n * output: DOM\n */\n\n function validateCards(cards) {\n if (!Array.isArray(cards)) {\n throw new Error('`cards` must be passed as an array');\n }\n for (var i = 0; i < cards.length; i++) {\n var card = cards[i];\n if (card.type !== _mobiledocDomRendererUtilsRenderType['default']) {\n throw new Error('Card \"' + card.name + '\" must be of type \"' + _mobiledocDomRendererUtilsRenderType['default'] + '\", was \"' + card.type + '\"');\n }\n if (!card.render) {\n throw new Error('Card \"' + card.name + '\" must define `render`');\n }\n }\n }\n\n function validateAtoms(atoms) {\n if (!Array.isArray(atoms)) {\n throw new Error('`atoms` must be passed as an array');\n }\n for (var i = 0; i < atoms.length; i++) {\n var atom = atoms[i];\n if (atom.type !== _mobiledocDomRendererUtilsRenderType['default']) {\n throw new Error('Atom \"' + atom.name + '\" must be type \"' + _mobiledocDomRendererUtilsRenderType['default'] + '\", was \"' + atom.type + '\"');\n }\n if (!atom.render) {\n throw new Error('Atom \"' + atom.name + '\" must define `render`');\n }\n }\n }\n\n var RendererFactory = (function () {\n function RendererFactory() {\n var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n var _ref$cards = _ref.cards;\n var cards = _ref$cards === undefined ? [] : _ref$cards;\n var _ref$atoms = _ref.atoms;\n var atoms = _ref$atoms === undefined ? [] : _ref$atoms;\n var _ref$cardOptions = _ref.cardOptions;\n var cardOptions = _ref$cardOptions === undefined ? {} : _ref$cardOptions;\n var unknownCardHandler = _ref.unknownCardHandler;\n var unknownAtomHandler = _ref.unknownAtomHandler;\n var _ref$markupElementRenderer = _ref.markupElementRenderer;\n var markupElementRenderer = _ref$markupElementRenderer === undefined ? {} : _ref$markupElementRenderer;\n var _ref$sectionElementRenderer = _ref.sectionElementRenderer;\n var sectionElementRenderer = _ref$sectionElementRenderer === undefined ? {} : _ref$sectionElementRenderer;\n var dom = _ref.dom;\n var _ref$markupSanitizer = _ref.markupSanitizer;\n var markupSanitizer = _ref$markupSanitizer === undefined ? null : _ref$markupSanitizer;\n\n _classCallCheck(this, RendererFactory);\n\n validateCards(cards);\n validateAtoms(atoms);\n\n if (!dom) {\n if (typeof window === 'undefined') {\n throw new Error('A `dom` option must be provided to the renderer when running without window.document');\n }\n dom = window.document;\n }\n\n this.options = {\n cards: cards,\n atoms: atoms,\n cardOptions: cardOptions,\n unknownCardHandler: unknownCardHandler,\n unknownAtomHandler: unknownAtomHandler,\n markupElementRenderer: markupElementRenderer,\n sectionElementRenderer: sectionElementRenderer,\n dom: dom,\n markupSanitizer: markupSanitizer\n };\n }\n\n _createClass(RendererFactory, [{\n key: 'render',\n value: function render(mobiledoc) {\n var version = mobiledoc.version;\n\n switch (version) {\n case _mobiledocDomRendererRenderers02.MOBILEDOC_VERSION:\n case undefined:\n case null:\n return new _mobiledocDomRendererRenderers02['default'](mobiledoc, this.options).render();\n case _mobiledocDomRendererRenderers03.MOBILEDOC_VERSION_0_3_0:\n case _mobiledocDomRendererRenderers03.MOBILEDOC_VERSION_0_3_1:\n case _mobiledocDomRendererRenderers03.MOBILEDOC_VERSION_0_3_2:\n return new _mobiledocDomRendererRenderers03['default'](mobiledoc, this.options).render();\n default:\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n }]);\n\n return RendererFactory;\n })();\n\n exports['default'] = RendererFactory;\n});","define('mobiledoc-dom-renderer/renderers/0-2', ['exports', 'mobiledoc-dom-renderer/utils/dom', 'mobiledoc-dom-renderer/cards/image', 'mobiledoc-dom-renderer/utils/render-type', 'mobiledoc-dom-renderer/utils/section-types', 'mobiledoc-dom-renderer/utils/tag-names', 'mobiledoc-dom-renderer/utils/sanitization-utils', 'mobiledoc-dom-renderer/utils/render-utils'], function (exports, _mobiledocDomRendererUtilsDom, _mobiledocDomRendererCardsImage, _mobiledocDomRendererUtilsRenderType, _mobiledocDomRendererUtilsSectionTypes, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils, _mobiledocDomRendererUtilsRenderUtils) {\n 'use strict';\n\n 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'); } }; })();\n\n 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; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var MOBILEDOC_VERSION = '0.2.0';\n\n exports.MOBILEDOC_VERSION = MOBILEDOC_VERSION;\n var IMAGE_SECTION_TAG_NAME = 'img';\n\n function validateVersion(version) {\n if (version !== MOBILEDOC_VERSION) {\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n\n var Renderer = (function () {\n function Renderer(mobiledoc, options) {\n var _this = this;\n\n _classCallCheck(this, Renderer);\n\n var cards = options.cards;\n var cardOptions = options.cardOptions;\n var unknownCardHandler = options.unknownCardHandler;\n var markupElementRenderer = options.markupElementRenderer;\n var sectionElementRenderer = options.sectionElementRenderer;\n var dom = options.dom;\n var version = mobiledoc.version;\n var sectionData = mobiledoc.sections;\n\n validateVersion(version);\n\n var _sectionData = _slicedToArray(sectionData, 2);\n\n var markerTypes = _sectionData[0];\n var sections = _sectionData[1];\n\n this.dom = dom;\n this.root = dom.createDocumentFragment();\n this.markerTypes = markerTypes;\n this.sections = sections;\n this.cards = cards;\n this.cardOptions = cardOptions;\n this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;\n\n this.sectionElementRenderer = {\n '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultSectionElementRenderer\n };\n Object.keys(sectionElementRenderer).forEach(function (key) {\n _this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key];\n });\n\n this.markupElementRenderer = {\n '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultMarkupElementRenderer\n };\n Object.keys(markupElementRenderer).forEach(function (key) {\n _this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key];\n });\n\n this._renderCallbacks = [];\n this._teardownCallbacks = [];\n this._renderedChildNodes = [];\n }\n\n _createClass(Renderer, [{\n key: 'render',\n value: function render() {\n var _this2 = this;\n\n this.sections.forEach(function (section) {\n var rendered = _this2.renderSection(section);\n if (rendered) {\n _this2.root.appendChild(rendered);\n }\n });\n for (var i = 0; i < this._renderCallbacks.length; i++) {\n this._renderCallbacks[i]();\n }\n // maintain a reference to child nodes so they can be cleaned up later by teardown\n this._renderedChildNodes = [];\n var node = this.root.firstChild;\n while (node) {\n this._renderedChildNodes.push(node);\n node = node.nextSibling;\n }\n return { result: this.root, teardown: function teardown() {\n return _this2.teardown();\n } };\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n for (var i = 0; i < this._teardownCallbacks.length; i++) {\n this._teardownCallbacks[i]();\n }\n for (var i = 0; i < this._renderedChildNodes.length; i++) {\n var node = this._renderedChildNodes[i];\n if (node.parentNode) {\n node.parentNode.removeChild(node);\n }\n }\n }\n }, {\n key: 'renderSection',\n value: function renderSection(section) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n return this.renderMarkupSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.IMAGE_SECTION_TYPE:\n return this.renderImageSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n return this.renderListSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE:\n return this.renderCardSection(section);\n default:\n throw new Error('Cannot render mobiledoc section of type \"' + type + '\"');\n }\n }\n }, {\n key: 'renderMarkersOnElement',\n value: function renderMarkersOnElement(element, markers) {\n var elements = [element];\n var currentElement = element;\n\n var pushElement = function pushElement(openedElement) {\n currentElement.appendChild(openedElement);\n elements.push(openedElement);\n currentElement = openedElement;\n };\n\n for (var i = 0, l = markers.length; i < l; i++) {\n var marker = markers[i];\n\n var _marker = _slicedToArray(marker, 3);\n\n var openTypes = _marker[0];\n var closeCount = _marker[1];\n var text = _marker[2];\n\n for (var j = 0, m = openTypes.length; j < m; j++) {\n var markerType = this.markerTypes[openTypes[j]];\n\n var _markerType = _slicedToArray(markerType, 2);\n\n var tagName = _markerType[0];\n var _markerType$1 = _markerType[1];\n var attrs = _markerType$1 === undefined ? [] : _markerType$1;\n\n if ((0, _mobiledocDomRendererUtilsTagNames.isValidMarkerType)(tagName)) {\n pushElement(this.renderMarkupElement(tagName, attrs));\n } else {\n closeCount--;\n }\n }\n\n currentElement.appendChild((0, _mobiledocDomRendererUtilsDom.createTextNode)(this.dom, text));\n\n for (var j = 0, m = closeCount; j < m; j++) {\n elements.pop();\n currentElement = elements[elements.length - 1];\n }\n }\n }\n\n /**\n * @param attrs Array\n */\n }, {\n key: 'renderMarkupElement',\n value: function renderMarkupElement(tagName, attrs) {\n tagName = tagName.toLowerCase();\n attrs = (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAttributes)(attrs);\n\n var renderer = this.markupElementRendererFor(tagName);\n return renderer(tagName, this.dom, attrs);\n }\n }, {\n key: 'markupElementRendererFor',\n value: function markupElementRendererFor(tagName) {\n return this.markupElementRenderer[tagName] || this.markupElementRenderer.__default__;\n }\n }, {\n key: 'renderListItem',\n value: function renderListItem(markers) {\n var element = this.dom.createElement('li');\n this.renderMarkersOnElement(element, markers);\n return element;\n }\n }, {\n key: 'renderListSection',\n value: function renderListSection(_ref) {\n var _this3 = this;\n\n var _ref2 = _slicedToArray(_ref, 3);\n\n var type = _ref2[0];\n var tagName = _ref2[1];\n var listItems = _ref2[2];\n\n if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE)) {\n return;\n }\n var element = this.dom.createElement(tagName);\n listItems.forEach(function (li) {\n element.appendChild(_this3.renderListItem(li));\n });\n return element;\n }\n }, {\n key: 'renderImageSection',\n value: function renderImageSection(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var type = _ref32[0];\n var src = _ref32[1];\n\n var element = this.dom.createElement(IMAGE_SECTION_TAG_NAME);\n element.src = src;\n return element;\n }\n }, {\n key: 'findCard',\n value: function findCard(name) {\n for (var i = 0; i < this.cards.length; i++) {\n if (this.cards[i].name === name) {\n return this.cards[i];\n }\n }\n if (name === _mobiledocDomRendererCardsImage['default'].name) {\n return _mobiledocDomRendererCardsImage['default'];\n }\n return this._createUnknownCard(name);\n }\n }, {\n key: '_createUnknownCard',\n value: function _createUnknownCard(name) {\n return {\n name: name,\n type: _mobiledocDomRendererUtilsRenderType['default'],\n render: this.unknownCardHandler\n };\n }\n }, {\n key: '_createCardArgument',\n value: function _createCardArgument(card) {\n var _this4 = this;\n\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var env = {\n name: card.name,\n isInEditor: false,\n dom: this.dom,\n didRender: function didRender(callback) {\n return _this4._registerRenderCallback(callback);\n },\n onTeardown: function onTeardown(callback) {\n return _this4._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, payload: payload };\n }\n }, {\n key: '_registerRenderCallback',\n value: function _registerRenderCallback(callback) {\n this._renderCallbacks.push(callback);\n }\n }, {\n key: '_registerTeardownCallback',\n value: function _registerTeardownCallback(callback) {\n this._teardownCallbacks.push(callback);\n }\n }, {\n key: 'renderCardSection',\n value: function renderCardSection(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 3);\n\n var type = _ref42[0];\n var name = _ref42[1];\n var payload = _ref42[2];\n\n var card = this.findCard(name);\n\n var cardArg = this._createCardArgument(card, payload);\n var rendered = card.render(cardArg);\n\n this._validateCardRender(rendered, card.name);\n\n return rendered;\n }\n }, {\n key: '_validateCardRender',\n value: function _validateCardRender(rendered, cardName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'object') {\n throw new Error('Card \"' + cardName + '\" must render ' + _mobiledocDomRendererUtilsRenderType['default'] + ', but result was \"' + rendered + '\"');\n }\n }\n }, {\n key: 'renderMarkupSection',\n value: function renderMarkupSection(_ref5) {\n var _ref52 = _slicedToArray(_ref5, 3);\n\n var type = _ref52[0];\n var tagName = _ref52[1];\n var markers = _ref52[2];\n\n tagName = tagName.toLowerCase();\n if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE)) {\n return;\n }\n\n var renderer = this.sectionElementRendererFor(tagName);\n var element = renderer(tagName, this.dom);\n\n this.renderMarkersOnElement(element, markers);\n return element;\n }\n }, {\n key: 'sectionElementRendererFor',\n value: function sectionElementRendererFor(tagName) {\n return this.sectionElementRenderer[tagName] || this.sectionElementRenderer.__default__;\n }\n }, {\n key: '_defaultUnknownCardHandler',\n get: function get() {\n return function (_ref6) {\n var name = _ref6.env.name;\n\n throw new Error('Card \"' + name + '\" not found but no unknownCardHandler was registered');\n };\n }\n }]);\n\n return Renderer;\n })();\n\n exports['default'] = Renderer;\n});","define('mobiledoc-dom-renderer/renderers/0-3', ['exports', 'mobiledoc-dom-renderer/utils/dom', 'mobiledoc-dom-renderer/cards/image', 'mobiledoc-dom-renderer/utils/render-type', 'mobiledoc-dom-renderer/utils/section-types', 'mobiledoc-dom-renderer/utils/tag-names', 'mobiledoc-dom-renderer/utils/sanitization-utils', 'mobiledoc-dom-renderer/utils/render-utils', 'mobiledoc-dom-renderer/utils/marker-types'], function (exports, _mobiledocDomRendererUtilsDom, _mobiledocDomRendererCardsImage, _mobiledocDomRendererUtilsRenderType, _mobiledocDomRendererUtilsSectionTypes, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils, _mobiledocDomRendererUtilsRenderUtils, _mobiledocDomRendererUtilsMarkerTypes) {\n 'use strict';\n\n 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'); } }; })();\n\n 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; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n var MOBILEDOC_VERSION_0_3_0 = '0.3.0';\n exports.MOBILEDOC_VERSION_0_3_0 = MOBILEDOC_VERSION_0_3_0;\n var MOBILEDOC_VERSION_0_3_1 = '0.3.1';\n exports.MOBILEDOC_VERSION_0_3_1 = MOBILEDOC_VERSION_0_3_1;\n var MOBILEDOC_VERSION_0_3_2 = '0.3.2';\n\n exports.MOBILEDOC_VERSION_0_3_2 = MOBILEDOC_VERSION_0_3_2;\n var IMAGE_SECTION_TAG_NAME = 'img';\n\n function validateVersion(version) {\n switch (version) {\n case MOBILEDOC_VERSION_0_3_0:\n case MOBILEDOC_VERSION_0_3_1:\n case MOBILEDOC_VERSION_0_3_2:\n return;\n default:\n throw new Error('Unexpected Mobiledoc version \"' + version + '\"');\n }\n }\n\n var Renderer = (function () {\n function Renderer(mobiledoc, state) {\n var _this = this;\n\n _classCallCheck(this, Renderer);\n\n var cards = state.cards;\n var cardOptions = state.cardOptions;\n var atoms = state.atoms;\n var unknownCardHandler = state.unknownCardHandler;\n var unknownAtomHandler = state.unknownAtomHandler;\n var markupElementRenderer = state.markupElementRenderer;\n var sectionElementRenderer = state.sectionElementRenderer;\n var dom = state.dom;\n var version = mobiledoc.version;\n var sections = mobiledoc.sections;\n var atomTypes = mobiledoc.atoms;\n var cardTypes = mobiledoc.cards;\n var markerTypes = mobiledoc.markups;\n\n validateVersion(version);\n\n this.dom = dom;\n this.root = this.dom.createDocumentFragment();\n this.sections = sections;\n this.atomTypes = atomTypes;\n this.cardTypes = cardTypes;\n this.markerTypes = markerTypes;\n this.cards = cards;\n this.atoms = atoms;\n this.cardOptions = cardOptions;\n this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler;\n this.unknownAtomHandler = unknownAtomHandler || this._defaultUnknownAtomHandler;\n\n this.sectionElementRenderer = {\n '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultSectionElementRenderer\n };\n Object.keys(sectionElementRenderer).forEach(function (key) {\n _this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key];\n });\n\n this.markupElementRenderer = {\n '__default__': _mobiledocDomRendererUtilsRenderUtils.defaultMarkupElementRenderer\n };\n Object.keys(markupElementRenderer).forEach(function (key) {\n _this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key];\n });\n\n this._renderCallbacks = [];\n this._teardownCallbacks = [];\n }\n\n _createClass(Renderer, [{\n key: 'render',\n value: function render() {\n var _this2 = this;\n\n this.sections.forEach(function (section) {\n var rendered = _this2.renderSection(section);\n if (rendered) {\n _this2.root.appendChild(rendered);\n }\n });\n for (var i = 0; i < this._renderCallbacks.length; i++) {\n this._renderCallbacks[i]();\n }\n // maintain a reference to child nodes so they can be cleaned up later by teardown\n this._renderedChildNodes = Array.prototype.slice.call(this.root.childNodes);\n return { result: this.root, teardown: function teardown() {\n return _this2.teardown();\n } };\n }\n }, {\n key: 'teardown',\n value: function teardown() {\n for (var i = 0; i < this._teardownCallbacks.length; i++) {\n this._teardownCallbacks[i]();\n }\n for (var i = 0; i < this._renderedChildNodes.length; i++) {\n var node = this._renderedChildNodes[i];\n if (node.parentNode) {\n node.parentNode.removeChild(node);\n }\n }\n }\n }, {\n key: 'renderSection',\n value: function renderSection(section) {\n var _section = _slicedToArray(section, 1);\n\n var type = _section[0];\n\n switch (type) {\n case _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n return this.renderMarkupSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.IMAGE_SECTION_TYPE:\n return this.renderImageSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n return this.renderListSection(section);\n case _mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE:\n return this.renderCardSection(section);\n default:\n throw new Error('Cannot render mobiledoc section of type \"' + type + '\"');\n }\n }\n }, {\n key: 'renderMarkersOnElement',\n value: function renderMarkersOnElement(element, markers) {\n var elements = [element];\n var currentElement = element;\n\n var pushElement = function pushElement(openedElement) {\n currentElement.appendChild(openedElement);\n elements.push(openedElement);\n currentElement = openedElement;\n };\n\n for (var i = 0, l = markers.length; i < l; i++) {\n var marker = markers[i];\n\n var _marker = _slicedToArray(marker, 4);\n\n var type = _marker[0];\n var openTypes = _marker[1];\n var closeCount = _marker[2];\n var value = _marker[3];\n\n for (var j = 0, m = openTypes.length; j < m; j++) {\n var markerType = this.markerTypes[openTypes[j]];\n\n var _markerType = _slicedToArray(markerType, 2);\n\n var tagName = _markerType[0];\n var _markerType$1 = _markerType[1];\n var attrs = _markerType$1 === undefined ? [] : _markerType$1;\n\n if ((0, _mobiledocDomRendererUtilsTagNames.isValidMarkerType)(tagName)) {\n pushElement(this.renderMarkupElement(tagName, attrs));\n } else {\n closeCount--;\n }\n }\n\n switch (type) {\n case _mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE:\n currentElement.appendChild((0, _mobiledocDomRendererUtilsDom.createTextNode)(this.dom, value));\n break;\n case _mobiledocDomRendererUtilsMarkerTypes.ATOM_MARKER_TYPE:\n currentElement.appendChild(this._renderAtom(value));\n break;\n default:\n throw new Error('Unknown markup type (' + type + ')');\n }\n\n for (var j = 0, m = closeCount; j < m; j++) {\n elements.pop();\n currentElement = elements[elements.length - 1];\n }\n }\n }\n\n /**\n * @param attrs Array\n */\n }, {\n key: 'renderMarkupElement',\n value: function renderMarkupElement(tagName, attrs) {\n tagName = tagName.toLowerCase();\n attrs = (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAttributes)(attrs);\n\n var renderer = this.markupElementRendererFor(tagName);\n return renderer(tagName, this.dom, attrs);\n }\n }, {\n key: 'markupElementRendererFor',\n value: function markupElementRendererFor(tagName) {\n return this.markupElementRenderer[tagName] || this.markupElementRenderer.__default__;\n }\n }, {\n key: 'renderListItem',\n value: function renderListItem(markers) {\n var element = this.dom.createElement('li');\n this.renderMarkersOnElement(element, markers);\n return element;\n }\n }, {\n key: 'renderListSection',\n value: function renderListSection(_ref) {\n var _this3 = this;\n\n var _ref2 = _slicedToArray(_ref, 3);\n\n var type = _ref2[0];\n var tagName = _ref2[1];\n var listItems = _ref2[2];\n\n if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE)) {\n return;\n }\n var element = this.dom.createElement(tagName);\n listItems.forEach(function (li) {\n element.appendChild(_this3.renderListItem(li));\n });\n return element;\n }\n }, {\n key: 'renderImageSection',\n value: function renderImageSection(_ref3) {\n var _ref32 = _slicedToArray(_ref3, 2);\n\n var type = _ref32[0];\n var src = _ref32[1];\n\n var element = this.dom.createElement(IMAGE_SECTION_TAG_NAME);\n element.src = src;\n return element;\n }\n }, {\n key: 'findCard',\n value: function findCard(name) {\n for (var i = 0; i < this.cards.length; i++) {\n if (this.cards[i].name === name) {\n return this.cards[i];\n }\n }\n if (name === _mobiledocDomRendererCardsImage['default'].name) {\n return _mobiledocDomRendererCardsImage['default'];\n }\n return this._createUnknownCard(name);\n }\n }, {\n key: '_findCardByIndex',\n value: function _findCardByIndex(index) {\n var cardType = this.cardTypes[index];\n if (!cardType) {\n throw new Error('No card definition found at index ' + index);\n }\n\n var _cardType = _slicedToArray(cardType, 2);\n\n var name = _cardType[0];\n var payload = _cardType[1];\n\n var card = this.findCard(name);\n\n return {\n card: card,\n payload: payload\n };\n }\n }, {\n key: '_createUnknownCard',\n value: function _createUnknownCard(name) {\n return {\n name: name,\n type: _mobiledocDomRendererUtilsRenderType['default'],\n render: this.unknownCardHandler\n };\n }\n }, {\n key: '_createCardArgument',\n value: function _createCardArgument(card) {\n var _this4 = this;\n\n var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var env = {\n name: card.name,\n isInEditor: false,\n dom: this.dom,\n didRender: function didRender(callback) {\n return _this4._registerRenderCallback(callback);\n },\n onTeardown: function onTeardown(callback) {\n return _this4._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, payload: payload };\n }\n }, {\n key: '_registerTeardownCallback',\n value: function _registerTeardownCallback(callback) {\n this._teardownCallbacks.push(callback);\n }\n }, {\n key: '_registerRenderCallback',\n value: function _registerRenderCallback(callback) {\n this._renderCallbacks.push(callback);\n }\n }, {\n key: 'renderCardSection',\n value: function renderCardSection(_ref4) {\n var _ref42 = _slicedToArray(_ref4, 2);\n\n var type = _ref42[0];\n var index = _ref42[1];\n\n var _findCardByIndex2 = this._findCardByIndex(index);\n\n var card = _findCardByIndex2.card;\n var payload = _findCardByIndex2.payload;\n\n var cardArg = this._createCardArgument(card, payload);\n var rendered = card.render(cardArg);\n\n this._validateCardRender(rendered, card.name);\n\n return rendered;\n }\n }, {\n key: '_validateCardRender',\n value: function _validateCardRender(rendered, cardName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'object') {\n throw new Error('Card \"' + cardName + '\" must render ' + _mobiledocDomRendererUtilsRenderType['default'] + ', but result was \"' + rendered + '\"');\n }\n }\n }, {\n key: 'findAtom',\n value: function findAtom(name) {\n for (var i = 0; i < this.atoms.length; i++) {\n if (this.atoms[i].name === name) {\n return this.atoms[i];\n }\n }\n return this._createUnknownAtom(name);\n }\n }, {\n key: '_createUnknownAtom',\n value: function _createUnknownAtom(name) {\n return {\n name: name,\n type: _mobiledocDomRendererUtilsRenderType['default'],\n render: this.unknownAtomHandler\n };\n }\n }, {\n key: '_createAtomArgument',\n value: function _createAtomArgument(atom, value, payload) {\n var _this5 = this;\n\n var env = {\n name: atom.name,\n isInEditor: false,\n dom: this.dom,\n onTeardown: function onTeardown(callback) {\n return _this5._registerTeardownCallback(callback);\n }\n };\n\n var options = this.cardOptions;\n\n return { env: env, options: options, value: value, payload: payload };\n }\n }, {\n key: '_validateAtomRender',\n value: function _validateAtomRender(rendered, atomName) {\n if (!rendered) {\n return;\n }\n\n if (typeof rendered !== 'object') {\n throw new Error('Atom \"' + atomName + '\" must render ' + _mobiledocDomRendererUtilsRenderType['default'] + ', but result was \"' + rendered + '\"');\n }\n }\n }, {\n key: '_findAtomByIndex',\n value: function _findAtomByIndex(index) {\n var atomType = this.atomTypes[index];\n if (!atomType) {\n throw new Error('No atom definition found at index ' + index);\n }\n\n var _atomType = _slicedToArray(atomType, 3);\n\n var name = _atomType[0];\n var value = _atomType[1];\n var payload = _atomType[2];\n\n var atom = this.findAtom(name);\n\n return {\n atom: atom,\n value: value,\n payload: payload\n };\n }\n }, {\n key: '_renderAtom',\n value: function _renderAtom(index) {\n var _findAtomByIndex2 = this._findAtomByIndex(index);\n\n var atom = _findAtomByIndex2.atom;\n var value = _findAtomByIndex2.value;\n var payload = _findAtomByIndex2.payload;\n\n var atomArg = this._createAtomArgument(atom, value, payload);\n var rendered = atom.render(atomArg);\n\n this._validateAtomRender(rendered, atom.name);\n\n return rendered || (0, _mobiledocDomRendererUtilsDom.createTextNode)(this.dom, '');\n }\n }, {\n key: 'renderMarkupSection',\n value: function renderMarkupSection(_ref5) {\n var _ref52 = _slicedToArray(_ref5, 4);\n\n var type = _ref52[0];\n var tagName = _ref52[1];\n var markers = _ref52[2];\n var _ref52$3 = _ref52[3];\n var attributes = _ref52$3 === undefined ? [] : _ref52$3;\n\n tagName = tagName.toLowerCase();\n if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE)) {\n return;\n }\n\n var attrsObj = (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAttributes)(attributes);\n var renderer = this.sectionElementRendererFor(tagName);\n var element = renderer(tagName, this.dom, attrsObj);\n\n this.renderMarkersOnElement(element, markers);\n return element;\n }\n }, {\n key: 'sectionElementRendererFor',\n value: function sectionElementRendererFor(tagName) {\n return this.sectionElementRenderer[tagName] || this.sectionElementRenderer.__default__;\n }\n }, {\n key: '_defaultUnknownCardHandler',\n get: function get() {\n return function (_ref6) {\n var name = _ref6.env.name;\n\n throw new Error('Card \"' + name + '\" not found but no unknownCardHandler was registered');\n };\n }\n }, {\n key: '_defaultUnknownAtomHandler',\n get: function get() {\n return function (_ref7) {\n var name = _ref7.env.name;\n\n throw new Error('Atom \"' + name + '\" not found but no unknownAtomHandler was registered');\n };\n }\n }]);\n\n return Renderer;\n })();\n\n exports['default'] = Renderer;\n});","define(\"mobiledoc-dom-renderer/utils/array-utils\", [\"exports\"], function (exports) {\n \"use strict\";\n\n exports.includes = includes;\n exports.kvArrayToObject = kvArrayToObject;\n exports.objectToSortedKVArray = objectToSortedKVArray;\n\n function includes(array, detectValue) {\n for (var i = 0; i < array.length; i++) {\n var value = array[i];\n if (value === detectValue) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @param {Array} array of key1,value1,key2,value2,...\n * @return {Object} {key1:value1, key2:value2, ...}\n * @private\n */\n\n function kvArrayToObject(array) {\n if (!Array.isArray(array)) {\n return {};\n }\n\n var obj = {};\n for (var i = 0; i < array.length; i += 2) {\n var key = array[i];\n var value = array[i + 1];\n\n obj[key] = value;\n }\n return obj;\n }\n\n /**\n * @param {Object} {key1:value1, key2:value2, ...}\n * @return {Array} array of key1,value1,key2,value2,...\n * @private\n */\n\n function objectToSortedKVArray(obj) {\n var keys = Object.keys(obj).sort();\n var result = [];\n keys.forEach(function (k) {\n result.push(k);\n result.push(obj[k]);\n });\n return result;\n }\n});","define('mobiledoc-dom-renderer/utils/dom', ['exports'], function (exports) {\n 'use strict';\n\n exports.createTextNode = createTextNode;\n exports.normalizeTagName = normalizeTagName;\n function addHTMLSpaces(text) {\n var nbsp = ' ';\n return text.replace(/ /g, ' ' + nbsp);\n }\n\n function createTextNode(dom, text) {\n return dom.createTextNode(addHTMLSpaces(text));\n }\n\n function normalizeTagName(tagName) {\n return tagName.toLowerCase();\n }\n});","define(\"mobiledoc-dom-renderer/utils/marker-types\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var MARKUP_MARKER_TYPE = 0;\n exports.MARKUP_MARKER_TYPE = MARKUP_MARKER_TYPE;\n var ATOM_MARKER_TYPE = 1;\n exports.ATOM_MARKER_TYPE = ATOM_MARKER_TYPE;\n});","define('mobiledoc-dom-renderer/utils/render-type', ['exports'], function (exports) {\n 'use strict';\n\n exports['default'] = 'dom';\n});","define('mobiledoc-dom-renderer/utils/render-utils', ['exports', 'mobiledoc-dom-renderer/utils/tag-names', 'mobiledoc-dom-renderer/utils/sanitization-utils'], function (exports, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils) {\n 'use strict';\n\n exports.defaultSectionElementRenderer = defaultSectionElementRenderer;\n exports.defaultMarkupElementRenderer = defaultMarkupElementRenderer;\n var VALID_ATTRIBUTES = ['data-md-text-align'];\n\n exports.VALID_ATTRIBUTES = VALID_ATTRIBUTES;\n function _isValidAttribute(attr) {\n return VALID_ATTRIBUTES.indexOf(attr) !== -1;\n }\n\n function handleMarkupSectionAttribute(element, attributeKey, attributeValue) {\n if (!_isValidAttribute(attributeKey)) {\n throw new Error('Cannot use attribute: ' + attributeKey);\n }\n\n element.setAttribute(attributeKey, attributeValue);\n }\n\n function defaultSectionElementRenderer(tagName, dom) {\n var attrsObj = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n var element = undefined;\n if ((0, _mobiledocDomRendererUtilsTagNames.isMarkupSectionElementName)(tagName)) {\n element = dom.createElement(tagName);\n\n Object.keys(attrsObj).forEach(function (k) {\n handleMarkupSectionAttribute(element, k, attrsObj[k]);\n });\n } else {\n element = dom.createElement('div');\n element.setAttribute('class', tagName);\n }\n\n return element;\n }\n\n function sanitizeAttribute(tagName, attrName, attrValue) {\n if (tagName === 'a' && attrName === 'href') {\n return (0, _mobiledocDomRendererUtilsSanitizationUtils.sanitizeHref)(attrValue);\n } else {\n return attrValue;\n }\n }\n\n function defaultMarkupElementRenderer(tagName, dom, attrsObj) {\n var element = dom.createElement(tagName);\n Object.keys(attrsObj).forEach(function (attrName) {\n var attrValue = attrsObj[attrName];\n attrValue = sanitizeAttribute(tagName, attrName, attrValue);\n element.setAttribute(attrName, attrValue);\n });\n return element;\n }\n});","define('mobiledoc-dom-renderer/utils/sanitization-utils', ['exports', 'mobiledoc-dom-renderer/utils/array-utils'], function (exports, _mobiledocDomRendererUtilsArrayUtils) {\n 'use strict';\n\n exports.sanitizeHref = sanitizeHref;\n exports.reduceAttributes = reduceAttributes;\n\n var PROTOCOL_REGEXP = /^([a-z0-9.+-]+:)/i;\n\n var badProtocols = ['javascript:', // jshint ignore:line\n 'vbscript:' // jshint ignore:line\n ];\n\n function getProtocol(url) {\n var matches = url && url.match(PROTOCOL_REGEXP);\n var protocol = matches && matches[0] || ':';\n return protocol;\n }\n\n function sanitizeHref(url) {\n var protocol = getProtocol(url).toLowerCase();\n if ((0, _mobiledocDomRendererUtilsArrayUtils.includes)(badProtocols, protocol)) {\n return 'unsafe:' + url;\n }\n return url;\n }\n\n /**\n * @param attributes array\n * @return obj with normalized attribute names (lowercased)\n */\n\n function reduceAttributes(attributes) {\n var obj = {};\n for (var i = 0; i < attributes.length; i += 2) {\n var key = attributes[i];\n var val = attributes[i + 1];\n obj[key.toLowerCase()] = val;\n }\n return obj;\n }\n});","define(\"mobiledoc-dom-renderer/utils/section-types\", [\"exports\"], function (exports) {\n \"use strict\";\n\n var MARKUP_SECTION_TYPE = 1;\n exports.MARKUP_SECTION_TYPE = MARKUP_SECTION_TYPE;\n var IMAGE_SECTION_TYPE = 2;\n exports.IMAGE_SECTION_TYPE = IMAGE_SECTION_TYPE;\n var LIST_SECTION_TYPE = 3;\n exports.LIST_SECTION_TYPE = LIST_SECTION_TYPE;\n var CARD_SECTION_TYPE = 10;\n exports.CARD_SECTION_TYPE = CARD_SECTION_TYPE;\n});","define('mobiledoc-dom-renderer/utils/tag-names', ['exports', 'mobiledoc-dom-renderer/utils/section-types', 'mobiledoc-dom-renderer/utils/dom'], function (exports, _mobiledocDomRendererUtilsSectionTypes, _mobiledocDomRendererUtilsDom) {\n 'use strict';\n\n exports.isValidSectionTagName = isValidSectionTagName;\n exports.isMarkupSectionElementName = isMarkupSectionElementName;\n exports.isValidMarkerType = isValidMarkerType;\n\n var MARKUP_SECTION_TAG_NAMES = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'pull-quote', 'aside'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n var MARKUP_SECTION_ELEMENT_NAMES = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'aside'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n var LIST_SECTION_TAG_NAMES = ['ul', 'ol'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n var MARKUP_TYPES = ['b', 'i', 'strong', 'em', 'a', 'u', 'sub', 'sup', 's', 'code'].map(_mobiledocDomRendererUtilsDom.normalizeTagName);\n\n function contains(array, item) {\n return array.indexOf(item) !== -1;\n }\n\n function isValidSectionTagName(tagName, sectionType) {\n tagName = (0, _mobiledocDomRendererUtilsDom.normalizeTagName)(tagName);\n\n switch (sectionType) {\n case _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE:\n return contains(MARKUP_SECTION_TAG_NAMES, tagName);\n case _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE:\n return contains(LIST_SECTION_TAG_NAMES, tagName);\n default:\n throw new Error('Cannot validate tagName for unknown section type \"' + sectionType + '\"');\n }\n }\n\n function isMarkupSectionElementName(tagName) {\n tagName = (0, _mobiledocDomRendererUtilsDom.normalizeTagName)(tagName);\n return contains(MARKUP_SECTION_ELEMENT_NAMES, tagName);\n }\n\n function isValidMarkerType(type) {\n type = (0, _mobiledocDomRendererUtilsDom.normalizeTagName)(type);\n return contains(MARKUP_TYPES, type);\n }\n});","define('mobiledoc-kit/cards/image', ['exports', 'mobiledoc-kit/utils/placeholder-image-src'], function (exports, _mobiledocKitUtilsPlaceholderImageSrc) {\n 'use strict';\n\n exports['default'] = {\n name: 'image',\n type: 'dom',\n\n render: function render(_ref) {\n var payload = _ref.payload;\n\n var img = document.createElement('img');\n img.src = payload.src || _mobiledocKitUtilsPlaceholderImageSrc['default'];\n return img;\n }\n };\n});","define('mobiledoc-kit/editor/edit-history', ['exports', 'mobiledoc-kit/parsers/mobiledoc', 'mobiledoc-kit/utils/fixed-queue'], function (exports, _mobiledocKitParsersMobiledoc, _mobiledocKitUtilsFixedQueue) {\n 'use strict';\n\n 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'); } }; })();\n\n 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; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n function findLeafSectionAtIndex(post, index) {\n var section = undefined;\n post.walkAllLeafSections(function (_section, _index) {\n if (index === _index) {\n section = _section;\n }\n });\n return section;\n }\n\n var Snapshot = (function () {\n function Snapshot(takenAt, editor) {\n var editAction = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2];\n\n _classCallCheck(this, Snapshot);\n\n this.mobiledoc = editor.serialize();\n this.editor = editor;\n this.editAction = editAction;\n this.takenAt = takenAt;\n\n this.snapshotRange();\n }\n\n _createClass(Snapshot, [{\n key: 'snapshotRange',\n value: function snapshotRange() {\n var _editor = this.editor;\n var range = _editor.range;\n var cursor = _editor.cursor;\n\n if (cursor.hasCursor() && !range.isBlank) {\n var head = range.head;\n var tail = range.tail;\n\n this.range = {\n head: [head.leafSectionIndex, head.offset],\n tail: [tail.leafSectionIndex, tail.offset]\n };\n }\n }\n }, {\n key: 'getRange',\n value: function getRange(post) {\n if (this.range) {\n var _range = this.range;\n var head = _range.head;\n var tail = _range.tail;\n var _head = head;\n\n var _head2 = _slicedToArray(_head, 2);\n\n var headLeafSectionIndex = _head2[0];\n var headOffset = _head2[1];\n var _tail = tail;\n\n var _tail2 = _slicedToArray(_tail, 2);\n\n var tailLeafSectionIndex = _tail2[0];\n var tailOffset = _tail2[1];\n\n var headSection = findLeafSectionAtIndex(post, headLeafSectionIndex);\n var tailSection = findLeafSectionAtIndex(post, tailLeafSectionIndex);\n\n head = headSection.toPosition(headOffset);\n tail = tailSection.toPosition(tailOffset);\n\n return head.toRange(tail);\n }\n }\n }, {\n key: 'groupsWith',\n value: function groupsWith(groupingTimeout, editAction, takenAt) {\n return editAction !== null && this.editAction === editAction && this.takenAt + groupingTimeout > takenAt;\n }\n }]);\n\n return Snapshot;\n })();\n\n exports.Snapshot = Snapshot;\n\n var EditHistory = (function () {\n function EditHistory(editor, queueLength, groupingTimeout) {\n _classCallCheck(this, EditHistory);\n\n this.editor = editor;\n this._undoStack = new _mobiledocKitUtilsFixedQueue['default'](queueLength);\n this._redoStack = new _mobiledocKitUtilsFixedQueue['default'](queueLength);\n\n this._pendingSnapshot = null;\n this._groupingTimeout = groupingTimeout;\n }\n\n _createClass(EditHistory, [{\n key: 'snapshot',\n value: function snapshot() {\n // update the current snapshot with the range read from DOM\n if (this._pendingSnapshot) {\n this._pendingSnapshot.snapshotRange();\n }\n }\n }, {\n key: 'storeSnapshot',\n value: function storeSnapshot() {\n var editAction = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0];\n\n var now = Date.now();\n // store pending snapshot\n var pendingSnapshot = this._pendingSnapshot;\n if (pendingSnapshot) {\n if (!pendingSnapshot.groupsWith(this._groupingTimeout, editAction, now)) {\n this._undoStack.push(pendingSnapshot);\n }\n this._redoStack.clear();\n }\n\n // take new pending snapshot to store next time `storeSnapshot` is called\n this._pendingSnapshot = new Snapshot(now, this.editor, editAction);\n }\n }, {\n key: 'stepBackward',\n value: function stepBackward(postEditor) {\n // Throw away the pending snapshot\n this._pendingSnapshot = null;\n\n var snapshot = this._undoStack.pop();\n if (snapshot) {\n this._redoStack.push(new Snapshot(Date.now(), this.editor));\n this._restoreFromSnapshot(snapshot, postEditor);\n }\n }\n }, {\n key: 'stepForward',\n value: function stepForward(postEditor) {\n var snapshot = this._redoStack.pop();\n if (snapshot) {\n this._undoStack.push(new Snapshot(Date.now(), this.editor));\n this._restoreFromSnapshot(snapshot, postEditor);\n }\n postEditor.cancelSnapshot();\n }\n }, {\n key: '_restoreFromSnapshot',\n value: function _restoreFromSnapshot(snapshot, postEditor) {\n var mobiledoc = snapshot.mobiledoc;\n var editor = this.editor;\n var builder = editor.builder;\n var post = editor.post;\n\n var restoredPost = _mobiledocKitParsersMobiledoc['default'].parse(builder, mobiledoc);\n\n postEditor.removeAllSections();\n postEditor.migrateSectionsFromPost(restoredPost);\n\n // resurrect snapshotted range if it exists\n var newRange = snapshot.getRange(post);\n if (newRange) {\n postEditor.setRange(newRange);\n }\n }\n }]);\n\n return EditHistory;\n })();\n\n exports['default'] = EditHistory;\n});","define('mobiledoc-kit/editor/edit-state', ['exports', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/cursor/range'], function (exports, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsCursorRange) {\n 'use strict';\n\n 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; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n /**\n * Used by {@link Editor} to manage its current state (cursor, active markups\n * and active sections).\n * @private\n */\n\n var EditState = (function () {\n function EditState(editor) {\n _classCallCheck(this, EditState);\n\n this.editor = editor;\n\n var defaultState = {\n range: _mobiledocKitUtilsCursorRange['default'].blankRange(),\n activeMarkups: [],\n activeSections: [],\n activeSectionTagNames: [],\n activeSectionAttributes: {}\n };\n\n this.prevState = this.state = defaultState;\n }\n\n _createClass(EditState, [{\n key: 'updateRange',\n value: function updateRange(newRange) {\n this.prevState = this.state;\n this.state = this._readState(newRange);\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.editor = null;\n this.prevState = this.state = null;\n }\n\n /**\n * @return {Boolean}\n */\n }, {\n key: 'rangeDidChange',\n value: function rangeDidChange() {\n var range = this.state.range;\n var prevRange = this.prevState.range;\n\n return !prevRange.isEqual(range);\n }\n\n /**\n * @return {Boolean} Whether the input mode (active markups or active section tag names)\n * has changed.\n */\n }, {\n key: 'inputModeDidChange',\n value: function inputModeDidChange() {\n var state = this.state;\n var prevState = this.prevState;\n\n return !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(state.activeMarkups, prevState.activeMarkups) || !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)(state.activeSectionTagNames, prevState.activeSectionTagNames) || !(0, _mobiledocKitUtilsArrayUtils.isArrayEqual)((0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(state.activeSectionAttributes), (0, _mobiledocKitUtilsArrayUtils.objectToSortedKVArray)(prevState.activeSectionAttributes));\n }\n\n /**\n * @return {Range}\n */\n }, {\n key: 'toggleMarkupState',\n\n /**\n * Update the editor's markup state. This is used when, e.g.,\n * a user types meta+B when the editor has a cursor but no selected text;\n * in this case the editor needs to track that it has an active \"b\" markup\n * and apply it to the next text the user types.\n */\n value: function toggleMarkupState(markup) {\n if ((0, _mobiledocKitUtilsArrayUtils.contains)(this.activeMarkups, markup)) {\n this._removeActiveMarkup(markup);\n } else {\n this._addActiveMarkup(markup);\n }\n }\n }, {\n key: '_readState',\n value: function _readState(range) {\n var state = {\n range: range,\n activeMarkups: this._readActiveMarkups(range),\n activeSections: this._readActiveSections(range)\n };\n // Section objects are 'live', so to check that they changed, we\n // need to map their tagNames now (and compare to mapped tagNames later).\n // In addition, to catch changes from ul -> ol, we keep track of the\n // un-nested tag names (otherwise we'd only see li -> li change)\n state.activeSectionTagNames = state.activeSections.map(function (s) {\n return s.isNested ? s.parent.tagName : s.tagName;\n });\n state.activeSectionAttributes = this._readSectionAttributes(state.activeSections);\n return state;\n }\n }, {\n key: '_readActiveSections',\n value: function _readActiveSections(range) {\n var head = range.head;\n var tail = range.tail;\n var post = this.editor.post;\n\n if (range.isBlank) {\n return [];\n } else {\n return post.sections.readRange(head.section, tail.section);\n }\n }\n }, {\n key: '_readActiveMarkups',\n value: function _readActiveMarkups(range) {\n var post = this.editor.post;\n\n return post.markupsInRange(range);\n }\n }, {\n key: '_readSectionAttributes',\n value: function _readSectionAttributes(sections) {\n return sections.reduce(function (sectionAttributes, s) {\n var attributes = s.isNested ? s.parent.attributes : s.attributes;\n Object.keys(attributes || {}).forEach(function (attrName) {\n var camelizedAttrName = attrName.replace(/^data-md-/, '');\n var attrValue = attributes[attrName];\n sectionAttributes[camelizedAttrName] = sectionAttributes[camelizedAttrName] || [];\n if (!(0, _mobiledocKitUtilsArrayUtils.contains)(sectionAttributes[camelizedAttrName], attrValue)) {\n sectionAttributes[camelizedAttrName].push(attrValue);\n }\n });\n return sectionAttributes;\n }, {});\n }\n }, {\n key: '_removeActiveMarkup',\n value: function _removeActiveMarkup(markup) {\n var index = this.state.activeMarkups.indexOf(markup);\n this.state.activeMarkups.splice(index, 1);\n }\n }, {\n key: '_addActiveMarkup',\n value: function _addActiveMarkup(markup) {\n this.state.activeMarkups.push(markup);\n }\n }, {\n key: 'range',\n get: function get() {\n return this.state.range;\n }\n\n /**\n * @return {Section[]}\n */\n }, {\n key: 'activeSections',\n get: function get() {\n return this.state.activeSections;\n }\n\n /**\n * @return {Object}\n */\n }, {\n key: 'activeSectionAttributes',\n get: function get() {\n return this.state.activeSectionAttributes;\n }\n\n /**\n * @return {Markup[]}\n */\n }, {\n key: 'activeMarkups',\n get: function get() {\n return this.state.activeMarkups;\n }\n }]);\n\n return EditState;\n })();\n\n exports['default'] = EditState;\n});","define('mobiledoc-kit/editor/editor', ['exports', 'mobiledoc-kit/views/tooltip', 'mobiledoc-kit/editor/post', 'mobiledoc-kit/cards/image', 'mobiledoc-kit/utils/key', 'mobiledoc-kit/parsers/mobiledoc', 'mobiledoc-kit/parsers/html', 'mobiledoc-kit/parsers/dom', 'mobiledoc-kit/renderers/editor-dom', 'mobiledoc-kit/models/render-tree', 'mobiledoc-kit/renderers/mobiledoc', 'mobiledoc-kit/utils/merge', 'mobiledoc-kit/utils/dom-utils', 'mobiledoc-kit/utils/array-utils', 'mobiledoc-kit/utils/element-utils', 'mobiledoc-kit/utils/cursor', 'mobiledoc-kit/utils/cursor/range', 'mobiledoc-kit/utils/cursor/position', 'mobiledoc-kit/utils/environment', 'mobiledoc-kit/models/post-node-builder', 'mobiledoc-kit/editor/text-input-handlers', 'mobiledoc-kit/editor/key-commands', 'mobiledoc-kit/models/card', 'mobiledoc-kit/utils/assert', 'mobiledoc-kit/editor/mutation-handler', 'mobiledoc-kit/editor/edit-history', 'mobiledoc-kit/editor/event-manager', 'mobiledoc-kit/editor/edit-state', 'mobiledoc-dom-renderer', 'mobiledoc-text-renderer', 'mobiledoc-kit/models/lifecycle-callbacks', 'mobiledoc-kit/utils/log-manager', 'mobiledoc-kit/utils/to-range', 'mobiledoc-kit/utils/mobiledoc-error'], function (exports, _mobiledocKitViewsTooltip, _mobiledocKitEditorPost, _mobiledocKitCardsImage, _mobiledocKitUtilsKey, _mobiledocKitParsersMobiledoc, _mobiledocKitParsersHtml, _mobiledocKitParsersDom, _mobiledocKitRenderersEditorDom, _mobiledocKitModelsRenderTree, _mobiledocKitRenderersMobiledoc, _mobiledocKitUtilsMerge, _mobiledocKitUtilsDomUtils, _mobiledocKitUtilsArrayUtils, _mobiledocKitUtilsElementUtils, _mobiledocKitUtilsCursor, _mobiledocKitUtilsCursorRange, _mobiledocKitUtilsCursorPosition, _mobiledocKitUtilsEnvironment, _mobiledocKitModelsPostNodeBuilder, _mobiledocKitEditorTextInputHandlers, _mobiledocKitEditorKeyCommands, _mobiledocKitModelsCard, _mobiledocKitUtilsAssert, _mobiledocKitEditorMutationHandler, _mobiledocKitEditorEditHistory, _mobiledocKitEditorEventManager, _mobiledocKitEditorEditState, _mobiledocDomRenderer, _mobiledocTextRenderer, _mobiledocKitModelsLifecycleCallbacks, _mobiledocKitUtilsLogManager, _mobiledocKitUtilsToRange, _mobiledocKitUtilsMobiledocError) {\n 'use strict';\n\n 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; }; })();\n\n function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\n // This export may later be deprecated, but re-export it from the renderer here\n // for consumers that may depend on it.\n Object.defineProperty(exports, 'EDITOR_ELEMENT_CLASS_NAME', {\n enumerable: true,\n get: function get() {\n return _mobiledocKitRenderersEditorDom.EDITOR_ELEMENT_CLASS_NAME;\n }\n });\n\n var defaults = {\n placeholder: 'Write here...',\n spellcheck: true,\n autofocus: true,\n showLinkTooltips: true,\n undoDepth: 5,\n undoBlockTimeout: 5000, // ms for an undo event\n cards: [],\n atoms: [],\n cardOptions: {},\n unknownCardHandler: function unknownCardHandler(_ref) {\n var env = _ref.env;\n\n throw new _mobiledocKitUtilsMobiledocError['default']('Unknown card encountered: ' + env.name);\n },\n unknownAtomHandler: function unknownAtomHandler(_ref2) {\n var env = _ref2.env;\n\n throw new _mobiledocKitUtilsMobiledocError['default']('Unknown atom encountered: ' + env.name);\n },\n mobiledoc: null,\n html: null\n };\n\n var CALLBACK_QUEUES = {\n DID_UPDATE: 'didUpdate',\n WILL_RENDER: 'willRender',\n DID_RENDER: 'didRender',\n WILL_DELETE: 'willDelete',\n DID_DELETE: 'didDelete',\n WILL_HANDLE_NEWLINE: 'willHandleNewline',\n CURSOR_DID_CHANGE: 'cursorDidChange',\n DID_REPARSE: 'didReparse',\n POST_DID_CHANGE: 'postDidChange',\n INPUT_MODE_DID_CHANGE: 'inputModeDidChange'\n };\n\n /**\n * The Editor is a core component of mobiledoc-kit. After instantiating\n * an editor, use {@link Editor#render} to display the editor on the web page.\n *\n * An editor uses a {@link Post} internally to represent the displayed document.\n * The post can be serialized as mobiledoc using {@link Editor#serialize}. Mobiledoc\n * is the transportable \"over-the-wire\" format (JSON) that is suited for persisting\n * and sharing between editors and renderers (for display, e.g.), whereas the Post\n * model is better suited for programmatic editing.\n *\n * The editor will call registered callbacks for certain state changes. These are:\n * * {@link Editor#cursorDidChange} -- The cursor position or selection changed.\n * * {@link Editor#postDidChange} -- The contents of the post changed due to user input or\n * programmatic editing. This hook can be used with {@link Editor#serialize}\n * to auto-save a post as it is being edited.\n * * {@link Editor#inputModeDidChange} -- The active section(s) or markup(s) at the current cursor\n * position or selection have changed. This hook can be used with\n * {@link Editor#activeMarkups} and {@link Editor#activeSections} to implement\n * a custom toolbar.\n * * {@link Editor#onTextInput} -- Register callbacks when the user enters text\n * that matches a given string or regex.\n * * {@link Editor#beforeToggleMarkup} -- Register callbacks that will be run before\n * applying changes from {@link Editor#toggleMarkup}\n */\n\n var Editor = (function () {\n /**\n * @param {Object} [options]\n * @param {Object} [options.mobiledoc] The mobiledoc to load into the editor.\n * Supersedes `options.html`.\n * @param {String|DOM} [options.html] The html (as a string or DOM fragment)\n * to parse and load into the editor.\n * Will be ignored if `options.mobiledoc` is also passed.\n * @param {Array} [options.parserPlugins=[]]\n * @param {Array} [options.cards=[]] The cards that the editor may render.\n * @param {Array} [options.atoms=[]] The atoms that the editor may render.\n * @param {Function} [options.unknownCardHandler] Invoked by the editor's renderer\n * whenever it encounters an unknown card.\n * @param {Function} [options.unknownAtomHandler] Invoked by the editor's renderer\n * whenever it encounters an unknown atom.\n * @param {String} [options.placeholder] Default text to show before user starts typing.\n * @param {Boolean} [options.spellcheck=true] Whether to enable spellcheck\n * @param {Boolean} [options.autofocus=true] Whether to focus the editor when it is first rendered.\n * @param {Boolean} [options.showLinkTooltips=true] Whether to show the url tooltip for links\n * @param {number} [options.undoDepth=5] How many undo levels will be available.\n * Set to 0 to disable undo/redo functionality.\n * @return {Editor}\n * @public\n */\n\n function Editor() {\n var _this = this;\n\n var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n\n _classCallCheck(this, Editor);\n\n (0, _mobiledocKitUtilsAssert['default'])('editor create accepts an options object. For legacy usage passing an element for the first argument, consider the `html` option for loading DOM or HTML posts. For other cases call `editor.render(domNode)` after editor creation', options && !options.nodeType);\n this._views = [];\n this.isEditable = true;\n this._parserPlugins = options.parserPlugins || [];\n\n // FIXME: This should merge onto this.options\n (0, _mobiledocKitUtilsMerge.mergeWithOptions)(this, defaults, options);\n this.cards.push(_mobiledocKitCardsImage['default']);\n\n _mobiledocKitEditorKeyCommands.DEFAULT_KEY_COMMANDS.forEach(function (kc) {\n return _this.registerKeyCommand(kc);\n });\n\n this._logManager = new _mobiledocKitUtilsLogManager['default']();\n this._parser = new _mobiledocKitParsersDom['default'](this.builder);\n var cards = this.cards;\n var atoms = this.atoms;\n var unknownCardHandler = this.unknownCardHandler;\n var unknownAtomHandler = this.unknownAtomHandler;\n var cardOptions = this.cardOptions;\n\n this._renderer = new _mobiledocKitRenderersEditorDom['default'](this, cards, atoms, unknownCardHandler, unknownAtomHandler, cardOptions);\n\n this.post = this.loadPost();\n this._renderTree = new _mobiledocKitModelsRenderTree['default'](this.post);\n\n this._editHistory = new _mobiledocKitEditorEditHistory['default'](this, this.undoDepth, this.undoBlockTimeout);\n this._eventManager = new _mobiledocKitEditorEventManager['default'](this);\n this._mutationHandler = new _mobiledocKitEditorMutationHandler['default'](this);\n this._editState = new _mobiledocKitEditorEditState['default'](this);\n this._callbacks = new _mobiledocKitModelsLifecycleCallbacks['default']((0, _mobiledocKitUtilsArrayUtils.values)(CALLBACK_QUEUES));\n this._beforeHooks = { toggleMarkup: [] };\n\n _mobiledocKitEditorTextInputHandlers.DEFAULT_TEXT_INPUT_HANDLERS.forEach(function (handler) {\n return _this.onTextInput(handler);\n });\n\n this.hasRendered = false;\n }\n\n /**\n * Turns on verbose logging for the editor.\n * @param {Array} [logTypes=[]] If present, only the given log types will be logged.\n * @public\n */\n\n _createClass(Editor, [{\n key: 'enableLogging',\n value: function enableLogging() {\n var logTypes = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n if (logTypes.length === 0) {\n this._logManager.enableAll();\n } else {\n this._logManager.enableTypes(logTypes);\n }\n }\n\n /**\n * Disable all logging\n * @public\n */\n }, {\n key: 'disableLogging',\n value: function disableLogging() {\n this._logManager.disable();\n }\n\n /**\n * @private\n */\n }, {\n key: 'loggerFor',\n value: function loggerFor(type) {\n return this._logManager['for'](type);\n }\n\n /**\n * The editor's instance of a post node builder.\n * @type {PostNodeBuilder}\n */\n }, {\n key: 'loadPost',\n value: function loadPost() {\n var mobiledoc = this.mobiledoc;\n var html = this.html;\n\n if (mobiledoc) {\n return _mobiledocKitParsersMobiledoc['default'].parse(this.builder, mobiledoc);\n } else if (html) {\n if (typeof html === 'string') {\n var options = { plugins: this._parserPlugins };\n return new _mobiledocKitParsersHtml['default'](this.builder, options).parse(this.html);\n } else {\n var dom = html;\n return this._parser.parse(dom);\n }\n } else {\n return this.builder.createPost([this.builder.createMarkupSection()]);\n }\n }\n }, {\n key: 'rerender',\n value: function rerender() {\n var _this2 = this;\n\n var postRenderNode = this.post.renderNode;\n\n // if we haven't rendered this post's renderNode before, mark it dirty\n if (!postRenderNode.element) {\n (0, _mobiledocKitUtilsAssert['default'])('Must call `render` before `rerender` can be called', this.hasRendered);\n postRenderNode.element = this.element;\n postRenderNode.markDirty();\n }\n\n this.runCallbacks(CALLBACK_QUEUES.WILL_RENDER);\n this._mutationHandler.suspendObservation(function () {\n _this2._renderer.render(_this2._renderTree);\n });\n this.runCallbacks(CALLBACK_QUEUES.DID_RENDER);\n }\n\n /**\n * @param {Element} element The DOM element to render into.\n * Its contents will be replaced by the editor's rendered post.\n * @public\n */\n }, {\n key: 'render',\n value: function render(element) {\n (0, _mobiledocKitUtilsAssert['default'])('Cannot render an editor twice. Use `rerender` to update the ' + 'rendering of an existing editor instance.', !this.hasRendered);\n\n element.spellcheck = this.spellcheck;\n\n (0, _mobiledocKitUtilsDomUtils.clearChildNodes)(element);\n\n this.element = element;\n\n if (this.showLinkTooltips) {\n this._addTooltip();\n }\n\n // A call to `run` will trigger the didUpdatePostCallbacks hooks with a\n // postEditor.\n this.run(function () {});\n\n // Only set `hasRendered` to true after calling `run` to ensure that\n // no cursorDidChange or other callbacks get fired before the editor is\n // done rendering\n this.hasRendered = true;\n this.rerender();\n\n this._mutationHandler.init();\n this._eventManager.init();\n\n if (this.isEditable === false) {\n this.disableEditing();\n } else {\n this.enableEditing();\n }\n\n if (this.autofocus) {\n this.selectRange(this.post.headPosition());\n }\n }\n }, {\n key: '_addTooltip',\n value: function _addTooltip() {\n this.addView(new _mobiledocKitViewsTooltip['default']({\n rootElement: this.element,\n showForTag: 'a'\n }));\n }\n }, {\n key: 'registerKeyCommand',\n\n /**\n * @param {Object} keyCommand The key command to register. It must specify a\n * modifier key (meta, ctrl, etc), a string representing the ascii key, and\n * a `run` method that will be passed the editor instance when the key command\n * is invoked\n * @public\n */\n value: function registerKeyCommand(rawKeyCommand) {\n var keyCommand = (0, _mobiledocKitEditorKeyCommands.buildKeyCommand)(rawKeyCommand);\n (0, _mobiledocKitUtilsAssert['default'])('Key Command is not valid', (0, _mobiledocKitEditorKeyCommands.validateKeyCommand)(keyCommand));\n this.keyCommands.unshift(keyCommand);\n }\n\n /**\n * @param {String} name If the keyCommand event has a name attribute it can be removed.\n * @public\n */\n }, {\n key: 'unregisterKeyCommands',\n value: function unregisterKeyCommands(name) {\n for (var i = this.keyCommands.length - 1; i > -1; i--) {\n var keyCommand = this.keyCommands[i];\n\n if (keyCommand.name === name) {\n this.keyCommands.splice(i, 1);\n }\n }\n }\n\n /**\n * Convenience for {@link PostEditor#deleteAtPosition}. Deletes and puts the\n * cursor in the new position.\n * @public\n */\n }, {\n key: 'deleteAtPosition',\n value: function deleteAtPosition(position, direction, _ref3) {\n var unit = _ref3.unit;\n\n this.run(function (postEditor) {\n var nextPosition = postEditor.deleteAtPosition(position, direction, { unit: unit });\n postEditor.setRange(nextPosition);\n });\n }\n\n /**\n * Convenience for {@link PostEditor#deleteRange}. Deletes and puts the\n * cursor in the new position.\n * @param {Range} range\n * @public\n */\n }, {\n key: 'deleteRange',\n value: function deleteRange(range) {\n this.run(function (postEditor) {\n var nextPosition = postEditor.deleteRange(range);\n postEditor.setRange(nextPosition);\n });\n }\n\n /**\n * @private\n */\n }, {\n key: 'performDelete',\n value: function performDelete() {\n var _ref4 = arguments.length <= 0 || arguments[0] === undefined ? { direction: _mobiledocKitUtilsKey.DIRECTION.BACKWARD, unit: 'char' } : arguments[0];\n\n var direction = _ref4.direction;\n var unit = _ref4.unit;\n var range = this.range;\n\n this.runCallbacks(CALLBACK_QUEUES.WILL_DELETE, [range, direction, unit]);\n if (range.isCollapsed) {\n this.deleteAtPosition(range.head, direction, { unit: unit });\n } else {\n this.deleteRange(range);\n }\n this.runCallbacks(CALLBACK_QUEUES.DID_DELETE, [range, direction, unit]);\n }\n }, {\n key: 'handleNewline',\n value: function handleNewline(event) {\n var _this3 = this;\n\n if (!this.hasCursor()) {\n return;\n }\n\n event.preventDefault();\n\n var range = this.range;\n\n this.run(function (postEditor) {\n var cursorSection = undefined;\n if (!range.isCollapsed) {\n var nextPosition = postEditor.deleteRange(range);\n cursorSection = nextPosition.section;\n if (cursorSection && cursorSection.isBlank) {\n postEditor.setRange(cursorSection.headPosition());\n return;\n }\n }\n\n // Above logic might delete redundant range, so callback must run after it.\n var defaultPrevented = false;\n var event = { preventDefault: function preventDefault() {\n defaultPrevented = true;\n } };\n _this3.runCallbacks(CALLBACK_QUEUES.WILL_HANDLE_NEWLINE, [event]);\n if (defaultPrevented) {\n return;\n }\n\n cursorSection = postEditor.splitSection(range.head)[1];\n postEditor.setRange(cursorSection.headPosition());\n });\n }\n\n /**\n * Notify the editor that the post did change, and run associated\n * callbacks.\n * @private\n */\n }, {\n key: '_postDidChange',\n value: function _postDidChange() {\n this.runCallbacks(CALLBACK_QUEUES.POST_DID_CHANGE);\n }\n\n /**\n * Selects the given range or position. If given a collapsed range or a position, this positions the cursor\n * at the range's position. Otherwise a selection is created in the editor\n * surface encompassing the range.\n * @param {Range|Position} range\n */\n }, {\n key: 'selectRange',\n value: function selectRange(range) {\n range = (0, _mobiledocKitUtilsToRange['default'])(range);\n\n this.cursor.selectRange(range);\n this.range = range;\n }\n }, {\n key: '_readRangeFromDOM',\n value: function _readRangeFromDOM() {\n this.range = this.cursor.offsets;\n }\n }, {\n key: 'setPlaceholder',\n value: function setPlaceholder(placeholder) {\n (0, _mobiledocKitUtilsElementUtils.setData)(this.element, 'placeholder', placeholder);\n }\n }, {\n key: '_reparsePost',\n value: function _reparsePost() {\n var post = this._parser.parse(this.element);\n this.run(function (postEditor) {\n postEditor.removeAllSections();\n postEditor.migrateSectionsFromPost(post);\n postEditor.setRange(_mobiledocKitUtilsCursorRange['default'].blankRange());\n });\n\n this.runCallbacks(CALLBACK_QUEUES.DID_REPARSE);\n this._postDidChange();\n }\n }, {\n key: '_reparseSections',\n value: function _reparseSections() {\n var _this4 = this;\n\n var sections = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n var currentRange = undefined;\n sections.forEach(function (section) {\n _this4._parser.reparseSection(section, _this4._renderTree);\n });\n this._removeDetachedSections();\n\n if (this._renderTree.isDirty) {\n currentRange = this.range;\n }\n\n // force the current snapshot's range to remain the same rather than\n // rereading it from DOM after the new character is applied and the browser\n // updates the cursor position\n var range = this._editHistory._pendingSnapshot.range;\n this.run(function () {\n _this4._editHistory._pendingSnapshot.range = range;\n });\n this.rerender();\n if (currentRange) {\n this.selectRange(currentRange);\n }\n\n this.runCallbacks(CALLBACK_QUEUES.DID_REPARSE);\n this._postDidChange();\n }\n\n // FIXME this should be able to be removed now -- if any sections are detached,\n // it's due to a bug in the code.\n }, {\n key: '_removeDetachedSections',\n value: function _removeDetachedSections() {\n (0, _mobiledocKitUtilsArrayUtils.forEach)((0, _mobiledocKitUtilsArrayUtils.filter)(this.post.sections, function (s) {\n return !s.renderNode.isAttached();\n }), function (s) {\n return s.renderNode.scheduleForRemoval();\n });\n }\n\n /**\n * The sections from the cursor's selection start to the selection end\n * @type {Section[]}\n */\n }, {\n key: 'detectMarkupInRange',\n value: function detectMarkupInRange(range, markupTagName) {\n var markups = this.post.markupsInRange(range);\n return (0, _mobiledocKitUtilsArrayUtils.detect)(markups, function (markup) {\n return markup.hasTag(markupTagName);\n });\n }\n\n /**\n * @type {Markup[]}\n * @public\n */\n }, {\n key: 'hasActiveMarkup',\n\n /**\n * @param {Markup|String} markup A markup instance, or a string (e.g. \"b\")\n * @return {boolean}\n */\n value: function hasActiveMarkup(markup) {\n var matchesFn = undefined;\n if (typeof markup === 'string') {\n (function () {\n var tagName = (0, _mobiledocKitUtilsDomUtils.normalizeTagName)(markup);\n matchesFn = function (m) {\n return m.tagName === tagName;\n };\n })();\n } else {\n matchesFn = function (m) {\n return m === markup;\n };\n }\n\n return !!(0, _mobiledocKitUtilsArrayUtils.detect)(this.activeMarkups, matchesFn);\n }\n\n /**\n * @param {String} version The mobiledoc version to serialize to.\n * @return {Mobiledoc} Serialized mobiledoc\n * @public\n */\n }, {\n key: 'serialize',\n value: function serialize() {\n var version = arguments.length <= 0 || arguments[0] === undefined ? _mobiledocKitRenderersMobiledoc.MOBILEDOC_VERSION : arguments[0];\n\n return this.serializePost(this.post, 'mobiledoc', { version: version });\n }\n\n /**\n * Serialize the editor's post to the requested format.\n * Note that only mobiledoc format is lossless. If cards or atoms are present\n * in the post, the html and text formats will omit them in output because\n * the editor does not have access to the html and text versions of the\n * cards/atoms.\n * @param {string} format The format to serialize ('mobiledoc', 'text', 'html')\n * @return {Object|String} The editor's post, serialized to {format}\n * @public\n */\n }, {\n key: 'serializeTo',\n value: function serializeTo(format) {\n var post = this.post;\n return this.serializePost(post, format);\n }\n\n /**\n * @param {Post}\n * @param {String} format Same as {serializeTo}\n * @param {Object} [options]\n * @param {String} [options.version=MOBILEDOC_VERSION] version to serialize to\n * @return {Object|String}\n * @private\n */\n }, {\n key: 'serializePost',\n value: function serializePost(post, format) {\n var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n var validFormats = ['mobiledoc', 'html', 'text'];\n (0, _mobiledocKitUtilsAssert['default'])('Unrecognized serialization format ' + format, (0, _mobiledocKitUtilsArrayUtils.contains)(validFormats, format));\n\n if (format === 'mobiledoc') {\n var version = options.version || _mobiledocKitRenderersMobiledoc.MOBILEDOC_VERSION;\n return _mobiledocKitRenderersMobiledoc['default'].render(post, version);\n } else {\n var rendered = undefined;\n var mobiledoc = this.serializePost(post, 'mobiledoc');\n var unknownCardHandler = function unknownCardHandler() {};\n var unknownAtomHandler = function unknownAtomHandler() {};\n var rendererOptions = { unknownCardHandler: unknownCardHandler, unknownAtomHandler: unknownAtomHandler };\n\n switch (format) {\n case 'html':\n {\n var result = undefined;\n if (_mobiledocKitUtilsEnvironment['default'].hasDOM()) {\n rendered = new _mobiledocDomRenderer['default'](rendererOptions).render(mobiledoc);\n result = '
.\n // deals with typical case of
Text
Text