135 lines
3.8 KiB
JavaScript
135 lines
3.8 KiB
JavaScript
import {Schema} from 'prosemirror-model'
|
|
|
|
// :: Schema
|
|
// 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).
|
|
|
|
// BASIC
|
|
const basicSchemaContent = {
|
|
nodes: {
|
|
// :: NodeSpec The top level document node.
|
|
doc: {
|
|
content: 'block+',
|
|
},
|
|
// :: NodeSpec A plain paragraph textblock. Represented in the DOM
|
|
// as a `<p>` element.
|
|
paragraph: {
|
|
content: 'inline*',
|
|
group: 'block',
|
|
parseDOM: [{tag: 'p'}],
|
|
toDOM () { return ['p', 0] },
|
|
},
|
|
// :: NodeSpec A hard line break, represented in the DOM as `<br>`.
|
|
hardBreak: {
|
|
inline: true,
|
|
group: 'inline',
|
|
selectable: false,
|
|
parseDOM: [{tag: 'br'}],
|
|
toDOM () { return ['br'] },
|
|
},
|
|
// :: NodeSpec The text node.
|
|
text: {
|
|
group: 'inline',
|
|
},
|
|
},
|
|
marks: {
|
|
// :: 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'}],
|
|
toDOM () { return ['em', 0] },
|
|
},
|
|
// :: 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 => node.style.fontWeight !== 'normal' && null},
|
|
{style: 'font-weight', getAttrs: value => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null}],
|
|
toDOM () { return ['strong', 0] },
|
|
},
|
|
},
|
|
}
|
|
|
|
// HEADERS
|
|
const headersSchemaContent = {
|
|
nodes: {
|
|
// :: 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}},
|
|
content: 'inline*',
|
|
marks: 'em',
|
|
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] },
|
|
},
|
|
},
|
|
}
|
|
|
|
// LISTS
|
|
const listSchemaContent = {
|
|
nodes: {
|
|
// A bullet list node spec, represented in the DOM as `<ul>`.
|
|
bulletList: {
|
|
content: 'listItem+',
|
|
group: 'block',
|
|
parseDOM: [{tag: 'ul'}],
|
|
toDOM () { return ['ul', 0] },
|
|
},
|
|
// A list item (`<li>`) spec.
|
|
listItem: {
|
|
content: 'paragraph+',
|
|
parseDOM: [{tag: 'li'}],
|
|
toDOM () { return ['li', 0] },
|
|
defining: true,
|
|
},
|
|
},
|
|
}
|
|
const linkSchemaContent = { // eslint-disable-line no-unused-vars
|
|
marks: {
|
|
link: {
|
|
attrs: {
|
|
href: {},
|
|
title: {default: null},
|
|
},
|
|
inclusive: false,
|
|
parseDOM: [{tag: 'a[href]',
|
|
getAttrs (dom) {
|
|
return {href: dom.getAttribute('href'), title: dom.getAttribute('title')}
|
|
}}],
|
|
toDOM (node) { let {href, title} = node.attrs; return ['a', {href, title}, 0] },
|
|
},
|
|
},
|
|
}
|
|
|
|
const basicSchema = new Schema(basicSchemaContent)
|
|
|
|
const headersSchema = new Schema({
|
|
nodes: basicSchema.spec.nodes.append(headersSchemaContent.nodes),
|
|
marks: basicSchema.spec.marks,
|
|
})
|
|
|
|
const listSchema = new Schema({
|
|
nodes: headersSchema.spec.nodes.append(listSchemaContent.nodes),
|
|
marks: headersSchema.spec.marks,
|
|
})
|
|
|
|
const fullSchema = listSchema
|
|
|
|
export { basicSchema, headersSchema, listSchema, fullSchema }
|