74 lines
2.4 KiB
JavaScript
74 lines
2.4 KiB
JavaScript
import {isElementEmpty, onlyInlineContent} from "./utils.mjs";
|
|
|
|
export const ol = {
|
|
content: "(list_item | list_item_text)+",
|
|
managed: {attributes: ["start"]},
|
|
group: "block",
|
|
attrs: {order: {default: 1}},
|
|
parseDOM: [{tag: "ol", getAttrs: el => ({order: el.hasAttribute("start") ? Number(el.start) : 1})}],
|
|
toDOM: node => node.attrs.order === 1 ? ["ol", 0] : ["ol", {start: node.attrs.order}, 0]
|
|
};
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
export const ul = {
|
|
content: "(list_item | list_item_text)+",
|
|
group: "block",
|
|
parseDOM: [{tag: "ul"}],
|
|
toDOM: () => ["ul", 0]
|
|
};
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/**
|
|
* ProseMirror enforces a stricter subset of HTML where block and inline content cannot be mixed. For example, the
|
|
* following is valid HTML:
|
|
* <ul>
|
|
* <li>
|
|
* The first list item.
|
|
* <ul>
|
|
* <li>An embedded list.</li>
|
|
* </ul>
|
|
* </li>
|
|
* </ul>
|
|
*
|
|
* But, since the contents of the <li> would mix inline content (the text), with block content (the inner <ul>), the
|
|
* schema is defined to only allow block content, and would transform the items to look like this:
|
|
* <ul>
|
|
* <li>
|
|
* <p>The first list item.</p>
|
|
* <ul>
|
|
* <li><p>An embedded list.</p></li>
|
|
* </ul>
|
|
* </li>
|
|
* </ul>
|
|
*
|
|
* We can address this by hooking into the DOM parsing and 'tagging' the extra paragraph elements inserted this way so
|
|
* that when the contents are serialized again, they can be removed. This is left as a TODO for now.
|
|
*/
|
|
|
|
// In order to preserve existing HTML we define two types of list nodes. One that contains block content, and one that
|
|
// contains text content. We default to block content if the element is empty, in order to make integration with the
|
|
// wrapping and lifting helpers simpler.
|
|
export const li = {
|
|
content: "paragraph block*",
|
|
defining: true,
|
|
parseDOM: [{tag: "li", getAttrs: el => {
|
|
// If this contains only inline content and no other elements, do not use this node type.
|
|
if ( !isElementEmpty(el) && onlyInlineContent(el) ) return false;
|
|
}}],
|
|
toDOM: () => ["li", 0]
|
|
};
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
export const liText = {
|
|
content: "text*",
|
|
defining: true,
|
|
parseDOM: [{tag: "li", getAttrs: el => {
|
|
// If this contains any non-inline elements, do not use this node type.
|
|
if ( isElementEmpty(el) || !onlyInlineContent(el) ) return false;
|
|
}}],
|
|
toDOM: () => ["li", 0]
|
|
};
|