UNPKG

prosemirror-schema-basic

Version:
167 lines (150 loc) 5.35 kB
import {Schema, NodeSpec, MarkSpec, DOMOutputSpec} from "prosemirror-model" const pDOM: DOMOutputSpec = ["p", 0], blockquoteDOM: DOMOutputSpec = ["blockquote", 0], hrDOM: DOMOutputSpec = ["hr"], preDOM: DOMOutputSpec = ["pre", ["code", 0]], brDOM: DOMOutputSpec = ["br"] /// [Specs](#model.NodeSpec) for the nodes defined in this schema. export const nodes = { /// NodeSpec The top level document node. doc: { content: "block+" } as NodeSpec, /// A plain paragraph textblock. Represented in the DOM /// as a `<p>` element. paragraph: { content: "inline*", group: "block", parseDOM: [{tag: "p"}], toDOM() { return pDOM } } as NodeSpec, /// A blockquote (`<blockquote>`) wrapping one or more blocks. blockquote: { content: "block+", group: "block", defining: true, parseDOM: [{tag: "blockquote"}], toDOM() { return blockquoteDOM } } as NodeSpec, /// A horizontal rule (`<hr>`). horizontal_rule: { group: "block", parseDOM: [{tag: "hr"}], toDOM() { return hrDOM } } as NodeSpec, /// A heading textblock, with a `level` attribute that /// should hold the number 1 to 6. Parsed and serialized as `<h1>` to /// `<h6>` elements. heading: { attrs: {level: {default: 1, validate: "number"}}, content: "inline*", group: "block", defining: true, parseDOM: [{tag: "h1", attrs: {level: 1}}, {tag: "h2", attrs: {level: 2}}, {tag: "h3", attrs: {level: 3}}, {tag: "h4", attrs: {level: 4}}, {tag: "h5", attrs: {level: 5}}, {tag: "h6", attrs: {level: 6}}], toDOM(node) { return ["h" + node.attrs.level, 0] } } as NodeSpec, /// A code listing. Disallows marks or non-text inline /// nodes by default. Represented as a `<pre>` element with a /// `<code>` element inside of it. code_block: { content: "text*", marks: "", group: "block", code: true, defining: true, parseDOM: [{tag: "pre", preserveWhitespace: "full"}], toDOM() { return preDOM } } as NodeSpec, /// The text node. text: { group: "inline" } as NodeSpec, /// An inline image (`<img>`) node. Supports `src`, /// `alt`, and `href` attributes. The latter two default to the empty /// string. image: { inline: true, attrs: { src: {validate: "string"}, alt: {default: null, validate: "string|null"}, title: {default: null, validate: "string|null"} }, group: "inline", draggable: true, parseDOM: [{tag: "img[src]", getAttrs(dom: HTMLElement) { return { src: dom.getAttribute("src"), title: dom.getAttribute("title"), alt: dom.getAttribute("alt") } }}], toDOM(node) { let {src, alt, title} = node.attrs; return ["img", {src, alt, title}] } } as NodeSpec, /// A hard line break, represented in the DOM as `<br>`. hard_break: { inline: true, group: "inline", selectable: false, parseDOM: [{tag: "br"}], toDOM() { return brDOM } } as NodeSpec } const emDOM: DOMOutputSpec = ["em", 0], strongDOM: DOMOutputSpec = ["strong", 0], codeDOM: DOMOutputSpec = ["code", 0] /// [Specs](#model.MarkSpec) for the marks in the schema. export const marks = { /// A link. Has `href` and `title` attributes. `title` /// defaults to the empty string. Rendered and parsed as an `<a>` /// element. link: { attrs: { href: {validate: "string"}, title: {default: null, validate: "string|null"} }, inclusive: false, parseDOM: [{tag: "a[href]", getAttrs(dom: HTMLElement) { return {href: dom.getAttribute("href"), title: dom.getAttribute("title")} }}], toDOM(node) { let {href, title} = node.attrs; return ["a", {href, title}, 0] } } as MarkSpec, /// An emphasis mark. Rendered as an `<em>` element. Has parse rules /// that also match `<i>` and `font-style: italic`. em: { parseDOM: [ {tag: "i"}, {tag: "em"}, {style: "font-style=italic"}, {style: "font-style=normal", clearMark: m => m.type.name == "em"} ], toDOM() { return emDOM } } as MarkSpec, /// A strong mark. Rendered as `<strong>`, parse rules also match /// `<b>` and `font-weight: bold`. strong: { parseDOM: [ {tag: "strong"}, // This works around a Google Docs misbehavior where // pasted content will be inexplicably wrapped in `<b>` // tags with a font-weight normal. {tag: "b", getAttrs: (node: HTMLElement) => node.style.fontWeight != "normal" && null}, {style: "font-weight=400", clearMark: m => m.type.name == "strong"}, {style: "font-weight", getAttrs: (value: string) => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null}, ], toDOM() { return strongDOM } } as MarkSpec, /// Code font mark. Represented as a `<code>` element. code: { code: true, parseDOM: [{tag: "code"}], toDOM() { return codeDOM } } as MarkSpec } /// This schema roughly corresponds to the document schema used by /// [CommonMark](http://commonmark.org/), minus the list elements, /// which are defined in the [`prosemirror-schema-list`](#schema-list) /// module. /// /// To reuse elements from this schema, extend or read from its /// `spec.nodes` and `spec.marks` [properties](#model.Schema.spec). export const schema = new Schema({nodes, marks})