rittenhop-ghost/versions/5.94.2/node_modules/mobiledoc-dom-renderer/dist/tests/built-amd-tests.js

1855 lines
67 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

define('tests/helpers/create-mobiledoc', ['exports', 'mobiledoc-dom-renderer/utils/section-types', 'mobiledoc-dom-renderer/utils/marker-types', 'mobiledoc-dom-renderer/utils/array-utils'], function (exports, _mobiledocDomRendererUtilsSectionTypes, _mobiledocDomRendererUtilsMarkerTypes, _mobiledocDomRendererUtilsArrayUtils) {
'use strict';
exports.createBlankMobiledoc = createBlankMobiledoc;
exports.createMobiledocWithAtom = createMobiledocWithAtom;
exports.createMobiledocWithCard = createMobiledocWithCard;
exports.createSimpleMobiledoc = createSimpleMobiledoc;
var MOBILEDOC_VERSION_0_3_2 = '0.3.2';
function createBlankMobiledoc() {
var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var _ref$version = _ref.version;
var version = _ref$version === undefined ? MOBILEDOC_VERSION_0_3_2 : _ref$version;
return {
version: version,
atoms: [],
cards: [],
markups: [],
sections: []
};
}
function createMobiledocWithAtom() {
var _ref2 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var _ref2$version = _ref2.version;
var version = _ref2$version === undefined ? MOBILEDOC_VERSION_0_3_2 : _ref2$version;
var atom = _ref2.atom;
return {
version: version,
atoms: [atom],
cards: [],
markups: [],
sections: [[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[_mobiledocDomRendererUtilsMarkerTypes.ATOM_MARKER_TYPE, [], 0, 0]]]]
};
}
function createMobiledocWithCard() {
var _ref3 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var _ref3$version = _ref3.version;
var version = _ref3$version === undefined ? MOBILEDOC_VERSION_0_3_2 : _ref3$version;
var card = _ref3.card;
return {
version: version,
atoms: [],
cards: [[card.name, card.payload || {}]],
markups: [],
sections: [[_mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE, 0]]
};
}
function createSimpleMobiledoc() {
var _ref4 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var _ref4$sectionName = _ref4.sectionName;
var sectionName = _ref4$sectionName === undefined ? 'p' : _ref4$sectionName;
var _ref4$text = _ref4.text;
var text = _ref4$text === undefined ? 'hello world' : _ref4$text;
var _ref4$markup = _ref4.markup;
var markup = _ref4$markup === undefined ? null : _ref4$markup;
var _ref4$version = _ref4.version;
var version = _ref4$version === undefined ? MOBILEDOC_VERSION_0_3_2 : _ref4$version;
var _ref4$attributes = _ref4.attributes;
var attributes = _ref4$attributes === undefined ? {} : _ref4$attributes;
var openedMarkups = markup ? [0] : [];
var closedMarkups = markup ? 1 : 0;
var markups = markup ? [markup] : [];
var section = [_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, sectionName, [[_mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, openedMarkups, closedMarkups, text]]];
if (version === MOBILEDOC_VERSION_0_3_2) {
section.push((0, _mobiledocDomRendererUtilsArrayUtils.objectToSortedKVArray)(attributes));
}
return {
version: version,
atoms: [],
cards: [],
markups: markups,
sections: [section]
};
}
});
define('tests/helpers/dom', ['exports'], function (exports) {
/* global SimpleDOM */
'use strict';
exports.childNodesLength = childNodesLength;
exports.outerHTML = outerHTML;
exports.innerHTML = innerHTML;
exports.escapeQuotes = escapeQuotes;
function childNodesLength(element) {
var length = 0;
var node = element.firstChild;
while (node) {
length++;
node = node.nextSibling;
}
return length;
}
function outerHTML(node) {
if (node.outerHTML) {
return node.outerHTML;
} else {
var serializer = new SimpleDOM.HTMLSerializer([]);
return serializer.serialize(node);
}
}
function innerHTML(parentNode) {
var content = [];
var node = parentNode.firstChild;
while (node) {
content.push(outerHTML(node));
node = node.nextSibling;
}
return content.join('');
}
function escapeQuotes(string) {
return string.replace(/"/g, '&quot;');
}
});
QUnit.module('JSHint - tests/jshint/cards');
QUnit.test('tests/jshint/cards/image.js should pass jshint', function(assert) {
assert.ok(true, 'tests/jshint/cards/image.js should pass jshint.');
});
QUnit.module('JSHint - tests/jshint/helpers');
QUnit.test('tests/jshint/helpers/create-mobiledoc.js should pass jshint', function(assert) {
assert.ok(true, 'tests/jshint/helpers/create-mobiledoc.js should pass jshint.');
});
QUnit.module('JSHint - tests/jshint/helpers');
QUnit.test('tests/jshint/helpers/dom.js should pass jshint', function(assert) {
assert.ok(true, 'tests/jshint/helpers/dom.js should pass jshint.');
});
QUnit.module('JSHint - tests/jshint');
QUnit.test('tests/jshint/index.js should pass jshint', function(assert) {
assert.ok(true, 'tests/jshint/index.js should pass jshint.');
});
QUnit.module('JSHint - tests/jshint');
QUnit.test('tests/jshint/renderer-factory.js should pass jshint', function(assert) {
assert.ok(true, 'tests/jshint/renderer-factory.js should pass jshint.');
});
QUnit.module('JSHint - tests/jshint/renderers');
QUnit.test('tests/jshint/renderers/0-2.js should pass jshint', function(assert) {
assert.ok(true, 'tests/jshint/renderers/0-2.js should pass jshint.');
});
QUnit.module('JSHint - tests/jshint/renderers');
QUnit.test('tests/jshint/renderers/0-3.js should pass jshint', function(assert) {
assert.ok(true, 'tests/jshint/renderers/0-3.js should pass jshint.');
});
QUnit.module('JSHint - tests/jshint/unit/renderers');
QUnit.test('tests/jshint/unit/renderers/0-2-test.js should pass jshint', function(assert) {
assert.ok(true, 'tests/jshint/unit/renderers/0-2-test.js should pass jshint.');
});
QUnit.module('JSHint - tests/jshint/unit/renderers');
QUnit.test('tests/jshint/unit/renderers/0-3-test.js should pass jshint', function(assert) {
assert.ok(true, 'tests/jshint/unit/renderers/0-3-test.js should pass jshint.');
});
QUnit.module('JSHint - tests/jshint/unit/utils');
QUnit.test('tests/jshint/unit/utils/array-utils-test.js should pass jshint', function(assert) {
assert.ok(true, 'tests/jshint/unit/utils/array-utils-test.js should pass jshint.');
});
QUnit.module('JSHint - tests/jshint/unit/utils');
QUnit.test('tests/jshint/unit/utils/sanitization-utils-test.js should pass jshint', function(assert) {
assert.ok(true, 'tests/jshint/unit/utils/sanitization-utils-test.js should pass jshint.');
});
QUnit.module('JSHint - tests/jshint/utils');
QUnit.test('tests/jshint/utils/array-utils.js should pass jshint', function(assert) {
assert.ok(true, 'tests/jshint/utils/array-utils.js should pass jshint.');
});
QUnit.module('JSHint - tests/jshint/utils');
QUnit.test('tests/jshint/utils/dom.js should pass jshint', function(assert) {
assert.ok(true, 'tests/jshint/utils/dom.js should pass jshint.');
});
QUnit.module('JSHint - tests/jshint/utils');
QUnit.test('tests/jshint/utils/marker-types.js should pass jshint', function(assert) {
assert.ok(true, 'tests/jshint/utils/marker-types.js should pass jshint.');
});
QUnit.module('JSHint - tests/jshint/utils');
QUnit.test('tests/jshint/utils/render-type.js should pass jshint', function(assert) {
assert.ok(true, 'tests/jshint/utils/render-type.js should pass jshint.');
});
QUnit.module('JSHint - tests/jshint/utils');
QUnit.test('tests/jshint/utils/render-utils.js should pass jshint', function(assert) {
assert.ok(true, 'tests/jshint/utils/render-utils.js should pass jshint.');
});
QUnit.module('JSHint - tests/jshint/utils');
QUnit.test('tests/jshint/utils/sanitization-utils.js should pass jshint', function(assert) {
assert.ok(true, 'tests/jshint/utils/sanitization-utils.js should pass jshint.');
});
QUnit.module('JSHint - tests/jshint/utils');
QUnit.test('tests/jshint/utils/section-types.js should pass jshint', function(assert) {
assert.ok(true, 'tests/jshint/utils/section-types.js should pass jshint.');
});
QUnit.module('JSHint - tests/jshint/utils');
QUnit.test('tests/jshint/utils/tag-names.js should pass jshint', function(assert) {
assert.ok(true, 'tests/jshint/utils/tag-names.js should pass jshint.');
});
define('tests/unit/renderers/0-2-test', ['exports', 'mobiledoc-dom-renderer', 'mobiledoc-dom-renderer/utils/section-types', '../../helpers/dom'], function (exports, _mobiledocDomRenderer, _mobiledocDomRendererUtilsSectionTypes, _helpersDom) {
/* global QUnit, SimpleDOM */
'use strict';
var _QUnit = QUnit;
var test = _QUnit.test;
var _module = _QUnit.module;
var MOBILEDOC_VERSION = '0.2.0';
var dataUri = "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=";
var renderer = undefined;
// Add tests that should run with both simple-dom and
// the window.document in this function.
function generateTests() {
test('renders an empty mobiledoc', function (assert) {
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], // markers
[] // sections
]
};
var _renderer$render = renderer.render(mobiledoc);
var rendered = _renderer$render.result;
assert.ok(!!rendered, 'renders result');
assert.ok(!rendered.firstChild, 'has no sections');
});
test('renders a mobiledoc without markups', function (assert) {
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], // markers
[// sections
[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[[], 0, 'hello world']]]]]
};
var renderResult = renderer.render(mobiledoc);
var rendered = renderResult.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
assert.equal(rendered.firstChild.tagName, 'P', 'renders a P');
assert.equal(rendered.firstChild.firstChild.nodeValue, 'hello world', 'renders the text');
});
test('renders markup section "pull-quote" as div with class', function (assert) {
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], // markers
[// sections
[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'pull-quote', [[[], 0, 'hello world']]]]]
};
var _renderer$render2 = renderer.render(mobiledoc);
var rendered = _renderer$render2.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
var sectionEl = rendered.firstChild;
assert.equal((0, _helpersDom.outerHTML)(sectionEl), '<div class="pull-quote">hello world</div>');
});
test('renders a mobiledoc with simple (no attributes) markup', function (assert) {
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[// markers
['B']], [// sections
[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[[0], 1, 'hello world']]]]]
};
var _renderer$render3 = renderer.render(mobiledoc);
var rendered = _renderer$render3.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
var sectionEl = rendered.firstChild;
assert.equal(sectionEl.firstChild.tagName, 'B');
assert.equal(sectionEl.firstChild.firstChild.nodeValue, 'hello world');
});
test('renders a mobiledoc with complex (has attributes) markup', function (assert) {
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[// markers
['A', ['href', 'http://google.com']]], [// sections
[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[[0], 1, 'hello world']]]]]
};
var _renderer$render4 = renderer.render(mobiledoc);
var rendered = _renderer$render4.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
var sectionEl = rendered.firstChild;
assert.equal((0, _helpersDom.innerHTML)(sectionEl), '<a href="http://google.com">hello world</a>');
assert.equal((0, _helpersDom.innerHTML)(sectionEl), '<a href="http://google.com">hello world</a>');
});
test('renders a mobiledoc with multiple markups in a section', function (assert) {
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[// markers
['B'], ['I']], [// sections
[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[[0], 0, 'hello '], // b
[[1], 0, 'brave '], // b+i
[[], 1, 'new '], // close i
[[], 1, 'world'] // close b
]]]]
};
var _renderer$render5 = renderer.render(mobiledoc);
var rendered = _renderer$render5.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
var sectionEl = rendered.childNodes.item(0);
assert.equal((0, _helpersDom.innerHTML)(sectionEl), '<b>hello <i>brave new </i>world</b>');
});
test('renders a mobiledoc with image section', function (assert) {
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], // markers
[// sections
[_mobiledocDomRendererUtilsSectionTypes.IMAGE_SECTION_TYPE, dataUri]]]
};
var _renderer$render6 = renderer.render(mobiledoc);
var rendered = _renderer$render6.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
var sectionEl = rendered.childNodes.item(0);
assert.equal(sectionEl.src, dataUri);
});
test('renders a mobiledoc with built-in image card', function (assert) {
assert.expect(3);
var cardName = 'image';
var payload = {
src: dataUri
};
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], // markers
[// sections
[_mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE, cardName, payload]]]
};
var _renderer$render7 = renderer.render(mobiledoc);
var rendered = _renderer$render7.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
var sectionEl = rendered.childNodes.item(0);
assert.equal(sectionEl.tagName, 'IMG');
assert.equal(sectionEl.src, dataUri);
});
test('render mobiledoc with list section and list items', function (assert) {
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], [[_mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE, 'ul', [[[[], 0, 'first item']], [[[], 0, 'second item']]]]]]
};
var _renderer$render8 = renderer.render(mobiledoc, document.createElement('div'));
var rendered = _renderer$render8.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
var section = rendered.firstChild;
assert.equal(section.tagName, 'UL');
assert.equal((0, _helpersDom.childNodesLength)(section), 2, '2 list items');
assert.equal(section.firstChild.tagName, 'LI', 'correct tagName for item 1');
assert.equal(section.firstChild.firstChild.nodeValue, 'first item', 'correct text node for item 1');
assert.equal(section.lastChild.tagName, 'LI', 'correct tagName for item 2');
assert.equal(section.lastChild.firstChild.nodeValue, 'second item', 'correct text node for item 2');
});
test('renders a mobiledoc with card section', function (assert) {
assert.expect(8);
var cardName = 'title-card';
var expectedPayload = { name: 'bob' };
var expectedOptions = { foo: 'bar' };
var TitleCard = {
name: cardName,
type: 'dom',
render: function render(_ref) {
var env = _ref.env;
var options = _ref.options;
var payload = _ref.payload;
var name = env.name;
var isInEditor = env.isInEditor;
var onTeardown = env.onTeardown;
var didRender = env.didRender;
assert.equal(name, cardName, 'has name');
assert.ok(!isInEditor, 'not isInEditor');
assert.ok(!!onTeardown, 'has onTeardown');
assert.ok(!!didRender, 'has didRender');
assert.deepEqual(options, expectedOptions);
assert.deepEqual(payload, expectedPayload);
return document.createTextNode(payload.name);
}
};
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], // markers
[// sections
[_mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE, cardName, expectedPayload]]]
};
renderer = new _mobiledocDomRenderer['default']({ cards: [TitleCard], cardOptions: expectedOptions });
var _renderer$render9 = renderer.render(mobiledoc);
var rendered = _renderer$render9.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
assert.equal((0, _helpersDom.innerHTML)(rendered), expectedPayload.name);
});
test('throws when given invalid card type', function (assert) {
var cardName = 'bad';
var card = {
name: cardName,
type: 'text',
render: function render() {}
};
var cards = [card];
assert.throws(function () {
new _mobiledocDomRenderer['default']({ cards: cards });
}, // jshint ignore: line
new RegExp('Card "' + cardName + '" must be of type "' + _mobiledocDomRenderer.RENDER_TYPE + '"'));
});
test('throws when given card without `render`', function (assert) {
var cardName = 'bad';
var card = {
name: cardName,
type: _mobiledocDomRenderer.RENDER_TYPE,
render: undefined
};
var cards = [card];
assert.throws(function () {
new _mobiledocDomRenderer['default']({ cards: cards });
}, // jshint ignore: line
new RegExp('Card "' + cardName + '" must define `render`'));
});
test('throws if card render returns invalid result', function (assert) {
var card = {
name: 'bad',
type: 'dom',
render: function render() {
return 'string';
}
};
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], [[_mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE, card.name]]]
};
renderer = new _mobiledocDomRenderer['default']({ cards: [card] });
assert.throws(function () {
return renderer.render(mobiledoc);
}, /Card "bad" must render dom/);
});
test('card may render nothing', function (assert) {
var card = {
name: 'ok',
type: 'dom',
render: function render() {}
};
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], [[_mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE, card.name]]]
};
renderer = new _mobiledocDomRenderer['default']({ cards: [card] });
renderer.render(mobiledoc);
assert.ok(true, 'No error thrown');
});
test('rendering nested mobiledocs in cards', function (assert) {
var renderer = undefined;
var cards = [{
name: 'nested-card',
type: 'dom',
render: function render(_ref2) {
var payload = _ref2.payload;
var _renderer$render10 = renderer.render(payload.mobiledoc);
var rendered = _renderer$render10.result;
return rendered;
}
}];
var innerMobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], // markers
[// sections
[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[[], 0, 'hello world']]]]]
};
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], // markers
[// sections
[_mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE, 'nested-card', { mobiledoc: innerMobiledoc }]]]
};
renderer = new _mobiledocDomRenderer['default']({ cards: cards });
var _renderer$render11 = renderer.render(mobiledoc);
var rendered = _renderer$render11.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
var card = rendered.firstChild;
assert.equal((0, _helpersDom.childNodesLength)(card), 1, 'card has 1 child');
assert.equal(card.tagName, 'P', 'card has P child');
assert.equal(card.innerText, 'hello world');
});
test('rendering unknown card without unknownCardHandler throws', function (assert) {
var cardName = 'not-known';
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], [[_mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE, cardName]]]
};
renderer = new _mobiledocDomRenderer['default']({ cards: [], unknownCardHandler: undefined });
assert.throws(function () {
return renderer.render(mobiledoc);
}, new RegExp('Card "' + cardName + '" not found.*no unknownCardHandler'));
});
test('rendering unknown card uses unknownCardHandler', function (assert) {
assert.expect(6);
var cardName = 'my-card';
var expectedOptions = {};
var expectedPayload = {};
var unknownCardHandler = function unknownCardHandler(_ref3) {
var env = _ref3.env;
var options = _ref3.options;
var payload = _ref3.payload;
assert.equal(env.name, cardName, 'name is correct');
assert.ok(!env.isInEditor, 'not in editor');
assert.ok(!!env.onTeardown, 'has onTeardown');
assert.ok(!!env.didRender, 'has didRender');
assert.deepEqual(options, expectedOptions, 'correct options');
assert.deepEqual(payload, expectedPayload, 'correct payload');
};
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], [[_mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE, cardName, expectedPayload]]]
};
renderer = new _mobiledocDomRenderer['default']({
cards: [], cardOptions: expectedOptions, unknownCardHandler: unknownCardHandler
});
renderer.render(mobiledoc);
});
test('throws if given an object of cards', function (assert) {
var cards = {};
assert.throws(function () {
new _mobiledocDomRenderer['default']({ cards: cards });
}, // jshint ignore: line
new RegExp('`cards` must be passed as an array'));
});
test('multiple spaces should preserve whitespace with nbsps', function (assert) {
var space = ' ';
var repeat = function repeat(str, count) {
var result = '';
while (count--) {
result += str;
}
return result;
};
var text = [repeat(space, 4), 'some', repeat(space, 5), 'text', repeat(space, 6)].join('');
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], // markers
[// sections
[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[[], 0, text]]]]]
};
var nbsp = ' ';
var sn = space + nbsp;
var expectedText = [repeat(sn, 2), 'some', repeat(sn, 2), space, 'text', repeat(sn, 3)].join('');
var _renderer$render12 = renderer.render(mobiledoc);
var rendered = _renderer$render12.result;
var textNode = rendered.firstChild.firstChild;
assert.equal(textNode.nodeValue, expectedText, 'renders the text');
});
test('replaces tab characters with EM SPACE', function (assert) {
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], // markers
[// sections
[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[[], 0, "\tHello world"]]]]]
};
var _renderer$render13 = renderer.render(mobiledoc);
var rendered = _renderer$render13.result;
var elementNode = rendered.firstChild.firstChild;
assert.equal(elementNode.nodeValue, 'Helloworld', 'replaces tabs with &emsp;');
});
test('throws when given unexpected mobiledoc version', function (assert) {
var mobiledoc = {
version: '0.1.0',
sections: [[], []]
};
assert.throws(function () {
return renderer.render(mobiledoc);
}, /Unexpected Mobiledoc version.*0.1.0/);
mobiledoc.version = '0.2.1';
assert.throws(function () {
return renderer.render(mobiledoc);
}, /Unexpected Mobiledoc version.*0.2.1/);
});
test('XSS: unexpected markup and list section tag names are not renderered', function (assert) {
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], [[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'script', [[[], 0, 'alert("markup section XSS")']]], [_mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE, 'script', [[[[], 0, 'alert("list section XSS")']]]]]]
};
var _renderer$render14 = renderer.render(mobiledoc);
var result = _renderer$render14.result;
var content = (0, _helpersDom.outerHTML)(result);
assert.ok(content.indexOf('script') === -1, 'no script tag rendered');
});
test('XSS: unexpected markup types are not rendered', function (assert) {
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[['b'], // valid
['em'], // valid
['script'] // invalid
], [[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'p', [[[0], 0, 'bold text'], [[1, 2], 3, 'alert("markup XSS")'], [[], 0, 'plain text']]]]]
};
var _renderer$render15 = renderer.render(mobiledoc);
var result = _renderer$render15.result;
var content = (0, _helpersDom.outerHTML)(result);
assert.ok(content.indexOf('script') === -1, 'no script tag rendered');
});
test('XSS: links with dangerous href values are not rendered', function (assert) {
var unsafeHref = 'javascript:alert("link XSS")'; // jshint ignore:line
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[["a", ["href", unsafeHref]]], [[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, "p", [[[0], 1, "link text"], [[], 0, "plain text"]]]]]
};
var _renderer$render16 = renderer.render(mobiledoc);
var result = _renderer$render16.result;
var content = (0, _helpersDom.outerHTML)(result);
assert.equal(content, '<p><a href="unsafe:' + (0, _helpersDom.escapeQuotes)(unsafeHref) + '">link text</a>plain text</p>');
});
test('renders a mobiledoc with sectionElementRenderer', function (assert) {
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], // markers
[// sections
[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[[], 0, 'hello world']]], [_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'p', [[[], 0, 'hello world']]], [_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'h1', [[[], 0, 'hello world']]]]]
};
renderer = new _mobiledocDomRenderer['default']({
sectionElementRenderer: {
p: function p() {
return document.createElement('pre');
},
H1: function H1(tagName, dom) {
return dom.createElement('h2');
}
}
});
var renderResult = renderer.render(mobiledoc);
var rendered = renderResult.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 3, 'renders three sections');
assert.equal(rendered.firstChild.tagName, 'PRE', 'renders a pre');
assert.equal(rendered.firstChild.textContent, 'hello world', 'renders the text');
assert.equal(rendered.childNodes.item(1).tagName, 'PRE', 'renders a pre');
assert.equal(rendered.lastChild.tagName, 'H2', 'renders an h2');
});
test('renders a mobiledoc with markupElementRenderer', function (assert) {
var mobiledoc = {
"version": MOBILEDOC_VERSION,
"sections": [[["A", ["href", "#foo"]]], [[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, "p", [[[], 0, "Lorem ipsum "], [[0], 1, "dolor"], [[], 0, " sit amet."]]]]]
};
renderer = new _mobiledocDomRenderer['default']({
markupElementRenderer: {
A: function A(tagName, dom, attrs) {
var element = dom.createElement('span');
element.setAttribute('data-tag', tagName);
element.setAttribute('data-href', attrs.href);
return element;
}
}
});
var renderResult = renderer.render(mobiledoc);
var rendered = renderResult.result;
assert.equal(rendered.firstChild.childNodes[1].textContent, 'dolor', 'renders text inside of marker');
assert.equal(rendered.firstChild.childNodes[1].tagName, 'SPAN', 'transforms markup nodes');
assert.propEqual(rendered.firstChild.childNodes[1].dataset, { tag: "a", href: "#foo" }, 'passes original tag and attributes to transform');
assert.equal(rendered.firstChild.childNodes[0].textContent, 'Lorem ipsum ', 'renders plain text nodes');
assert.equal(rendered.firstChild.childNodes[2].nodeType, 3, 'renders text nodes as proper type');
});
test('unexpected markup types are not passed to markup renderer', function (assert) {
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[['script'] // invalid
], [[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'p', [[[0], 1, 'alert("markup XSS")']]]]]
};
renderer = new _mobiledocDomRenderer['default']({
markupElementRenderer: {
SCRIPT: function SCRIPT(tagName, dom) {
return dom.createElement('script');
}
}
});
var _renderer$render17 = renderer.render(mobiledoc);
var result = _renderer$render17.result;
var content = (0, _helpersDom.outerHTML)(result);
assert.ok(content.indexOf('script') === -1, 'no script tag rendered');
});
}
_module('Unit: Mobiledoc DOM Renderer - 0.2', {
beforeEach: function beforeEach() {
renderer = new _mobiledocDomRenderer['default']();
}
});
generateTests();
test('teardown removes rendered sections from dom', function (assert) {
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], [[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'p', [[[], 0, 'Hello world']]]]]
};
var _renderer$render18 = renderer.render(mobiledoc);
var rendered = _renderer$render18.result;
var teardown = _renderer$render18.teardown;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
var fixture = document.getElementById('qunit-fixture');
fixture.appendChild(rendered);
assert.ok((0, _helpersDom.childNodesLength)(fixture) === 1, 'precond - result is appended');
teardown();
assert.ok((0, _helpersDom.childNodesLength)(fixture) === 0, 'rendered result removed after teardown');
});
test('teardown hook calls registered teardown methods', function (assert) {
var cardName = 'title-card';
var didTeardown = false;
var card = {
name: cardName,
type: 'dom',
render: function render(_ref4) {
var env = _ref4.env;
env.onTeardown(function () {
return didTeardown = true;
});
}
};
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], [[_mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE, cardName]]]
};
renderer = new _mobiledocDomRenderer['default']({ cards: [card] });
var _renderer$render19 = renderer.render(mobiledoc);
var teardown = _renderer$render19.teardown;
assert.ok(!didTeardown, 'teardown not called');
teardown();
assert.ok(didTeardown, 'teardown called');
});
test('render hook calls registered didRender callbacks', function (assert) {
var cardName = 'title-card';
var didRender = false;
var card = {
name: cardName,
type: 'dom',
render: function render(_ref5) {
var env = _ref5.env;
env.didRender(function () {
return didRender = true;
});
}
};
var mobiledoc = {
version: MOBILEDOC_VERSION,
sections: [[], [[_mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE, cardName]]]
};
renderer = new _mobiledocDomRenderer['default']({ cards: [card] });
assert.ok(!didRender, 'didRender not called');
renderer.render(mobiledoc);
assert.ok(didRender, 'didRender called');
});
_module('Unit: Mobiledoc DOM Renderer w/ SimpleDOM - 0.2', {
beforeEach: function beforeEach() {
renderer = new _mobiledocDomRenderer['default']({ dom: new SimpleDOM.Document() });
}
});
generateTests();
});
define('tests/unit/renderers/0-3-test', ['exports', 'mobiledoc-dom-renderer', 'mobiledoc-dom-renderer/cards/image', 'mobiledoc-dom-renderer/utils/section-types', '../../helpers/dom', 'mobiledoc-dom-renderer/utils/marker-types', '../../helpers/create-mobiledoc'], function (exports, _mobiledocDomRenderer, _mobiledocDomRendererCardsImage, _mobiledocDomRendererUtilsSectionTypes, _helpersDom, _mobiledocDomRendererUtilsMarkerTypes, _helpersCreateMobiledoc) {
/* global QUnit, SimpleDOM */
'use strict';
var _QUnit = QUnit;
var test = _QUnit.test;
var _module = _QUnit.module;
var MOBILEDOC_VERSION_0_3_0 = '0.3.0';
var MOBILEDOC_VERSION_0_3_1 = '0.3.1';
var MOBILEDOC_VERSION_0_3_2 = '0.3.2';
var dataUri = "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=";
var renderer = undefined;
// Add tests that should run with both simple-dom and
// the window.document in this function.
function generateTests() {
test('renders an empty mobiledoc', function (assert) {
var _renderer$render = renderer.render((0, _helpersCreateMobiledoc.createBlankMobiledoc)());
var rendered = _renderer$render.result;
assert.ok(!!rendered, 'renders result');
assert.equal((0, _helpersDom.childNodesLength)(rendered), 0, 'has no sections');
});
test('renders a mobiledoc without markups', function (assert) {
var mobiledoc = (0, _helpersCreateMobiledoc.createSimpleMobiledoc)({ text: 'hello world' });
var renderResult = renderer.render(mobiledoc);
var rendered = renderResult.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
assert.equal(rendered.firstChild.tagName, 'P', 'renders a P');
assert.equal(rendered.firstChild.firstChild.nodeValue, 'hello world', 'renders the text');
});
test('renders 0.3.0 markup section "pull-quote" as div with class', function (assert) {
var mobiledoc = (0, _helpersCreateMobiledoc.createSimpleMobiledoc)({
version: MOBILEDOC_VERSION_0_3_0,
sectionName: 'pull-quote',
text: 'hello world'
});
var _renderer$render2 = renderer.render(mobiledoc);
var rendered = _renderer$render2.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
var sectionEl = rendered.firstChild;
assert.equal((0, _helpersDom.outerHTML)(sectionEl), '<div class="pull-quote">hello world</div>');
});
test('renders 0.3.2 markup section attributes', function (assert) {
var mobiledoc = (0, _helpersCreateMobiledoc.createSimpleMobiledoc)({
version: MOBILEDOC_VERSION_0_3_2,
sectionName: 'p',
text: 'hello world',
attributes: { 'data-md-text-align': 'center' }
});
var _renderer$render3 = renderer.render(mobiledoc);
var rendered = _renderer$render3.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
var sectionEl = rendered.firstChild;
assert.equal((0, _helpersDom.outerHTML)(sectionEl), '<p data-md-text-align="center">hello world</p>');
});
test('throws when given invalid attribute', function (assert) {
var mobiledoc = (0, _helpersCreateMobiledoc.createSimpleMobiledoc)({
version: MOBILEDOC_VERSION_0_3_2,
sectionName: 'p',
text: 'hello world',
attributes: { 'data-md-bad-attribute': 'something' }
});
assert.throws(function () {
renderer.render(mobiledoc);
}, // jshint ignore: line
new RegExp('Cannot use attribute: data-md-bad-attribute'));
});
test('renders 0.3.1 markup section "pull-quote" as div with class', function (assert) {
var mobiledoc = (0, _helpersCreateMobiledoc.createSimpleMobiledoc)({
version: MOBILEDOC_VERSION_0_3_1,
sectionName: 'pull-quote',
text: 'hello world'
});
var _renderer$render4 = renderer.render(mobiledoc);
var rendered = _renderer$render4.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
var sectionEl = rendered.firstChild;
assert.equal((0, _helpersDom.outerHTML)(sectionEl), '<div class="pull-quote">hello world</div>');
});
test('renders markup section "aside"', function (assert) {
var mobiledoc = (0, _helpersCreateMobiledoc.createSimpleMobiledoc)({
version: MOBILEDOC_VERSION_0_3_1,
sectionName: 'aside',
text: 'hello world'
});
var _renderer$render5 = renderer.render(mobiledoc);
var rendered = _renderer$render5.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
var sectionEl = rendered.firstChild;
assert.equal((0, _helpersDom.outerHTML)(sectionEl), '<aside>hello world</aside>');
});
test('renders a mobiledoc with simple (no attributes) markup', function (assert) {
var mobiledoc = (0, _helpersCreateMobiledoc.createSimpleMobiledoc)({
version: MOBILEDOC_VERSION_0_3_1,
sectionName: 'aside',
text: 'hello world',
markup: ['B']
});
var _renderer$render6 = renderer.render(mobiledoc);
var rendered = _renderer$render6.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
var sectionEl = rendered.firstChild;
assert.equal((0, _helpersDom.innerHTML)(sectionEl), '<b>hello world</b>');
});
test('renders a mobiledoc with complex (has attributes) markup', function (assert) {
var mobiledoc = (0, _helpersCreateMobiledoc.createSimpleMobiledoc)({
version: MOBILEDOC_VERSION_0_3_1,
sectionName: 'aside',
text: 'hello world',
markup: ['A', ['href', 'http://google.com']]
});
var _renderer$render7 = renderer.render(mobiledoc);
var rendered = _renderer$render7.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
var sectionEl = rendered.firstChild;
assert.equal((0, _helpersDom.innerHTML)(sectionEl), '<a href="http://google.com">hello world</a>');
});
test('renders a mobiledoc with multiple markups in a section', function (assert) {
var mobiledoc = {
version: MOBILEDOC_VERSION_0_3_0,
atoms: [],
cards: [],
markups: [['B'], ['I']],
sections: [[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[_mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [0], 0, 'hello '], // b
[_mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [1], 0, 'brave '], // b+i
[_mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 1, 'new '], // close i
[_mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 1, 'world'] // close b
]]]
};
var _renderer$render8 = renderer.render(mobiledoc);
var rendered = _renderer$render8.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
var sectionEl = rendered.firstChild;
assert.equal((0, _helpersDom.innerHTML)(sectionEl), '<b>hello <i>brave new </i>world</b>');
});
test('renders a mobiledoc with image section', function (assert) {
var mobiledoc = {
version: MOBILEDOC_VERSION_0_3_0,
atoms: [],
cards: [],
markups: [],
sections: [[_mobiledocDomRendererUtilsSectionTypes.IMAGE_SECTION_TYPE, dataUri]]
};
var _renderer$render9 = renderer.render(mobiledoc);
var rendered = _renderer$render9.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
var sectionEl = rendered.firstChild;
assert.equal(sectionEl.src, dataUri);
});
test('renders a mobiledoc with built-in image card', function (assert) {
assert.expect(3);
var cardName = _mobiledocDomRendererCardsImage['default'].name;
var payload = { src: dataUri };
var mobiledoc = {
version: MOBILEDOC_VERSION_0_3_0,
atoms: [],
cards: [[cardName, payload]],
markups: [],
sections: [[_mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE, 0]]
};
var _renderer$render10 = renderer.render(mobiledoc);
var rendered = _renderer$render10.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
var sectionEl = rendered.firstChild;
assert.equal(sectionEl.tagName, 'IMG');
assert.equal(sectionEl.src, dataUri);
});
test('render mobiledoc with list section and list items', function (assert) {
var mobiledoc = {
version: MOBILEDOC_VERSION_0_3_0,
atoms: [],
cards: [],
markups: [],
sections: [[_mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE, 'ul', [[[_mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 0, 'first item']], [[_mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 0, 'second item']]]]]
};
var _renderer$render11 = renderer.render(mobiledoc, document.createElement('div'));
var rendered = _renderer$render11.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
var section = rendered.firstChild;
assert.equal(section.tagName, 'UL');
assert.equal((0, _helpersDom.childNodesLength)(section), 2, '2 list items');
var items = section.childNodes;
assert.equal(items.item(0).tagName, 'LI', 'correct tagName for item 1');
assert.equal(items.item(0).firstChild.nodeValue, 'first item', 'correct text node for item 1');
assert.equal(items.item(1).tagName, 'LI', 'correct tagName for item 2');
assert.equal(items.item(1).firstChild.nodeValue, 'second item', 'correct text node for item 2');
});
test('renders a mobiledoc with card section', function (assert) {
assert.expect(9);
var cardName = 'title-card';
var expectedPayload = { name: 'bob' };
var expectedOptions = { foo: 'bar' };
var expectedDom = window.document;
var TitleCard = {
name: cardName,
type: 'dom',
render: function render(_ref) {
var env = _ref.env;
var payload = _ref.payload;
var options = _ref.options;
assert.deepEqual(payload, expectedPayload, 'correct payload');
assert.deepEqual(options, expectedOptions, 'correct options');
assert.equal(env.name, cardName, 'correct name');
assert.ok(!env.isInEditor, 'isInEditor correct');
assert.ok(!!env.onTeardown, 'has onTeardown hook');
assert.ok(!!env.didRender, 'has didRender hook');
assert.deepEqual(env.dom, expectedDom, 'env has dom');
return document.createTextNode(payload.name);
}
};
var mobiledoc = {
version: MOBILEDOC_VERSION_0_3_0,
atoms: [],
cards: [[cardName, expectedPayload]],
markups: [],
sections: [[_mobiledocDomRendererUtilsSectionTypes.CARD_SECTION_TYPE, 0]]
};
renderer = new _mobiledocDomRenderer['default']({ cards: [TitleCard], cardOptions: expectedOptions, dom: expectedDom });
var _renderer$render12 = renderer.render(mobiledoc);
var rendered = _renderer$render12.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
assert.equal((0, _helpersDom.innerHTML)(rendered), expectedPayload.name);
});
test('throws when given invalid card type', function (assert) {
var cardName = 'bad';
var card = {
name: cardName,
type: 'text',
render: function render() {}
};
var cards = [card];
assert.throws(function () {
new _mobiledocDomRenderer['default']({ cards: cards });
}, // jshint ignore: line
new RegExp('Card "' + cardName + '" must be of type "' + _mobiledocDomRenderer.RENDER_TYPE + '"'));
});
test('throws when given card without `render`', function (assert) {
var cardName = 'bad';
var card = {
name: cardName,
type: _mobiledocDomRenderer.RENDER_TYPE,
render: undefined
};
var cards = [card];
assert.throws(function () {
new _mobiledocDomRenderer['default']({ cards: cards });
}, // jshint ignore: line
new RegExp('Card "' + cardName + '" must define `render`'));
});
test('throws if card render returns invalid result', function (assert) {
var card = {
name: 'bad',
type: 'dom',
render: function render() {
return 'string';
}
};
var mobiledoc = (0, _helpersCreateMobiledoc.createMobiledocWithCard)({
version: MOBILEDOC_VERSION_0_3_0,
card: { name: card.name }
});
renderer = new _mobiledocDomRenderer['default']({ cards: [card] });
assert.throws(function () {
return renderer.render(mobiledoc);
}, /Card "bad" must render dom/);
});
test('card may render nothing', function (assert) {
var card = {
name: 'ok',
type: 'dom',
render: function render() {}
};
var mobiledoc = (0, _helpersCreateMobiledoc.createMobiledocWithCard)({
version: MOBILEDOC_VERSION_0_3_0,
card: { name: card.name }
});
renderer = new _mobiledocDomRenderer['default']({ cards: [card] });
renderer.render(mobiledoc);
assert.ok(true, 'No error thrown');
});
test('rendering nested mobiledocs in cards', function (assert) {
var renderer = undefined;
var cardName = 'nested-card';
var cards = [{
name: cardName,
type: 'dom',
render: function render(_ref2) {
var payload = _ref2.payload;
var _renderer$render13 = renderer.render(payload.mobiledoc);
var rendered = _renderer$render13.result;
return rendered;
}
}];
var innerMobiledoc = (0, _helpersCreateMobiledoc.createSimpleMobiledoc)({
version: MOBILEDOC_VERSION_0_3_0,
text: 'hello world'
});
var mobiledoc = (0, _helpersCreateMobiledoc.createMobiledocWithCard)({
version: MOBILEDOC_VERSION_0_3_0,
card: { name: cardName, payload: { mobiledoc: innerMobiledoc } }
});
renderer = new _mobiledocDomRenderer['default']({ cards: cards });
var _renderer$render14 = renderer.render(mobiledoc);
var rendered = _renderer$render14.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
var card = rendered.firstChild;
assert.equal((0, _helpersDom.childNodesLength)(card), 1, 'card has 1 child');
assert.equal(card.tagName, 'P', 'card has P child');
assert.equal(card.innerText, 'hello world');
});
test('rendering unknown card without unknownCardHandler throws', function (assert) {
var cardName = 'not-known';
var mobiledoc = (0, _helpersCreateMobiledoc.createMobiledocWithCard)({
version: MOBILEDOC_VERSION_0_3_0,
card: { name: cardName }
});
renderer = new _mobiledocDomRenderer['default']({ cards: [], unknownCardHandler: undefined });
assert.throws(function () {
return renderer.render(mobiledoc);
}, new RegExp('Card "' + cardName + '" not found.*no unknownCardHandler'));
});
test('rendering unknown card uses unknownCardHandler', function (assert) {
assert.expect(6);
var cardName = 'my-card';
var expectedOptions = {};
var expectedPayload = {};
var unknownCardHandler = function unknownCardHandler(_ref3) {
var env = _ref3.env;
var options = _ref3.options;
var payload = _ref3.payload;
assert.equal(env.name, cardName, 'name is correct');
assert.ok(!env.isInEditor, 'not in editor');
assert.ok(!!env.onTeardown, 'has onTeardown');
assert.ok(!!env.didRender, 'has didRender');
assert.deepEqual(options, expectedOptions, 'correct options');
assert.deepEqual(payload, expectedPayload, 'correct payload');
};
var mobiledoc = (0, _helpersCreateMobiledoc.createMobiledocWithCard)({
version: MOBILEDOC_VERSION_0_3_0,
card: { name: cardName, payload: expectedPayload }
});
renderer = new _mobiledocDomRenderer['default']({
cards: [], cardOptions: expectedOptions, unknownCardHandler: unknownCardHandler
});
renderer.render(mobiledoc);
});
test('throws if given an object of cards', function (assert) {
var cards = {};
assert.throws(function () {
new _mobiledocDomRenderer['default']({ cards: cards });
}, // jshint ignore: line
new RegExp('`cards` must be passed as an array'));
});
test('multiple spaces should preserve whitespace with nbsps', function (assert) {
var space = ' ';
var repeat = function repeat(str, count) {
var result = '';
while (count--) {
result += str;
}
return result;
};
var text = [repeat(space, 4), 'some', repeat(space, 5), 'text', repeat(space, 6)].join('');
var mobiledoc = (0, _helpersCreateMobiledoc.createSimpleMobiledoc)({
version: MOBILEDOC_VERSION_0_3_0,
text: text
});
var nbsp = ' ';
var sn = space + nbsp;
var expectedText = [repeat(sn, 2), 'some', repeat(sn, 2), space, 'text', repeat(sn, 3)].join('');
var _renderer$render15 = renderer.render(mobiledoc);
var rendered = _renderer$render15.result;
var textNode = rendered.firstChild.firstChild;
assert.equal(textNode.nodeValue, expectedText, 'renders the text');
});
test('throws when given unexpected mobiledoc version', function (assert) {
var mobiledoc = (0, _helpersCreateMobiledoc.createBlankMobiledoc)({ version: '0.1.0' });
assert.throws(function () {
return renderer.render(mobiledoc);
}, /Unexpected Mobiledoc version.*0.1.0/);
mobiledoc.version = '0.2.1';
assert.throws(function () {
return renderer.render(mobiledoc);
}, /Unexpected Mobiledoc version.*0.2.1/);
});
test('XSS: unexpected markup and list section tag names are not renderered', function (assert) {
var mobiledoc = {
version: MOBILEDOC_VERSION_0_3_0,
atoms: [],
cards: [],
markups: [],
sections: [[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'script', [[_mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 0, 'alert("markup section XSS")']]], [_mobiledocDomRendererUtilsSectionTypes.LIST_SECTION_TYPE, 'script', [[[_mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 0, 'alert("list section XSS")']]]]]
};
var _renderer$render16 = renderer.render(mobiledoc);
var result = _renderer$render16.result;
var content = (0, _helpersDom.outerHTML)(result);
assert.ok(content.indexOf('script') === -1, 'no script tag rendered');
});
test('XSS: unexpected markup types are not rendered', function (assert) {
var mobiledoc = {
version: MOBILEDOC_VERSION_0_3_0,
atoms: [],
cards: [],
markups: [['b'], // valid
['em'], // valid
['script'] // invalid
],
sections: [[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'p', [[_mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [0], 0, 'bold text'], [_mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [1, 2], 3, 'alert("markup XSS")'], [_mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 0, 'plain text']]]]
};
var _renderer$render17 = renderer.render(mobiledoc);
var result = _renderer$render17.result;
var content = (0, _helpersDom.outerHTML)(result);
assert.ok(content.indexOf('script') === -1, 'no script tag rendered');
});
test('XSS: links with dangerous href values are sanitized', function (assert) {
var unsafeHref = 'javascript:alert("link XSS")'; // jshint ignore:line
var mobiledoc = {
version: MOBILEDOC_VERSION_0_3_0,
atoms: [],
cards: [],
markups: [['a', ['href', unsafeHref]]],
sections: [[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'p', [[_mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [0], 1, 'link text'], [_mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 0, 'plain text']]]]
};
var _renderer$render18 = renderer.render(mobiledoc);
var result = _renderer$render18.result;
var content = (0, _helpersDom.outerHTML)(result);
assert.equal(content, '<p><a href="unsafe:' + (0, _helpersDom.escapeQuotes)(unsafeHref) + '">link text</a>plain text</p>');
});
test('XSS: "a" markups are sanitized if upper or lower case', function (assert) {
var unsafeHref = 'javascript:alert("link XSS")'; // jshint ignore:line
var markups = [['a', ['href', unsafeHref]], ['A', ['href', unsafeHref]], ['a', ['HREF', unsafeHref]]];
markups.forEach(function (markup) {
var mobiledoc = (0, _helpersCreateMobiledoc.createSimpleMobiledoc)({ markup: markup });
var _renderer$render19 = renderer.render(mobiledoc);
var result = _renderer$render19.result;
var content = (0, _helpersDom.outerHTML)(result);
assert.equal(content, '<p><a href="unsafe:' + (0, _helpersDom.escapeQuotes)(unsafeHref) + '">hello world</a></p>');
});
});
test('renders a mobiledoc with atom', function (assert) {
assert.expect(8);
var atomName = 'hello-atom';
var expectedPayload = { name: 'bob' };
var expectedOptions = { foo: 'bar' };
var expectedValue = '@BOB';
var expectedDom = window.document;
var atom = {
name: atomName,
type: 'dom',
render: function render(_ref4) {
var env = _ref4.env;
var payload = _ref4.payload;
var value = _ref4.value;
var options = _ref4.options;
assert.deepEqual(payload, expectedPayload, 'correct payload');
assert.deepEqual(options, expectedOptions, 'correct options');
assert.equal(value, expectedValue, 'correct value');
assert.equal(env.name, atomName, 'correct name');
assert.ok(!env.isInEditor, 'isInEditor correct');
assert.ok(!!env.onTeardown, 'has onTeardown hook');
assert.deepEqual(env.dom, expectedDom, 'env has dom');
return document.createTextNode('Hello ' + value);
}
};
var mobiledoc = {
version: MOBILEDOC_VERSION_0_3_0,
atoms: [['hello-atom', expectedValue, expectedPayload]],
cards: [],
markups: [],
sections: [[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[_mobiledocDomRendererUtilsMarkerTypes.ATOM_MARKER_TYPE, [], 0, 0]]]]
};
renderer = new _mobiledocDomRenderer['default']({ atoms: [atom], cardOptions: expectedOptions, dom: expectedDom });
var _renderer$render20 = renderer.render(mobiledoc);
var rendered = _renderer$render20.result;
var sectionEl = rendered.firstChild;
assert.equal(sectionEl.textContent, 'Hello ' + expectedValue);
});
test('throws when given atom with invalid type', function (assert) {
var atom = {
name: 'bad',
type: 'other',
render: function render() {}
};
assert.throws(function () {
new _mobiledocDomRenderer['default']({ atoms: [atom] });
}, // jshint ignore:line
/Atom "bad" must be type "dom"/);
});
test('throws when given atom without `render`', function (assert) {
var atom = {
name: 'bad',
type: 'dom',
render: undefined
};
assert.throws(function () {
new _mobiledocDomRenderer['default']({ atoms: [atom] });
}, // jshint ignore:line
/Atom "bad" must define.*render/);
});
test('throws if atom render returns invalid result', function (assert) {
var atom = {
name: 'bad',
type: 'dom',
render: function render() {
return 'string';
}
};
var mobiledoc = {
version: MOBILEDOC_VERSION_0_3_0,
atoms: [['bad', 'Bob', { id: 42 }]],
cards: [],
markups: [],
sections: [[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[_mobiledocDomRendererUtilsMarkerTypes.ATOM_MARKER_TYPE, [], 0, 0]]]]
};
renderer = new _mobiledocDomRenderer['default']({ atoms: [atom] });
assert.throws(function () {
return renderer.render(mobiledoc);
}, /Atom "bad" must render dom/);
});
test('atom may render nothing', function (assert) {
var atom = {
name: 'ok',
type: 'dom',
render: function render() {}
};
var mobiledoc = (0, _helpersCreateMobiledoc.createMobiledocWithAtom)({
version: MOBILEDOC_VERSION_0_3_0,
atom: ['ok', 'Bob', { id: 42 }]
});
renderer = new _mobiledocDomRenderer['default']({ atoms: [atom] });
renderer.render(mobiledoc);
assert.ok(true, 'No error thrown');
});
test('throws when rendering unknown atom without unknownAtomHandler', function (assert) {
var mobiledoc = (0, _helpersCreateMobiledoc.createMobiledocWithAtom)({
version: MOBILEDOC_VERSION_0_3_0,
atom: ['missing-atom', 'Bob', { id: 42 }]
});
renderer = new _mobiledocDomRenderer['default']({ atoms: [], unknownAtomHandler: undefined });
assert.throws(function () {
return renderer.render(mobiledoc);
}, /Atom "missing-atom" not found.*no unknownAtomHandler/);
});
test('rendering unknown atom uses unknownAtomHandler', function (assert) {
assert.expect(4);
var atomName = 'missing-atom';
var expectedPayload = { id: 42 };
var cardOptions = {};
var mobiledoc = (0, _helpersCreateMobiledoc.createMobiledocWithAtom)({
version: MOBILEDOC_VERSION_0_3_0,
atom: ['missing-atom', 'Bob', { id: 42 }]
});
var unknownAtomHandler = function unknownAtomHandler(_ref5) {
var env = _ref5.env;
var payload = _ref5.payload;
var options = _ref5.options;
assert.equal(env.name, atomName, 'correct name');
assert.ok(!!env.onTeardown, 'onTeardown hook exists');
assert.deepEqual(payload, expectedPayload, 'correct payload');
assert.deepEqual(options, cardOptions, 'correct options');
};
renderer = new _mobiledocDomRenderer['default']({ atoms: [], unknownAtomHandler: unknownAtomHandler, cardOptions: cardOptions });
renderer.render(mobiledoc);
});
test('renders a mobiledoc with sectionElementRenderer', function (assert) {
var mobiledoc = {
version: MOBILEDOC_VERSION_0_3_0,
atoms: [],
cards: [],
markups: [],
sections: [[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'P', [[_mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 0, 'hello world']]], [_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'p', [[_mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 0, 'hello world']]], [_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, 'h1', [[_mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 0, 'hello world']]]]
};
renderer = new _mobiledocDomRenderer['default']({
sectionElementRenderer: {
p: function p() {
return document.createElement('pre');
},
H1: function H1(tagName, dom) {
return dom.createElement('h2');
}
}
});
var renderResult = renderer.render(mobiledoc);
var rendered = renderResult.result;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 3, 'renders three sections');
assert.equal(rendered.firstChild.tagName, 'PRE', 'renders a pre');
assert.equal(rendered.firstChild.textContent, 'hello world', 'renders the text');
assert.equal(rendered.childNodes.item(1).tagName, 'PRE', 'renders a pre');
assert.equal(rendered.childNodes.item(2).tagName, 'H2', 'renders an h2');
});
test('renders a mobiledoc with markupElementRenderer', function (assert) {
var mobiledoc = {
version: MOBILEDOC_VERSION_0_3_0,
atoms: [],
cards: [],
markups: [["a", ["href", "#foo"]]],
sections: [[_mobiledocDomRendererUtilsSectionTypes.MARKUP_SECTION_TYPE, "p", [[_mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 0, "Lorem ipsum "], [_mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [0], 1, "dolor"], [_mobiledocDomRendererUtilsMarkerTypes.MARKUP_MARKER_TYPE, [], 0, " sit amet."]]]]
};
renderer = new _mobiledocDomRenderer['default']({
markupElementRenderer: {
A: function A(tagName, dom, attrs) {
var element = dom.createElement('span');
element.setAttribute('data-tag', tagName);
element.setAttribute('data-href', attrs.href);
return element;
}
}
});
var renderResult = renderer.render(mobiledoc);
var rendered = renderResult.result;
assert.equal(rendered.firstChild.childNodes[1].textContent, 'dolor', 'renders text inside of marker');
assert.equal(rendered.firstChild.childNodes[1].tagName, 'SPAN', 'transforms markup nodes');
assert.propEqual(rendered.firstChild.childNodes[1].dataset, { tag: "a", href: "#foo" }, 'passes original tag and attributes to transform');
assert.equal(rendered.firstChild.childNodes[0].textContent, 'Lorem ipsum ', 'renders plain text nodes');
assert.equal(rendered.firstChild.childNodes[2].nodeType, 3, 'renders text nodes as proper type');
});
test('unexpected markup types are not handled by markup renderer', function (assert) {
var mobiledoc = (0, _helpersCreateMobiledoc.createSimpleMobiledoc)({
version: MOBILEDOC_VERSION_0_3_0,
markup: ['script'],
text: 'alert("markup XSS")'
});
renderer = new _mobiledocDomRenderer['default']({
markupElementRenderer: {
SCRIPT: function SCRIPT(markerType, dom) {
return dom.createElement('script');
}
}
});
var _renderer$render21 = renderer.render(mobiledoc);
var result = _renderer$render21.result;
var content = (0, _helpersDom.outerHTML)(result);
assert.ok(content.indexOf('script') === -1, 'no script tag rendered');
});
}
_module('Unit: Mobiledoc DOM Renderer - 0.3', {
beforeEach: function beforeEach() {
renderer = new _mobiledocDomRenderer['default']();
}
});
generateTests();
test('teardown removes rendered sections from dom', function (assert) {
var mobiledoc = (0, _helpersCreateMobiledoc.createSimpleMobiledoc)({
version: MOBILEDOC_VERSION_0_3_0,
text: 'Hello world'
});
var _renderer$render22 = renderer.render(mobiledoc);
var rendered = _renderer$render22.result;
var teardown = _renderer$render22.teardown;
assert.equal((0, _helpersDom.childNodesLength)(rendered), 1, 'renders 1 section');
var fixture = document.getElementById('qunit-fixture');
fixture.appendChild(rendered);
assert.ok((0, _helpersDom.childNodesLength)(fixture) === 1, 'precond - result is appended');
teardown();
assert.ok((0, _helpersDom.childNodesLength)(fixture) === 0, 'rendered result removed after teardown');
});
test('teardown hook calls registered teardown methods', function (assert) {
var cardName = 'title-card';
var didTeardown = false;
var card = {
name: cardName,
type: 'dom',
render: function render(_ref6) {
var env = _ref6.env;
env.onTeardown(function () {
return didTeardown = true;
});
}
};
var mobiledoc = (0, _helpersCreateMobiledoc.createMobiledocWithCard)({
version: MOBILEDOC_VERSION_0_3_0,
card: { name: cardName }
});
renderer = new _mobiledocDomRenderer['default']({ cards: [card] });
var _renderer$render23 = renderer.render(mobiledoc);
var teardown = _renderer$render23.teardown;
assert.ok(!didTeardown, 'teardown not called');
teardown();
assert.ok(didTeardown, 'teardown called');
});
test('render hook calls registered didRender callbacks', function (assert) {
var cardName = 'title-card';
var didRender = false;
var card = {
name: cardName,
type: 'dom',
render: function render(_ref7) {
var env = _ref7.env;
env.didRender(function () {
return didRender = true;
});
}
};
var mobiledoc = (0, _helpersCreateMobiledoc.createMobiledocWithCard)({
version: MOBILEDOC_VERSION_0_3_0,
card: { name: cardName }
});
renderer = new _mobiledocDomRenderer['default']({ cards: [card] });
assert.ok(!didRender, 'didRender not called');
renderer.render(mobiledoc);
assert.ok(!!didRender, 'didRender called');
});
_module('Unit: Mobiledoc DOM Renderer w/ SimpleDOM - 0.3', {
beforeEach: function beforeEach() {
renderer = new _mobiledocDomRenderer['default']({ dom: new SimpleDOM.Document() });
}
});
generateTests();
});
define('tests/unit/utils/array-utils-test', ['exports', 'mobiledoc-dom-renderer/utils/array-utils'], function (exports, _mobiledocDomRendererUtilsArrayUtils) {
/* global QUnit */
'use strict';
var _QUnit = QUnit;
var test = _QUnit.test;
var _module = _QUnit.module;
_module('Unit: Mobiledoc DOM Renderer - Array utils');
test('#kvArrayToObject', function (assert) {
assert.deepEqual((0, _mobiledocDomRendererUtilsArrayUtils.kvArrayToObject)([]), {});
assert.deepEqual((0, _mobiledocDomRendererUtilsArrayUtils.kvArrayToObject)(['data-md-text-align', 'center']), {
'data-md-text-align': 'center'
});
});
test('#objectToSortedKVArray', function (assert) {
assert.deepEqual((0, _mobiledocDomRendererUtilsArrayUtils.objectToSortedKVArray)({}), []);
assert.deepEqual((0, _mobiledocDomRendererUtilsArrayUtils.objectToSortedKVArray)({
'data-md-text-align': 'center'
}), ['data-md-text-align', 'center']);
assert.deepEqual((0, _mobiledocDomRendererUtilsArrayUtils.objectToSortedKVArray)({
'data-md-text-align': 'center',
'data-md-color': 'red'
}), ['data-md-color', 'red', 'data-md-text-align', 'center']);
});
});
define('tests/unit/utils/sanitization-utils-test', ['exports', 'mobiledoc-dom-renderer/utils/sanitization-utils'], function (exports, _mobiledocDomRendererUtilsSanitizationUtils) {
/* global QUnit */
'use strict';
var _QUnit = QUnit;
var test = _QUnit.test;
var _module = _QUnit.module;
_module('Unit: Mobiledoc DOM Renderer - Sanitization utils');
test('#sanitizeHref', function (assert) {
var unsafe = ['javascript:alert("XSS")', // jshint ignore: line
'jaVasCript:alert("XSS")', // jshint ignore: line
'javascript:javascript:alert("XSS")', // jshint ignore: line
'java script:alert("XSS")', // jshint ignore: line
'ja vas cri pt::alert("XSS")', // jshint ignore: line
'vbscript:alert("XSS")' // jshint ignore: line
];
for (var i = 0; i < unsafe.length; i++) {
var url = unsafe[i];
assert.equal((0, _mobiledocDomRendererUtilsSanitizationUtils.sanitizeHref)(url), 'unsafe:' + url);
}
var safe = ['http://www.google.com', 'https://www.google.com', 'ftp://google.com', 'http://www.google.com/with-path', 'www.google.com', 'tel:12345', 'mailto:john@doe.com'];
for (var i = 0; i < safe.length; i++) {
var url = safe[i];
assert.equal((0, _mobiledocDomRendererUtilsSanitizationUtils.sanitizeHref)(url), url);
}
});
});