Files
2025-01-04 00:34:03 +01:00

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]
};