Skip to content

Commit 9830b82

Browse files
ntachevadimodiikoevska
authored
Editor enhancements docs (#2222)
* docs(editor): plugin and schema docs * docs(editor): add schema docs * docs(editor): updates * docs(editor): create new schema docs and sampple * docs(editor): update articles * Update _contentTemplates/editor/general.md Co-authored-by: Dimo Dimov <961014+dimodi@users.noreply.github.com> * Update _contentTemplates/editor/general.md Co-authored-by: Dimo Dimov <961014+dimodi@users.noreply.github.com> * Update _contentTemplates/editor/general.md Co-authored-by: Iva Stefanova Koevska-Atanasova <koevska@progress.com> * Update _contentTemplates/editor/general.md Co-authored-by: Iva Stefanova Koevska-Atanasova <koevska@progress.com> * Update _contentTemplates/editor/general.md Co-authored-by: Iva Stefanova Koevska-Atanasova <koevska@progress.com> * Update components/editor/prosemirror-plugins.md Co-authored-by: Iva Stefanova Koevska-Atanasova <koevska@progress.com> * Update components/editor/prosemirror-plugins.md Co-authored-by: Iva Stefanova Koevska-Atanasova <koevska@progress.com> * Update components/editor/prosemirror-plugins.md Co-authored-by: Iva Stefanova Koevska-Atanasova <koevska@progress.com> * Update components/editor/prosemirror-plugins.md Co-authored-by: Iva Stefanova Koevska-Atanasova <koevska@progress.com> * Update _contentTemplates/editor/general.md Co-authored-by: Dimo Dimov <961014+dimodi@users.noreply.github.com> * Update _contentTemplates/editor/general.md Co-authored-by: Dimo Dimov <961014+dimodi@users.noreply.github.com> * Update components/editor/prosemirror-plugins.md Co-authored-by: Dimo Dimov <961014+dimodi@users.noreply.github.com> * Update components/editor/prosemirror-plugins.md Co-authored-by: Dimo Dimov <961014+dimodi@users.noreply.github.com> * Update components/editor/prosemirror-schema/create-new-schema.md Co-authored-by: Dimo Dimov <961014+dimodi@users.noreply.github.com> * Update components/editor/prosemirror-schema/create-new-schema.md Co-authored-by: Dimo Dimov <961014+dimodi@users.noreply.github.com> * Update components/editor/prosemirror-schema/create-new-schema.md Co-authored-by: Dimo Dimov <961014+dimodi@users.noreply.github.com> * Update components/editor/prosemirror-schema/create-new-schema.md Co-authored-by: Dimo Dimov <961014+dimodi@users.noreply.github.com> * Update components/editor/prosemirror-schema/overview.md Co-authored-by: Iva Stefanova Koevska-Atanasova <koevska@progress.com> * Update components/editor/prosemirror-plugins.md Co-authored-by: Iva Stefanova Koevska-Atanasova <koevska@progress.com> * Update _contentTemplates/editor/general.md Co-authored-by: Iva Stefanova Koevska-Atanasova <koevska@progress.com> * Update components/editor/prosemirror-schema/overview.md Co-authored-by: Iva Stefanova Koevska-Atanasova <koevska@progress.com> * Update components/editor/prosemirror-schema/overview.md Co-authored-by: Iva Stefanova Koevska-Atanasova <koevska@progress.com> * Update components/editor/prosemirror-schema/overview.md Co-authored-by: Iva Stefanova Koevska-Atanasova <koevska@progress.com> * Update components/editor/prosemirror-schema/modify-default-schema.md Co-authored-by: Iva Stefanova Koevska-Atanasova <koevska@progress.com> * Update components/editor/prosemirror-schema/modify-default-schema.md Co-authored-by: Iva Stefanova Koevska-Atanasova <koevska@progress.com> * Update components/editor/prosemirror-schema/modify-default-schema.md Co-authored-by: Iva Stefanova Koevska-Atanasova <koevska@progress.com> * Update components/editor/prosemirror-schema/modify-default-schema.md Co-authored-by: Iva Stefanova Koevska-Atanasova <koevska@progress.com> * Update components/editor/prosemirror-schema/create-new-schema.md Co-authored-by: Iva Stefanova Koevska-Atanasova <koevska@progress.com> * docs(editor): address feedback * chore(editor): update samples and links * chore(editor): address feedback * chore(editor): update structure and remove repeating info * chore(editor): minor fixes * chore(editor): update exteral links --------- Co-authored-by: Dimo Dimov <961014+dimodi@users.noreply.github.com> Co-authored-by: Iva Stefanova Koevska-Atanasova <koevska@progress.com>
1 parent d3c4c2b commit 9830b82

File tree

7 files changed

+596
-0
lines changed

7 files changed

+596
-0
lines changed

_config.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,9 @@ navigation:
216216
"*components/editor/edit-modes":
217217
title: "Edit Modes"
218218
position: 80
219+
"*components/editor/prosemirror-schema":
220+
title: "ProseMirror Schema"
221+
position: 120
219222
"*components/panelbar/data-binding":
220223
title: "Data Binding"
221224
position: 2

_contentTemplates/editor/general.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,33 @@ This section applies only to Blazor **Server** apps. Blazor **WebAssembly** apps
1111
Blazor **Server** apps use the **SignalR WebSocket** to send the Editor `Value` from the browser to the server .NET runtime and vice-versa. The default SignalR maximum message size is **32 KB**. To work with larger content (especially paste images as Base64 strings), [increase the max WebSocket message size for the Blazor application]({%slug common-kb-increase-signalr-max-message-size%}).
1212

1313
#end
14+
#prosemirror-schema-prerequisites
15+
## Prerequisites
16+
17+
To work with ProseMirror, make sure you are familiar with:
18+
19+
* JavaScript&mdash;ProseMirror is a JavaScript library and the schema uses JavaScript syntax.
20+
* <a href="https://prosemirror.net/docs/guide/#schema" target="_blank">ProseMirror Schema</a>&mdash;The schema structure and its children (<a href="https://prosemirror.net/docs/ref/#model.NodeType" target="_blank">nodes</a> and <a href="https://prosemirror.net/docs/ref/#model.MarkType" target="_blank">marks</a>).
21+
22+
Modifying the ProseMirror Schema is outside of the Editor scope and we do not provide support for such customizations.
23+
#end
24+
25+
#prosemirror-schema-general-info
26+
The Editor accepts a custom ProseMirror schema through its `Schema` parameter. Set this `string` parameter to the name of a JavaScript function that:
27+
28+
* Is declared in the global scope (the `window` object).
29+
* Returns an instance of the <a href="https://prosemirror.net/docs/ref/#model.Schema" target="_blank">ProseMirror `Schema` class</a>(the updated schema). You can access this class from the `ProseMirror` object of the event arguments.
30+
* Accepts a single argument.
31+
32+
The Editor will call this function and will pass an argument object that contains the following properties:
33+
34+
@[template](/_contentTemplates/common/parameters-table-styles.md#table-layout)
35+
36+
| Property | Description |
37+
|----------|-------------|
38+
| `getSchema` | A function that returns the current <a href="https://prosemirror.net/docs/ref/#model.Schema" target="_blank">`Schema` object</a>. 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. |
39+
| `getView` | A function that returns the currently used instance of the <a href="https://prosemirror.net/docs/ref/#view.EditorView" target="_blank">`EditorView` object</a>. Before the Editor is initialized, the view (the result of the function) is null. |
40+
| `ProseMirror` | An object that contains various ProseMirror classes and functions. |
41+
42+
> 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.
43+
#end

components/editor/overview.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ Images in the content area of the Editor are resizable. To grab the resize handl
8282

8383
The Telerik UI for [Blazor Editor](https://www.telerik.com/blazor-ui/editor) uses the ProseMirror engine and it depends on it. You do not need to add any extra assets or references yourself, though, we have taken care of everything internally.
8484

85+
## ProseMirror Schema and Plugins
86+
87+
The Editor uses a built-in <a href="https://prosemirror.net/docs/guide/#schema" target="_blank">ProseMirror Schema</a> containing some of the most common HTML tags and a set of predefined <a href="https://prosemirror.net/docs/ref/#state.Plugin_System" target="_blank">ProseMirror Plugins</a> for its basic functionalities. You can customize the default ProseMirror [Schema]({%slug editor-prosemirror-schema-overview%}) and [Plugins]({%slug editor-prosemirror-plugins%}) to achieve the desired functionality in the Editor for Blazor.
88+
8589
## Editor Parameters
8690

8791
The following table lists Editor parameters, which are not discussed elsewhere in the component documentation.
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
---
2+
title: ProseMirror Plugins
3+
page_title: ProseMirror Plugins
4+
description: Explore how to use the ProseMirror Plugins in the Editor for Blazor uses.
5+
slug: editor-prosemirror-plugins
6+
tags: telerik,blazor,editor,prosemirror,plugins
7+
published: True
8+
position: 130
9+
---
10+
11+
# ProseMirror Plugins
12+
13+
The Telerik UI for Blazor Editor component is based on the <a href="https://prosemirror.net/" target="_blank">ProseMirror library</a>. ProseMirror provides a set of tools and concepts for building rich text editors, using user interface inspired by what-you-see-is-what-you-get.
14+
15+
## Plugins Concept
16+
17+
The ProseMirror <a href="https://prosemirror.net/docs/ref/#state.Plugin_System" target="_blank">plugin system</a> enables developers to create custom tools and functionality. One of the main building blocks of each editor is its <a href="https://prosemirror.net/docs/ref/#state" target="_blank">`EditorState`</a> object. The state is created through a static <a href="https://prosemirror.net/docs/ref/#state.EditorState%5Ecreate" target="_blank">`create`</a> method which takes a configuration object, containing the starting document node, the <a href="https://prosemirror.net/docs/ref/#model.Schema" target="_blank">`Schema`</a>, and a collection of <a href="https://prosemirror.net/docs/ref/#state.Plugin" target="_blank">plugins</a> which will be active in this state.
18+
19+
Plugins are instances of the <a href="https://prosemirror.net/docs/ref/#state.Plugin" target="_blank">`Plugin` class</a> and can model a wide variety of features. The basic ones may only add some <a href="https://prosemirror.net/docs/ref/#view.EditorProps" target="_blank">properties</a> to the Editor view to respond to certain events. More complicated features may add a new state to the editor and update it based on <a href="https://prosemirror.net/docs/ref/#state.Transaction" target="_blank">transactions</a>.
20+
21+
For further details about the ProseMirror plugins, refer to <a href="https://prosemirror.net/docs/guide/#state.plugins" target="_blank">this ProseMirror guide</a>.
22+
23+
Modifying the ProseMirror plugins is outside of the Editor scope and we do not provide support for such customizations.
24+
25+
## Adding a Custom Plugin
26+
27+
ProseMirror is a JavaScript library and the plugins use JavaScript syntax.
28+
29+
To add a custom plugin to the Editor, use the `Plugins` parameter. Set this `string` parameter to the name of a JavaScript function that:
30+
31+
* Is declared in the global scope (`window` object).
32+
* Returns custom ProseMirror plugins.
33+
* Accepts a single argument.
34+
35+
The Editor will call this function and will pass an argument object that contains the following properties:
36+
37+
@[template](/_contentTemplates/common/parameters-table-styles.md#table-layout)
38+
39+
| Property | Description |
40+
|----------|-------------|
41+
| `getSchema` | A function that returns the current <a href="https://prosemirror.net/docs/ref/#model.Schema" target="_blank">`Schema` object</a>. Before the Editor is initialized, the `Schema` is the default `Schema`. After the Editor is initialized, the returned `Schema` is the updated schema. If you don't provide a custom schema, this function always returns the default schema. |
42+
| `getView` | A function that returns the currently used instance of the <a href="https://prosemirror.net/docs/ref/#view.EditorView" target="_blank">`EditorView` object</a>. Before the Editor is initialized, the view (the result of the function) is null. |
43+
| `ProseMirror` | An object that contains various ProseMirror classes and functions.|
44+
| `getPlugins` | A function that accepts `Schema` as an argument and returns the default Editor plugins. The function must return an array of ProseMirror plugins. |
45+
46+
> To ensure all the built-in functionalities of the Editor are working correctly, the result array must contain the default plugins which can be retrieved by calling the `getPlugins` function.
47+
48+
>caption Adding a Placeholder Plugin
49+
50+
```CSHTML
51+
@using Telerik.Blazor.Components.Editor
52+
@inject IJSRuntime js
53+
54+
<TelerikEditor @bind-Value="@EditorValue"
55+
Plugins="pluginsProvider"
56+
Height="400px"
57+
Width="700px">
58+
</TelerikEditor>
59+
60+
@code {
61+
private string EditorValue { get; set; }
62+
63+
protected override async Task OnAfterRenderAsync(bool firstRender)
64+
{
65+
if (firstRender)
66+
{
67+
//Plug the styles with JavaScript as shown below or set the EditMode to `Div` - https://docs.telerik.com/blazor-ui/components/editor/edit-modes/div
68+
await js.InvokeVoidAsync("injectEditorStyleTag");
69+
}
70+
}
71+
}
72+
73+
@* Move JavaScript code to a separate JS file in production *@
74+
<script suppress-error="BL9992">
75+
window.pluginsProvider = (args) => {
76+
const schema = args.getSchema();
77+
var placeHolderKey = new args.ProseMirror.PluginKey("placeholder");
78+
79+
function placeholder(emptyMessage) {
80+
console.log(args);
81+
return new args.ProseMirror.Plugin({
82+
key: placeHolderKey,
83+
props: {
84+
decorations: (state) => {
85+
const { doc } = state;
86+
const empty =
87+
doc.textContent === "" &&
88+
doc.childCount <= 1 &&
89+
doc.content.size <= 2;
90+
if (!empty) {
91+
return args.ProseMirror.DecorationSet.empty;
92+
}
93+
const decorations = [];
94+
const decAttrs = {
95+
class: "placeholder",
96+
"data-placeholder": emptyMessage,
97+
};
98+
doc.descendants((node, pos) => {
99+
decorations.push(args.ProseMirror.Decoration.node(pos, pos + node.nodeSize, decAttrs));
100+
});
101+
return args.ProseMirror.DecorationSet.create(doc, decorations);
102+
}
103+
}
104+
});
105+
}
106+
107+
return [...args.getPlugins(schema), placeholder("Enter some content ...")];
108+
}
109+
110+
function injectEditorStyleTag() {
111+
var doc = document.querySelector("iframe").contentWindow.document;
112+
var head = doc.querySelector("head");
113+
114+
var style = doc.createElement("style");
115+
style.type = "text/css";
116+
117+
var iframeStyles = `p.placeholder:first-child:before {
118+
content: attr(data-placeholder);
119+
float: left;
120+
color: rgb(0, 0, 0, 0.5);
121+
cursor: text;
122+
height: 0;
123+
font-style: italic;
124+
}`;
125+
126+
style.appendChild(doc.createTextNode(iframeStyles));
127+
head.appendChild(style);
128+
};
129+
</script>
130+
```
131+
132+
## See Also
133+
134+
* [Live Demo: Editor - ProseMirror Plugins](https://demos.telerik.com/blazor-ui/editor/prosemirror-plugins)
135+
* [ProseMirror Schema]({%slug editor-prosemirror-schema-overview%})
136+
137+
138+
<!-- # Examples
139+
140+
List here the KB articles created as part of https://github.com/telerik/blazor/issues/9608
141+
142+
Similar to how this is handle in the Grid State article - https://docs.telerik.com/blazor-ui/components/grid/state#examples
143+
-->

0 commit comments

Comments
 (0)