@qarakash/blockwriteai 1.0.7
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/LICENSE +21 -0
- package/README.md +642 -0
- package/dist/blockwriteai-favicon.svg +20 -0
- package/dist/blockwriteai-logo.svg +26 -0
- package/dist/blockwriteai.css +3762 -0
- package/dist/blockwriteai.js +6771 -0
- package/dist/plugins/blockwriteai-advanced-blocks.js +2462 -0
- package/dist/plugins/blockwriteai-ai.js +637 -0
- package/dist/plugins/blockwriteai-code-assist.js +609 -0
- package/dist/plugins/blockwriteai-drawing.js +178 -0
- package/dist/plugins/blockwriteai-history.js +23 -0
- package/dist/plugins/blockwriteai-mermaid.js +1986 -0
- package/dist/plugins/blockwriteai-signature-flow.js +493 -0
- package/dist/plugins/blockwriteai-signature.js +463 -0
- package/package.json +63 -0
- package/types/index.d.ts +197 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 qarAkash
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,642 @@
|
|
|
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
|
+
- Mermaid-style drawing designer with shapes, arrows, images, text formatting, ruler, workspace resizing, and preview/export support.
|
|
19
|
+
- Charts, LaTeX, audio, drawing, layout columns, signature, signature flow, AI writing, and optional history plugins.
|
|
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 GitHub CDN link directly from the current main build:
|
|
69
|
+
|
|
70
|
+
```html
|
|
71
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/qarAkash/BlockWriteAI@main/dist/blockwriteai.css">
|
|
72
|
+
|
|
73
|
+
<script src="https://cdn.jsdelivr.net/gh/qarAkash/BlockWriteAI@main/dist/blockwriteai.js"></script>
|
|
74
|
+
<script src="https://cdn.jsdelivr.net/gh/qarAkash/BlockWriteAI@main/dist/plugins/blockwriteai-code-assist.js"></script>
|
|
75
|
+
<script src="https://cdn.jsdelivr.net/gh/qarAkash/BlockWriteAI@main/dist/plugins/blockwriteai-advanced-blocks.js"></script>
|
|
76
|
+
<script src="https://cdn.jsdelivr.net/gh/qarAkash/BlockWriteAI@main/dist/plugins/blockwriteai-ai.js"></script>
|
|
77
|
+
<script src="https://cdn.jsdelivr.net/gh/qarAkash/BlockWriteAI@main/dist/plugins/blockwriteai-signature.js"></script>
|
|
78
|
+
<script src="https://cdn.jsdelivr.net/gh/qarAkash/BlockWriteAI@main/dist/plugins/blockwriteai-signature-flow.js"></script>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`blockwriteai-advanced-blocks.js` is kept as the compatibility bundle. New
|
|
82
|
+
licensed delivery can load Drawing and Mermaid separately:
|
|
83
|
+
|
|
84
|
+
```html
|
|
85
|
+
<script src="https://cdn.jsdelivr.net/gh/qarAkash/BlockWriteAI@main/dist/plugins/blockwriteai-drawing.js"></script>
|
|
86
|
+
<script src="https://cdn.jsdelivr.net/gh/qarAkash/BlockWriteAI@main/dist/plugins/blockwriteai-mermaid.js"></script>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Load History only when a project needs the history dropdown:
|
|
90
|
+
|
|
91
|
+
```html
|
|
92
|
+
<script src="https://cdn.jsdelivr.net/gh/qarAkash/BlockWriteAI@main/dist/plugins/blockwriteai-history.js"></script>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
For locked production builds, replace `@main` with a release tag after publishing.
|
|
96
|
+
|
|
97
|
+
### Premium License Gating
|
|
98
|
+
|
|
99
|
+
Drawing, Mermaid drawing, Signature, Signature Flow, and AI can be licensed through
|
|
100
|
+
the BlockWriteAI Platform. Normal editor blocks continue to work without a license.
|
|
101
|
+
Premium tools are shown as locked until the license endpoint returns an active trial
|
|
102
|
+
or subscription.
|
|
103
|
+
|
|
104
|
+
```js
|
|
105
|
+
const editor = new BlockWriteAI({
|
|
106
|
+
holder: "#editor",
|
|
107
|
+
licenseKey: "bwai_live_xxxxx",
|
|
108
|
+
premium: {
|
|
109
|
+
verifyEndpoint: "http://localhost/blockwriteai-platform/api/license_verify.php",
|
|
110
|
+
usageEndpoint: "http://localhost/blockwriteai-platform/api/ai_usage.php"
|
|
111
|
+
},
|
|
112
|
+
ai: {
|
|
113
|
+
endpoint: "/api/ai.php"
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
The verify endpoint must return a `features` object with these keys when enabled:
|
|
119
|
+
|
|
120
|
+
```json
|
|
121
|
+
{
|
|
122
|
+
"drawing": true,
|
|
123
|
+
"mermaid": true,
|
|
124
|
+
"signature": true,
|
|
125
|
+
"signature_flow": true,
|
|
126
|
+
"ai": true
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The AI plugin calls `premium.usageEndpoint` before each AI request so the platform
|
|
131
|
+
can enforce the 7-day trial and daily prompt limits.
|
|
132
|
+
|
|
133
|
+
For stronger production security, do not load premium plugin files directly from a
|
|
134
|
+
public CDN. Load the free core first, request the premium plugins from your
|
|
135
|
+
BlockWriteAI Platform, and create the editor only after the server has verified
|
|
136
|
+
the license. The platform serves Drawing, Mermaid, Signature, Signature Flow,
|
|
137
|
+
and AI as separate plugin files after checking the requested feature flags:
|
|
138
|
+
|
|
139
|
+
```html
|
|
140
|
+
<link rel="stylesheet" href="/BlockWriteAI/dist/blockwriteai.css">
|
|
141
|
+
<script src="/BlockWriteAI/dist/blockwriteai.js"></script>
|
|
142
|
+
<script src="/BlockWriteAI/dist/plugins/blockwriteai-code-assist.js"></script>
|
|
143
|
+
<script>
|
|
144
|
+
async function boot() {
|
|
145
|
+
await BlockWriteAI.loadPremiumPlugins({
|
|
146
|
+
licenseKey: "bwai_live_xxxxx",
|
|
147
|
+
endpoint: "http://localhost/blockwriteai-platform/api/premium_plugins.php",
|
|
148
|
+
features: ["drawing", "mermaid", "signature", "signature_flow", "ai"]
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
window.editor = new BlockWriteAI({
|
|
152
|
+
holder: "#editor",
|
|
153
|
+
licenseKey: "bwai_live_xxxxx",
|
|
154
|
+
premium: {
|
|
155
|
+
verifyEndpoint: "http://localhost/blockwriteai-platform/api/license_verify.php",
|
|
156
|
+
usageEndpoint: "http://localhost/blockwriteai-platform/api/ai_usage.php"
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
boot();
|
|
161
|
+
</script>
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
This matters because browser-only locks can be edited in DevTools. Server-side
|
|
165
|
+
license verification, usage metering, signature event storage, and verified
|
|
166
|
+
premium bundle delivery are the enforceable parts.
|
|
167
|
+
|
|
168
|
+
### npm
|
|
169
|
+
|
|
170
|
+
Package name:
|
|
171
|
+
|
|
172
|
+
```text
|
|
173
|
+
@qarakash/blockwriteai
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Install:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
npm install @qarakash/blockwriteai
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Bundler entry points:
|
|
183
|
+
|
|
184
|
+
```js
|
|
185
|
+
import BlockWriteAI from "@qarakash/blockwriteai";
|
|
186
|
+
import "@qarakash/blockwriteai/css";
|
|
187
|
+
import "@qarakash/blockwriteai/plugins/code-assist";
|
|
188
|
+
import "@qarakash/blockwriteai/plugins/advanced";
|
|
189
|
+
import "@qarakash/blockwriteai/plugins/ai";
|
|
190
|
+
import "@qarakash/blockwriteai/plugins/history";
|
|
191
|
+
import "@qarakash/blockwriteai/plugins/signature";
|
|
192
|
+
import "@qarakash/blockwriteai/plugins/signature-flow";
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
After npm publishing, the same package is also available through npm CDNs:
|
|
196
|
+
|
|
197
|
+
```html
|
|
198
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.7/dist/blockwriteai.css">
|
|
199
|
+
<script src="https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.7/dist/blockwriteai.js"></script>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Python
|
|
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. Pass `history=True` only on pages where you want the optional History dropdown:
|
|
225
|
+
|
|
226
|
+
```python
|
|
227
|
+
from blockwriteai_editor import stylesheet_tag, script_tags
|
|
228
|
+
|
|
229
|
+
print(stylesheet_tag("/static/blockwriteai"))
|
|
230
|
+
print(script_tags("/static/blockwriteai"))
|
|
231
|
+
print(script_tags("/static/blockwriteai", history=True))
|
|
232
|
+
print(script_tags("/static/blockwriteai", ai=True))
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### PHP / Composer
|
|
236
|
+
|
|
237
|
+
Package name:
|
|
238
|
+
|
|
239
|
+
```text
|
|
240
|
+
qarakash/blockwriteai
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Install:
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
composer require qarakash/blockwriteai
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Publish assets into your public folder:
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
cp -R vendor/qarakash/blockwriteai/dist public/blockwriteai
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
PHP helper. Pass `history: true` only on pages where you want the optional History dropdown, and `ai: true` only on pages where you want the AI drawer:
|
|
256
|
+
|
|
257
|
+
```php
|
|
258
|
+
use QarAkash\BlockWriteAI\BlockWriteAIAssets;
|
|
259
|
+
|
|
260
|
+
echo BlockWriteAIAssets::stylesheetTag('/blockwriteai');
|
|
261
|
+
echo BlockWriteAIAssets::scriptTags('/blockwriteai');
|
|
262
|
+
echo BlockWriteAIAssets::scriptTags('/blockwriteai', plugins: true, history: true, ai: true);
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Local XAMPP Demo
|
|
266
|
+
|
|
267
|
+
Copy the `BlockWriteAI` folder into your web root, for example:
|
|
268
|
+
|
|
269
|
+
```text
|
|
270
|
+
C:\xampp\htdocs\BlockWriteAI
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Open:
|
|
274
|
+
|
|
275
|
+
```text
|
|
276
|
+
http://localhost/BlockWriteAI/examples/
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## Browser Usage
|
|
280
|
+
|
|
281
|
+
```html
|
|
282
|
+
<link rel="stylesheet" href="/BlockWriteAI/dist/blockwriteai.css">
|
|
283
|
+
|
|
284
|
+
<div id="editor"></div>
|
|
285
|
+
|
|
286
|
+
<script src="/BlockWriteAI/dist/blockwriteai.js"></script>
|
|
287
|
+
<script src="/BlockWriteAI/dist/plugins/blockwriteai-code-assist.js"></script>
|
|
288
|
+
<script src="/BlockWriteAI/dist/plugins/blockwriteai-advanced-blocks.js"></script>
|
|
289
|
+
<script src="/BlockWriteAI/dist/plugins/blockwriteai-signature.js"></script>
|
|
290
|
+
<script src="/BlockWriteAI/dist/plugins/blockwriteai-signature-flow.js"></script>
|
|
291
|
+
|
|
292
|
+
<script>
|
|
293
|
+
const editor = new BlockWriteAI({
|
|
294
|
+
holder: "#editor",
|
|
295
|
+
maxWidth: "960px", // optional; omit for full-width editor shell
|
|
296
|
+
placeholder: "Write something, or press / for blocks",
|
|
297
|
+
data: {
|
|
298
|
+
blocks: [
|
|
299
|
+
{
|
|
300
|
+
type: "paragraph",
|
|
301
|
+
data: {
|
|
302
|
+
text: "Hello from BlockWriteAI",
|
|
303
|
+
alignment: "left"
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
]
|
|
307
|
+
},
|
|
308
|
+
onChange(data) {
|
|
309
|
+
console.log("Changed document", data);
|
|
310
|
+
},
|
|
311
|
+
async onSave(data) {
|
|
312
|
+
await fetch("/save-document.php", {
|
|
313
|
+
method: "POST",
|
|
314
|
+
headers: {
|
|
315
|
+
"Content-Type": "application/json"
|
|
316
|
+
},
|
|
317
|
+
body: JSON.stringify(data)
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
</script>
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
By default, BlockWriteAI mounts the full branded editor shell: logo, product subtitle,
|
|
325
|
+
`Editor` heading, centered AI progress, and the right-aligned JSON sync status. If no
|
|
326
|
+
`data` is provided, the editor starts with one empty paragraph block automatically. Use
|
|
327
|
+
`shell: false` when you only want the raw editor surface, or pass `maxWidth: "960px"` /
|
|
328
|
+
`shell: { maxWidth: "960px" }` to constrain the editor width in your project.
|
|
329
|
+
|
|
330
|
+
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.
|
|
331
|
+
|
|
332
|
+
## Saving JSON
|
|
333
|
+
|
|
334
|
+
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.
|
|
335
|
+
|
|
336
|
+
```js
|
|
337
|
+
document.querySelector("#save").addEventListener("click", async () => {
|
|
338
|
+
const data = await editor.save();
|
|
339
|
+
|
|
340
|
+
await fetch("/save-document.php", {
|
|
341
|
+
method: "POST",
|
|
342
|
+
headers: {
|
|
343
|
+
"Content-Type": "application/json"
|
|
344
|
+
},
|
|
345
|
+
body: JSON.stringify(data)
|
|
346
|
+
});
|
|
347
|
+
});
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
The default toolbar includes a Save button. Use `onSave` to receive the JSON response when the user clicks it:
|
|
351
|
+
|
|
352
|
+
```js
|
|
353
|
+
const editor = new BlockWriteAI({
|
|
354
|
+
holder: "#editor",
|
|
355
|
+
async onSave(data) {
|
|
356
|
+
await fetch("/documents/123", {
|
|
357
|
+
method: "POST",
|
|
358
|
+
headers: {
|
|
359
|
+
"Content-Type": "application/json"
|
|
360
|
+
},
|
|
361
|
+
body: JSON.stringify(data)
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## AI Plugin
|
|
368
|
+
|
|
369
|
+
Load the optional AI plugin only on pages where you want writing assistance. The browser plugin never receives your OpenAI API key; it calls your own server endpoint.
|
|
370
|
+
|
|
371
|
+
```html
|
|
372
|
+
<script src="/blockwriteai/blockwriteai.js"></script>
|
|
373
|
+
<script src="/blockwriteai/plugins/blockwriteai-ai.js"></script>
|
|
374
|
+
|
|
375
|
+
<script>
|
|
376
|
+
const editor = new BlockWriteAI({
|
|
377
|
+
holder: "#editor",
|
|
378
|
+
ai: {
|
|
379
|
+
endpoint: "/api/blockwriteai-ai.php"
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
</script>
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
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.
|
|
386
|
+
|
|
387
|
+
The drawer can also be opened without selecting text from the centered AI button in the editor toolbar, or programmatically with `editor.openAI()`.
|
|
388
|
+
|
|
389
|
+
Available AI drawer actions:
|
|
390
|
+
|
|
391
|
+
- Improve writing
|
|
392
|
+
- Fix grammar
|
|
393
|
+
- Summarize
|
|
394
|
+
- Expand
|
|
395
|
+
- Make professional
|
|
396
|
+
- Generate BlockWriteAI blocks from a prompt
|
|
397
|
+
|
|
398
|
+
## Preview Pages
|
|
399
|
+
|
|
400
|
+
Create any page in your application and add a preview container. BlockWriteAI will load saved JSON and render the document HTML inside that container.
|
|
401
|
+
|
|
402
|
+
```html
|
|
403
|
+
<link rel="stylesheet" href="/blockwriteai/blockwriteai.css">
|
|
404
|
+
|
|
405
|
+
<div class="blockwriteai-preview" data-source="/documents/123.json"></div>
|
|
406
|
+
|
|
407
|
+
<script src="/blockwriteai/blockwriteai.js"></script>
|
|
408
|
+
<script src="/blockwriteai/plugins/blockwriteai-advanced-blocks.js"></script>
|
|
409
|
+
<script src="/blockwriteai/plugins/blockwriteai-signature.js"></script>
|
|
410
|
+
<script src="/blockwriteai/plugins/blockwriteai-signature-flow.js"></script>
|
|
411
|
+
<script>
|
|
412
|
+
BlockWriteAI.mountPreviews();
|
|
413
|
+
</script>
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
The JSON endpoint can return either a BlockWriteAI document directly or an API wrapper such as:
|
|
417
|
+
|
|
418
|
+
```json
|
|
419
|
+
{
|
|
420
|
+
"ok": true,
|
|
421
|
+
"data": {
|
|
422
|
+
"time": 1779540000000,
|
|
423
|
+
"version": "1.0.7",
|
|
424
|
+
"blocks": []
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
Example PHP receiver:
|
|
430
|
+
|
|
431
|
+
```php
|
|
432
|
+
<?php
|
|
433
|
+
header('Content-Type: application/json');
|
|
434
|
+
|
|
435
|
+
$json = file_get_contents('php://input');
|
|
436
|
+
$data = json_decode($json, true);
|
|
437
|
+
|
|
438
|
+
if (!$data || !isset($data['blocks']) || !is_array($data['blocks'])) {
|
|
439
|
+
http_response_code(422);
|
|
440
|
+
echo json_encode(['error' => 'Invalid BlockWriteAI document']);
|
|
441
|
+
exit;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
file_put_contents(__DIR__ . '/saved-document.json', json_encode($data, JSON_PRETTY_PRINT));
|
|
445
|
+
|
|
446
|
+
echo json_encode(['ok' => true]);
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
## Uploads
|
|
450
|
+
|
|
451
|
+
The demo includes `examples/upload.php` and stores files under `examples/uploads/`. For production, replace this with your own storage layer.
|
|
452
|
+
|
|
453
|
+
```js
|
|
454
|
+
const editor = new BlockWriteAI({
|
|
455
|
+
holder: "#editor",
|
|
456
|
+
uploadOutput: ["upload", "base64"],
|
|
457
|
+
upload: {
|
|
458
|
+
image: async (file) => {
|
|
459
|
+
const form = new FormData();
|
|
460
|
+
form.append("file", file);
|
|
461
|
+
form.append("kind", "image");
|
|
462
|
+
|
|
463
|
+
const response = await fetch("/BlockWriteAI/examples/upload.php", {
|
|
464
|
+
method: "POST",
|
|
465
|
+
body: form
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
return response.json();
|
|
469
|
+
},
|
|
470
|
+
file: async (file) => {
|
|
471
|
+
const form = new FormData();
|
|
472
|
+
form.append("file", file);
|
|
473
|
+
form.append("kind", "file");
|
|
474
|
+
|
|
475
|
+
const response = await fetch("/BlockWriteAI/examples/upload.php", {
|
|
476
|
+
method: "POST",
|
|
477
|
+
body: form
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
return response.json();
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
`uploadOutput` controls what gets written into the saved JSON:
|
|
487
|
+
|
|
488
|
+
- `"base64"` or `["base64"]` stores uploaded media directly in the block JSON. This is the default.
|
|
489
|
+
- `"upload"` or `["upload"]` stores the response from your upload handler, such as a server URL.
|
|
490
|
+
- `["upload", "base64"]` stores both, useful when you want server files plus a portable JSON backup.
|
|
491
|
+
|
|
492
|
+
Expected upload response:
|
|
493
|
+
|
|
494
|
+
```json
|
|
495
|
+
{
|
|
496
|
+
"url": "/BlockWriteAI/examples/uploads/example.pdf",
|
|
497
|
+
"name": "example.pdf",
|
|
498
|
+
"size": 12345,
|
|
499
|
+
"type": "application/pdf"
|
|
500
|
+
}
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
When both outputs are enabled, saved image and attachment items include the server response under `upload` and the inline file data under `base64`.
|
|
504
|
+
|
|
505
|
+
## API Methods
|
|
506
|
+
|
|
507
|
+
```js
|
|
508
|
+
await editor.save(); // Get JSON document
|
|
509
|
+
editor.getData(); // Get current data synchronously
|
|
510
|
+
editor.render(data); // Replace editor content
|
|
511
|
+
editor.clear(); // Reset editor
|
|
512
|
+
editor.exportHTML(); // Export HTML
|
|
513
|
+
editor.exportMarkdown(); // Export Markdown API, hidden from the default UI
|
|
514
|
+
editor.importHTML(html); // Import HTML into blocks
|
|
515
|
+
editor.setReadOnly(true); // Toggle read-only mode
|
|
516
|
+
editor.undo(); // Undo last change
|
|
517
|
+
editor.redo(); // Redo last undo
|
|
518
|
+
editor.destroy(); // Remove editor instance
|
|
519
|
+
BlockWriteAI.mountPreviews(); // Render JSON into .blockwriteai-preview containers
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
## Data Shape
|
|
523
|
+
|
|
524
|
+
```json
|
|
525
|
+
{
|
|
526
|
+
"time": 1779540000000,
|
|
527
|
+
"version": "1.0.7",
|
|
528
|
+
"blocks": [
|
|
529
|
+
{
|
|
530
|
+
"id": "block-title",
|
|
531
|
+
"type": "heading",
|
|
532
|
+
"data": {
|
|
533
|
+
"level": 2,
|
|
534
|
+
"text": "BlockWriteAI document",
|
|
535
|
+
"alignment": "left"
|
|
536
|
+
}
|
|
537
|
+
},
|
|
538
|
+
{
|
|
539
|
+
"id": "block-body",
|
|
540
|
+
"type": "paragraph",
|
|
541
|
+
"data": {
|
|
542
|
+
"text": "Reusable content saved as JSON."
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
]
|
|
546
|
+
}
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
## Tool Control
|
|
550
|
+
|
|
551
|
+
Limit available blocks per project:
|
|
552
|
+
|
|
553
|
+
```js
|
|
554
|
+
const editor = new BlockWriteAI({
|
|
555
|
+
holder: "#editor",
|
|
556
|
+
tools: [
|
|
557
|
+
"paragraph",
|
|
558
|
+
"heading",
|
|
559
|
+
"image",
|
|
560
|
+
"list",
|
|
561
|
+
"table"
|
|
562
|
+
]
|
|
563
|
+
});
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
Disable specific tools:
|
|
567
|
+
|
|
568
|
+
```js
|
|
569
|
+
const editor = new BlockWriteAI({
|
|
570
|
+
holder: "#editor",
|
|
571
|
+
tools: {
|
|
572
|
+
raw: false,
|
|
573
|
+
attaches: false
|
|
574
|
+
}
|
|
575
|
+
});
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
## Autosave
|
|
579
|
+
|
|
580
|
+
```js
|
|
581
|
+
const editor = new BlockWriteAI({
|
|
582
|
+
holder: "#editor",
|
|
583
|
+
autosave: {
|
|
584
|
+
key: "blockwriteai-draft",
|
|
585
|
+
load: true
|
|
586
|
+
}
|
|
587
|
+
});
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
## Security Notes
|
|
591
|
+
|
|
592
|
+
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.
|
|
593
|
+
|
|
594
|
+
For production applications:
|
|
595
|
+
|
|
596
|
+
- Validate JSON on the server.
|
|
597
|
+
- Sanitize output again before public rendering.
|
|
598
|
+
- Restrict upload types and file sizes.
|
|
599
|
+
- Store uploaded files outside executable PHP paths when possible.
|
|
600
|
+
- Add authentication before saving documents.
|
|
601
|
+
|
|
602
|
+
## GitHub
|
|
603
|
+
|
|
604
|
+
Repository target:
|
|
605
|
+
|
|
606
|
+
```text
|
|
607
|
+
https://github.com/qarAkash/BlockWriteAI.git
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
## Publishing Packages
|
|
611
|
+
|
|
612
|
+
After a release is ready, publish each package from the repository root.
|
|
613
|
+
|
|
614
|
+
Create a Git release tag for script-link/CDN users:
|
|
615
|
+
|
|
616
|
+
```bash
|
|
617
|
+
git tag v1.0.7
|
|
618
|
+
git push origin v1.0.7
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
Publish npm:
|
|
622
|
+
|
|
623
|
+
```bash
|
|
624
|
+
npm publish --access public
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
Publish Python:
|
|
628
|
+
|
|
629
|
+
```bash
|
|
630
|
+
python -m build
|
|
631
|
+
python -m twine upload dist/*
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
Publish Composer:
|
|
635
|
+
|
|
636
|
+
```text
|
|
637
|
+
Submit https://github.com/qarAkash/BlockWriteAI to Packagist as qarakash/blockwriteai.
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
## Status
|
|
641
|
+
|
|
642
|
+
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.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="BlockWriteAI">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="bwai-favicon-bg" x1="8" y1="8" x2="56" y2="56" gradientUnits="userSpaceOnUse">
|
|
4
|
+
<stop offset="0" stop-color="#102033"/>
|
|
5
|
+
<stop offset="1" stop-color="#172A46"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
<linearGradient id="bwai-favicon-accent" x1="16" y1="18" x2="48" y2="48" gradientUnits="userSpaceOnUse">
|
|
8
|
+
<stop offset="0" stop-color="#2BEA8A"/>
|
|
9
|
+
<stop offset="1" stop-color="#10B981"/>
|
|
10
|
+
</linearGradient>
|
|
11
|
+
</defs>
|
|
12
|
+
<rect x="6" y="6" width="52" height="52" rx="16" fill="url(#bwai-favicon-bg)"/>
|
|
13
|
+
<rect x="18" y="18" width="10" height="10" rx="2.5" fill="#FFFFFF"/>
|
|
14
|
+
<rect x="31" y="18" width="10" height="10" rx="2.5" fill="#FFFFFF" opacity="0.92"/>
|
|
15
|
+
<rect x="18" y="31" width="10" height="10" rx="2.5" fill="url(#bwai-favicon-accent)"/>
|
|
16
|
+
<path d="M33.2 43.1L45 31.3C45.7 30.6 46.8 30.6 47.5 31.3L51.1 34.9C51.8 35.6 51.8 36.7 51.1 37.4L39.3 49.2L31.5 50.8L33.2 43.1Z" fill="#FFFFFF"/>
|
|
17
|
+
<path d="M43.1 33.3L49.2 39.4" stroke="#10B981" stroke-width="3" stroke-linecap="round"/>
|
|
18
|
+
<circle cx="51" cy="51" r="7" fill="#19B86B" stroke="#FFFFFF" stroke-width="3"/>
|
|
19
|
+
<path d="M49.5 16.5H55.5M52.5 13.5V19.5" stroke="#19B86B" stroke-width="3" stroke-linecap="round"/>
|
|
20
|
+
</svg>
|