Skip to content

Commit 5e45072

Browse files
committed
feat: Support read only mode
1 parent 4c8839b commit 5e45072

File tree

5 files changed

+164
-145
lines changed

5 files changed

+164
-145
lines changed

docs/index.html

+89-79
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@
1818
<button id="button" type="button">Save</button>
1919
<div id="output-data"></div>
2020

21+
<br />
22+
23+
read only mode
24+
<div id="read-only-editorjs"></div>
25+
2126
<script src="https://cdn.jsdelivr.net/npm/@editorjs/editorjs@latest"></script>
2227

2328
<!-- For demo -->
@@ -66,95 +71,93 @@
6671

6772
const editorJSConfig = {};
6873

69-
const editorJS = new EditorJS({
70-
data,
71-
tools: {
72-
layout: {
73-
class: EditorJSLayout.LayoutBlockTool,
74-
config: {
75-
EditorJS,
76-
editorJSConfig,
77-
enableLayoutEditing: false,
78-
enableLayoutSaving: true,
79-
initialData: {
80-
itemContent: {
81-
1: {
82-
blocks: [],
83-
},
84-
},
85-
layout: {
86-
type: "container",
87-
id: "",
88-
className: "",
89-
style: "border: 1px solid #000000; ",
90-
children: [
91-
{
92-
type: "item",
93-
id: "",
94-
className: "",
95-
style:
96-
"border: 1px solid #000000; display: inline-block; ",
97-
itemContentId: "1",
98-
},
99-
],
74+
const tools = {
75+
layout: {
76+
class: EditorJSLayout.LayoutBlockTool,
77+
config: {
78+
EditorJS,
79+
editorJSConfig,
80+
enableLayoutEditing: false,
81+
enableLayoutSaving: true,
82+
initialData: {
83+
itemContent: {
84+
1: {
85+
blocks: [],
10086
},
10187
},
88+
layout: {
89+
type: "container",
90+
id: "",
91+
className: "",
92+
style: "border: 1px solid #000000; ",
93+
children: [
94+
{
95+
type: "item",
96+
id: "",
97+
className: "",
98+
style: "border: 1px solid #000000; display: inline-block; ",
99+
itemContentId: "1",
100+
},
101+
],
102+
},
102103
},
103104
},
104-
twoColumns: {
105-
class: EditorJSLayout.LayoutBlockTool,
106-
config: {
107-
EditorJS,
108-
editorJSConfig,
109-
enableLayoutEditing: false,
110-
enableLayoutSaving: false,
111-
initialData: {
112-
itemContent: {
113-
1: {
114-
blocks: [],
115-
},
116-
2: {
117-
blocks: [],
118-
},
105+
},
106+
twoColumns: {
107+
class: EditorJSLayout.LayoutBlockTool,
108+
config: {
109+
EditorJS,
110+
editorJSConfig,
111+
enableLayoutEditing: false,
112+
enableLayoutSaving: false,
113+
initialData: {
114+
itemContent: {
115+
1: {
116+
blocks: [],
119117
},
120-
layout: {
121-
type: "container",
122-
id: "",
123-
className: "",
124-
style:
125-
"border: 1px solid #000000; display: flex; justify-content: space-around; padding: 16px; ",
126-
children: [
127-
{
128-
type: "item",
129-
id: "",
130-
className: "",
131-
style: "border: 1px solid #000000; padding: 8px; ",
132-
itemContentId: "1",
133-
},
134-
{
135-
type: "item",
136-
id: "",
137-
className: "",
138-
style: "border: 1px solid #000000; padding: 8px; ",
139-
itemContentId: "2",
140-
},
141-
],
118+
2: {
119+
blocks: [],
142120
},
143121
},
122+
layout: {
123+
type: "container",
124+
id: "",
125+
className: "",
126+
style:
127+
"border: 1px solid #000000; display: flex; justify-content: space-around; padding: 16px; ",
128+
children: [
129+
{
130+
type: "item",
131+
id: "",
132+
className: "",
133+
style: "border: 1px solid #000000; padding: 8px; ",
134+
itemContentId: "1",
135+
},
136+
{
137+
type: "item",
138+
id: "",
139+
className: "",
140+
style: "border: 1px solid #000000; padding: 8px; ",
141+
itemContentId: "2",
142+
},
143+
],
144+
},
144145
},
145-
shortcut: "CMD+2",
146-
toolbox: {
147-
icon: `
148-
<svg xmlns='http://www.w3.org/2000/svg' width="16" height="16" viewBox='0 0 512 512'>
149-
<rect x='128' y='128' width='336' height='336' rx='57' ry='57' fill='none' stroke='currentColor' stroke-linejoin='round' stroke-width='32'/>
150-
<path d='M383.5 128l.5-24a56.16 56.16 0 00-56-56H112a64.19 64.19 0 00-64 64v216a56.16 56.16 0 0056 56h24' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='32'/>
151-
</svg>
152-
`,
153-
title: "2 columns",
154-
},
146+
},
147+
shortcut: "CMD+2",
148+
toolbox: {
149+
icon: `
150+
<svg xmlns='http://www.w3.org/2000/svg' width="16" height="16" viewBox='0 0 512 512'>
151+
<rect x='128' y='128' width='336' height='336' rx='57' ry='57' fill='none' stroke='currentColor' stroke-linejoin='round' stroke-width='32'/>
152+
<path d='M383.5 128l.5-24a56.16 56.16 0 00-56-56H112a64.19 64.19 0 00-64 64v216a56.16 56.16 0 0056 56h24' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='32'/>
153+
</svg>
154+
`,
155+
title: "2 columns",
155156
},
156157
},
157-
});
158+
};
159+
160+
const editorJS = new EditorJS({ data, tools });
158161

159162
document.querySelector("#button").addEventListener("click", async () => {
160163
const outputData = await editorJS.save();
@@ -163,6 +166,13 @@
163166
outputData
164167
);
165168
});
169+
170+
new EditorJS({
171+
holder: "read-only-editorjs",
172+
data,
173+
readOnly: true,
174+
tools,
175+
});
166176
</script>
167177
</body>
168178
</html>

src/LayoutBlockTool.ts

+8
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ interface LayoutBlockToolDispatchData {
4949
}
5050

5151
class LayoutBlockTool implements BlockTool {
52+
static get isReadOnlySupported() {
53+
return true;
54+
}
55+
5256
static get shortcut() {
5357
return "CMD+L";
5458
}
@@ -68,6 +72,7 @@ class LayoutBlockTool implements BlockTool {
6872
}
6973

7074
#config!: LayoutBlockToolConfig;
75+
#readOnly: boolean;
7176
#wrapper: HTMLDivElement;
7277

7378
#itemContent: LayoutBlockItemContentData;
@@ -76,7 +81,9 @@ class LayoutBlockTool implements BlockTool {
7681
constructor({
7782
config,
7883
data,
84+
readOnly,
7985
}: BlockToolConstructorOptions<LayoutBlockToolData, LayoutBlockToolConfig>) {
86+
this.#readOnly = readOnly;
8087
this.#wrapper = document.createElement("div");
8188

8289
this.#itemContent = {};
@@ -152,6 +159,7 @@ class LayoutBlockTool implements BlockTool {
152159
dispatchData: this.#dispatchData,
153160
editorJSConfig: this.#config.editorJSConfig,
154161
itemContentData: this.#itemContent,
162+
readOnly: this.#readOnly,
155163
})
156164
);
157165
}

src/container.ts

+21-16
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,23 @@ interface ValidatedLayoutBlockContainerData extends LayoutBlockContainerData {
2222
)[];
2323
}
2424

25-
const renderContainer = ({
26-
EditorJS,
27-
data,
28-
dispatchData,
29-
editorJSConfig,
30-
itemContentData,
31-
}: {
25+
interface RenderContext {
3226
EditorJS: LayoutBlockToolConfig["EditorJS"];
33-
data: LayoutBlockContainerData;
3427
dispatchData: LayoutBlockToolDispatchData;
3528
editorJSConfig: LayoutBlockToolConfig["editorJSConfig"];
29+
readOnly: boolean;
30+
}
31+
32+
interface RenderContainerProps extends RenderContext {
33+
data: LayoutBlockContainerData;
3634
itemContentData: LayoutBlockItemContentData;
37-
}) => {
35+
}
36+
37+
const renderContainer = ({
38+
data,
39+
itemContentData,
40+
...context
41+
}: RenderContainerProps) => {
3842
const wrapper = document.createElement("div");
3943

4044
wrapper.id = data.id;
@@ -47,10 +51,8 @@ const renderContainer = ({
4751
switch (child.type) {
4852
case "container": {
4953
childElement = renderContainer({
50-
EditorJS,
54+
...context,
5155
data: child,
52-
dispatchData,
53-
editorJSConfig,
5456
itemContentData,
5557
});
5658

@@ -59,10 +61,8 @@ const renderContainer = ({
5961

6062
case "item": {
6163
childElement = renderItem({
62-
EditorJS,
64+
...context,
6365
data: child,
64-
dispatchData,
65-
editorJSConfig,
6666
itemContentData,
6767
});
6868

@@ -83,4 +83,9 @@ const renderContainer = ({
8383
};
8484

8585
export { renderContainer };
86-
export type { LayoutBlockContainerData, ValidatedLayoutBlockContainerData };
86+
export type {
87+
LayoutBlockContainerData,
88+
RenderContainerProps,
89+
RenderContext,
90+
ValidatedLayoutBlockContainerData,
91+
};

src/item.ts

+11-19
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
import type {
2-
LayoutBlockToolConfig,
3-
LayoutBlockToolDispatchData,
4-
} from "./LayoutBlockTool";
1+
import type { RenderContext } from "./container";
52
import { renderItemContent } from "./itemContent";
63
import type { LayoutBlockItemContentData } from "./itemContent";
74

@@ -15,19 +12,12 @@ interface LayoutBlockItemData {
1512

1613
interface ValidatedLayoutBlockItemData extends LayoutBlockItemData {}
1714

18-
const renderItem = ({
19-
EditorJS,
20-
data,
21-
dispatchData,
22-
editorJSConfig,
23-
itemContentData,
24-
}: {
25-
EditorJS: LayoutBlockToolConfig["EditorJS"];
15+
interface RenderItemProps extends RenderContext {
2616
data: LayoutBlockItemData;
27-
dispatchData: LayoutBlockToolDispatchData;
28-
editorJSConfig: LayoutBlockToolConfig["editorJSConfig"];
2917
itemContentData: LayoutBlockItemContentData;
30-
}) => {
18+
}
19+
20+
const renderItem = ({ data, itemContentData, ...context }: RenderItemProps) => {
3121
const wrapper = document.createElement("div");
3222

3323
wrapper.id = data.id;
@@ -38,10 +28,8 @@ const renderItem = ({
3828

3929
wrapper.append(
4030
renderItemContent({
41-
EditorJS,
31+
...context,
4232
data: editorJSData,
43-
dispatchData,
44-
editorJSConfig,
4533
itemContentId: data.itemContentId,
4634
})
4735
);
@@ -50,4 +38,8 @@ const renderItem = ({
5038
};
5139

5240
export { renderItem };
53-
export type { LayoutBlockItemData, ValidatedLayoutBlockItemData };
41+
export type {
42+
LayoutBlockItemData,
43+
RenderItemProps,
44+
ValidatedLayoutBlockItemData,
45+
};

0 commit comments

Comments
 (0)