Modify the Default ProseMirror Schema
This article describes how you can modify the default ProseMirror schema that the Editor for Blazor uses. Updating the existing schema is useful if you want to:
- Extend the Editor capabilities and allow end users to add more kinds of HTML tags than the predefined ones.
- Allow adding more attributes to the predefined HTML elements.
- Restrict end users from adding some of the predefined HTML elements.
Prerequisites
To work with ProseMirror, make sure you are familiar with:
- JavaScript—ProseMirror is a JavaScript library and the schema uses JavaScript syntax.
- ProseMirror Schema—The schema structure and its children (nodes and marks).
Modifying the ProseMirror Schema is outside of the Editor scope and we do not provide support for such customizations.
Basics
The Editor accepts a custom ProseMirror schema through its Schema
parameter. Set this string
parameter to the name of a JavaScript function that:
- Is declared in the global scope (the
window
object). - Returns an instance of the ProseMirror
Schema
class(the updated schema). You can access this class from theProseMirror
object of the event arguments. - Accepts a single argument.
The Editor will call this function and will pass an argument object that contains the following properties:
Property | Description |
---|---|
getSchema |
A function that returns the current Schema object. Before the Editor is initialized, the returned Schema object is the default schema of the Editor. After the Editor is initialized, the returned Schema object is the updated schema. If you don't provide a custom schema, this function always returns the default schema. |
getView |
A function that returns the currently used instance of the EditorView object. Before the Editor is initialized, the view (the result of the function) is null. |
ProseMirror |
An object that contains various ProseMirror classes and functions. |
You can set a custom schema only once during initialization of the Editor component. Further changes to the schema will not take effect and the component will continue using the initial custom or built-in schema.
Modifying the Schema
The below example shows how to:
- Get the default ProseMirror schema.
- Add a
data-id
attribute to the<p>
node. - Remove the default
horizontal_rule
node that does not allow any attributes and add a custom node for the<hr>
element that allows setting a CSSclass
. - Add a
mark
for the<s>
element. - Return the updated schema, so the Editor can use it.
The Editor in this example uses the
Div
edit mode, so the style for the<hr>
element is applied. If you use the defaultIframe
edit mode, you have to plug the styles with JavaScript as shown in this example.
<style>
hr.custom-hr {
border-color: red;
}
</style>
<TelerikEditor @bind-Value="@TheEditorValue"
Schema="schemaProvider"
EditMode="@EditorEditMode.Div">
</TelerikEditor>
@code {
private string TheEditorValue { get; set; }
protected override Task OnInitializedAsync()
{
TheEditorValue = @"
A horizontal rule with a custom class
<hr class='custom-hr' />
<p data-id='paragraph-data-id'>
A paragraph with a 'data-id' attribute.
</p>
<s>
An s element.
</s>";
return base.OnInitializedAsync();
}
}
@* Move JavaScript code to a separate JS file in production *@
<script suppress-error="BL9992">
var tagMark = (tag) => ({
[tag]: {
name: tag,
inclusive: true,
parseDOM: [{ tag }],
toDOM: () => [tag, 0],
},
});
var updatedHr = {
attrs: {
class: { default: null },
},
group: "block",
parseDOM: [
{
tag: "hr",
getAttrs: (dom) => ({
class: dom.getAttribute("class")
}),
},
],
toDOM: (node) => {
return ["hr", { class: node.attrs.class }];
},
};
window.schemaProvider = (args) => {
const schema = args.getSchema();
const Schema = args.ProseMirror.Schema
const paragraph = { ...schema.spec.nodes.get("paragraph") };
paragraph.attrs["data-id"] = { default: null };
let nodes = schema.spec.nodes.update("paragraph", paragraph);
nodes = nodes.remove("horizontal_rule");
nodes = nodes.addToEnd("hr", updatedHr);
const markStrikeThrough = tagMark("s");
const marks = schema.spec.marks.append(markStrikeThrough);
const newSchema = new Schema({ nodes, marks });
return newSchema;
}
</script>