diff --git a/src/js/models/markup-section.js b/src/js/models/markup-section.js index 89e837e5c..824190d63 100644 --- a/src/js/models/markup-section.js +++ b/src/js/models/markup-section.js @@ -2,7 +2,15 @@ import Markerable from './_markerable'; import { normalizeTagName } from '../utils/dom-utils'; import { MARKUP_SECTION_TYPE } from './types'; +// valid values of `tagName` for a MarkupSection export const VALID_MARKUP_SECTION_TAGNAMES = [ + 'p', 'h3', 'h2', 'h1', 'blockquote', 'ul', 'ol', 'pull-quote' +].map(normalizeTagName); + +// valid element names for a MarkupSection. A MarkupSection with a tagName +// not in this should be rendered as a div with a className matching the +// tagName, instead +export const MARKUP_SECTION_ELEMENT_NAMES = [ 'p', 'h3', 'h2', 'h1', 'blockquote', 'ul', 'ol' ].map(normalizeTagName); export const DEFAULT_TAG_NAME = VALID_MARKUP_SECTION_TAGNAMES[0]; diff --git a/src/js/renderers/editor-dom.js b/src/js/renderers/editor-dom.js index 5f9d591b4..61e7d18bd 100644 --- a/src/js/renderers/editor-dom.js +++ b/src/js/renderers/editor-dom.js @@ -11,6 +11,7 @@ import { } from '../models/types'; import { startsWith, endsWith } from '../utils/string-utils'; import { addClassName } from '../utils/dom-utils'; +import { MARKUP_SECTION_ELEMENT_NAMES } from '../models/markup-section'; export const NO_BREAK_SPACE = '\u00A0'; export const SPACE = ' '; @@ -36,7 +37,15 @@ function penultimateParentOf(element, parentElement) { } function renderMarkupSection(section) { - return document.createElement(section.tagName); + let element; + if (MARKUP_SECTION_ELEMENT_NAMES.indexOf(section.tagName) !== -1) { + element = document.createElement(section.tagName); + } else { + element = document.createElement('div'); + addClassName(element, section.tagName); + } + + return element; } function renderListSection(section) { diff --git a/tests/unit/renderers/editor-dom-test.js b/tests/unit/renderers/editor-dom-test.js index d2f9a6919..2c247be1c 100644 --- a/tests/unit/renderers/editor-dom-test.js +++ b/tests/unit/renderers/editor-dom-test.js @@ -575,6 +575,20 @@ test('removes nested children of removed render nodes', (assert) => { 'section render node has all children removed'); }); +test('renders markup section "pull-quote" as
', (assert) => { + const post = Helpers.postAbstract.build(({post, markupSection, marker}) => { + return post([markupSection('pull-quote', [marker('abc')])]); + }); + const renderTree = new RenderTree(post); + render(renderTree); + + const expectedDOM = Helpers.dom.build(t => { + return t('div', {"class": "pull-quote"}, [t.text('abc')]); + }); + + assert.equal(renderTree.rootElement.innerHTML, expectedDOM.outerHTML); +}); + /* test("It renders a renderTree with rendered dirty section", (assert) => { /* diff --git a/tests/unit/renderers/mobiledoc-test.js b/tests/unit/renderers/mobiledoc-test.js index d148b425d..77624f9b8 100644 --- a/tests/unit/renderers/mobiledoc-test.js +++ b/tests/unit/renderers/mobiledoc-test.js @@ -175,3 +175,19 @@ test('renders a post with a list', (assert) => { ] }); }); + +test('renders a pull-quote as markup section', (assert) => { + const post = Helpers.postAbstract.build(({post, markupSection, marker}) => { + return post([markupSection('pull-quote', [marker('abc')])]); + }); + const mobiledoc = render(post); + assert.deepEqual(mobiledoc, { + version: MOBILEDOC_VERSION, + sections: [ + [], + [ + [1, 'pull-quote', [[[], 0, 'abc']]] + ] + ] + }); +});