mobiledoc-dom-renderer
Advanced tools
Comparing version 0.6.3 to 0.6.4-0
@@ -0,4 +1,12 @@ | ||
<a name="0.6.4-0"></a> | ||
## 0.6.4-0 (2017-03-06) | ||
* fix(href-sanitization): Accept markupSanitizer option, downcase tagName and attributeName (#50) ([aa1aedc](https://github.com/bustlelabs/mobiledoc-dom-renderer/commit/aa1aedc)), closes [#49](https://github.com/bustlelabs/mobiledoc-dom-renderer/issues/49) [#48](https://github.com/bustlelabs/mobiledoc-dom-renderer/issues/48) | ||
<a name="0.6.3"></a> | ||
## 0.6.3 (2017-02-22) | ||
* 0.6.3 ([a3d94c8](https://github.com/bustlelabs/mobiledoc-dom-renderer/commit/a3d94c8)) | ||
* Revert usage of glimmer/build for building (for now) (#46) ([c23676a](https://github.com/bustlelabs/mobiledoc-dom-renderer/commit/c23676a)) | ||
@@ -5,0 +13,0 @@ |
@@ -78,18 +78,22 @@ define('mobiledoc-dom-renderer/cards/image', ['exports', 'mobiledoc-dom-renderer/utils/render-type'], function (exports, _mobiledocDomRendererUtilsRenderType) { | ||
var cards = _ref.cards; | ||
var atoms = _ref.atoms; | ||
var cardOptions = _ref.cardOptions; | ||
var _ref$cards = _ref.cards; | ||
var cards = _ref$cards === undefined ? [] : _ref$cards; | ||
var _ref$atoms = _ref.atoms; | ||
var atoms = _ref$atoms === undefined ? [] : _ref$atoms; | ||
var _ref$cardOptions = _ref.cardOptions; | ||
var cardOptions = _ref$cardOptions === undefined ? {} : _ref$cardOptions; | ||
var unknownCardHandler = _ref.unknownCardHandler; | ||
var unknownAtomHandler = _ref.unknownAtomHandler; | ||
var markupElementRenderer = _ref.markupElementRenderer; | ||
var sectionElementRenderer = _ref.sectionElementRenderer; | ||
var _ref$markupElementRenderer = _ref.markupElementRenderer; | ||
var markupElementRenderer = _ref$markupElementRenderer === undefined ? {} : _ref$markupElementRenderer; | ||
var _ref$sectionElementRenderer = _ref.sectionElementRenderer; | ||
var sectionElementRenderer = _ref$sectionElementRenderer === undefined ? {} : _ref$sectionElementRenderer; | ||
var dom = _ref.dom; | ||
var _ref$markupSanitizer = _ref.markupSanitizer; | ||
var markupSanitizer = _ref$markupSanitizer === undefined ? null : _ref$markupSanitizer; | ||
_classCallCheck(this, RendererFactory); | ||
cards = cards || []; | ||
validateCards(cards); | ||
atoms = atoms || []; | ||
validateAtoms(atoms); | ||
cardOptions = cardOptions || {}; | ||
@@ -111,3 +115,4 @@ if (!dom) { | ||
sectionElementRenderer: sectionElementRenderer, | ||
dom: dom | ||
dom: dom, | ||
markupSanitizer: markupSanitizer | ||
}; | ||
@@ -140,3 +145,3 @@ } | ||
}); | ||
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'], function (exports, _mobiledocDomRendererUtilsDom, _mobiledocDomRendererCardsImage, _mobiledocDomRendererUtilsRenderType, _mobiledocDomRendererUtilsSectionTypes, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils) { | ||
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) { | ||
'use strict'; | ||
@@ -155,21 +160,2 @@ | ||
function createElementFromMarkerType(dom) { | ||
var _ref = arguments.length <= 1 || arguments[1] === undefined ? ['', []] : arguments[1]; | ||
var _ref2 = _slicedToArray(_ref, 2); | ||
var tagName = _ref2[0]; | ||
var attributes = _ref2[1]; | ||
var element = dom.createElement(tagName); | ||
attributes = attributes || []; | ||
for (var i = 0, l = attributes.length; i < l; i = i + 2) { | ||
var propName = attributes[i], | ||
propValue = attributes[i + 1]; | ||
element.setAttribute(propName, (0, _mobiledocDomRendererUtilsSanitizationUtils.sanitizeAttributeValue)(propName, propValue, tagName)); | ||
} | ||
return element; | ||
} | ||
function validateVersion(version) { | ||
@@ -183,2 +169,4 @@ if (version !== MOBILEDOC_VERSION) { | ||
function Renderer(mobiledoc, options) { | ||
var _this = this; | ||
_classCallCheck(this, Renderer); | ||
@@ -192,2 +180,3 @@ | ||
var dom = options.dom; | ||
var markupSanitizer = options.markupSanitizer; | ||
var version = mobiledoc.version; | ||
@@ -210,20 +199,17 @@ var sectionData = mobiledoc.sections; | ||
this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler; | ||
this.markupSanitizer = (0, _mobiledocDomRendererUtilsRenderUtils.createMarkupSanitizerWithFallback)(markupSanitizer); | ||
this.sectionElementRenderer = {}; | ||
if (sectionElementRenderer) { | ||
for (var key in sectionElementRenderer) { | ||
if (sectionElementRenderer.hasOwnProperty(key)) { | ||
this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key]; | ||
} | ||
} | ||
} | ||
this.sectionElementRenderer = { | ||
'__default__': _mobiledocDomRendererUtilsRenderUtils.defaultSectionElementRenderer | ||
}; | ||
Object.keys(sectionElementRenderer).forEach(function (key) { | ||
_this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key]; | ||
}); | ||
this.markupElementRenderer = {}; | ||
if (markupElementRenderer) { | ||
for (var key in markupElementRenderer) { | ||
if (markupElementRenderer.hasOwnProperty(key)) { | ||
this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key]; | ||
} | ||
} | ||
} | ||
this.markupElementRenderer = { | ||
'__default__': _mobiledocDomRendererUtilsRenderUtils.defaultMarkupElementRenderer | ||
}; | ||
Object.keys(markupElementRenderer).forEach(function (key) { | ||
_this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key]; | ||
}); | ||
@@ -238,8 +224,8 @@ this._renderCallbacks = []; | ||
value: function render() { | ||
var _this = this; | ||
var _this2 = this; | ||
this.sections.forEach(function (section) { | ||
var rendered = _this.renderSection(section); | ||
var rendered = _this2.renderSection(section); | ||
if (rendered) { | ||
_this.root.appendChild(rendered); | ||
_this2.root.appendChild(rendered); | ||
} | ||
@@ -258,3 +244,3 @@ }); | ||
return { result: this.root, teardown: function teardown() { | ||
return _this.teardown(); | ||
return _this2.teardown(); | ||
} }; | ||
@@ -326,11 +312,3 @@ } | ||
if ((0, _mobiledocDomRendererUtilsTagNames.isValidMarkerType)(tagName)) { | ||
var lowerCaseTagName = tagName.toLowerCase(); | ||
if (this.markupElementRenderer[lowerCaseTagName]) { | ||
var attrObj = (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAndSanitizeAttributes)(attrs, lowerCaseTagName); | ||
var openedElement = this.markupElementRenderer[lowerCaseTagName](tagName, this.dom, attrObj); | ||
pushElement(openedElement); | ||
} else { | ||
var openedElement = createElementFromMarkerType(this.dom, markerType); | ||
pushElement(openedElement); | ||
} | ||
pushElement(this.renderMarkupElement(tagName, attrs)); | ||
} else { | ||
@@ -349,3 +327,44 @@ closeCount--; | ||
} | ||
/** | ||
* @param attrs Array | ||
*/ | ||
}, { | ||
key: 'renderMarkupElement', | ||
value: function renderMarkupElement(tagName, attrs) { | ||
tagName = tagName.toLowerCase(); | ||
attrs = this.sanitizeAttributes(tagName, (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAttributes)(attrs)); | ||
var renderer = this.markupElementRendererFor(tagName); | ||
return renderer(tagName, this.dom, attrs); | ||
} | ||
}, { | ||
key: 'markupElementRendererFor', | ||
value: function markupElementRendererFor(tagName) { | ||
return this.markupElementRenderer[tagName] || this.markupElementRenderer.__default__; | ||
} | ||
}, { | ||
key: 'sanitizeAttributes', | ||
value: function sanitizeAttributes(tagName, attrsObj) { | ||
var _this3 = this; | ||
var sanitized = {}; | ||
Object.keys(attrsObj).forEach(function (attributeName) { | ||
var attributeValue = attrsObj[attributeName]; | ||
sanitized[attributeName] = _this3.sanitizeAttribute({ tagName: tagName, attributeName: attributeName, attributeValue: attributeValue }); | ||
}); | ||
return sanitized; | ||
} | ||
}, { | ||
key: 'sanitizeAttribute', | ||
value: function sanitizeAttribute(_ref) { | ||
var tagName = _ref.tagName; | ||
var attributeName = _ref.attributeName; | ||
var attributeValue = _ref.attributeValue; | ||
return this.markupSanitizer({ tagName: tagName, attributeName: attributeName, attributeValue: attributeValue }); | ||
} | ||
}, { | ||
key: 'renderListItem', | ||
@@ -359,10 +378,10 @@ value: function renderListItem(markers) { | ||
key: 'renderListSection', | ||
value: function renderListSection(_ref3) { | ||
var _this2 = this; | ||
value: function renderListSection(_ref2) { | ||
var _this4 = this; | ||
var _ref32 = _slicedToArray(_ref3, 3); | ||
var _ref22 = _slicedToArray(_ref2, 3); | ||
var type = _ref32[0]; | ||
var tagName = _ref32[1]; | ||
var listItems = _ref32[2]; | ||
var type = _ref22[0]; | ||
var tagName = _ref22[1]; | ||
var listItems = _ref22[2]; | ||
@@ -374,3 +393,3 @@ if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE)) { | ||
listItems.forEach(function (li) { | ||
element.appendChild(_this2.renderListItem(li)); | ||
element.appendChild(_this4.renderListItem(li)); | ||
}); | ||
@@ -381,7 +400,7 @@ return element; | ||
key: 'renderImageSection', | ||
value: function renderImageSection(_ref4) { | ||
var _ref42 = _slicedToArray(_ref4, 2); | ||
value: function renderImageSection(_ref3) { | ||
var _ref32 = _slicedToArray(_ref3, 2); | ||
var type = _ref42[0]; | ||
var src = _ref42[1]; | ||
var type = _ref32[0]; | ||
var src = _ref32[1]; | ||
@@ -417,3 +436,3 @@ var element = this.dom.createElement(IMAGE_SECTION_TAG_NAME); | ||
value: function _createCardArgument(card) { | ||
var _this3 = this; | ||
var _this5 = this; | ||
@@ -427,6 +446,6 @@ var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
didRender: function didRender(callback) { | ||
return _this3._registerRenderCallback(callback); | ||
return _this5._registerRenderCallback(callback); | ||
}, | ||
onTeardown: function onTeardown(callback) { | ||
return _this3._registerTeardownCallback(callback); | ||
return _this5._registerTeardownCallback(callback); | ||
} | ||
@@ -451,8 +470,8 @@ }; | ||
key: 'renderCardSection', | ||
value: function renderCardSection(_ref5) { | ||
var _ref52 = _slicedToArray(_ref5, 3); | ||
value: function renderCardSection(_ref4) { | ||
var _ref42 = _slicedToArray(_ref4, 3); | ||
var type = _ref52[0]; | ||
var name = _ref52[1]; | ||
var payload = _ref52[2]; | ||
var type = _ref42[0]; | ||
var name = _ref42[1]; | ||
var payload = _ref42[2]; | ||
@@ -481,9 +500,10 @@ var card = this.findCard(name); | ||
key: 'renderMarkupSection', | ||
value: function renderMarkupSection(_ref6) { | ||
var _ref62 = _slicedToArray(_ref6, 3); | ||
value: function renderMarkupSection(_ref5) { | ||
var _ref52 = _slicedToArray(_ref5, 3); | ||
var type = _ref62[0]; | ||
var tagName = _ref62[1]; | ||
var markers = _ref62[2]; | ||
var type = _ref52[0]; | ||
var tagName = _ref52[1]; | ||
var markers = _ref52[2]; | ||
tagName = tagName.toLowerCase(); | ||
if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE)) { | ||
@@ -493,12 +513,4 @@ return; | ||
var element = undefined; | ||
var lowerCaseTagName = tagName.toLowerCase(); | ||
if (this.sectionElementRenderer[lowerCaseTagName]) { | ||
element = this.sectionElementRenderer[lowerCaseTagName](tagName, this.dom); | ||
} else if ((0, _mobiledocDomRendererUtilsTagNames.isMarkupSectionElementName)(tagName)) { | ||
element = this.dom.createElement(tagName); | ||
} else { | ||
element = this.dom.createElement('div'); | ||
element.setAttribute('class', tagName); | ||
} | ||
var renderer = this.sectionElementRendererFor(tagName); | ||
var element = renderer(tagName, this.dom); | ||
@@ -509,6 +521,11 @@ this.renderMarkersOnElement(element, markers); | ||
}, { | ||
key: 'sectionElementRendererFor', | ||
value: function sectionElementRendererFor(tagName) { | ||
return this.sectionElementRenderer[tagName] || this.sectionElementRenderer.__default__; | ||
} | ||
}, { | ||
key: '_defaultUnknownCardHandler', | ||
get: function get() { | ||
return function (_ref7) { | ||
var name = _ref7.env.name; | ||
return function (_ref6) { | ||
var name = _ref6.env.name; | ||
@@ -525,3 +542,3 @@ throw new Error('Card "' + name + '" not found but no unknownCardHandler was registered'); | ||
}); | ||
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/marker-types'], function (exports, _mobiledocDomRendererUtilsDom, _mobiledocDomRendererCardsImage, _mobiledocDomRendererUtilsRenderType, _mobiledocDomRendererUtilsSectionTypes, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils, _mobiledocDomRendererUtilsMarkerTypes) { | ||
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) { | ||
'use strict'; | ||
@@ -544,24 +561,9 @@ | ||
function createElementFromMarkerType(dom) { | ||
var _ref = arguments.length <= 1 || arguments[1] === undefined ? ['', []] : arguments[1]; | ||
var _ref2 = _slicedToArray(_ref, 2); | ||
var tagName = _ref2[0]; | ||
var attributes = _ref2[1]; | ||
var element = dom.createElement(tagName); | ||
attributes = attributes || []; | ||
for (var i = 0, l = attributes.length; i < l; i = i + 2) { | ||
var propName = attributes[i], | ||
propValue = attributes[i + 1]; | ||
element.setAttribute(propName, (0, _mobiledocDomRendererUtilsSanitizationUtils.sanitizeAttributeValue)(propName, propValue, tagName)); | ||
} | ||
return element; | ||
} | ||
function validateVersion(version) { | ||
if (version !== MOBILEDOC_VERSION_0_3_0 && version !== MOBILEDOC_VERSION_0_3_1) { | ||
throw new Error('Unexpected Mobiledoc version "' + version + '"'); | ||
switch (version) { | ||
case MOBILEDOC_VERSION_0_3_0: | ||
case MOBILEDOC_VERSION_0_3_1: | ||
return; | ||
default: | ||
throw new Error('Unexpected Mobiledoc version "' + version + '"'); | ||
} | ||
@@ -572,2 +574,4 @@ } | ||
function Renderer(mobiledoc, state) { | ||
var _this = this; | ||
_classCallCheck(this, Renderer); | ||
@@ -583,2 +587,3 @@ | ||
var dom = state.dom; | ||
var markupSanitizer = state.markupSanitizer; | ||
var version = mobiledoc.version; | ||
@@ -603,20 +608,17 @@ var sections = mobiledoc.sections; | ||
this.unknownAtomHandler = unknownAtomHandler || this._defaultUnknownAtomHandler; | ||
this.markupSanitizer = (0, _mobiledocDomRendererUtilsRenderUtils.createMarkupSanitizerWithFallback)(markupSanitizer); | ||
this.sectionElementRenderer = {}; | ||
if (sectionElementRenderer) { | ||
for (var key in sectionElementRenderer) { | ||
if (sectionElementRenderer.hasOwnProperty(key)) { | ||
this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key]; | ||
} | ||
} | ||
} | ||
this.sectionElementRenderer = { | ||
'__default__': _mobiledocDomRendererUtilsRenderUtils.defaultSectionElementRenderer | ||
}; | ||
Object.keys(sectionElementRenderer).forEach(function (key) { | ||
_this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key]; | ||
}); | ||
this.markupElementRenderer = {}; | ||
if (markupElementRenderer) { | ||
for (var key in markupElementRenderer) { | ||
if (markupElementRenderer.hasOwnProperty(key)) { | ||
this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key]; | ||
} | ||
} | ||
} | ||
this.markupElementRenderer = { | ||
'__default__': _mobiledocDomRendererUtilsRenderUtils.defaultMarkupElementRenderer | ||
}; | ||
Object.keys(markupElementRenderer).forEach(function (key) { | ||
_this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key]; | ||
}); | ||
@@ -630,8 +632,8 @@ this._renderCallbacks = []; | ||
value: function render() { | ||
var _this = this; | ||
var _this2 = this; | ||
this.sections.forEach(function (section) { | ||
var rendered = _this.renderSection(section); | ||
var rendered = _this2.renderSection(section); | ||
if (rendered) { | ||
_this.root.appendChild(rendered); | ||
_this2.root.appendChild(rendered); | ||
} | ||
@@ -645,3 +647,3 @@ }); | ||
return { result: this.root, teardown: function teardown() { | ||
return _this.teardown(); | ||
return _this2.teardown(); | ||
} }; | ||
@@ -714,11 +716,3 @@ } | ||
if ((0, _mobiledocDomRendererUtilsTagNames.isValidMarkerType)(tagName)) { | ||
var lowerCaseTagName = tagName.toLowerCase(); | ||
if (this.markupElementRenderer[lowerCaseTagName]) { | ||
var attrObj = (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAndSanitizeAttributes)(attrs, lowerCaseTagName); | ||
var openedElement = this.markupElementRenderer[lowerCaseTagName](tagName, this.dom, attrObj); | ||
pushElement(openedElement); | ||
} else { | ||
var openedElement = createElementFromMarkerType(this.dom, markerType); | ||
pushElement(openedElement); | ||
} | ||
pushElement(this.renderMarkupElement(tagName, attrs)); | ||
} else { | ||
@@ -746,3 +740,44 @@ closeCount--; | ||
} | ||
/** | ||
* @param attrs Array | ||
*/ | ||
}, { | ||
key: 'renderMarkupElement', | ||
value: function renderMarkupElement(tagName, attrs) { | ||
tagName = tagName.toLowerCase(); | ||
attrs = this.sanitizeAttributes(tagName, (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAttributes)(attrs)); | ||
var renderer = this.markupElementRendererFor(tagName); | ||
return renderer(tagName, this.dom, attrs); | ||
} | ||
}, { | ||
key: 'markupElementRendererFor', | ||
value: function markupElementRendererFor(tagName) { | ||
return this.markupElementRenderer[tagName] || this.markupElementRenderer.__default__; | ||
} | ||
}, { | ||
key: 'sanitizeAttributes', | ||
value: function sanitizeAttributes(tagName, attrsObj) { | ||
var _this3 = this; | ||
var sanitized = {}; | ||
Object.keys(attrsObj).forEach(function (attributeName) { | ||
var attributeValue = attrsObj[attributeName]; | ||
sanitized[attributeName] = _this3.sanitizeAttribute({ tagName: tagName, attributeName: attributeName, attributeValue: attributeValue }); | ||
}); | ||
return sanitized; | ||
} | ||
}, { | ||
key: 'sanitizeAttribute', | ||
value: function sanitizeAttribute(_ref) { | ||
var tagName = _ref.tagName; | ||
var attributeName = _ref.attributeName; | ||
var attributeValue = _ref.attributeValue; | ||
return this.markupSanitizer({ tagName: tagName, attributeName: attributeName, attributeValue: attributeValue }); | ||
} | ||
}, { | ||
key: 'renderListItem', | ||
@@ -756,10 +791,10 @@ value: function renderListItem(markers) { | ||
key: 'renderListSection', | ||
value: function renderListSection(_ref3) { | ||
var _this2 = this; | ||
value: function renderListSection(_ref2) { | ||
var _this4 = this; | ||
var _ref32 = _slicedToArray(_ref3, 3); | ||
var _ref22 = _slicedToArray(_ref2, 3); | ||
var type = _ref32[0]; | ||
var tagName = _ref32[1]; | ||
var listItems = _ref32[2]; | ||
var type = _ref22[0]; | ||
var tagName = _ref22[1]; | ||
var listItems = _ref22[2]; | ||
@@ -771,3 +806,3 @@ if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE)) { | ||
listItems.forEach(function (li) { | ||
element.appendChild(_this2.renderListItem(li)); | ||
element.appendChild(_this4.renderListItem(li)); | ||
}); | ||
@@ -778,7 +813,7 @@ return element; | ||
key: 'renderImageSection', | ||
value: function renderImageSection(_ref4) { | ||
var _ref42 = _slicedToArray(_ref4, 2); | ||
value: function renderImageSection(_ref3) { | ||
var _ref32 = _slicedToArray(_ref3, 2); | ||
var type = _ref42[0]; | ||
var src = _ref42[1]; | ||
var type = _ref32[0]; | ||
var src = _ref32[1]; | ||
@@ -834,3 +869,3 @@ var element = this.dom.createElement(IMAGE_SECTION_TAG_NAME); | ||
value: function _createCardArgument(card) { | ||
var _this3 = this; | ||
var _this5 = this; | ||
@@ -844,6 +879,6 @@ var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
didRender: function didRender(callback) { | ||
return _this3._registerRenderCallback(callback); | ||
return _this5._registerRenderCallback(callback); | ||
}, | ||
onTeardown: function onTeardown(callback) { | ||
return _this3._registerTeardownCallback(callback); | ||
return _this5._registerTeardownCallback(callback); | ||
} | ||
@@ -868,7 +903,7 @@ }; | ||
key: 'renderCardSection', | ||
value: function renderCardSection(_ref5) { | ||
var _ref52 = _slicedToArray(_ref5, 2); | ||
value: function renderCardSection(_ref4) { | ||
var _ref42 = _slicedToArray(_ref4, 2); | ||
var type = _ref52[0]; | ||
var index = _ref52[1]; | ||
var type = _ref42[0]; | ||
var index = _ref42[1]; | ||
@@ -920,3 +955,3 @@ var _findCardByIndex2 = this._findCardByIndex(index); | ||
value: function _createAtomArgument(atom, value, payload) { | ||
var _this4 = this; | ||
var _this6 = this; | ||
@@ -928,3 +963,3 @@ var env = { | ||
onTeardown: function onTeardown(callback) { | ||
return _this4._registerTeardownCallback(callback); | ||
return _this6._registerTeardownCallback(callback); | ||
} | ||
@@ -988,9 +1023,10 @@ }; | ||
key: 'renderMarkupSection', | ||
value: function renderMarkupSection(_ref6) { | ||
var _ref62 = _slicedToArray(_ref6, 3); | ||
value: function renderMarkupSection(_ref5) { | ||
var _ref52 = _slicedToArray(_ref5, 3); | ||
var type = _ref62[0]; | ||
var tagName = _ref62[1]; | ||
var markers = _ref62[2]; | ||
var type = _ref52[0]; | ||
var tagName = _ref52[1]; | ||
var markers = _ref52[2]; | ||
tagName = tagName.toLowerCase(); | ||
if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE)) { | ||
@@ -1000,12 +1036,4 @@ return; | ||
var element = undefined; | ||
var lowerCaseTagName = tagName.toLowerCase(); | ||
if (this.sectionElementRenderer[lowerCaseTagName]) { | ||
element = this.sectionElementRenderer[lowerCaseTagName](tagName, this.dom); | ||
} else if ((0, _mobiledocDomRendererUtilsTagNames.isMarkupSectionElementName)(tagName)) { | ||
element = this.dom.createElement(tagName); | ||
} else { | ||
element = this.dom.createElement('div'); | ||
element.setAttribute('class', tagName); | ||
} | ||
var renderer = this.sectionElementRendererFor(tagName); | ||
var element = renderer(tagName, this.dom); | ||
@@ -1016,6 +1044,11 @@ this.renderMarkersOnElement(element, markers); | ||
}, { | ||
key: 'sectionElementRendererFor', | ||
value: function sectionElementRendererFor(tagName) { | ||
return this.sectionElementRenderer[tagName] || this.sectionElementRenderer.__default__; | ||
} | ||
}, { | ||
key: '_defaultUnknownCardHandler', | ||
get: function get() { | ||
return function (_ref7) { | ||
var name = _ref7.env.name; | ||
return function (_ref6) { | ||
var name = _ref6.env.name; | ||
@@ -1028,4 +1061,4 @@ throw new Error('Card "' + name + '" not found but no unknownCardHandler was registered'); | ||
get: function get() { | ||
return function (_ref8) { | ||
var name = _ref8.env.name; | ||
return function (_ref7) { | ||
var name = _ref7.env.name; | ||
@@ -1095,2 +1128,57 @@ throw new Error('Atom "' + name + '" not found but no unknownAtomHandler was registered'); | ||
}); | ||
define('mobiledoc-dom-renderer/utils/render-utils', ['exports', 'mobiledoc-dom-renderer/utils/tag-names', 'mobiledoc-dom-renderer/utils/sanitization-utils'], function (exports, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils) { | ||
'use strict'; | ||
exports.createMarkupSanitizerWithFallback = createMarkupSanitizerWithFallback; | ||
exports.defaultSectionElementRenderer = defaultSectionElementRenderer; | ||
exports.defaultMarkupElementRenderer = defaultMarkupElementRenderer; | ||
function defaultMarkupSanitizer(_ref) { | ||
var tagName = _ref.tagName; | ||
var attributeName = _ref.attributeName; | ||
var attributeValue = _ref.attributeValue; | ||
if (tagName === 'a' && attributeName === 'href') { | ||
return (0, _mobiledocDomRendererUtilsSanitizationUtils.sanitizeHref)(attributeValue); | ||
} else { | ||
return attributeValue; | ||
} | ||
} | ||
/* | ||
* return a sanitizer function that first uses the passed sanitizer | ||
* (if present), and then uses the default sanitizer if that didn't return | ||
* a string | ||
*/ | ||
function createMarkupSanitizerWithFallback(sanitizer) { | ||
if (sanitizer) { | ||
return function () { | ||
return sanitizer.apply(undefined, arguments) || defaultMarkupSanitizer.apply(undefined, arguments); | ||
}; | ||
} else { | ||
return defaultMarkupSanitizer; | ||
} | ||
} | ||
function defaultSectionElementRenderer(tagName, dom) { | ||
var element = undefined; | ||
if ((0, _mobiledocDomRendererUtilsTagNames.isMarkupSectionElementName)(tagName)) { | ||
element = dom.createElement(tagName); | ||
} else { | ||
element = dom.createElement('div'); | ||
element.setAttribute('class', tagName); | ||
} | ||
return element; | ||
} | ||
function defaultMarkupElementRenderer(tagName, dom, attrsObj) { | ||
var element = dom.createElement(tagName); | ||
Object.keys(attrsObj).forEach(function (key) { | ||
element.setAttribute(key, attrsObj[key]); | ||
}); | ||
return element; | ||
} | ||
}); | ||
define('mobiledoc-dom-renderer/utils/sanitization-utils', ['exports', 'mobiledoc-dom-renderer/utils/array-utils', 'mobiledoc-dom-renderer/utils/dom'], function (exports, _mobiledocDomRendererUtilsArrayUtils, _mobiledocDomRendererUtilsDom) { | ||
@@ -1101,4 +1189,4 @@ /* globals module */ | ||
exports.sanitizeAttributeValue = sanitizeAttributeValue; | ||
exports.reduceAndSanitizeAttributes = reduceAndSanitizeAttributes; | ||
exports.sanitizeHref = sanitizeHref; | ||
exports.reduceAttributes = reduceAttributes; | ||
@@ -1136,17 +1224,15 @@ var badProtocols = ['javascript:', // jshint ignore:line | ||
function sanitizeAttributeValue(attributeName, attributeValue, tagName) { | ||
if (tagName === 'a' && attributeName === 'href') { | ||
return sanitizeHref(attributeValue); | ||
} | ||
return attributeValue; | ||
} | ||
/** | ||
* @param attributes array | ||
* @return obj with normalized attribute names (lowercased) | ||
*/ | ||
function reduceAndSanitizeAttributes(attributes, tagName) { | ||
var attrsObj = {}; | ||
for (var i = 0, l = attributes.length; i < l; i = i + 2) { | ||
var propName = attributes[i], | ||
propValue = attributes[i + 1]; | ||
attrsObj[propName] = sanitizeAttributeValue(propName, propValue, tagName); | ||
function reduceAttributes(attributes) { | ||
var obj = {}; | ||
for (var i = 0; i < attributes.length; i += 2) { | ||
var key = attributes[i]; | ||
var val = attributes[i + 1]; | ||
obj[key.toLowerCase()] = val; | ||
} | ||
return attrsObj; | ||
return obj; | ||
} | ||
@@ -1153,0 +1239,0 @@ }); |
@@ -55,18 +55,22 @@ 'use strict'; | ||
var cards = _ref.cards; | ||
var atoms = _ref.atoms; | ||
var cardOptions = _ref.cardOptions; | ||
var _ref$cards = _ref.cards; | ||
var cards = _ref$cards === undefined ? [] : _ref$cards; | ||
var _ref$atoms = _ref.atoms; | ||
var atoms = _ref$atoms === undefined ? [] : _ref$atoms; | ||
var _ref$cardOptions = _ref.cardOptions; | ||
var cardOptions = _ref$cardOptions === undefined ? {} : _ref$cardOptions; | ||
var unknownCardHandler = _ref.unknownCardHandler; | ||
var unknownAtomHandler = _ref.unknownAtomHandler; | ||
var markupElementRenderer = _ref.markupElementRenderer; | ||
var sectionElementRenderer = _ref.sectionElementRenderer; | ||
var _ref$markupElementRenderer = _ref.markupElementRenderer; | ||
var markupElementRenderer = _ref$markupElementRenderer === undefined ? {} : _ref$markupElementRenderer; | ||
var _ref$sectionElementRenderer = _ref.sectionElementRenderer; | ||
var sectionElementRenderer = _ref$sectionElementRenderer === undefined ? {} : _ref$sectionElementRenderer; | ||
var dom = _ref.dom; | ||
var _ref$markupSanitizer = _ref.markupSanitizer; | ||
var markupSanitizer = _ref$markupSanitizer === undefined ? null : _ref$markupSanitizer; | ||
_classCallCheck(this, RendererFactory); | ||
cards = cards || []; | ||
validateCards(cards); | ||
atoms = atoms || []; | ||
validateAtoms(atoms); | ||
cardOptions = cardOptions || {}; | ||
@@ -88,3 +92,4 @@ if (!dom) { | ||
sectionElementRenderer: sectionElementRenderer, | ||
dom: dom | ||
dom: dom, | ||
markupSanitizer: markupSanitizer | ||
}; | ||
@@ -91,0 +96,0 @@ } |
@@ -21,2 +21,4 @@ 'use strict'; | ||
var _utilsRenderUtils = require('../utils/render-utils'); | ||
var MOBILEDOC_VERSION = '0.2.0'; | ||
@@ -27,21 +29,2 @@ | ||
function createElementFromMarkerType(dom) { | ||
var _ref = arguments.length <= 1 || arguments[1] === undefined ? ['', []] : arguments[1]; | ||
var _ref2 = _slicedToArray(_ref, 2); | ||
var tagName = _ref2[0]; | ||
var attributes = _ref2[1]; | ||
var element = dom.createElement(tagName); | ||
attributes = attributes || []; | ||
for (var i = 0, l = attributes.length; i < l; i = i + 2) { | ||
var propName = attributes[i], | ||
propValue = attributes[i + 1]; | ||
element.setAttribute(propName, (0, _utilsSanitizationUtils.sanitizeAttributeValue)(propName, propValue, tagName)); | ||
} | ||
return element; | ||
} | ||
function validateVersion(version) { | ||
@@ -55,2 +38,4 @@ if (version !== MOBILEDOC_VERSION) { | ||
function Renderer(mobiledoc, options) { | ||
var _this = this; | ||
_classCallCheck(this, Renderer); | ||
@@ -64,2 +49,3 @@ | ||
var dom = options.dom; | ||
var markupSanitizer = options.markupSanitizer; | ||
var version = mobiledoc.version; | ||
@@ -82,20 +68,17 @@ var sectionData = mobiledoc.sections; | ||
this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler; | ||
this.markupSanitizer = (0, _utilsRenderUtils.createMarkupSanitizerWithFallback)(markupSanitizer); | ||
this.sectionElementRenderer = {}; | ||
if (sectionElementRenderer) { | ||
for (var key in sectionElementRenderer) { | ||
if (sectionElementRenderer.hasOwnProperty(key)) { | ||
this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key]; | ||
} | ||
} | ||
} | ||
this.sectionElementRenderer = { | ||
'__default__': _utilsRenderUtils.defaultSectionElementRenderer | ||
}; | ||
Object.keys(sectionElementRenderer).forEach(function (key) { | ||
_this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key]; | ||
}); | ||
this.markupElementRenderer = {}; | ||
if (markupElementRenderer) { | ||
for (var key in markupElementRenderer) { | ||
if (markupElementRenderer.hasOwnProperty(key)) { | ||
this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key]; | ||
} | ||
} | ||
} | ||
this.markupElementRenderer = { | ||
'__default__': _utilsRenderUtils.defaultMarkupElementRenderer | ||
}; | ||
Object.keys(markupElementRenderer).forEach(function (key) { | ||
_this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key]; | ||
}); | ||
@@ -110,8 +93,8 @@ this._renderCallbacks = []; | ||
value: function render() { | ||
var _this = this; | ||
var _this2 = this; | ||
this.sections.forEach(function (section) { | ||
var rendered = _this.renderSection(section); | ||
var rendered = _this2.renderSection(section); | ||
if (rendered) { | ||
_this.root.appendChild(rendered); | ||
_this2.root.appendChild(rendered); | ||
} | ||
@@ -130,3 +113,3 @@ }); | ||
return { result: this.root, teardown: function teardown() { | ||
return _this.teardown(); | ||
return _this2.teardown(); | ||
} }; | ||
@@ -198,11 +181,3 @@ } | ||
if ((0, _utilsTagNames.isValidMarkerType)(tagName)) { | ||
var lowerCaseTagName = tagName.toLowerCase(); | ||
if (this.markupElementRenderer[lowerCaseTagName]) { | ||
var attrObj = (0, _utilsSanitizationUtils.reduceAndSanitizeAttributes)(attrs, lowerCaseTagName); | ||
var openedElement = this.markupElementRenderer[lowerCaseTagName](tagName, this.dom, attrObj); | ||
pushElement(openedElement); | ||
} else { | ||
var openedElement = createElementFromMarkerType(this.dom, markerType); | ||
pushElement(openedElement); | ||
} | ||
pushElement(this.renderMarkupElement(tagName, attrs)); | ||
} else { | ||
@@ -221,3 +196,44 @@ closeCount--; | ||
} | ||
/** | ||
* @param attrs Array | ||
*/ | ||
}, { | ||
key: 'renderMarkupElement', | ||
value: function renderMarkupElement(tagName, attrs) { | ||
tagName = tagName.toLowerCase(); | ||
attrs = this.sanitizeAttributes(tagName, (0, _utilsSanitizationUtils.reduceAttributes)(attrs)); | ||
var renderer = this.markupElementRendererFor(tagName); | ||
return renderer(tagName, this.dom, attrs); | ||
} | ||
}, { | ||
key: 'markupElementRendererFor', | ||
value: function markupElementRendererFor(tagName) { | ||
return this.markupElementRenderer[tagName] || this.markupElementRenderer.__default__; | ||
} | ||
}, { | ||
key: 'sanitizeAttributes', | ||
value: function sanitizeAttributes(tagName, attrsObj) { | ||
var _this3 = this; | ||
var sanitized = {}; | ||
Object.keys(attrsObj).forEach(function (attributeName) { | ||
var attributeValue = attrsObj[attributeName]; | ||
sanitized[attributeName] = _this3.sanitizeAttribute({ tagName: tagName, attributeName: attributeName, attributeValue: attributeValue }); | ||
}); | ||
return sanitized; | ||
} | ||
}, { | ||
key: 'sanitizeAttribute', | ||
value: function sanitizeAttribute(_ref) { | ||
var tagName = _ref.tagName; | ||
var attributeName = _ref.attributeName; | ||
var attributeValue = _ref.attributeValue; | ||
return this.markupSanitizer({ tagName: tagName, attributeName: attributeName, attributeValue: attributeValue }); | ||
} | ||
}, { | ||
key: 'renderListItem', | ||
@@ -231,10 +247,10 @@ value: function renderListItem(markers) { | ||
key: 'renderListSection', | ||
value: function renderListSection(_ref3) { | ||
var _this2 = this; | ||
value: function renderListSection(_ref2) { | ||
var _this4 = this; | ||
var _ref32 = _slicedToArray(_ref3, 3); | ||
var _ref22 = _slicedToArray(_ref2, 3); | ||
var type = _ref32[0]; | ||
var tagName = _ref32[1]; | ||
var listItems = _ref32[2]; | ||
var type = _ref22[0]; | ||
var tagName = _ref22[1]; | ||
var listItems = _ref22[2]; | ||
@@ -246,3 +262,3 @@ if (!(0, _utilsTagNames.isValidSectionTagName)(tagName, _utilsSectionTypes.LIST_SECTION_TYPE)) { | ||
listItems.forEach(function (li) { | ||
element.appendChild(_this2.renderListItem(li)); | ||
element.appendChild(_this4.renderListItem(li)); | ||
}); | ||
@@ -253,7 +269,7 @@ return element; | ||
key: 'renderImageSection', | ||
value: function renderImageSection(_ref4) { | ||
var _ref42 = _slicedToArray(_ref4, 2); | ||
value: function renderImageSection(_ref3) { | ||
var _ref32 = _slicedToArray(_ref3, 2); | ||
var type = _ref42[0]; | ||
var src = _ref42[1]; | ||
var type = _ref32[0]; | ||
var src = _ref32[1]; | ||
@@ -289,3 +305,3 @@ var element = this.dom.createElement(IMAGE_SECTION_TAG_NAME); | ||
value: function _createCardArgument(card) { | ||
var _this3 = this; | ||
var _this5 = this; | ||
@@ -299,6 +315,6 @@ var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
didRender: function didRender(callback) { | ||
return _this3._registerRenderCallback(callback); | ||
return _this5._registerRenderCallback(callback); | ||
}, | ||
onTeardown: function onTeardown(callback) { | ||
return _this3._registerTeardownCallback(callback); | ||
return _this5._registerTeardownCallback(callback); | ||
} | ||
@@ -323,8 +339,8 @@ }; | ||
key: 'renderCardSection', | ||
value: function renderCardSection(_ref5) { | ||
var _ref52 = _slicedToArray(_ref5, 3); | ||
value: function renderCardSection(_ref4) { | ||
var _ref42 = _slicedToArray(_ref4, 3); | ||
var type = _ref52[0]; | ||
var name = _ref52[1]; | ||
var payload = _ref52[2]; | ||
var type = _ref42[0]; | ||
var name = _ref42[1]; | ||
var payload = _ref42[2]; | ||
@@ -353,9 +369,10 @@ var card = this.findCard(name); | ||
key: 'renderMarkupSection', | ||
value: function renderMarkupSection(_ref6) { | ||
var _ref62 = _slicedToArray(_ref6, 3); | ||
value: function renderMarkupSection(_ref5) { | ||
var _ref52 = _slicedToArray(_ref5, 3); | ||
var type = _ref62[0]; | ||
var tagName = _ref62[1]; | ||
var markers = _ref62[2]; | ||
var type = _ref52[0]; | ||
var tagName = _ref52[1]; | ||
var markers = _ref52[2]; | ||
tagName = tagName.toLowerCase(); | ||
if (!(0, _utilsTagNames.isValidSectionTagName)(tagName, _utilsSectionTypes.MARKUP_SECTION_TYPE)) { | ||
@@ -365,12 +382,4 @@ return; | ||
var element = undefined; | ||
var lowerCaseTagName = tagName.toLowerCase(); | ||
if (this.sectionElementRenderer[lowerCaseTagName]) { | ||
element = this.sectionElementRenderer[lowerCaseTagName](tagName, this.dom); | ||
} else if ((0, _utilsTagNames.isMarkupSectionElementName)(tagName)) { | ||
element = this.dom.createElement(tagName); | ||
} else { | ||
element = this.dom.createElement('div'); | ||
element.setAttribute('class', tagName); | ||
} | ||
var renderer = this.sectionElementRendererFor(tagName); | ||
var element = renderer(tagName, this.dom); | ||
@@ -381,6 +390,11 @@ this.renderMarkersOnElement(element, markers); | ||
}, { | ||
key: 'sectionElementRendererFor', | ||
value: function sectionElementRendererFor(tagName) { | ||
return this.sectionElementRenderer[tagName] || this.sectionElementRenderer.__default__; | ||
} | ||
}, { | ||
key: '_defaultUnknownCardHandler', | ||
get: function get() { | ||
return function (_ref7) { | ||
var name = _ref7.env.name; | ||
return function (_ref6) { | ||
var name = _ref6.env.name; | ||
@@ -387,0 +401,0 @@ throw new Error('Card "' + name + '" not found but no unknownCardHandler was registered'); |
@@ -21,2 +21,4 @@ 'use strict'; | ||
var _utilsRenderUtils = require('../utils/render-utils'); | ||
var _utilsMarkerTypes = require('../utils/marker-types'); | ||
@@ -33,24 +35,9 @@ | ||
function createElementFromMarkerType(dom) { | ||
var _ref = arguments.length <= 1 || arguments[1] === undefined ? ['', []] : arguments[1]; | ||
var _ref2 = _slicedToArray(_ref, 2); | ||
var tagName = _ref2[0]; | ||
var attributes = _ref2[1]; | ||
var element = dom.createElement(tagName); | ||
attributes = attributes || []; | ||
for (var i = 0, l = attributes.length; i < l; i = i + 2) { | ||
var propName = attributes[i], | ||
propValue = attributes[i + 1]; | ||
element.setAttribute(propName, (0, _utilsSanitizationUtils.sanitizeAttributeValue)(propName, propValue, tagName)); | ||
} | ||
return element; | ||
} | ||
function validateVersion(version) { | ||
if (version !== MOBILEDOC_VERSION_0_3_0 && version !== MOBILEDOC_VERSION_0_3_1) { | ||
throw new Error('Unexpected Mobiledoc version "' + version + '"'); | ||
switch (version) { | ||
case MOBILEDOC_VERSION_0_3_0: | ||
case MOBILEDOC_VERSION_0_3_1: | ||
return; | ||
default: | ||
throw new Error('Unexpected Mobiledoc version "' + version + '"'); | ||
} | ||
@@ -61,2 +48,4 @@ } | ||
function Renderer(mobiledoc, state) { | ||
var _this = this; | ||
_classCallCheck(this, Renderer); | ||
@@ -72,2 +61,3 @@ | ||
var dom = state.dom; | ||
var markupSanitizer = state.markupSanitizer; | ||
var version = mobiledoc.version; | ||
@@ -92,20 +82,17 @@ var sections = mobiledoc.sections; | ||
this.unknownAtomHandler = unknownAtomHandler || this._defaultUnknownAtomHandler; | ||
this.markupSanitizer = (0, _utilsRenderUtils.createMarkupSanitizerWithFallback)(markupSanitizer); | ||
this.sectionElementRenderer = {}; | ||
if (sectionElementRenderer) { | ||
for (var key in sectionElementRenderer) { | ||
if (sectionElementRenderer.hasOwnProperty(key)) { | ||
this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key]; | ||
} | ||
} | ||
} | ||
this.sectionElementRenderer = { | ||
'__default__': _utilsRenderUtils.defaultSectionElementRenderer | ||
}; | ||
Object.keys(sectionElementRenderer).forEach(function (key) { | ||
_this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key]; | ||
}); | ||
this.markupElementRenderer = {}; | ||
if (markupElementRenderer) { | ||
for (var key in markupElementRenderer) { | ||
if (markupElementRenderer.hasOwnProperty(key)) { | ||
this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key]; | ||
} | ||
} | ||
} | ||
this.markupElementRenderer = { | ||
'__default__': _utilsRenderUtils.defaultMarkupElementRenderer | ||
}; | ||
Object.keys(markupElementRenderer).forEach(function (key) { | ||
_this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key]; | ||
}); | ||
@@ -119,8 +106,8 @@ this._renderCallbacks = []; | ||
value: function render() { | ||
var _this = this; | ||
var _this2 = this; | ||
this.sections.forEach(function (section) { | ||
var rendered = _this.renderSection(section); | ||
var rendered = _this2.renderSection(section); | ||
if (rendered) { | ||
_this.root.appendChild(rendered); | ||
_this2.root.appendChild(rendered); | ||
} | ||
@@ -134,3 +121,3 @@ }); | ||
return { result: this.root, teardown: function teardown() { | ||
return _this.teardown(); | ||
return _this2.teardown(); | ||
} }; | ||
@@ -203,11 +190,3 @@ } | ||
if ((0, _utilsTagNames.isValidMarkerType)(tagName)) { | ||
var lowerCaseTagName = tagName.toLowerCase(); | ||
if (this.markupElementRenderer[lowerCaseTagName]) { | ||
var attrObj = (0, _utilsSanitizationUtils.reduceAndSanitizeAttributes)(attrs, lowerCaseTagName); | ||
var openedElement = this.markupElementRenderer[lowerCaseTagName](tagName, this.dom, attrObj); | ||
pushElement(openedElement); | ||
} else { | ||
var openedElement = createElementFromMarkerType(this.dom, markerType); | ||
pushElement(openedElement); | ||
} | ||
pushElement(this.renderMarkupElement(tagName, attrs)); | ||
} else { | ||
@@ -235,3 +214,44 @@ closeCount--; | ||
} | ||
/** | ||
* @param attrs Array | ||
*/ | ||
}, { | ||
key: 'renderMarkupElement', | ||
value: function renderMarkupElement(tagName, attrs) { | ||
tagName = tagName.toLowerCase(); | ||
attrs = this.sanitizeAttributes(tagName, (0, _utilsSanitizationUtils.reduceAttributes)(attrs)); | ||
var renderer = this.markupElementRendererFor(tagName); | ||
return renderer(tagName, this.dom, attrs); | ||
} | ||
}, { | ||
key: 'markupElementRendererFor', | ||
value: function markupElementRendererFor(tagName) { | ||
return this.markupElementRenderer[tagName] || this.markupElementRenderer.__default__; | ||
} | ||
}, { | ||
key: 'sanitizeAttributes', | ||
value: function sanitizeAttributes(tagName, attrsObj) { | ||
var _this3 = this; | ||
var sanitized = {}; | ||
Object.keys(attrsObj).forEach(function (attributeName) { | ||
var attributeValue = attrsObj[attributeName]; | ||
sanitized[attributeName] = _this3.sanitizeAttribute({ tagName: tagName, attributeName: attributeName, attributeValue: attributeValue }); | ||
}); | ||
return sanitized; | ||
} | ||
}, { | ||
key: 'sanitizeAttribute', | ||
value: function sanitizeAttribute(_ref) { | ||
var tagName = _ref.tagName; | ||
var attributeName = _ref.attributeName; | ||
var attributeValue = _ref.attributeValue; | ||
return this.markupSanitizer({ tagName: tagName, attributeName: attributeName, attributeValue: attributeValue }); | ||
} | ||
}, { | ||
key: 'renderListItem', | ||
@@ -245,10 +265,10 @@ value: function renderListItem(markers) { | ||
key: 'renderListSection', | ||
value: function renderListSection(_ref3) { | ||
var _this2 = this; | ||
value: function renderListSection(_ref2) { | ||
var _this4 = this; | ||
var _ref32 = _slicedToArray(_ref3, 3); | ||
var _ref22 = _slicedToArray(_ref2, 3); | ||
var type = _ref32[0]; | ||
var tagName = _ref32[1]; | ||
var listItems = _ref32[2]; | ||
var type = _ref22[0]; | ||
var tagName = _ref22[1]; | ||
var listItems = _ref22[2]; | ||
@@ -260,3 +280,3 @@ if (!(0, _utilsTagNames.isValidSectionTagName)(tagName, _utilsSectionTypes.LIST_SECTION_TYPE)) { | ||
listItems.forEach(function (li) { | ||
element.appendChild(_this2.renderListItem(li)); | ||
element.appendChild(_this4.renderListItem(li)); | ||
}); | ||
@@ -267,7 +287,7 @@ return element; | ||
key: 'renderImageSection', | ||
value: function renderImageSection(_ref4) { | ||
var _ref42 = _slicedToArray(_ref4, 2); | ||
value: function renderImageSection(_ref3) { | ||
var _ref32 = _slicedToArray(_ref3, 2); | ||
var type = _ref42[0]; | ||
var src = _ref42[1]; | ||
var type = _ref32[0]; | ||
var src = _ref32[1]; | ||
@@ -323,3 +343,3 @@ var element = this.dom.createElement(IMAGE_SECTION_TAG_NAME); | ||
value: function _createCardArgument(card) { | ||
var _this3 = this; | ||
var _this5 = this; | ||
@@ -333,6 +353,6 @@ var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
didRender: function didRender(callback) { | ||
return _this3._registerRenderCallback(callback); | ||
return _this5._registerRenderCallback(callback); | ||
}, | ||
onTeardown: function onTeardown(callback) { | ||
return _this3._registerTeardownCallback(callback); | ||
return _this5._registerTeardownCallback(callback); | ||
} | ||
@@ -357,7 +377,7 @@ }; | ||
key: 'renderCardSection', | ||
value: function renderCardSection(_ref5) { | ||
var _ref52 = _slicedToArray(_ref5, 2); | ||
value: function renderCardSection(_ref4) { | ||
var _ref42 = _slicedToArray(_ref4, 2); | ||
var type = _ref52[0]; | ||
var index = _ref52[1]; | ||
var type = _ref42[0]; | ||
var index = _ref42[1]; | ||
@@ -409,3 +429,3 @@ var _findCardByIndex2 = this._findCardByIndex(index); | ||
value: function _createAtomArgument(atom, value, payload) { | ||
var _this4 = this; | ||
var _this6 = this; | ||
@@ -417,3 +437,3 @@ var env = { | ||
onTeardown: function onTeardown(callback) { | ||
return _this4._registerTeardownCallback(callback); | ||
return _this6._registerTeardownCallback(callback); | ||
} | ||
@@ -477,9 +497,10 @@ }; | ||
key: 'renderMarkupSection', | ||
value: function renderMarkupSection(_ref6) { | ||
var _ref62 = _slicedToArray(_ref6, 3); | ||
value: function renderMarkupSection(_ref5) { | ||
var _ref52 = _slicedToArray(_ref5, 3); | ||
var type = _ref62[0]; | ||
var tagName = _ref62[1]; | ||
var markers = _ref62[2]; | ||
var type = _ref52[0]; | ||
var tagName = _ref52[1]; | ||
var markers = _ref52[2]; | ||
tagName = tagName.toLowerCase(); | ||
if (!(0, _utilsTagNames.isValidSectionTagName)(tagName, _utilsSectionTypes.MARKUP_SECTION_TYPE)) { | ||
@@ -489,12 +510,4 @@ return; | ||
var element = undefined; | ||
var lowerCaseTagName = tagName.toLowerCase(); | ||
if (this.sectionElementRenderer[lowerCaseTagName]) { | ||
element = this.sectionElementRenderer[lowerCaseTagName](tagName, this.dom); | ||
} else if ((0, _utilsTagNames.isMarkupSectionElementName)(tagName)) { | ||
element = this.dom.createElement(tagName); | ||
} else { | ||
element = this.dom.createElement('div'); | ||
element.setAttribute('class', tagName); | ||
} | ||
var renderer = this.sectionElementRendererFor(tagName); | ||
var element = renderer(tagName, this.dom); | ||
@@ -505,6 +518,11 @@ this.renderMarkersOnElement(element, markers); | ||
}, { | ||
key: 'sectionElementRendererFor', | ||
value: function sectionElementRendererFor(tagName) { | ||
return this.sectionElementRenderer[tagName] || this.sectionElementRenderer.__default__; | ||
} | ||
}, { | ||
key: '_defaultUnknownCardHandler', | ||
get: function get() { | ||
return function (_ref7) { | ||
var name = _ref7.env.name; | ||
return function (_ref6) { | ||
var name = _ref6.env.name; | ||
@@ -517,4 +535,4 @@ throw new Error('Card "' + name + '" not found but no unknownCardHandler was registered'); | ||
get: function get() { | ||
return function (_ref8) { | ||
var name = _ref8.env.name; | ||
return function (_ref7) { | ||
var name = _ref7.env.name; | ||
@@ -521,0 +539,0 @@ throw new Error('Atom "' + name + '" not found but no unknownAtomHandler was registered'); |
@@ -5,4 +5,4 @@ /* globals module */ | ||
exports.sanitizeAttributeValue = sanitizeAttributeValue; | ||
exports.reduceAndSanitizeAttributes = reduceAndSanitizeAttributes; | ||
exports.sanitizeHref = sanitizeHref; | ||
exports.reduceAttributes = reduceAttributes; | ||
@@ -44,17 +44,15 @@ var _arrayUtils = require('./array-utils'); | ||
function sanitizeAttributeValue(attributeName, attributeValue, tagName) { | ||
if (tagName === 'a' && attributeName === 'href') { | ||
return sanitizeHref(attributeValue); | ||
} | ||
return attributeValue; | ||
} | ||
/** | ||
* @param attributes array | ||
* @return obj with normalized attribute names (lowercased) | ||
*/ | ||
function reduceAndSanitizeAttributes(attributes, tagName) { | ||
var attrsObj = {}; | ||
for (var i = 0, l = attributes.length; i < l; i = i + 2) { | ||
var propName = attributes[i], | ||
propValue = attributes[i + 1]; | ||
attrsObj[propName] = sanitizeAttributeValue(propName, propValue, tagName); | ||
function reduceAttributes(attributes) { | ||
var obj = {}; | ||
for (var i = 0; i < attributes.length; i += 2) { | ||
var key = attributes[i]; | ||
var val = attributes[i + 1]; | ||
obj[key.toLowerCase()] = val; | ||
} | ||
return attrsObj; | ||
return obj; | ||
} |
@@ -298,18 +298,22 @@ ;(function() { | ||
var cards = _ref.cards; | ||
var atoms = _ref.atoms; | ||
var cardOptions = _ref.cardOptions; | ||
var _ref$cards = _ref.cards; | ||
var cards = _ref$cards === undefined ? [] : _ref$cards; | ||
var _ref$atoms = _ref.atoms; | ||
var atoms = _ref$atoms === undefined ? [] : _ref$atoms; | ||
var _ref$cardOptions = _ref.cardOptions; | ||
var cardOptions = _ref$cardOptions === undefined ? {} : _ref$cardOptions; | ||
var unknownCardHandler = _ref.unknownCardHandler; | ||
var unknownAtomHandler = _ref.unknownAtomHandler; | ||
var markupElementRenderer = _ref.markupElementRenderer; | ||
var sectionElementRenderer = _ref.sectionElementRenderer; | ||
var _ref$markupElementRenderer = _ref.markupElementRenderer; | ||
var markupElementRenderer = _ref$markupElementRenderer === undefined ? {} : _ref$markupElementRenderer; | ||
var _ref$sectionElementRenderer = _ref.sectionElementRenderer; | ||
var sectionElementRenderer = _ref$sectionElementRenderer === undefined ? {} : _ref$sectionElementRenderer; | ||
var dom = _ref.dom; | ||
var _ref$markupSanitizer = _ref.markupSanitizer; | ||
var markupSanitizer = _ref$markupSanitizer === undefined ? null : _ref$markupSanitizer; | ||
_classCallCheck(this, RendererFactory); | ||
cards = cards || []; | ||
validateCards(cards); | ||
atoms = atoms || []; | ||
validateAtoms(atoms); | ||
cardOptions = cardOptions || {}; | ||
@@ -331,3 +335,4 @@ if (!dom) { | ||
sectionElementRenderer: sectionElementRenderer, | ||
dom: dom | ||
dom: dom, | ||
markupSanitizer: markupSanitizer | ||
}; | ||
@@ -360,3 +365,3 @@ } | ||
}); | ||
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'], function (exports, _mobiledocDomRendererUtilsDom, _mobiledocDomRendererCardsImage, _mobiledocDomRendererUtilsRenderType, _mobiledocDomRendererUtilsSectionTypes, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils) { | ||
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) { | ||
'use strict'; | ||
@@ -375,21 +380,2 @@ | ||
function createElementFromMarkerType(dom) { | ||
var _ref = arguments.length <= 1 || arguments[1] === undefined ? ['', []] : arguments[1]; | ||
var _ref2 = _slicedToArray(_ref, 2); | ||
var tagName = _ref2[0]; | ||
var attributes = _ref2[1]; | ||
var element = dom.createElement(tagName); | ||
attributes = attributes || []; | ||
for (var i = 0, l = attributes.length; i < l; i = i + 2) { | ||
var propName = attributes[i], | ||
propValue = attributes[i + 1]; | ||
element.setAttribute(propName, (0, _mobiledocDomRendererUtilsSanitizationUtils.sanitizeAttributeValue)(propName, propValue, tagName)); | ||
} | ||
return element; | ||
} | ||
function validateVersion(version) { | ||
@@ -403,2 +389,4 @@ if (version !== MOBILEDOC_VERSION) { | ||
function Renderer(mobiledoc, options) { | ||
var _this = this; | ||
_classCallCheck(this, Renderer); | ||
@@ -412,2 +400,3 @@ | ||
var dom = options.dom; | ||
var markupSanitizer = options.markupSanitizer; | ||
var version = mobiledoc.version; | ||
@@ -430,20 +419,17 @@ var sectionData = mobiledoc.sections; | ||
this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler; | ||
this.markupSanitizer = (0, _mobiledocDomRendererUtilsRenderUtils.createMarkupSanitizerWithFallback)(markupSanitizer); | ||
this.sectionElementRenderer = {}; | ||
if (sectionElementRenderer) { | ||
for (var key in sectionElementRenderer) { | ||
if (sectionElementRenderer.hasOwnProperty(key)) { | ||
this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key]; | ||
} | ||
} | ||
} | ||
this.sectionElementRenderer = { | ||
'__default__': _mobiledocDomRendererUtilsRenderUtils.defaultSectionElementRenderer | ||
}; | ||
Object.keys(sectionElementRenderer).forEach(function (key) { | ||
_this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key]; | ||
}); | ||
this.markupElementRenderer = {}; | ||
if (markupElementRenderer) { | ||
for (var key in markupElementRenderer) { | ||
if (markupElementRenderer.hasOwnProperty(key)) { | ||
this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key]; | ||
} | ||
} | ||
} | ||
this.markupElementRenderer = { | ||
'__default__': _mobiledocDomRendererUtilsRenderUtils.defaultMarkupElementRenderer | ||
}; | ||
Object.keys(markupElementRenderer).forEach(function (key) { | ||
_this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key]; | ||
}); | ||
@@ -458,8 +444,8 @@ this._renderCallbacks = []; | ||
value: function render() { | ||
var _this = this; | ||
var _this2 = this; | ||
this.sections.forEach(function (section) { | ||
var rendered = _this.renderSection(section); | ||
var rendered = _this2.renderSection(section); | ||
if (rendered) { | ||
_this.root.appendChild(rendered); | ||
_this2.root.appendChild(rendered); | ||
} | ||
@@ -478,3 +464,3 @@ }); | ||
return { result: this.root, teardown: function teardown() { | ||
return _this.teardown(); | ||
return _this2.teardown(); | ||
} }; | ||
@@ -546,11 +532,3 @@ } | ||
if ((0, _mobiledocDomRendererUtilsTagNames.isValidMarkerType)(tagName)) { | ||
var lowerCaseTagName = tagName.toLowerCase(); | ||
if (this.markupElementRenderer[lowerCaseTagName]) { | ||
var attrObj = (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAndSanitizeAttributes)(attrs, lowerCaseTagName); | ||
var openedElement = this.markupElementRenderer[lowerCaseTagName](tagName, this.dom, attrObj); | ||
pushElement(openedElement); | ||
} else { | ||
var openedElement = createElementFromMarkerType(this.dom, markerType); | ||
pushElement(openedElement); | ||
} | ||
pushElement(this.renderMarkupElement(tagName, attrs)); | ||
} else { | ||
@@ -569,3 +547,44 @@ closeCount--; | ||
} | ||
/** | ||
* @param attrs Array | ||
*/ | ||
}, { | ||
key: 'renderMarkupElement', | ||
value: function renderMarkupElement(tagName, attrs) { | ||
tagName = tagName.toLowerCase(); | ||
attrs = this.sanitizeAttributes(tagName, (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAttributes)(attrs)); | ||
var renderer = this.markupElementRendererFor(tagName); | ||
return renderer(tagName, this.dom, attrs); | ||
} | ||
}, { | ||
key: 'markupElementRendererFor', | ||
value: function markupElementRendererFor(tagName) { | ||
return this.markupElementRenderer[tagName] || this.markupElementRenderer.__default__; | ||
} | ||
}, { | ||
key: 'sanitizeAttributes', | ||
value: function sanitizeAttributes(tagName, attrsObj) { | ||
var _this3 = this; | ||
var sanitized = {}; | ||
Object.keys(attrsObj).forEach(function (attributeName) { | ||
var attributeValue = attrsObj[attributeName]; | ||
sanitized[attributeName] = _this3.sanitizeAttribute({ tagName: tagName, attributeName: attributeName, attributeValue: attributeValue }); | ||
}); | ||
return sanitized; | ||
} | ||
}, { | ||
key: 'sanitizeAttribute', | ||
value: function sanitizeAttribute(_ref) { | ||
var tagName = _ref.tagName; | ||
var attributeName = _ref.attributeName; | ||
var attributeValue = _ref.attributeValue; | ||
return this.markupSanitizer({ tagName: tagName, attributeName: attributeName, attributeValue: attributeValue }); | ||
} | ||
}, { | ||
key: 'renderListItem', | ||
@@ -579,10 +598,10 @@ value: function renderListItem(markers) { | ||
key: 'renderListSection', | ||
value: function renderListSection(_ref3) { | ||
var _this2 = this; | ||
value: function renderListSection(_ref2) { | ||
var _this4 = this; | ||
var _ref32 = _slicedToArray(_ref3, 3); | ||
var _ref22 = _slicedToArray(_ref2, 3); | ||
var type = _ref32[0]; | ||
var tagName = _ref32[1]; | ||
var listItems = _ref32[2]; | ||
var type = _ref22[0]; | ||
var tagName = _ref22[1]; | ||
var listItems = _ref22[2]; | ||
@@ -594,3 +613,3 @@ if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE)) { | ||
listItems.forEach(function (li) { | ||
element.appendChild(_this2.renderListItem(li)); | ||
element.appendChild(_this4.renderListItem(li)); | ||
}); | ||
@@ -601,7 +620,7 @@ return element; | ||
key: 'renderImageSection', | ||
value: function renderImageSection(_ref4) { | ||
var _ref42 = _slicedToArray(_ref4, 2); | ||
value: function renderImageSection(_ref3) { | ||
var _ref32 = _slicedToArray(_ref3, 2); | ||
var type = _ref42[0]; | ||
var src = _ref42[1]; | ||
var type = _ref32[0]; | ||
var src = _ref32[1]; | ||
@@ -637,3 +656,3 @@ var element = this.dom.createElement(IMAGE_SECTION_TAG_NAME); | ||
value: function _createCardArgument(card) { | ||
var _this3 = this; | ||
var _this5 = this; | ||
@@ -647,6 +666,6 @@ var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
didRender: function didRender(callback) { | ||
return _this3._registerRenderCallback(callback); | ||
return _this5._registerRenderCallback(callback); | ||
}, | ||
onTeardown: function onTeardown(callback) { | ||
return _this3._registerTeardownCallback(callback); | ||
return _this5._registerTeardownCallback(callback); | ||
} | ||
@@ -671,8 +690,8 @@ }; | ||
key: 'renderCardSection', | ||
value: function renderCardSection(_ref5) { | ||
var _ref52 = _slicedToArray(_ref5, 3); | ||
value: function renderCardSection(_ref4) { | ||
var _ref42 = _slicedToArray(_ref4, 3); | ||
var type = _ref52[0]; | ||
var name = _ref52[1]; | ||
var payload = _ref52[2]; | ||
var type = _ref42[0]; | ||
var name = _ref42[1]; | ||
var payload = _ref42[2]; | ||
@@ -701,9 +720,10 @@ var card = this.findCard(name); | ||
key: 'renderMarkupSection', | ||
value: function renderMarkupSection(_ref6) { | ||
var _ref62 = _slicedToArray(_ref6, 3); | ||
value: function renderMarkupSection(_ref5) { | ||
var _ref52 = _slicedToArray(_ref5, 3); | ||
var type = _ref62[0]; | ||
var tagName = _ref62[1]; | ||
var markers = _ref62[2]; | ||
var type = _ref52[0]; | ||
var tagName = _ref52[1]; | ||
var markers = _ref52[2]; | ||
tagName = tagName.toLowerCase(); | ||
if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE)) { | ||
@@ -713,12 +733,4 @@ return; | ||
var element = undefined; | ||
var lowerCaseTagName = tagName.toLowerCase(); | ||
if (this.sectionElementRenderer[lowerCaseTagName]) { | ||
element = this.sectionElementRenderer[lowerCaseTagName](tagName, this.dom); | ||
} else if ((0, _mobiledocDomRendererUtilsTagNames.isMarkupSectionElementName)(tagName)) { | ||
element = this.dom.createElement(tagName); | ||
} else { | ||
element = this.dom.createElement('div'); | ||
element.setAttribute('class', tagName); | ||
} | ||
var renderer = this.sectionElementRendererFor(tagName); | ||
var element = renderer(tagName, this.dom); | ||
@@ -729,6 +741,11 @@ this.renderMarkersOnElement(element, markers); | ||
}, { | ||
key: 'sectionElementRendererFor', | ||
value: function sectionElementRendererFor(tagName) { | ||
return this.sectionElementRenderer[tagName] || this.sectionElementRenderer.__default__; | ||
} | ||
}, { | ||
key: '_defaultUnknownCardHandler', | ||
get: function get() { | ||
return function (_ref7) { | ||
var name = _ref7.env.name; | ||
return function (_ref6) { | ||
var name = _ref6.env.name; | ||
@@ -745,3 +762,3 @@ throw new Error('Card "' + name + '" not found but no unknownCardHandler was registered'); | ||
}); | ||
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/marker-types'], function (exports, _mobiledocDomRendererUtilsDom, _mobiledocDomRendererCardsImage, _mobiledocDomRendererUtilsRenderType, _mobiledocDomRendererUtilsSectionTypes, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils, _mobiledocDomRendererUtilsMarkerTypes) { | ||
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) { | ||
'use strict'; | ||
@@ -764,24 +781,9 @@ | ||
function createElementFromMarkerType(dom) { | ||
var _ref = arguments.length <= 1 || arguments[1] === undefined ? ['', []] : arguments[1]; | ||
var _ref2 = _slicedToArray(_ref, 2); | ||
var tagName = _ref2[0]; | ||
var attributes = _ref2[1]; | ||
var element = dom.createElement(tagName); | ||
attributes = attributes || []; | ||
for (var i = 0, l = attributes.length; i < l; i = i + 2) { | ||
var propName = attributes[i], | ||
propValue = attributes[i + 1]; | ||
element.setAttribute(propName, (0, _mobiledocDomRendererUtilsSanitizationUtils.sanitizeAttributeValue)(propName, propValue, tagName)); | ||
} | ||
return element; | ||
} | ||
function validateVersion(version) { | ||
if (version !== MOBILEDOC_VERSION_0_3_0 && version !== MOBILEDOC_VERSION_0_3_1) { | ||
throw new Error('Unexpected Mobiledoc version "' + version + '"'); | ||
switch (version) { | ||
case MOBILEDOC_VERSION_0_3_0: | ||
case MOBILEDOC_VERSION_0_3_1: | ||
return; | ||
default: | ||
throw new Error('Unexpected Mobiledoc version "' + version + '"'); | ||
} | ||
@@ -792,2 +794,4 @@ } | ||
function Renderer(mobiledoc, state) { | ||
var _this = this; | ||
_classCallCheck(this, Renderer); | ||
@@ -803,2 +807,3 @@ | ||
var dom = state.dom; | ||
var markupSanitizer = state.markupSanitizer; | ||
var version = mobiledoc.version; | ||
@@ -823,20 +828,17 @@ var sections = mobiledoc.sections; | ||
this.unknownAtomHandler = unknownAtomHandler || this._defaultUnknownAtomHandler; | ||
this.markupSanitizer = (0, _mobiledocDomRendererUtilsRenderUtils.createMarkupSanitizerWithFallback)(markupSanitizer); | ||
this.sectionElementRenderer = {}; | ||
if (sectionElementRenderer) { | ||
for (var key in sectionElementRenderer) { | ||
if (sectionElementRenderer.hasOwnProperty(key)) { | ||
this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key]; | ||
} | ||
} | ||
} | ||
this.sectionElementRenderer = { | ||
'__default__': _mobiledocDomRendererUtilsRenderUtils.defaultSectionElementRenderer | ||
}; | ||
Object.keys(sectionElementRenderer).forEach(function (key) { | ||
_this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key]; | ||
}); | ||
this.markupElementRenderer = {}; | ||
if (markupElementRenderer) { | ||
for (var key in markupElementRenderer) { | ||
if (markupElementRenderer.hasOwnProperty(key)) { | ||
this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key]; | ||
} | ||
} | ||
} | ||
this.markupElementRenderer = { | ||
'__default__': _mobiledocDomRendererUtilsRenderUtils.defaultMarkupElementRenderer | ||
}; | ||
Object.keys(markupElementRenderer).forEach(function (key) { | ||
_this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key]; | ||
}); | ||
@@ -850,8 +852,8 @@ this._renderCallbacks = []; | ||
value: function render() { | ||
var _this = this; | ||
var _this2 = this; | ||
this.sections.forEach(function (section) { | ||
var rendered = _this.renderSection(section); | ||
var rendered = _this2.renderSection(section); | ||
if (rendered) { | ||
_this.root.appendChild(rendered); | ||
_this2.root.appendChild(rendered); | ||
} | ||
@@ -865,3 +867,3 @@ }); | ||
return { result: this.root, teardown: function teardown() { | ||
return _this.teardown(); | ||
return _this2.teardown(); | ||
} }; | ||
@@ -934,11 +936,3 @@ } | ||
if ((0, _mobiledocDomRendererUtilsTagNames.isValidMarkerType)(tagName)) { | ||
var lowerCaseTagName = tagName.toLowerCase(); | ||
if (this.markupElementRenderer[lowerCaseTagName]) { | ||
var attrObj = (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAndSanitizeAttributes)(attrs, lowerCaseTagName); | ||
var openedElement = this.markupElementRenderer[lowerCaseTagName](tagName, this.dom, attrObj); | ||
pushElement(openedElement); | ||
} else { | ||
var openedElement = createElementFromMarkerType(this.dom, markerType); | ||
pushElement(openedElement); | ||
} | ||
pushElement(this.renderMarkupElement(tagName, attrs)); | ||
} else { | ||
@@ -966,3 +960,44 @@ closeCount--; | ||
} | ||
/** | ||
* @param attrs Array | ||
*/ | ||
}, { | ||
key: 'renderMarkupElement', | ||
value: function renderMarkupElement(tagName, attrs) { | ||
tagName = tagName.toLowerCase(); | ||
attrs = this.sanitizeAttributes(tagName, (0, _mobiledocDomRendererUtilsSanitizationUtils.reduceAttributes)(attrs)); | ||
var renderer = this.markupElementRendererFor(tagName); | ||
return renderer(tagName, this.dom, attrs); | ||
} | ||
}, { | ||
key: 'markupElementRendererFor', | ||
value: function markupElementRendererFor(tagName) { | ||
return this.markupElementRenderer[tagName] || this.markupElementRenderer.__default__; | ||
} | ||
}, { | ||
key: 'sanitizeAttributes', | ||
value: function sanitizeAttributes(tagName, attrsObj) { | ||
var _this3 = this; | ||
var sanitized = {}; | ||
Object.keys(attrsObj).forEach(function (attributeName) { | ||
var attributeValue = attrsObj[attributeName]; | ||
sanitized[attributeName] = _this3.sanitizeAttribute({ tagName: tagName, attributeName: attributeName, attributeValue: attributeValue }); | ||
}); | ||
return sanitized; | ||
} | ||
}, { | ||
key: 'sanitizeAttribute', | ||
value: function sanitizeAttribute(_ref) { | ||
var tagName = _ref.tagName; | ||
var attributeName = _ref.attributeName; | ||
var attributeValue = _ref.attributeValue; | ||
return this.markupSanitizer({ tagName: tagName, attributeName: attributeName, attributeValue: attributeValue }); | ||
} | ||
}, { | ||
key: 'renderListItem', | ||
@@ -976,10 +1011,10 @@ value: function renderListItem(markers) { | ||
key: 'renderListSection', | ||
value: function renderListSection(_ref3) { | ||
var _this2 = this; | ||
value: function renderListSection(_ref2) { | ||
var _this4 = this; | ||
var _ref32 = _slicedToArray(_ref3, 3); | ||
var _ref22 = _slicedToArray(_ref2, 3); | ||
var type = _ref32[0]; | ||
var tagName = _ref32[1]; | ||
var listItems = _ref32[2]; | ||
var type = _ref22[0]; | ||
var tagName = _ref22[1]; | ||
var listItems = _ref22[2]; | ||
@@ -991,3 +1026,3 @@ if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE)) { | ||
listItems.forEach(function (li) { | ||
element.appendChild(_this2.renderListItem(li)); | ||
element.appendChild(_this4.renderListItem(li)); | ||
}); | ||
@@ -998,7 +1033,7 @@ return element; | ||
key: 'renderImageSection', | ||
value: function renderImageSection(_ref4) { | ||
var _ref42 = _slicedToArray(_ref4, 2); | ||
value: function renderImageSection(_ref3) { | ||
var _ref32 = _slicedToArray(_ref3, 2); | ||
var type = _ref42[0]; | ||
var src = _ref42[1]; | ||
var type = _ref32[0]; | ||
var src = _ref32[1]; | ||
@@ -1054,3 +1089,3 @@ var element = this.dom.createElement(IMAGE_SECTION_TAG_NAME); | ||
value: function _createCardArgument(card) { | ||
var _this3 = this; | ||
var _this5 = this; | ||
@@ -1064,6 +1099,6 @@ var payload = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
didRender: function didRender(callback) { | ||
return _this3._registerRenderCallback(callback); | ||
return _this5._registerRenderCallback(callback); | ||
}, | ||
onTeardown: function onTeardown(callback) { | ||
return _this3._registerTeardownCallback(callback); | ||
return _this5._registerTeardownCallback(callback); | ||
} | ||
@@ -1088,7 +1123,7 @@ }; | ||
key: 'renderCardSection', | ||
value: function renderCardSection(_ref5) { | ||
var _ref52 = _slicedToArray(_ref5, 2); | ||
value: function renderCardSection(_ref4) { | ||
var _ref42 = _slicedToArray(_ref4, 2); | ||
var type = _ref52[0]; | ||
var index = _ref52[1]; | ||
var type = _ref42[0]; | ||
var index = _ref42[1]; | ||
@@ -1140,3 +1175,3 @@ var _findCardByIndex2 = this._findCardByIndex(index); | ||
value: function _createAtomArgument(atom, value, payload) { | ||
var _this4 = this; | ||
var _this6 = this; | ||
@@ -1148,3 +1183,3 @@ var env = { | ||
onTeardown: function onTeardown(callback) { | ||
return _this4._registerTeardownCallback(callback); | ||
return _this6._registerTeardownCallback(callback); | ||
} | ||
@@ -1208,9 +1243,10 @@ }; | ||
key: 'renderMarkupSection', | ||
value: function renderMarkupSection(_ref6) { | ||
var _ref62 = _slicedToArray(_ref6, 3); | ||
value: function renderMarkupSection(_ref5) { | ||
var _ref52 = _slicedToArray(_ref5, 3); | ||
var type = _ref62[0]; | ||
var tagName = _ref62[1]; | ||
var markers = _ref62[2]; | ||
var type = _ref52[0]; | ||
var tagName = _ref52[1]; | ||
var markers = _ref52[2]; | ||
tagName = tagName.toLowerCase(); | ||
if (!(0, _mobiledocDomRendererUtilsTagNames.isValidSectionTagName)(tagName, _mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE)) { | ||
@@ -1220,12 +1256,4 @@ return; | ||
var element = undefined; | ||
var lowerCaseTagName = tagName.toLowerCase(); | ||
if (this.sectionElementRenderer[lowerCaseTagName]) { | ||
element = this.sectionElementRenderer[lowerCaseTagName](tagName, this.dom); | ||
} else if ((0, _mobiledocDomRendererUtilsTagNames.isMarkupSectionElementName)(tagName)) { | ||
element = this.dom.createElement(tagName); | ||
} else { | ||
element = this.dom.createElement('div'); | ||
element.setAttribute('class', tagName); | ||
} | ||
var renderer = this.sectionElementRendererFor(tagName); | ||
var element = renderer(tagName, this.dom); | ||
@@ -1236,6 +1264,11 @@ this.renderMarkersOnElement(element, markers); | ||
}, { | ||
key: 'sectionElementRendererFor', | ||
value: function sectionElementRendererFor(tagName) { | ||
return this.sectionElementRenderer[tagName] || this.sectionElementRenderer.__default__; | ||
} | ||
}, { | ||
key: '_defaultUnknownCardHandler', | ||
get: function get() { | ||
return function (_ref7) { | ||
var name = _ref7.env.name; | ||
return function (_ref6) { | ||
var name = _ref6.env.name; | ||
@@ -1248,4 +1281,4 @@ throw new Error('Card "' + name + '" not found but no unknownCardHandler was registered'); | ||
get: function get() { | ||
return function (_ref8) { | ||
var name = _ref8.env.name; | ||
return function (_ref7) { | ||
var name = _ref7.env.name; | ||
@@ -1315,2 +1348,57 @@ throw new Error('Atom "' + name + '" not found but no unknownAtomHandler was registered'); | ||
}); | ||
define('mobiledoc-dom-renderer/utils/render-utils', ['exports', 'mobiledoc-dom-renderer/utils/tag-names', 'mobiledoc-dom-renderer/utils/sanitization-utils'], function (exports, _mobiledocDomRendererUtilsTagNames, _mobiledocDomRendererUtilsSanitizationUtils) { | ||
'use strict'; | ||
exports.createMarkupSanitizerWithFallback = createMarkupSanitizerWithFallback; | ||
exports.defaultSectionElementRenderer = defaultSectionElementRenderer; | ||
exports.defaultMarkupElementRenderer = defaultMarkupElementRenderer; | ||
function defaultMarkupSanitizer(_ref) { | ||
var tagName = _ref.tagName; | ||
var attributeName = _ref.attributeName; | ||
var attributeValue = _ref.attributeValue; | ||
if (tagName === 'a' && attributeName === 'href') { | ||
return (0, _mobiledocDomRendererUtilsSanitizationUtils.sanitizeHref)(attributeValue); | ||
} else { | ||
return attributeValue; | ||
} | ||
} | ||
/* | ||
* return a sanitizer function that first uses the passed sanitizer | ||
* (if present), and then uses the default sanitizer if that didn't return | ||
* a string | ||
*/ | ||
function createMarkupSanitizerWithFallback(sanitizer) { | ||
if (sanitizer) { | ||
return function () { | ||
return sanitizer.apply(undefined, arguments) || defaultMarkupSanitizer.apply(undefined, arguments); | ||
}; | ||
} else { | ||
return defaultMarkupSanitizer; | ||
} | ||
} | ||
function defaultSectionElementRenderer(tagName, dom) { | ||
var element = undefined; | ||
if ((0, _mobiledocDomRendererUtilsTagNames.isMarkupSectionElementName)(tagName)) { | ||
element = dom.createElement(tagName); | ||
} else { | ||
element = dom.createElement('div'); | ||
element.setAttribute('class', tagName); | ||
} | ||
return element; | ||
} | ||
function defaultMarkupElementRenderer(tagName, dom, attrsObj) { | ||
var element = dom.createElement(tagName); | ||
Object.keys(attrsObj).forEach(function (key) { | ||
element.setAttribute(key, attrsObj[key]); | ||
}); | ||
return element; | ||
} | ||
}); | ||
define('mobiledoc-dom-renderer/utils/sanitization-utils', ['exports', 'mobiledoc-dom-renderer/utils/array-utils', 'mobiledoc-dom-renderer/utils/dom'], function (exports, _mobiledocDomRendererUtilsArrayUtils, _mobiledocDomRendererUtilsDom) { | ||
@@ -1321,4 +1409,4 @@ /* globals module */ | ||
exports.sanitizeAttributeValue = sanitizeAttributeValue; | ||
exports.reduceAndSanitizeAttributes = reduceAndSanitizeAttributes; | ||
exports.sanitizeHref = sanitizeHref; | ||
exports.reduceAttributes = reduceAttributes; | ||
@@ -1356,17 +1444,15 @@ var badProtocols = ['javascript:', // jshint ignore:line | ||
function sanitizeAttributeValue(attributeName, attributeValue, tagName) { | ||
if (tagName === 'a' && attributeName === 'href') { | ||
return sanitizeHref(attributeValue); | ||
} | ||
return attributeValue; | ||
} | ||
/** | ||
* @param attributes array | ||
* @return obj with normalized attribute names (lowercased) | ||
*/ | ||
function reduceAndSanitizeAttributes(attributes, tagName) { | ||
var attrsObj = {}; | ||
for (var i = 0, l = attributes.length; i < l; i = i + 2) { | ||
var propName = attributes[i], | ||
propValue = attributes[i + 1]; | ||
attrsObj[propName] = sanitizeAttributeValue(propName, propValue, tagName); | ||
function reduceAttributes(attributes) { | ||
var obj = {}; | ||
for (var i = 0; i < attributes.length; i += 2) { | ||
var key = attributes[i]; | ||
var val = attributes[i + 1]; | ||
obj[key.toLowerCase()] = val; | ||
} | ||
return attrsObj; | ||
return obj; | ||
} | ||
@@ -1373,0 +1459,0 @@ }); |
@@ -50,16 +50,14 @@ import Renderer_0_2, { | ||
constructor({ | ||
cards, | ||
atoms, | ||
cardOptions, | ||
cards=[], | ||
atoms=[], | ||
cardOptions={}, | ||
unknownCardHandler, | ||
unknownAtomHandler, | ||
markupElementRenderer, | ||
sectionElementRenderer, | ||
dom | ||
markupElementRenderer={}, | ||
sectionElementRenderer={}, | ||
dom, | ||
markupSanitizer=null | ||
}={}) { | ||
cards = cards || []; | ||
validateCards(cards); | ||
atoms = atoms || []; | ||
validateAtoms(atoms); | ||
cardOptions = cardOptions || {}; | ||
@@ -81,3 +79,4 @@ if (!dom) { | ||
sectionElementRenderer, | ||
dom | ||
dom, | ||
markupSanitizer | ||
}; | ||
@@ -84,0 +83,0 @@ } |
@@ -12,9 +12,12 @@ import { createTextNode } from '../utils/dom'; | ||
isValidSectionTagName, | ||
isMarkupSectionElementName, | ||
isValidMarkerType | ||
} from '../utils/tag-names'; | ||
import { | ||
reduceAndSanitizeAttributes, | ||
sanitizeAttributeValue | ||
reduceAttributes | ||
} from '../utils/sanitization-utils'; | ||
import { | ||
createMarkupSanitizerWithFallback, | ||
defaultSectionElementRenderer, | ||
defaultMarkupElementRenderer | ||
} from '../utils/render-utils'; | ||
@@ -25,14 +28,2 @@ export const MOBILEDOC_VERSION = '0.2.0'; | ||
function createElementFromMarkerType(dom, [tagName, attributes]=['', []]){ | ||
let element = dom.createElement(tagName); | ||
attributes = attributes || []; | ||
for (let i=0,l=attributes.length; i<l; i=i+2) { | ||
let propName = attributes[i], | ||
propValue = attributes[i+1]; | ||
element.setAttribute(propName, sanitizeAttributeValue(propName, propValue, tagName)); | ||
} | ||
return element; | ||
} | ||
function validateVersion(version) { | ||
@@ -52,3 +43,4 @@ if (version !== MOBILEDOC_VERSION) { | ||
sectionElementRenderer, | ||
dom | ||
dom, | ||
markupSanitizer | ||
} = options; | ||
@@ -70,20 +62,17 @@ let { | ||
this.unknownCardHandler = unknownCardHandler || this._defaultUnknownCardHandler; | ||
this.markupSanitizer = createMarkupSanitizerWithFallback(markupSanitizer); | ||
this.sectionElementRenderer = {}; | ||
if (sectionElementRenderer) { | ||
for (let key in sectionElementRenderer) { | ||
if (sectionElementRenderer.hasOwnProperty(key)) { | ||
this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key]; | ||
} | ||
} | ||
} | ||
this.sectionElementRenderer = { | ||
'__default__': defaultSectionElementRenderer | ||
}; | ||
Object.keys(sectionElementRenderer).forEach(key => { | ||
this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key]; | ||
}); | ||
this.markupElementRenderer = {}; | ||
if (markupElementRenderer) { | ||
for (let key in markupElementRenderer) { | ||
if (markupElementRenderer.hasOwnProperty(key)) { | ||
this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key]; | ||
} | ||
} | ||
} | ||
this.markupElementRenderer = { | ||
'__default__': defaultMarkupElementRenderer | ||
}; | ||
Object.keys(markupElementRenderer).forEach(key => { | ||
this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key]; | ||
}); | ||
@@ -167,11 +156,3 @@ this._renderCallbacks = []; | ||
if (isValidMarkerType(tagName)) { | ||
let lowerCaseTagName = tagName.toLowerCase(); | ||
if (this.markupElementRenderer[lowerCaseTagName]) { | ||
let attrObj = reduceAndSanitizeAttributes(attrs, lowerCaseTagName); | ||
let openedElement = this.markupElementRenderer[lowerCaseTagName](tagName, this.dom, attrObj); | ||
pushElement(openedElement); | ||
} else { | ||
let openedElement = createElementFromMarkerType(this.dom, markerType); | ||
pushElement(openedElement); | ||
} | ||
pushElement(this.renderMarkupElement(tagName, attrs)); | ||
} else { | ||
@@ -191,2 +172,33 @@ closeCount--; | ||
/** | ||
* @param attrs Array | ||
*/ | ||
renderMarkupElement(tagName, attrs) { | ||
tagName = tagName.toLowerCase(); | ||
attrs = this.sanitizeAttributes(tagName, reduceAttributes(attrs)); | ||
let renderer = this.markupElementRendererFor(tagName); | ||
return renderer(tagName, this.dom, attrs); | ||
} | ||
markupElementRendererFor(tagName) { | ||
return this.markupElementRenderer[tagName] || | ||
this.markupElementRenderer.__default__; | ||
} | ||
sanitizeAttributes(tagName, attrsObj) { | ||
let sanitized = {}; | ||
Object.keys(attrsObj).forEach(attributeName => { | ||
let attributeValue = attrsObj[attributeName]; | ||
sanitized[attributeName] = this.sanitizeAttribute({tagName, attributeName, attributeValue}); | ||
}); | ||
return sanitized; | ||
} | ||
sanitizeAttribute({tagName, attributeName, attributeValue}) { | ||
return this.markupSanitizer({tagName, attributeName, attributeValue}); | ||
} | ||
renderListItem(markers) { | ||
@@ -279,2 +291,3 @@ const element = this.dom.createElement('li'); | ||
renderMarkupSection([type, tagName, markers]) { | ||
tagName = tagName.toLowerCase(); | ||
if (!isValidSectionTagName(tagName, MARKUP_SECTION_TYPE)) { | ||
@@ -284,12 +297,4 @@ return; | ||
let element; | ||
let lowerCaseTagName = tagName.toLowerCase(); | ||
if (this.sectionElementRenderer[lowerCaseTagName]) { | ||
element = this.sectionElementRenderer[lowerCaseTagName](tagName, this.dom); | ||
} else if (isMarkupSectionElementName(tagName)) { | ||
element = this.dom.createElement(tagName); | ||
} else { | ||
element = this.dom.createElement('div'); | ||
element.setAttribute('class', tagName); | ||
} | ||
let renderer = this.sectionElementRendererFor(tagName); | ||
let element = renderer(tagName, this.dom); | ||
@@ -299,3 +304,8 @@ this.renderMarkersOnElement(element, markers); | ||
} | ||
sectionElementRendererFor(tagName) { | ||
return this.sectionElementRenderer[tagName] || | ||
this.sectionElementRenderer.__default__; | ||
} | ||
} | ||
@@ -12,9 +12,12 @@ import { createTextNode } from '../utils/dom'; | ||
isValidSectionTagName, | ||
isMarkupSectionElementName, | ||
isValidMarkerType | ||
} from '../utils/tag-names'; | ||
import { | ||
reduceAndSanitizeAttributes, | ||
sanitizeAttributeValue | ||
reduceAttributes | ||
} from '../utils/sanitization-utils'; | ||
import { | ||
createMarkupSanitizerWithFallback, | ||
defaultSectionElementRenderer, | ||
defaultMarkupElementRenderer | ||
} from '../utils/render-utils'; | ||
@@ -32,17 +35,9 @@ import { | ||
function createElementFromMarkerType(dom, [tagName, attributes]=['', []]){ | ||
let element = dom.createElement(tagName); | ||
attributes = attributes || []; | ||
for (let i=0,l=attributes.length; i<l; i=i+2) { | ||
let propName = attributes[i], | ||
propValue = attributes[i+1]; | ||
element.setAttribute(propName, sanitizeAttributeValue(propName, propValue, tagName)); | ||
} | ||
return element; | ||
} | ||
function validateVersion(version) { | ||
if (version !== MOBILEDOC_VERSION_0_3_0 && version !== MOBILEDOC_VERSION_0_3_1) { | ||
throw new Error(`Unexpected Mobiledoc version "${version}"`); | ||
switch (version) { | ||
case MOBILEDOC_VERSION_0_3_0: | ||
case MOBILEDOC_VERSION_0_3_1: | ||
return; | ||
default: | ||
throw new Error(`Unexpected Mobiledoc version "${version}"`); | ||
} | ||
@@ -62,3 +57,4 @@ } | ||
sectionElementRenderer, | ||
dom | ||
dom, | ||
markupSanitizer | ||
} = state; | ||
@@ -85,20 +81,17 @@ let { | ||
this.unknownAtomHandler = unknownAtomHandler || this._defaultUnknownAtomHandler; | ||
this.markupSanitizer = createMarkupSanitizerWithFallback(markupSanitizer); | ||
this.sectionElementRenderer = {}; | ||
if (sectionElementRenderer) { | ||
for (let key in sectionElementRenderer) { | ||
if (sectionElementRenderer.hasOwnProperty(key)) { | ||
this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key]; | ||
} | ||
} | ||
} | ||
this.sectionElementRenderer = { | ||
'__default__': defaultSectionElementRenderer | ||
}; | ||
Object.keys(sectionElementRenderer).forEach(key => { | ||
this.sectionElementRenderer[key.toLowerCase()] = sectionElementRenderer[key]; | ||
}); | ||
this.markupElementRenderer = {}; | ||
if (markupElementRenderer) { | ||
for (let key in markupElementRenderer) { | ||
if (markupElementRenderer.hasOwnProperty(key)) { | ||
this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key]; | ||
} | ||
} | ||
} | ||
this.markupElementRenderer = { | ||
'__default__': defaultMarkupElementRenderer | ||
}; | ||
Object.keys(markupElementRenderer).forEach(key => { | ||
this.markupElementRenderer[key.toLowerCase()] = markupElementRenderer[key]; | ||
}); | ||
@@ -181,12 +174,5 @@ this._renderCallbacks = []; | ||
let [tagName, attrs=[]] = markerType; | ||
if (isValidMarkerType(tagName)) { | ||
let lowerCaseTagName = tagName.toLowerCase(); | ||
if (this.markupElementRenderer[lowerCaseTagName]) { | ||
let attrObj = reduceAndSanitizeAttributes(attrs, lowerCaseTagName); | ||
let openedElement = this.markupElementRenderer[lowerCaseTagName](tagName, this.dom, attrObj); | ||
pushElement(openedElement); | ||
} else { | ||
let openedElement = createElementFromMarkerType(this.dom, markerType); | ||
pushElement(openedElement); | ||
} | ||
pushElement(this.renderMarkupElement(tagName, attrs)); | ||
} else { | ||
@@ -215,2 +201,33 @@ closeCount--; | ||
/** | ||
* @param attrs Array | ||
*/ | ||
renderMarkupElement(tagName, attrs) { | ||
tagName = tagName.toLowerCase(); | ||
attrs = this.sanitizeAttributes(tagName, reduceAttributes(attrs)); | ||
let renderer = this.markupElementRendererFor(tagName); | ||
return renderer(tagName, this.dom, attrs); | ||
} | ||
markupElementRendererFor(tagName) { | ||
return this.markupElementRenderer[tagName] || | ||
this.markupElementRenderer.__default__; | ||
} | ||
sanitizeAttributes(tagName, attrsObj) { | ||
let sanitized = {}; | ||
Object.keys(attrsObj).forEach(attributeName => { | ||
let attributeValue = attrsObj[attributeName]; | ||
sanitized[attributeName] = this.sanitizeAttribute({tagName, attributeName, attributeValue}); | ||
}); | ||
return sanitized; | ||
} | ||
sanitizeAttribute({tagName, attributeName, attributeValue}) { | ||
return this.markupSanitizer({tagName, attributeName, attributeValue}); | ||
} | ||
renderListItem(markers) { | ||
@@ -385,2 +402,3 @@ const element = this.dom.createElement('li'); | ||
renderMarkupSection([type, tagName, markers]) { | ||
tagName = tagName.toLowerCase(); | ||
if (!isValidSectionTagName(tagName, MARKUP_SECTION_TYPE)) { | ||
@@ -390,12 +408,4 @@ return; | ||
let element; | ||
let lowerCaseTagName = tagName.toLowerCase(); | ||
if (this.sectionElementRenderer[lowerCaseTagName]) { | ||
element = this.sectionElementRenderer[lowerCaseTagName](tagName, this.dom); | ||
} else if (isMarkupSectionElementName(tagName)) { | ||
element = this.dom.createElement(tagName); | ||
} else { | ||
element = this.dom.createElement('div'); | ||
element.setAttribute('class', tagName); | ||
} | ||
let renderer = this.sectionElementRendererFor(tagName); | ||
let element = renderer(tagName, this.dom); | ||
@@ -405,3 +415,8 @@ this.renderMarkersOnElement(element, markers); | ||
} | ||
sectionElementRendererFor(tagName) { | ||
return this.sectionElementRenderer[tagName] || | ||
this.sectionElementRenderer.__default__; | ||
} | ||
} | ||
@@ -33,3 +33,3 @@ /* globals module */ | ||
function sanitizeHref(url) { | ||
export function sanitizeHref(url) { | ||
let protocol = getProtocol(url); | ||
@@ -42,18 +42,14 @@ if (includes(badProtocols, protocol)) { | ||
export function sanitizeAttributeValue(attributeName, attributeValue, tagName) { | ||
if (tagName === 'a' && attributeName === 'href') { | ||
return sanitizeHref(attributeValue); | ||
/** | ||
* @param attributes array | ||
* @return obj with normalized attribute names (lowercased) | ||
*/ | ||
export function reduceAttributes(attributes) { | ||
let obj = {}; | ||
for (let i = 0; i < attributes.length; i += 2) { | ||
let key = attributes[i]; | ||
let val = attributes[i+1]; | ||
obj[key.toLowerCase()] = val; | ||
} | ||
return attributeValue; | ||
return obj; | ||
} | ||
export function reduceAndSanitizeAttributes(attributes, tagName) { | ||
let attrsObj = {}; | ||
for (let i=0,l=attributes.length; i<l; i=i+2) { | ||
let propName = attributes[i], | ||
propValue = attributes[i+1]; | ||
attrsObj[propName] = sanitizeAttributeValue(propName, propValue, tagName); | ||
} | ||
return attrsObj; | ||
} | ||
{ | ||
"name": "mobiledoc-dom-renderer", | ||
"version": "0.6.3", | ||
"version": "0.6.4-0", | ||
"description": "Renders Mobiledoc input to DOM output", | ||
"scripts": { | ||
"start": "broccoli serve", | ||
"test": "testem ci", | ||
@@ -7,0 +8,0 @@ "build": "rm -rf dist/ && broccoli build dist", |
@@ -132,5 +132,35 @@ ## Mobiledoc DOM Renderer [![Build Status](https://travis-ci.org/bustlelabs/mobiledoc-dom-renderer.svg?branch=master)](https://travis-ci.org/bustlelabs/mobiledoc-dom-renderer) | ||
#### markupSanitizer | ||
Use this renderer option to customize how markup attribute values are sanitized. | ||
The renderer's default markupSanitizer only sanitizes `href` values, prefixing | ||
unsafe values with the string `"unsafe:"`. All other attribute values are | ||
passed through unchanged. | ||
To change this behavior, pass your own markupSanitizer function when | ||
instantiating the renderer. If your markupSanitizer function returns a string, | ||
that value will be used when rendering. If it returns a falsy value, the | ||
renderer's default markupSanitizer will be used. | ||
``` | ||
var renderer = new MobiledocDOMRenderer({ | ||
markupSanitizer: function({tagName, attributeName, attributeValue}) { | ||
// This function will be called for every attribute on every markup. | ||
// Return a sanitized attributeValue or undefined (in which case the | ||
// default sanitizer will be used) | ||
} | ||
}); | ||
``` | ||
The default sanitization of href values uses an environment-appropriate url | ||
parser if it can find one. It's unlikely, but if the renderer is in an | ||
environment where it cannot determine a url parser it will throw. (This can | ||
happen when running the renderer in a VM Sandbox, like ember-cli-fastboot | ||
does.) In this case you must supply a custom markupSanitizer that can handle | ||
`href` sanitization. | ||
### Tests | ||
* `npm test` | ||
* To run tests via testem: `npm test` | ||
* To run tests in the browser: `npm start` and open http://localhost:4200/tests | ||
@@ -137,0 +167,0 @@ ### Releasing |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
513743
40
10260
171
0