@qarakash/blockwriteai 1.0.8 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +158 -602
- package/dist/blockwriteai.min.css +1 -0
- package/dist/blockwriteai.min.js +1 -0
- package/dist/plugins/blockwriteai-advanced-blocks.min.js +1 -0
- package/dist/plugins/blockwriteai-ai.min.js +1 -0
- package/dist/plugins/blockwriteai-code-assist.min.js +1 -0
- package/dist/plugins/blockwriteai-drawing.min.js +1 -0
- package/dist/plugins/blockwriteai-history.min.js +1 -0
- package/dist/plugins/blockwriteai-mermaid.min.js +1 -0
- package/dist/plugins/blockwriteai-signature-flow.min.js +1 -0
- package/dist/plugins/blockwriteai-signature.min.js +1 -0
- package/package.json +26 -18
- package/types/index.d.ts +1 -1
- package/dist/blockwriteai.css +0 -3762
- package/dist/blockwriteai.js +0 -6771
- package/dist/plugins/blockwriteai-advanced-blocks.js +0 -2282
- package/dist/plugins/blockwriteai-ai.js +0 -637
- package/dist/plugins/blockwriteai-code-assist.js +0 -609
- package/dist/plugins/blockwriteai-drawing.js +0 -178
- package/dist/plugins/blockwriteai-history.js +0 -23
- package/dist/plugins/blockwriteai-mermaid.js +0 -1986
- package/dist/plugins/blockwriteai-signature-flow.js +0 -493
- package/dist/plugins/blockwriteai-signature.js +0 -463
package/README.md
CHANGED
|
@@ -1,392 +1,201 @@
|
|
|
1
|
-
# BlockWriteAI
|
|
2
|
-
|
|
3
|
-
BlockWriteAI is a drop-in block writing editor for the web. It is built to feel familiar to Editor.js users, but ships as plain CSS and JavaScript files that can be used in PHP, Laravel, CodeIgniter, static HTML, dashboards, or any project that can load a script tag.
|
|
4
|
-
|
|
5
|
-
The editor stores and saves content as JSON first. Projects can render that JSON on any page by adding a BlockWriteAI preview container, while advanced document blocks such as tables, media galleries, attachments, diagrams, charts, signatures, and code editing remain available as plugins.
|
|
6
|
-
|
|
7
|
-
All public assets, package entry points, and browser globals use the `BlockWriteAI` name.
|
|
8
|
-
|
|
9
|
-
## Highlights
|
|
10
|
-
|
|
11
|
-
- Editor.js-style block JSON output.
|
|
12
|
-
- Plain script tag integration with no build step required.
|
|
13
|
-
- Paragraphs, headings, quotes, callouts, dividers, buttons, toggle blocks, raw HTML, links, embeds, tables, lists, and nested checklists.
|
|
14
|
-
- Floating inline toolbar with typography, colors, highlight, alignment, comments, links, and formatting controls.
|
|
15
|
-
- Multi-image upload, drag and drop, resize, crop, rotate, and gallery layout.
|
|
16
|
-
- Attachment blocks for documents and videos.
|
|
17
|
-
- Code block with formatting, syntax help, language detection, and suggestions.
|
|
18
|
-
- Charts, LaTeX, audio, layout columns, code assistance, and optional history plugins in the free plugin set.
|
|
19
|
-
- Premium plugins for Drawing, Mermaid, Signature, Signature Flow, and AI writing, delivered after server-side license verification.
|
|
20
|
-
- Undo, redo, autosave, block actions, drag reordering, and optional JSON save/export buttons.
|
|
21
|
-
- JSON-powered preview mounting for public document pages.
|
|
22
|
-
- JSON save API examples for future database storage.
|
|
23
|
-
|
|
24
|
-
## Project Structure
|
|
25
|
-
|
|
26
|
-
```text
|
|
27
|
-
BlockWriteAI/
|
|
28
|
-
package.json
|
|
29
|
-
composer.json
|
|
30
|
-
pyproject.toml
|
|
31
|
-
dist/
|
|
32
|
-
blockwriteai.css
|
|
33
|
-
blockwriteai.js
|
|
34
|
-
blockwriteai-logo.svg
|
|
35
|
-
blockwriteai-favicon.svg
|
|
36
|
-
plugins/
|
|
37
|
-
blockwriteai-advanced-blocks.js
|
|
38
|
-
blockwriteai-drawing.js
|
|
39
|
-
blockwriteai-mermaid.js
|
|
40
|
-
blockwriteai-ai.js
|
|
41
|
-
blockwriteai-code-assist.js
|
|
42
|
-
blockwriteai-history.js
|
|
43
|
-
blockwriteai-signature.js
|
|
44
|
-
blockwriteai-signature-flow.js
|
|
45
|
-
examples/
|
|
46
|
-
index.html
|
|
47
|
-
preview.html
|
|
48
|
-
upload.php
|
|
49
|
-
api/
|
|
50
|
-
document.php
|
|
51
|
-
preview.php
|
|
52
|
-
uploads/
|
|
53
|
-
.gitkeep
|
|
54
|
-
blockwriteai_editor/
|
|
55
|
-
static/blockwriteai/
|
|
56
|
-
src/
|
|
57
|
-
BlockWriteAIAssets.php
|
|
58
|
-
types/
|
|
59
|
-
index.d.ts
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
## Installation
|
|
63
|
-
|
|
64
|
-
BlockWriteAI can be consumed as a CDN/script-link package, an npm package, a Python static-assets package, or a Composer package.
|
|
65
|
-
|
|
66
|
-
### Script Link
|
|
67
|
-
|
|
68
|
-
Use the npm CDN for a locked release build:
|
|
1
|
+
# BlockWriteAI
|
|
69
2
|
|
|
70
|
-
|
|
71
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.8/dist/blockwriteai.css">
|
|
3
|
+
BlockWriteAI is a JSON-first block editor for web apps. It works with a script tag, npm, PHP/Composer, and Python static-file workflows.
|
|
72
4
|
|
|
73
|
-
|
|
74
|
-
<script src="https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.8/dist/plugins/blockwriteai-code-assist.js"></script>
|
|
75
|
-
<script src="https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.8/dist/plugins/blockwriteai-advanced-blocks.js"></script>
|
|
76
|
-
```
|
|
5
|
+
Use the free core editor for normal documents. Serve premium tools such as AI, Mermaid, Drawing, Signature, and Signature Flow only through your licensed server endpoint.
|
|
77
6
|
|
|
78
|
-
|
|
79
|
-
LaTeX, Audio, and Columns/Layout. Drawing, Mermaid, Signature, Signature Flow,
|
|
80
|
-
and AI are premium plugins and should not be loaded directly in production.
|
|
7
|
+
## Quick Start With CDN
|
|
81
8
|
|
|
82
|
-
|
|
9
|
+
Add the stylesheet, editor script, and free plugin bundle:
|
|
83
10
|
|
|
84
11
|
```html
|
|
85
|
-
<
|
|
12
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/blockwriteai.min.css">
|
|
13
|
+
|
|
14
|
+
<div id="editor"></div>
|
|
15
|
+
|
|
16
|
+
<script src="https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/blockwriteai.min.js"></script>
|
|
17
|
+
<script src="https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/plugins/blockwriteai-code-assist.min.js"></script>
|
|
18
|
+
<script src="https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/plugins/blockwriteai-advanced-blocks.min.js"></script>
|
|
19
|
+
<script>
|
|
20
|
+
const editor = new BlockWriteAI({
|
|
21
|
+
holder: "#editor",
|
|
22
|
+
placeholder: "Write something, or press / for blocks",
|
|
23
|
+
async onSave(data) {
|
|
24
|
+
await fetch("/api/documents", {
|
|
25
|
+
method: "POST",
|
|
26
|
+
headers: { "Content-Type": "application/json" },
|
|
27
|
+
body: JSON.stringify(data)
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
</script>
|
|
86
32
|
```
|
|
87
33
|
|
|
88
|
-
|
|
89
|
-
|
|
34
|
+
Use these CDN URLs for production:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/blockwriteai.min.css
|
|
38
|
+
https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/blockwriteai.min.js
|
|
39
|
+
https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/plugins/blockwriteai-code-assist.min.js
|
|
40
|
+
https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/plugins/blockwriteai-advanced-blocks.min.js
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Optional history plugin:
|
|
90
44
|
|
|
91
45
|
```html
|
|
92
|
-
https://cdn.jsdelivr.net/
|
|
46
|
+
<script src="https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/plugins/blockwriteai-history.min.js"></script>
|
|
93
47
|
```
|
|
94
48
|
|
|
95
|
-
|
|
49
|
+
## Install With Node
|
|
96
50
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
active trial or subscription. Without a valid license, those tools are not
|
|
101
|
-
registered and do not appear in the insert-block menu.
|
|
51
|
+
```bash
|
|
52
|
+
npm install @qarakash/blockwriteai
|
|
53
|
+
```
|
|
102
54
|
|
|
103
55
|
```js
|
|
56
|
+
import BlockWriteAI from "@qarakash/blockwriteai";
|
|
57
|
+
import "@qarakash/blockwriteai/css";
|
|
58
|
+
import "@qarakash/blockwriteai/plugins/code-assist/min";
|
|
59
|
+
import "@qarakash/blockwriteai/plugins/advanced/min";
|
|
60
|
+
|
|
104
61
|
const editor = new BlockWriteAI({
|
|
105
62
|
holder: "#editor",
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
features: ["drawing", "mermaid", "signature", "signature_flow", "ai"]
|
|
113
|
-
},
|
|
114
|
-
ai: {
|
|
115
|
-
endpoint: "/api/ai.php"
|
|
63
|
+
async onSave(data) {
|
|
64
|
+
await fetch("/api/documents", {
|
|
65
|
+
method: "POST",
|
|
66
|
+
headers: { "Content-Type": "application/json" },
|
|
67
|
+
body: JSON.stringify(data)
|
|
68
|
+
});
|
|
116
69
|
}
|
|
117
70
|
});
|
|
118
71
|
```
|
|
119
72
|
|
|
120
|
-
|
|
73
|
+
## Install With PHP
|
|
121
74
|
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
"drawing": true,
|
|
125
|
-
"mermaid": true,
|
|
126
|
-
"signature": true,
|
|
127
|
-
"signature_flow": true,
|
|
128
|
-
"ai": true
|
|
129
|
-
}
|
|
75
|
+
```bash
|
|
76
|
+
composer require qarakash/blockwriteai
|
|
130
77
|
```
|
|
131
78
|
|
|
132
|
-
|
|
133
|
-
|
|
79
|
+
Publish the package `dist` assets into a public asset directory in your app, then print the tags:
|
|
80
|
+
|
|
81
|
+
```php
|
|
82
|
+
<?php
|
|
83
|
+
|
|
84
|
+
use QarAkash\BlockWriteAI\BlockWriteAIAssets;
|
|
134
85
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
86
|
+
echo BlockWriteAIAssets::stylesheetTag('/assets/blockwriteai');
|
|
87
|
+
echo BlockWriteAIAssets::scriptTags('/assets/blockwriteai');
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Create the editor:
|
|
140
91
|
|
|
141
92
|
```html
|
|
142
|
-
<
|
|
143
|
-
<script src="https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.8/dist/blockwriteai.js"></script>
|
|
144
|
-
<script src="https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.8/dist/plugins/blockwriteai-code-assist.js"></script>
|
|
145
|
-
<script src="https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.8/dist/plugins/blockwriteai-advanced-blocks.js"></script>
|
|
93
|
+
<div id="editor"></div>
|
|
146
94
|
<script>
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
licenseKey: "bwai_live_xxxxx",
|
|
158
|
-
verifyEndpoint: "http://localhost/blockwriteai-platform/api/license_verify.php",
|
|
159
|
-
usageEndpoint: "http://localhost/blockwriteai-platform/api/ai_usage.php"
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
boot();
|
|
95
|
+
const editor = new BlockWriteAI({
|
|
96
|
+
holder: "#editor",
|
|
97
|
+
async onSave(data) {
|
|
98
|
+
await fetch("/api/documents/save.php", {
|
|
99
|
+
method: "POST",
|
|
100
|
+
headers: { "Content-Type": "application/json" },
|
|
101
|
+
body: JSON.stringify(data)
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
});
|
|
164
105
|
</script>
|
|
165
106
|
```
|
|
166
107
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
### npm
|
|
172
|
-
|
|
173
|
-
Package name:
|
|
174
|
-
|
|
175
|
-
```text
|
|
176
|
-
@qarakash/blockwriteai
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
Install:
|
|
180
|
-
|
|
181
|
-
```bash
|
|
182
|
-
npm install @qarakash/blockwriteai
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
Bundler entry points:
|
|
186
|
-
|
|
187
|
-
```js
|
|
188
|
-
import BlockWriteAI from "@qarakash/blockwriteai";
|
|
189
|
-
import "@qarakash/blockwriteai/css";
|
|
190
|
-
import "@qarakash/blockwriteai/plugins/code-assist";
|
|
191
|
-
import "@qarakash/blockwriteai/plugins/advanced";
|
|
192
|
-
import "@qarakash/blockwriteai/plugins/history";
|
|
108
|
+
## Install With Python
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
pip install blockwriteai-editor
|
|
193
112
|
```
|
|
194
113
|
|
|
195
|
-
|
|
114
|
+
Copy the packaged assets into your app static directory:
|
|
196
115
|
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
|
|
116
|
+
```python
|
|
117
|
+
from blockwriteai_editor import copy_static
|
|
118
|
+
|
|
119
|
+
copy_static("static/blockwriteai")
|
|
200
120
|
```
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
Package name:
|
|
205
|
-
|
|
206
|
-
```text
|
|
207
|
-
blockwriteai-editor
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
Install:
|
|
211
|
-
|
|
212
|
-
```bash
|
|
213
|
-
pip install blockwriteai-editor
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
Copy packaged static files into your Flask, Django, or any Python web app static directory:
|
|
217
|
-
|
|
218
|
-
```python
|
|
219
|
-
from blockwriteai_editor import copy_static
|
|
220
|
-
|
|
221
|
-
copy_static("static/blockwriteai")
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
Python helpers are also available for generating asset tags. `script_tags()` loads
|
|
225
|
-
only core/free plugins by default. Pass `history=True` only on pages where you want
|
|
226
|
-
the optional History dropdown:
|
|
121
|
+
|
|
122
|
+
Generate tags in Flask, Django, or any Python web app:
|
|
227
123
|
|
|
228
124
|
```python
|
|
229
|
-
from blockwriteai_editor import
|
|
125
|
+
from blockwriteai_editor import stylesheet_tag, script_tags
|
|
230
126
|
|
|
231
127
|
print(stylesheet_tag("/static/blockwriteai"))
|
|
232
128
|
print(script_tags("/static/blockwriteai"))
|
|
233
|
-
|
|
129
|
+
```
|
|
234
130
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
131
|
+
Then mount the editor in your template:
|
|
132
|
+
|
|
133
|
+
```html
|
|
134
|
+
<div id="editor"></div>
|
|
135
|
+
<script>
|
|
136
|
+
const editor = new BlockWriteAI({
|
|
137
|
+
holder: "#editor",
|
|
138
|
+
async onSave(data) {
|
|
139
|
+
await fetch("/api/documents", {
|
|
140
|
+
method: "POST",
|
|
141
|
+
headers: { "Content-Type": "application/json" },
|
|
142
|
+
body: JSON.stringify(data)
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
</script>
|
|
238
147
|
```
|
|
239
|
-
|
|
240
|
-
### PHP / Composer
|
|
241
|
-
|
|
242
|
-
Package name:
|
|
243
|
-
|
|
244
|
-
```text
|
|
245
|
-
qarakash/blockwriteai
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
Install:
|
|
249
|
-
|
|
250
|
-
```bash
|
|
251
|
-
composer require qarakash/blockwriteai
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
Publish assets into your public folder:
|
|
255
|
-
|
|
256
|
-
```bash
|
|
257
|
-
cp -R vendor/qarakash/blockwriteai/dist public/blockwriteai
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
PHP helper. `scriptTags()` loads only core/free plugins by default. Pass
|
|
261
|
-
`history: true` only on pages where you want the optional History dropdown:
|
|
262
148
|
|
|
263
|
-
|
|
264
|
-
use QarAkash\BlockWriteAI\BlockWriteAIAssets;
|
|
149
|
+
## Read Saved Documents
|
|
265
150
|
|
|
266
|
-
|
|
267
|
-
echo BlockWriteAIAssets::scriptTags('/blockwriteai');
|
|
268
|
-
echo BlockWriteAIAssets::scriptTags('/blockwriteai', plugins: true, history: true);
|
|
151
|
+
BlockWriteAI saves JSON. Store that JSON in your database, then render it later with a preview container:
|
|
269
152
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
## Local XAMPP Demo
|
|
276
|
-
|
|
277
|
-
Copy the `BlockWriteAI` folder into your web root, for example:
|
|
278
|
-
|
|
279
|
-
```text
|
|
280
|
-
C:\xampp\htdocs\BlockWriteAI
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
Open:
|
|
284
|
-
|
|
285
|
-
```text
|
|
286
|
-
http://localhost/BlockWriteAI/examples/
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
## Browser Usage
|
|
290
|
-
|
|
291
|
-
```html
|
|
292
|
-
<link rel="stylesheet" href="/BlockWriteAI/dist/blockwriteai.css">
|
|
293
|
-
|
|
294
|
-
<div id="editor"></div>
|
|
295
|
-
|
|
296
|
-
<script src="/BlockWriteAI/dist/blockwriteai.js"></script>
|
|
297
|
-
<script src="/BlockWriteAI/dist/plugins/blockwriteai-code-assist.js"></script>
|
|
298
|
-
<script src="/BlockWriteAI/dist/plugins/blockwriteai-advanced-blocks.js"></script>
|
|
153
|
+
```html
|
|
154
|
+
<link rel="stylesheet" href="/assets/blockwriteai/blockwriteai.min.css">
|
|
155
|
+
|
|
156
|
+
<div class="blockwriteai-preview" data-source="/api/documents/123.json"></div>
|
|
299
157
|
|
|
158
|
+
<script src="/assets/blockwriteai/blockwriteai.min.js"></script>
|
|
159
|
+
<script src="/assets/blockwriteai/plugins/blockwriteai-advanced-blocks.min.js"></script>
|
|
300
160
|
<script>
|
|
301
|
-
|
|
302
|
-
holder: "#editor",
|
|
303
|
-
maxWidth: "960px", // optional; omit for full-width editor shell
|
|
304
|
-
placeholder: "Write something, or press / for blocks",
|
|
305
|
-
data: {
|
|
306
|
-
blocks: [
|
|
307
|
-
{
|
|
308
|
-
type: "paragraph",
|
|
309
|
-
data: {
|
|
310
|
-
text: "Hello from BlockWriteAI",
|
|
311
|
-
alignment: "left"
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
]
|
|
315
|
-
},
|
|
316
|
-
onChange(data) {
|
|
317
|
-
console.log("Changed document", data);
|
|
318
|
-
},
|
|
319
|
-
async onSave(data) {
|
|
320
|
-
await fetch("/save-document.php", {
|
|
321
|
-
method: "POST",
|
|
322
|
-
headers: {
|
|
323
|
-
"Content-Type": "application/json"
|
|
324
|
-
},
|
|
325
|
-
body: JSON.stringify(data)
|
|
326
|
-
});
|
|
327
|
-
}
|
|
328
|
-
});
|
|
161
|
+
BlockWriteAI.mountPreviews();
|
|
329
162
|
</script>
|
|
330
163
|
```
|
|
331
164
|
|
|
332
|
-
|
|
333
|
-
`Editor` heading, centered AI progress, and the right-aligned JSON sync status. If no
|
|
334
|
-
`data` is provided, the editor starts with one empty paragraph block automatically. Use
|
|
335
|
-
`shell: false` when you only want the raw editor surface, or pass `maxWidth: "960px"` /
|
|
336
|
-
`shell: { maxWidth: "960px" }` to constrain the editor width in your project.
|
|
337
|
-
|
|
338
|
-
Built-in toolbar buttons are intentionally opt-in for package consumers. `saveButton`, `exportButton`, and `exportHtmlButton` default to `false`, so applications can use their own UI and call `editor.save()` when needed.
|
|
339
|
-
|
|
340
|
-
## Saving JSON
|
|
341
|
-
|
|
342
|
-
BlockWriteAI is designed to save JSON first. In production, store the JSON in your database and render it later in read-only mode or through exported HTML.
|
|
343
|
-
|
|
344
|
-
```js
|
|
345
|
-
document.querySelector("#save").addEventListener("click", async () => {
|
|
346
|
-
const data = await editor.save();
|
|
347
|
-
|
|
348
|
-
await fetch("/save-document.php", {
|
|
349
|
-
method: "POST",
|
|
350
|
-
headers: {
|
|
351
|
-
"Content-Type": "application/json"
|
|
352
|
-
},
|
|
353
|
-
body: JSON.stringify(data)
|
|
354
|
-
});
|
|
355
|
-
});
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
The default toolbar includes a Save button. Use `onSave` to receive the JSON response when the user clicks it:
|
|
359
|
-
|
|
360
|
-
```js
|
|
361
|
-
const editor = new BlockWriteAI({
|
|
362
|
-
holder: "#editor",
|
|
363
|
-
async onSave(data) {
|
|
364
|
-
await fetch("/documents/123", {
|
|
365
|
-
method: "POST",
|
|
366
|
-
headers: {
|
|
367
|
-
"Content-Type": "application/json"
|
|
368
|
-
},
|
|
369
|
-
body: JSON.stringify(data)
|
|
370
|
-
});
|
|
371
|
-
}
|
|
372
|
-
});
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
## AI Plugin
|
|
376
|
-
|
|
377
|
-
AI is a premium plugin. Load it through the platform premium bundle after license
|
|
378
|
-
verification. The browser plugin never receives your OpenAI API key; it calls
|
|
379
|
-
your own server endpoint.
|
|
165
|
+
The JSON endpoint can return a document directly:
|
|
380
166
|
|
|
381
|
-
```
|
|
382
|
-
|
|
167
|
+
```json
|
|
168
|
+
{
|
|
169
|
+
"time": 1779540000000,
|
|
170
|
+
"version": "1.0.10",
|
|
171
|
+
"blocks": []
|
|
172
|
+
}
|
|
173
|
+
```
|
|
383
174
|
|
|
175
|
+
It can also return a wrapper:
|
|
176
|
+
|
|
177
|
+
```json
|
|
178
|
+
{
|
|
179
|
+
"ok": true,
|
|
180
|
+
"data": {
|
|
181
|
+
"time": 1779540000000,
|
|
182
|
+
"version": "1.0.10",
|
|
183
|
+
"blocks": []
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Premium Plugins
|
|
189
|
+
|
|
190
|
+
Do not expose premium plugin files as normal public scripts. Load them after your server verifies an active license:
|
|
191
|
+
|
|
192
|
+
```html
|
|
384
193
|
<script>
|
|
385
|
-
async function
|
|
194
|
+
async function bootEditor() {
|
|
386
195
|
await BlockWriteAI.loadPremiumPlugins({
|
|
387
196
|
licenseKey: "bwai_live_xxxxx",
|
|
388
197
|
endpoint: "/blockwriteai-platform/api/premium_plugins.php",
|
|
389
|
-
features: ["ai"]
|
|
198
|
+
features: ["drawing", "mermaid", "signature", "signature_flow", "ai"]
|
|
390
199
|
});
|
|
391
200
|
|
|
392
201
|
window.editor = new BlockWriteAI({
|
|
@@ -397,282 +206,29 @@ your own server endpoint.
|
|
|
397
206
|
usageEndpoint: "/blockwriteai-platform/api/ai_usage.php"
|
|
398
207
|
},
|
|
399
208
|
ai: {
|
|
400
|
-
endpoint: "/api/blockwriteai-ai
|
|
209
|
+
endpoint: "/api/blockwriteai-ai"
|
|
401
210
|
}
|
|
402
211
|
});
|
|
403
212
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
```
|
|
407
|
-
|
|
408
|
-
The included demo endpoint is `examples/api/ai.php`. For local development, copy `examples/api/openai.local.example.php` to `examples/api/openai.local.php` and add a development key, or set `OPENAI_API_KEY` in the server environment. Do not expose the key in browser JavaScript.
|
|
409
|
-
|
|
410
|
-
The drawer can also be opened without selecting text from the centered AI button in the editor toolbar, or programmatically with `editor.openAI()`.
|
|
411
|
-
|
|
412
|
-
Available AI drawer actions:
|
|
413
|
-
|
|
414
|
-
- Improve writing
|
|
415
|
-
- Fix grammar
|
|
416
|
-
- Summarize
|
|
417
|
-
- Expand
|
|
418
|
-
- Make professional
|
|
419
|
-
- Generate BlockWriteAI blocks from a prompt
|
|
420
|
-
|
|
421
|
-
## Preview Pages
|
|
422
|
-
|
|
423
|
-
Create any page in your application and add a preview container. BlockWriteAI will load saved JSON and render the document HTML inside that container.
|
|
424
|
-
|
|
425
|
-
```html
|
|
426
|
-
<link rel="stylesheet" href="/blockwriteai/blockwriteai.css">
|
|
427
|
-
|
|
428
|
-
<div class="blockwriteai-preview" data-source="/documents/123.json"></div>
|
|
429
|
-
|
|
430
|
-
<script src="/blockwriteai/blockwriteai.js"></script>
|
|
431
|
-
<script src="/blockwriteai/plugins/blockwriteai-advanced-blocks.js"></script>
|
|
432
|
-
<script>
|
|
433
|
-
BlockWriteAI.mountPreviews();
|
|
213
|
+
|
|
214
|
+
bootEditor();
|
|
434
215
|
</script>
|
|
435
216
|
```
|
|
436
217
|
|
|
437
|
-
|
|
438
|
-
before `BlockWriteAI.mountPreviews()`:
|
|
218
|
+
The browser plugin must never receive private API keys. Keep OpenAI, billing, usage limits, and license checks on your server.
|
|
439
219
|
|
|
440
|
-
|
|
441
|
-
async function mountDocumentPreview() {
|
|
442
|
-
await BlockWriteAI.loadPremiumPlugins({
|
|
443
|
-
licenseKey: "bwai_live_xxxxx",
|
|
444
|
-
endpoint: "/blockwriteai-platform/api/premium_plugins.php",
|
|
445
|
-
features: ["drawing", "mermaid", "signature", "signature_flow", "ai"]
|
|
446
|
-
});
|
|
447
|
-
BlockWriteAI.mountPreviews();
|
|
448
|
-
}
|
|
449
|
-
mountDocumentPreview();
|
|
450
|
-
```
|
|
451
|
-
|
|
452
|
-
The JSON endpoint can return either a BlockWriteAI document directly or an API wrapper such as:
|
|
453
|
-
|
|
454
|
-
```json
|
|
455
|
-
{
|
|
456
|
-
"ok": true,
|
|
457
|
-
"data": {
|
|
458
|
-
"time": 1779540000000,
|
|
459
|
-
"version": "1.0.8",
|
|
460
|
-
"blocks": []
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
```
|
|
464
|
-
|
|
465
|
-
Example PHP receiver:
|
|
466
|
-
|
|
467
|
-
```php
|
|
468
|
-
<?php
|
|
469
|
-
header('Content-Type: application/json');
|
|
470
|
-
|
|
471
|
-
$json = file_get_contents('php://input');
|
|
472
|
-
$data = json_decode($json, true);
|
|
473
|
-
|
|
474
|
-
if (!$data || !isset($data['blocks']) || !is_array($data['blocks'])) {
|
|
475
|
-
http_response_code(422);
|
|
476
|
-
echo json_encode(['error' => 'Invalid BlockWriteAI document']);
|
|
477
|
-
exit;
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
file_put_contents(__DIR__ . '/saved-document.json', json_encode($data, JSON_PRETTY_PRINT));
|
|
481
|
-
|
|
482
|
-
echo json_encode(['ok' => true]);
|
|
483
|
-
```
|
|
484
|
-
|
|
485
|
-
## Uploads
|
|
486
|
-
|
|
487
|
-
The demo includes `examples/upload.php` and stores files under `examples/uploads/`. For production, replace this with your own storage layer.
|
|
488
|
-
|
|
489
|
-
```js
|
|
490
|
-
const editor = new BlockWriteAI({
|
|
491
|
-
holder: "#editor",
|
|
492
|
-
uploadOutput: ["upload", "base64"],
|
|
493
|
-
upload: {
|
|
494
|
-
image: async (file) => {
|
|
495
|
-
const form = new FormData();
|
|
496
|
-
form.append("file", file);
|
|
497
|
-
form.append("kind", "image");
|
|
498
|
-
|
|
499
|
-
const response = await fetch("/BlockWriteAI/examples/upload.php", {
|
|
500
|
-
method: "POST",
|
|
501
|
-
body: form
|
|
502
|
-
});
|
|
503
|
-
|
|
504
|
-
return response.json();
|
|
505
|
-
},
|
|
506
|
-
file: async (file) => {
|
|
507
|
-
const form = new FormData();
|
|
508
|
-
form.append("file", file);
|
|
509
|
-
form.append("kind", "file");
|
|
510
|
-
|
|
511
|
-
const response = await fetch("/BlockWriteAI/examples/upload.php", {
|
|
512
|
-
method: "POST",
|
|
513
|
-
body: form
|
|
514
|
-
});
|
|
515
|
-
|
|
516
|
-
return response.json();
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
});
|
|
520
|
-
```
|
|
220
|
+
## Release Checklist
|
|
521
221
|
|
|
522
|
-
|
|
222
|
+
1. Run `npm run build:min`.
|
|
223
|
+
2. Run `npm run check`.
|
|
224
|
+
3. Publish `@qarakash/blockwriteai` to npm.
|
|
225
|
+
4. Publish `qarakash/blockwriteai` to Packagist.
|
|
226
|
+
5. Publish `blockwriteai-editor` to PyPI.
|
|
227
|
+
6. Serve only the public asset directory from your application.
|
|
523
228
|
|
|
524
|
-
|
|
525
|
-
- `"upload"` or `["upload"]` stores the response from your upload handler, such as a server URL.
|
|
526
|
-
- `["upload", "base64"]` stores both, useful when you want server files plus a portable JSON backup.
|
|
527
|
-
|
|
528
|
-
Expected upload response:
|
|
529
|
-
|
|
530
|
-
```json
|
|
531
|
-
{
|
|
532
|
-
"url": "/BlockWriteAI/examples/uploads/example.pdf",
|
|
533
|
-
"name": "example.pdf",
|
|
534
|
-
"size": 12345,
|
|
535
|
-
"type": "application/pdf"
|
|
536
|
-
}
|
|
537
|
-
```
|
|
229
|
+
## Notes For Production
|
|
538
230
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
```js
|
|
544
|
-
await editor.save(); // Get JSON document
|
|
545
|
-
editor.getData(); // Get current data synchronously
|
|
546
|
-
editor.render(data); // Replace editor content
|
|
547
|
-
editor.clear(); // Reset editor
|
|
548
|
-
editor.exportHTML(); // Export HTML
|
|
549
|
-
editor.exportMarkdown(); // Export Markdown API, hidden from the default UI
|
|
550
|
-
editor.importHTML(html); // Import HTML into blocks
|
|
551
|
-
editor.setReadOnly(true); // Toggle read-only mode
|
|
552
|
-
editor.undo(); // Undo last change
|
|
553
|
-
editor.redo(); // Redo last undo
|
|
554
|
-
editor.destroy(); // Remove editor instance
|
|
555
|
-
BlockWriteAI.mountPreviews(); // Render JSON into .blockwriteai-preview containers
|
|
556
|
-
```
|
|
557
|
-
|
|
558
|
-
## Data Shape
|
|
559
|
-
|
|
560
|
-
```json
|
|
561
|
-
{
|
|
562
|
-
"time": 1779540000000,
|
|
563
|
-
"version": "1.0.8",
|
|
564
|
-
"blocks": [
|
|
565
|
-
{
|
|
566
|
-
"id": "block-title",
|
|
567
|
-
"type": "heading",
|
|
568
|
-
"data": {
|
|
569
|
-
"level": 2,
|
|
570
|
-
"text": "BlockWriteAI document",
|
|
571
|
-
"alignment": "left"
|
|
572
|
-
}
|
|
573
|
-
},
|
|
574
|
-
{
|
|
575
|
-
"id": "block-body",
|
|
576
|
-
"type": "paragraph",
|
|
577
|
-
"data": {
|
|
578
|
-
"text": "Reusable content saved as JSON."
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
]
|
|
582
|
-
}
|
|
583
|
-
```
|
|
584
|
-
|
|
585
|
-
## Tool Control
|
|
586
|
-
|
|
587
|
-
Limit available blocks per project:
|
|
588
|
-
|
|
589
|
-
```js
|
|
590
|
-
const editor = new BlockWriteAI({
|
|
591
|
-
holder: "#editor",
|
|
592
|
-
tools: [
|
|
593
|
-
"paragraph",
|
|
594
|
-
"heading",
|
|
595
|
-
"image",
|
|
596
|
-
"list",
|
|
597
|
-
"table"
|
|
598
|
-
]
|
|
599
|
-
});
|
|
600
|
-
```
|
|
601
|
-
|
|
602
|
-
Disable specific tools:
|
|
603
|
-
|
|
604
|
-
```js
|
|
605
|
-
const editor = new BlockWriteAI({
|
|
606
|
-
holder: "#editor",
|
|
607
|
-
tools: {
|
|
608
|
-
raw: false,
|
|
609
|
-
attaches: false
|
|
610
|
-
}
|
|
611
|
-
});
|
|
612
|
-
```
|
|
613
|
-
|
|
614
|
-
## Autosave
|
|
615
|
-
|
|
616
|
-
```js
|
|
617
|
-
const editor = new BlockWriteAI({
|
|
618
|
-
holder: "#editor",
|
|
619
|
-
autosave: {
|
|
620
|
-
key: "blockwriteai-draft",
|
|
621
|
-
load: true
|
|
622
|
-
}
|
|
623
|
-
});
|
|
624
|
-
```
|
|
625
|
-
|
|
626
|
-
## Security Notes
|
|
627
|
-
|
|
628
|
-
BlockWriteAI sanitizes normal rich text blocks before saving and exporting. Raw HTML blocks are intentionally treated as trusted HTML, so enable the raw HTML tool only for trusted users.
|
|
629
|
-
|
|
630
|
-
For production applications:
|
|
631
|
-
|
|
632
|
-
- Validate JSON on the server.
|
|
633
|
-
- Sanitize output again before public rendering.
|
|
634
|
-
- Restrict upload types and file sizes.
|
|
635
|
-
- Store uploaded files outside executable PHP paths when possible.
|
|
636
|
-
- Add authentication before saving documents.
|
|
637
|
-
|
|
638
|
-
## GitHub
|
|
639
|
-
|
|
640
|
-
Repository target:
|
|
641
|
-
|
|
642
|
-
```text
|
|
643
|
-
https://github.com/qarAkash/BlockWriteAI.git
|
|
644
|
-
```
|
|
645
|
-
|
|
646
|
-
## Publishing Packages
|
|
647
|
-
|
|
648
|
-
After a release is ready, publish each package from the repository root.
|
|
649
|
-
|
|
650
|
-
Create a Git release tag for script-link/CDN users:
|
|
651
|
-
|
|
652
|
-
```bash
|
|
653
|
-
git tag v1.0.8
|
|
654
|
-
git push origin v1.0.8
|
|
655
|
-
```
|
|
656
|
-
|
|
657
|
-
Publish npm:
|
|
658
|
-
|
|
659
|
-
```bash
|
|
660
|
-
npm publish --access public
|
|
661
|
-
```
|
|
662
|
-
|
|
663
|
-
Publish Python:
|
|
664
|
-
|
|
665
|
-
```bash
|
|
666
|
-
python -m build
|
|
667
|
-
python -m twine upload dist/*
|
|
668
|
-
```
|
|
669
|
-
|
|
670
|
-
Publish Composer:
|
|
671
|
-
|
|
672
|
-
```text
|
|
673
|
-
Submit https://github.com/qarAkash/BlockWriteAI to Packagist as qarakash/blockwriteai.
|
|
674
|
-
```
|
|
675
|
-
|
|
676
|
-
## Status
|
|
677
|
-
|
|
678
|
-
BlockWriteAI is currently an active custom editor library and demo project. It is suitable for continued feature development, integration testing, and database-backed storage work.
|
|
231
|
+
- Use the `.min.css` and `.min.js` files in public pages.
|
|
232
|
+
- Do not publish source folders, examples, build artifacts, package caches, or private configuration files.
|
|
233
|
+
- Browser-delivered CSS and JavaScript can always be downloaded. Protect paid features with server-side license checks and metered premium bundle delivery.
|
|
234
|
+
- Keep secret keys in backend environment variables only.
|