@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
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* BlockWriteAI Signature Plugin
|
|
3
|
+
* Adds an optional digital signature field block.
|
|
4
|
+
*/
|
|
5
|
+
(function (global) {
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
var BlockWriteAI = global.BlockWriteAI;
|
|
9
|
+
if (!BlockWriteAI || BlockWriteAI.__signaturePluginInstalled) return;
|
|
10
|
+
BlockWriteAI.__signaturePluginInstalled = true;
|
|
11
|
+
|
|
12
|
+
var H = BlockWriteAI.helpers || {};
|
|
13
|
+
var el = H.el;
|
|
14
|
+
var esc = H.escapeHTML || function (value) {
|
|
15
|
+
return String(value == null ? "" : value).replace(/[&<>"]/g, function (ch) {
|
|
16
|
+
return { "&": "&", "<": "<", ">": ">", '"': """ }[ch];
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
var sanitize = H.sanitizeHTML || function (value) { return String(value || ""); };
|
|
20
|
+
var faIcon = H.faIcon || function (name, label) {
|
|
21
|
+
return '<i class="fa-solid fa-' + esc(name) + '" aria-hidden="true"></i><span class="rbe-sr-only">' + esc(label || name) + "</span>";
|
|
22
|
+
};
|
|
23
|
+
var uid = H.uid || function (prefix) {
|
|
24
|
+
return (prefix || "signature") + "-" + Math.random().toString(36).slice(2, 9);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
function pluginAsset(path) {
|
|
28
|
+
try {
|
|
29
|
+
var base = (document.currentScript && document.currentScript.src) || document.baseURI;
|
|
30
|
+
return new URL(path, base).href;
|
|
31
|
+
} catch (error) {
|
|
32
|
+
return path;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
var LOGO_URL = pluginAsset("../blockwriteai-logo.svg");
|
|
37
|
+
var STORAGE_PREFIX = "blockwriteai-signature:";
|
|
38
|
+
|
|
39
|
+
function injectStyles() {
|
|
40
|
+
if (document.querySelector("style[data-blockwriteai-signature-plugin]")) return;
|
|
41
|
+
var style = document.createElement("style");
|
|
42
|
+
style.dataset.blockwriteaiSignaturePlugin = "true";
|
|
43
|
+
style.textContent =
|
|
44
|
+
".rbe-signature-editor,.rbe-output-signature{position:relative;overflow:hidden;border:1px solid #d7dee8;border-radius:8px;background:#fff;padding:16px;min-height:128px;box-sizing:border-box;max-width:100%;}" +
|
|
45
|
+
".rbe-signature-editor{display:grid;gap:12px;width:var(--rbe-signature-width,70%);max-width:100%;min-width:min(180px,100%);resize:none;container-type:inline-size;}" +
|
|
46
|
+
".rbe-signature-watermark{position:absolute;left:50%;top:50%;width:min(300px,76%);max-height:150px;object-fit:contain;opacity:.16;transform:translate(-50%,-50%);pointer-events:none;user-select:none;}" +
|
|
47
|
+
".rbe-signature-seal{position:absolute;right:14px;top:10px;z-index:4;width:44px;height:44px;background:#d40000;color:#fff;display:none;place-items:center;padding:0;border-radius:4px;box-shadow:0 10px 18px rgba(160,0,0,.22);pointer-events:none;}" +
|
|
48
|
+
".rbe-output-signature[data-signed='true'] .rbe-signature-seal{display:grid;}" +
|
|
49
|
+
".rbe-signature-seal-logo{display:block;width:32px;height:32px;}" +
|
|
50
|
+
".rbe-signature-toolbar{position:relative;z-index:2;display:flex;justify-content:space-between;gap:10px;align-items:center;}" +
|
|
51
|
+
".rbe-signature-static-label{font:800 14px/1.3 Arial,sans-serif;color:#344054;}" +
|
|
52
|
+
".rbe-signature-align-tools{display:flex;gap:6px;align-items:center;}" +
|
|
53
|
+
".rbe-signature-align-btn{width:34px;height:34px;border:1px solid #d7dee8;border-radius:8px;background:#fff;color:#344054;display:inline-grid;place-items:center;cursor:pointer;}" +
|
|
54
|
+
".rbe-signature-align-btn:hover,.rbe-signature-align-btn.is-active{border-color:#2563eb;background:#eaf1ff;color:#1d4ed8;}" +
|
|
55
|
+
".rbe-signature-preview{position:relative;z-index:1;display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:center;border:1px dashed #b6c4d6;border-radius:8px;background:rgba(248,251,255,.86);padding:14px;}" +
|
|
56
|
+
".rbe-signature-preview-name{font-family:'Brush Script MT','Segoe Script','Lucida Handwriting',cursive;font-size:20px;line-height:1.15;color:#111827;white-space:normal;overflow-wrap:anywhere;}" +
|
|
57
|
+
".rbe-signature-preview-copy{display:grid;gap:4px;color:#344054;font:13px/1.35 Arial,sans-serif;min-width:0;}" +
|
|
58
|
+
".rbe-signature-preview-copy strong{font-size:15px;color:#172033;}" +
|
|
59
|
+
".rbe-signature-resize-handle{position:absolute;right:7px;bottom:7px;z-index:3;width:18px;height:18px;border:0;border-radius:5px;background:#2563eb;color:#fff;box-shadow:0 8px 18px rgba(37,99,235,.22);cursor:nwse-resize;display:grid;place-items:center;padding:0;}" +
|
|
60
|
+
".rbe-signature-resize-handle:before{content:'';width:8px;height:8px;border-right:2px solid currentColor;border-bottom:2px solid currentColor;}" +
|
|
61
|
+
".rbe-output-signature{display:grid;gap:14px;margin:0 0 15px;container-type:inline-size;overflow:visible;min-width:0;}" +
|
|
62
|
+
".rbe-output-signature-label{position:relative;z-index:1;font:700 14px/1.4 Arial,sans-serif;color:#344054;}" +
|
|
63
|
+
".rbe-signature-unsigned{position:relative;z-index:1;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:center;width:min(640px,100%);max-width:100%;min-width:0;margin:0 auto;box-sizing:border-box;}" +
|
|
64
|
+
".rbe-signature-input{width:100%;min-width:0;min-height:42px;border:1px solid #cbd5e1;border-radius:8px;background:#fff;color:#111827;font:15px/1.15 'Brush Script MT','Segoe Script','Lucida Handwriting',cursive;padding:8px 10px;text-align:center;box-sizing:border-box;}" +
|
|
65
|
+
".rbe-signature-input::placeholder{color:#98a2b3;font:13px/1.35 Arial,sans-serif;}" +
|
|
66
|
+
".rbe-signature-apply{border:1px solid #1d4ed8;border-radius:8px;background:#2563eb;color:#fff;font:800 14px/1 Arial,sans-serif;padding:13px 16px;cursor:pointer;}" +
|
|
67
|
+
".rbe-signature-apply:hover{background:#1d4ed8;}" +
|
|
68
|
+
".rbe-output-signature.has-error .rbe-signature-input{border-color:#dc2626;box-shadow:0 0 0 3px rgba(220,38,38,.12);}" +
|
|
69
|
+
".rbe-signature-signed{position:relative;z-index:1;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:10px;align-items:center;min-width:0;min-height:80px;}" +
|
|
70
|
+
".rbe-signature-signed[hidden],.rbe-signature-unsigned[hidden]{display:none!important;}" +
|
|
71
|
+
".rbe-signature-name{min-width:0;font-family:'Brush Script MT','Segoe Script','Lucida Handwriting',cursive;font-size:20px;line-height:1.15;color:#050505;overflow-wrap:anywhere;}" +
|
|
72
|
+
".rbe-signature-meta{min-width:0;font-family:Arial,sans-serif;font-size:15px;line-height:1.18;color:#050505;display:grid;gap:2px;overflow-wrap:anywhere;}" +
|
|
73
|
+
".rbe-signature-meta strong{font-weight:500;}" +
|
|
74
|
+
".rbe-signature-meta strong,.rbe-signature-meta span,.rbe-signature-meta time{min-width:0;overflow-wrap:anywhere;}" +
|
|
75
|
+
".rbe-signature-meta time{font:inherit;}" +
|
|
76
|
+
".rbe-output-signature.is-compact{padding:10px;gap:10px;}" +
|
|
77
|
+
".rbe-output-signature.is-compact .rbe-signature-signed,.rbe-output-signature.is-compact .rbe-signature-unsigned{grid-template-columns:1fr;gap:8px;min-height:0;}" +
|
|
78
|
+
".rbe-output-signature.is-compact .rbe-signature-apply{width:100%;}" +
|
|
79
|
+
".rbe-output-signature.is-compact .rbe-signature-watermark{width:min(220px,86%);}" +
|
|
80
|
+
".rbe-output-signature.is-compact .rbe-signature-seal{right:8px;top:8px;width:36px;height:36px;}" +
|
|
81
|
+
".rbe-output-signature.is-compact .rbe-signature-seal-logo{width:26px;height:26px;}" +
|
|
82
|
+
".rbe-output-signature.is-compact .rbe-signature-meta{font-size:13px;line-height:1.22;}" +
|
|
83
|
+
"@container (max-width:320px){.rbe-signature-preview,.rbe-signature-signed{grid-template-columns:1fr;gap:8px;min-height:0;}.rbe-signature-unsigned{grid-template-columns:1fr;}.rbe-signature-apply{width:100%;}}" +
|
|
84
|
+
"@media (max-width:720px){.rbe-signature-editor{width:100%!important;}.rbe-signature-toolbar,.rbe-signature-preview,.rbe-signature-unsigned,.rbe-signature-signed{grid-template-columns:1fr;}.rbe-signature-toolbar{align-items:flex-start;}.rbe-signature-preview-name,.rbe-signature-name{white-space:normal;}.rbe-signature-apply{width:100%;}}";
|
|
85
|
+
document.head.appendChild(style);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function sealHTML(className) {
|
|
89
|
+
return (
|
|
90
|
+
'<span class="' +
|
|
91
|
+
esc(className) +
|
|
92
|
+
'" aria-hidden="true"><svg class="' +
|
|
93
|
+
esc(className + "-logo") +
|
|
94
|
+
'" viewBox="0 0 32 32" role="img" focusable="false"><path d="M7 4h12l6 6v15a3 3 0 0 1-3 3H10a3 3 0 0 1-3-3z" fill="#fff"/><path d="M19 4v6h6" fill="#ffe5e5"/><path d="M10 23c2-4 3-4 4 0 1-2 2-2 3 0 1-1 2-1 4 0" fill="none" stroke="#d40000" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/><path d="M22.5 17.5l4.6-4.6 2 2-4.6 4.6-3 .9z" fill="#fff"/><path d="M26.3 13.7l2 2" fill="none" stroke="#d40000" stroke-width="1.1" stroke-linecap="round"/></svg></span>'
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function cleanText(value) {
|
|
99
|
+
return String(value == null ? "" : value).trim();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function cleanAlignment(value) {
|
|
103
|
+
return value === "left" || value === "right" ? value : "center";
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function cleanWidth(value) {
|
|
107
|
+
value = Number(value || 70);
|
|
108
|
+
if (!Number.isFinite(value)) value = 70;
|
|
109
|
+
return Math.min(100, Math.max(14, Math.round(value)));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function layoutStyle(width, alignment) {
|
|
113
|
+
width = cleanWidth(width);
|
|
114
|
+
alignment = cleanAlignment(alignment);
|
|
115
|
+
var margin = alignment === "left" ? "margin-left:0;margin-right:auto;" : alignment === "right" ? "margin-left:auto;margin-right:0;" : "margin-left:auto;margin-right:auto;";
|
|
116
|
+
var justify = alignment === "left" ? "justify-self:start;" : alignment === "right" ? "justify-self:end;" : "justify-self:center;";
|
|
117
|
+
return "width:min(100%," + width + "%);" + margin + justify;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function applySignatureLayout(wrap) {
|
|
121
|
+
if (!wrap) return;
|
|
122
|
+
var width = cleanWidth(wrap.dataset.width);
|
|
123
|
+
var alignment = cleanAlignment(wrap.dataset.alignment);
|
|
124
|
+
wrap.dataset.width = String(width);
|
|
125
|
+
wrap.dataset.alignment = alignment;
|
|
126
|
+
wrap.style.width = "min(100%," + width + "%)";
|
|
127
|
+
wrap.style.marginLeft = alignment === "left" ? "0" : "auto";
|
|
128
|
+
wrap.style.marginRight = alignment === "right" ? "0" : "auto";
|
|
129
|
+
wrap.style.justifySelf = alignment === "left" ? "start" : alignment === "right" ? "end" : "center";
|
|
130
|
+
Array.prototype.slice.call(wrap.querySelectorAll(".rbe-signature-align-btn")).forEach(function (button) {
|
|
131
|
+
var active = button.dataset.align === alignment;
|
|
132
|
+
button.classList.toggle("is-active", active);
|
|
133
|
+
button.setAttribute("aria-pressed", active ? "true" : "false");
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function bindSignatureResize(editor, wrap) {
|
|
138
|
+
var handle = wrap && wrap.querySelector(".rbe-signature-resize-handle");
|
|
139
|
+
if (!handle || wrap.dataset.resizeReady === "true") return;
|
|
140
|
+
wrap.dataset.resizeReady = "true";
|
|
141
|
+
handle.addEventListener("pointerdown", function (event) {
|
|
142
|
+
event.preventDefault();
|
|
143
|
+
event.stopPropagation();
|
|
144
|
+
var parent = wrap.parentElement || wrap;
|
|
145
|
+
var parentWidth = Math.max(1, parent.getBoundingClientRect().width);
|
|
146
|
+
var startX = event.clientX;
|
|
147
|
+
var startWidth = wrap.getBoundingClientRect().width;
|
|
148
|
+
|
|
149
|
+
function move(moveEvent) {
|
|
150
|
+
var nextWidth = startWidth + moveEvent.clientX - startX;
|
|
151
|
+
wrap.dataset.width = String(cleanWidth((nextWidth / parentWidth) * 100));
|
|
152
|
+
applySignatureLayout(wrap);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function up() {
|
|
156
|
+
document.removeEventListener("pointermove", move);
|
|
157
|
+
document.removeEventListener("pointerup", up);
|
|
158
|
+
if (editor && typeof editor.changed === "function") editor.changed(true);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
document.addEventListener("pointermove", move);
|
|
162
|
+
document.addEventListener("pointerup", up);
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function formatSignatureDate(date) {
|
|
167
|
+
var pad = function (value) { return String(value).padStart(2, "0"); };
|
|
168
|
+
var offset = -date.getTimezoneOffset();
|
|
169
|
+
var sign = offset >= 0 ? "+" : "-";
|
|
170
|
+
var abs = Math.abs(offset);
|
|
171
|
+
return (
|
|
172
|
+
date.getFullYear() +
|
|
173
|
+
"." +
|
|
174
|
+
pad(date.getMonth() + 1) +
|
|
175
|
+
"." +
|
|
176
|
+
pad(date.getDate()) +
|
|
177
|
+
" " +
|
|
178
|
+
pad(date.getHours()) +
|
|
179
|
+
":" +
|
|
180
|
+
pad(date.getMinutes()) +
|
|
181
|
+
":" +
|
|
182
|
+
pad(date.getSeconds()) +
|
|
183
|
+
" " +
|
|
184
|
+
sign +
|
|
185
|
+
pad(Math.floor(abs / 60)) +
|
|
186
|
+
"'" +
|
|
187
|
+
pad(abs % 60) +
|
|
188
|
+
"'"
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function readStoredSignature(id) {
|
|
193
|
+
if (!id) return null;
|
|
194
|
+
try {
|
|
195
|
+
return JSON.parse(localStorage.getItem(STORAGE_PREFIX + id) || "null");
|
|
196
|
+
} catch (error) {
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function saveStoredSignature(id, record) {
|
|
202
|
+
if (!id) return;
|
|
203
|
+
try {
|
|
204
|
+
localStorage.setItem(STORAGE_PREFIX + id, JSON.stringify(record));
|
|
205
|
+
} catch (error) {
|
|
206
|
+
// Storage is best-effort; the DOM still becomes read-only after signing.
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function assignOutputStorageKeys(root) {
|
|
211
|
+
var boxes = Array.prototype.slice.call((root || document).querySelectorAll(".rbe-output-signature"));
|
|
212
|
+
var counts = {};
|
|
213
|
+
boxes.forEach(function (box) {
|
|
214
|
+
var id = box.dataset.signatureId || "";
|
|
215
|
+
counts[id] = (counts[id] || 0) + 1;
|
|
216
|
+
});
|
|
217
|
+
var seen = {};
|
|
218
|
+
boxes.forEach(function (box) {
|
|
219
|
+
var id = box.dataset.signatureId || uid("signature");
|
|
220
|
+
box.dataset.signatureId = id;
|
|
221
|
+
seen[id] = (seen[id] || 0) + 1;
|
|
222
|
+
box.dataset.signatureStorageKey = counts[id] > 1 ? id + ":" + seen[id] : id;
|
|
223
|
+
});
|
|
224
|
+
return boxes;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function uniqueEditorSignatureId(block, wrap) {
|
|
228
|
+
var id = (wrap && wrap.dataset.signatureId) || "";
|
|
229
|
+
var root = (block && block.closest && block.closest(".rbe")) || document;
|
|
230
|
+
var signatures = Array.prototype.slice.call(root.querySelectorAll(".rbe-signature-editor"));
|
|
231
|
+
var firstWithId = id ? signatures.find(function (item) { return item.dataset.signatureId === id; }) : null;
|
|
232
|
+
if (!id || (firstWithId && firstWithId !== wrap)) {
|
|
233
|
+
do {
|
|
234
|
+
id = uid("signature");
|
|
235
|
+
} while (signatures.some(function (item) { return item !== wrap && item.dataset.signatureId === id; }));
|
|
236
|
+
if (wrap) wrap.dataset.signatureId = id;
|
|
237
|
+
}
|
|
238
|
+
return id;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function applySignature(box, record) {
|
|
242
|
+
if (!box || !record || !record.name) return;
|
|
243
|
+
var unsigned = box.querySelector(".rbe-signature-unsigned");
|
|
244
|
+
var signed = box.querySelector(".rbe-signature-signed");
|
|
245
|
+
var name = box.querySelector(".rbe-signature-name");
|
|
246
|
+
var by = box.querySelector(".rbe-signature-by-name");
|
|
247
|
+
var time = box.querySelector(".rbe-signature-date");
|
|
248
|
+
var input = box.querySelector(".rbe-signature-input");
|
|
249
|
+
if (input) {
|
|
250
|
+
input.value = record.name;
|
|
251
|
+
input.readOnly = true;
|
|
252
|
+
}
|
|
253
|
+
if (name) name.textContent = record.name;
|
|
254
|
+
if (by) by.textContent = record.name;
|
|
255
|
+
if (time) {
|
|
256
|
+
time.textContent = record.dateLabel || formatSignatureDate(new Date(record.date || Date.now()));
|
|
257
|
+
if (record.date) time.setAttribute("datetime", record.date);
|
|
258
|
+
}
|
|
259
|
+
if (unsigned) unsigned.hidden = true;
|
|
260
|
+
if (signed) signed.hidden = false;
|
|
261
|
+
box.dataset.signed = "true";
|
|
262
|
+
box.classList.remove("has-error");
|
|
263
|
+
syncSignatureBoxSize(box);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function syncSignatureBoxSize(box) {
|
|
267
|
+
if (!box || !box.getBoundingClientRect) return;
|
|
268
|
+
var width = box.getBoundingClientRect().width;
|
|
269
|
+
box.classList.toggle("is-compact", width > 0 && width < 360);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function observeSignatureBox(box) {
|
|
273
|
+
if (!box || box.dataset.signatureResizeObserved === "true") return;
|
|
274
|
+
box.dataset.signatureResizeObserved = "true";
|
|
275
|
+
syncSignatureBoxSize(box);
|
|
276
|
+
if (typeof ResizeObserver === "undefined") {
|
|
277
|
+
window.addEventListener("resize", function () {
|
|
278
|
+
syncSignatureBoxSize(box);
|
|
279
|
+
});
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
var observer = new ResizeObserver(function () {
|
|
283
|
+
syncSignatureBoxSize(box);
|
|
284
|
+
});
|
|
285
|
+
observer.observe(box);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function signOutput(box) {
|
|
289
|
+
var input = box.querySelector(".rbe-signature-input");
|
|
290
|
+
var name = cleanText(input && input.value);
|
|
291
|
+
if (!name) {
|
|
292
|
+
box.classList.add("has-error");
|
|
293
|
+
if (input) input.focus();
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
var now = new Date();
|
|
297
|
+
var record = {
|
|
298
|
+
name: name,
|
|
299
|
+
date: now.toISOString(),
|
|
300
|
+
dateLabel: formatSignatureDate(now)
|
|
301
|
+
};
|
|
302
|
+
saveStoredSignature(box.dataset.signatureStorageKey || box.dataset.signatureId || "", record);
|
|
303
|
+
applySignature(box, record);
|
|
304
|
+
box.dispatchEvent(new CustomEvent("blockwriteai:signature-signed", { bubbles: true, detail: record }));
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
function initSignatureOutputs(root) {
|
|
308
|
+
injectStyles();
|
|
309
|
+
assignOutputStorageKeys(root).forEach(function (box) {
|
|
310
|
+
if (box.dataset.signatureReady === "true") return;
|
|
311
|
+
box.dataset.signatureReady = "true";
|
|
312
|
+
observeSignatureBox(box);
|
|
313
|
+
var stored = readStoredSignature(box.dataset.signatureStorageKey || box.dataset.signatureId || "");
|
|
314
|
+
if (stored && stored.name) applySignature(box, stored);
|
|
315
|
+
var input = box.querySelector(".rbe-signature-input");
|
|
316
|
+
var button = box.querySelector(".rbe-signature-apply");
|
|
317
|
+
if (button) {
|
|
318
|
+
button.addEventListener("click", function () {
|
|
319
|
+
signOutput(box);
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
if (input) {
|
|
323
|
+
input.addEventListener("input", function () {
|
|
324
|
+
box.classList.remove("has-error");
|
|
325
|
+
});
|
|
326
|
+
input.addEventListener("keydown", function (event) {
|
|
327
|
+
if (event.key === "Enter") {
|
|
328
|
+
event.preventDefault();
|
|
329
|
+
signOutput(box);
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
injectStyles();
|
|
337
|
+
|
|
338
|
+
BlockWriteAI.registerTool("signature", {
|
|
339
|
+
label: "Signature",
|
|
340
|
+
hint: "Digital signature field",
|
|
341
|
+
icon: "signature",
|
|
342
|
+
premiumFeature: "signature",
|
|
343
|
+
defaultData: function () {
|
|
344
|
+
return {
|
|
345
|
+
signatureId: uid("signature"),
|
|
346
|
+
label: "Signature",
|
|
347
|
+
width: 70,
|
|
348
|
+
alignment: "center"
|
|
349
|
+
};
|
|
350
|
+
},
|
|
351
|
+
render: function (body, data) {
|
|
352
|
+
injectStyles();
|
|
353
|
+
data = data || {};
|
|
354
|
+
var wrap = el("div", "rbe-signature-editor", {
|
|
355
|
+
dataset: {
|
|
356
|
+
signatureId: data.signatureId || uid("signature"),
|
|
357
|
+
width: cleanWidth(data.width),
|
|
358
|
+
alignment: cleanAlignment(data.alignment)
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
wrap.appendChild(el("img", "rbe-signature-watermark", { src: LOGO_URL, alt: "", "aria-hidden": "true" }));
|
|
362
|
+
|
|
363
|
+
var toolbar = el("div", "rbe-signature-toolbar");
|
|
364
|
+
toolbar.appendChild(el("div", "rbe-signature-static-label", { text: "Signature" }));
|
|
365
|
+
var alignTools = el("div", "rbe-signature-align-tools", { role: "toolbar", "aria-label": "Signature alignment" });
|
|
366
|
+
[
|
|
367
|
+
["left", "align-left", "Align left"],
|
|
368
|
+
["center", "align-center", "Align center"],
|
|
369
|
+
["right", "align-right", "Align right"]
|
|
370
|
+
].forEach(function (item) {
|
|
371
|
+
alignTools.appendChild(
|
|
372
|
+
el("button", "rbe-signature-align-btn", {
|
|
373
|
+
type: "button",
|
|
374
|
+
title: item[2],
|
|
375
|
+
html: faIcon(item[1], item[2]),
|
|
376
|
+
dataset: { align: item[0] },
|
|
377
|
+
"aria-label": item[2],
|
|
378
|
+
"aria-pressed": cleanAlignment(data.alignment) === item[0] ? "true" : "false",
|
|
379
|
+
disabled: this.readOnly
|
|
380
|
+
})
|
|
381
|
+
);
|
|
382
|
+
}, this);
|
|
383
|
+
toolbar.appendChild(alignTools);
|
|
384
|
+
wrap.appendChild(toolbar);
|
|
385
|
+
|
|
386
|
+
var preview = el("div", "rbe-signature-preview");
|
|
387
|
+
preview.appendChild(el("div", "rbe-signature-preview-name", { text: "Casey Jones" }));
|
|
388
|
+
preview.appendChild(
|
|
389
|
+
el("div", "rbe-signature-preview-copy", {
|
|
390
|
+
html:
|
|
391
|
+
"<strong>Blank signature input in preview</strong><span>Users type their name once; the signed block becomes read-only with date and time.</span>"
|
|
392
|
+
})
|
|
393
|
+
);
|
|
394
|
+
wrap.appendChild(preview);
|
|
395
|
+
if (!this.readOnly) {
|
|
396
|
+
wrap.appendChild(el("button", "rbe-signature-resize-handle", { type: "button", title: "Resize signature field", "aria-label": "Resize signature field" }));
|
|
397
|
+
}
|
|
398
|
+
body.appendChild(wrap);
|
|
399
|
+
applySignatureLayout(wrap);
|
|
400
|
+
bindSignatureResize(this, wrap);
|
|
401
|
+
var editor = this;
|
|
402
|
+
Array.prototype.slice.call(wrap.querySelectorAll(".rbe-signature-align-btn")).forEach(function (button) {
|
|
403
|
+
button.addEventListener("click", function () {
|
|
404
|
+
wrap.dataset.alignment = cleanAlignment(button.dataset.align);
|
|
405
|
+
applySignatureLayout(wrap);
|
|
406
|
+
if (editor && typeof editor.changed === "function") editor.changed(true);
|
|
407
|
+
});
|
|
408
|
+
});
|
|
409
|
+
},
|
|
410
|
+
serialize: function (block) {
|
|
411
|
+
var wrap = block.querySelector(".rbe-signature-editor");
|
|
412
|
+
return {
|
|
413
|
+
signatureId: uniqueEditorSignatureId(block, wrap),
|
|
414
|
+
label: "Signature",
|
|
415
|
+
width: cleanWidth(wrap && wrap.dataset.width),
|
|
416
|
+
alignment: cleanAlignment(wrap && wrap.dataset.alignment)
|
|
417
|
+
};
|
|
418
|
+
},
|
|
419
|
+
toHTML: function (data) {
|
|
420
|
+
injectStyles();
|
|
421
|
+
data = data || {};
|
|
422
|
+
var id = data.signatureId || uid("signature");
|
|
423
|
+
var label = "Signature";
|
|
424
|
+
return (
|
|
425
|
+
'<section class="rbe-output-signature" style="' +
|
|
426
|
+
esc(layoutStyle(data.width, data.alignment)) +
|
|
427
|
+
'" data-signature-id="' +
|
|
428
|
+
esc(id) +
|
|
429
|
+
'" data-signed="false">' +
|
|
430
|
+
sealHTML("rbe-signature-seal") +
|
|
431
|
+
'<img class="rbe-signature-watermark" src="' +
|
|
432
|
+
esc(LOGO_URL) +
|
|
433
|
+
'" alt="" aria-hidden="true"><div class="rbe-output-signature-label">' +
|
|
434
|
+
esc(label) +
|
|
435
|
+
'</div><div class="rbe-signature-unsigned"><input class="rbe-signature-input" type="text" autocomplete="name" placeholder="' +
|
|
436
|
+
esc("Enter your name here...") +
|
|
437
|
+
'"><button type="button" class="rbe-signature-apply">' +
|
|
438
|
+
faIcon("file-signature", "Sign") +
|
|
439
|
+
"<span>Sign</span></button></div>" +
|
|
440
|
+
'<div class="rbe-signature-signed" hidden><div class="rbe-signature-name"></div><div class="rbe-signature-meta"><strong>Digitally signed by <span class="rbe-signature-by-name"></span></strong><span>Date: <time class="rbe-signature-date"></time></span></div></div></section>'
|
|
441
|
+
);
|
|
442
|
+
},
|
|
443
|
+
toMarkdown: function (data) {
|
|
444
|
+
return "[Signature field: " + (data && data.label ? data.label : "Signature") + "]";
|
|
445
|
+
}
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
global.BlockWriteAISignature = {
|
|
449
|
+
init: initSignatureOutputs,
|
|
450
|
+
sign: signOutput,
|
|
451
|
+
formatDate: formatSignatureDate
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
if (document.readyState === "loading") {
|
|
455
|
+
document.addEventListener("DOMContentLoaded", function () {
|
|
456
|
+
initSignatureOutputs(document);
|
|
457
|
+
});
|
|
458
|
+
} else {
|
|
459
|
+
setTimeout(function () {
|
|
460
|
+
initSignatureOutputs(document);
|
|
461
|
+
}, 0);
|
|
462
|
+
}
|
|
463
|
+
})(typeof window !== "undefined" ? window : this);
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@qarakash/blockwriteai",
|
|
3
|
+
"version": "1.0.7",
|
|
4
|
+
"description": "BlockWriteAI JSON-first drop-in block writing editor with media, diagrams, signatures, AI writing, optional history, and preview mounting.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"blockwriteai",
|
|
7
|
+
"editor",
|
|
8
|
+
"rich-text-editor",
|
|
9
|
+
"block-editor",
|
|
10
|
+
"editorjs",
|
|
11
|
+
"wysiwyg",
|
|
12
|
+
"javascript",
|
|
13
|
+
"php",
|
|
14
|
+
"document-editor"
|
|
15
|
+
],
|
|
16
|
+
"homepage": "https://github.com/qarAkash/BlockWriteAI#readme",
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/qarAkash/BlockWriteAI/issues"
|
|
19
|
+
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/qarAkash/BlockWriteAI.git"
|
|
23
|
+
},
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"author": "qarAkash",
|
|
26
|
+
"main": "dist/blockwriteai.js",
|
|
27
|
+
"types": "types/index.d.ts",
|
|
28
|
+
"style": "dist/blockwriteai.css",
|
|
29
|
+
"unpkg": "dist/blockwriteai.js",
|
|
30
|
+
"jsdelivr": "dist/blockwriteai.js",
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"types",
|
|
34
|
+
"README.md",
|
|
35
|
+
"LICENSE"
|
|
36
|
+
],
|
|
37
|
+
"exports": {
|
|
38
|
+
".": {
|
|
39
|
+
"types": "./types/index.d.ts",
|
|
40
|
+
"require": "./dist/blockwriteai.js",
|
|
41
|
+
"default": "./dist/blockwriteai.js"
|
|
42
|
+
},
|
|
43
|
+
"./css": "./dist/blockwriteai.css",
|
|
44
|
+
"./plugins/advanced": "./dist/plugins/blockwriteai-advanced-blocks.js",
|
|
45
|
+
"./plugins/drawing": "./dist/plugins/blockwriteai-drawing.js",
|
|
46
|
+
"./plugins/mermaid": "./dist/plugins/blockwriteai-mermaid.js",
|
|
47
|
+
"./plugins/code-assist": "./dist/plugins/blockwriteai-code-assist.js",
|
|
48
|
+
"./plugins/history": "./dist/plugins/blockwriteai-history.js",
|
|
49
|
+
"./plugins/ai": "./dist/plugins/blockwriteai-ai.js",
|
|
50
|
+
"./plugins/signature": "./dist/plugins/blockwriteai-signature.js",
|
|
51
|
+
"./plugins/signature-flow": "./dist/plugins/blockwriteai-signature-flow.js",
|
|
52
|
+
"./logo": "./dist/blockwriteai-logo.svg",
|
|
53
|
+
"./favicon": "./dist/blockwriteai-favicon.svg",
|
|
54
|
+
"./package.json": "./package.json"
|
|
55
|
+
},
|
|
56
|
+
"scripts": {
|
|
57
|
+
"check": "node --check dist/blockwriteai.js && node --check dist/plugins/blockwriteai-advanced-blocks.js && node --check dist/plugins/blockwriteai-drawing.js && node --check dist/plugins/blockwriteai-mermaid.js && node --check dist/plugins/blockwriteai-code-assist.js && node --check dist/plugins/blockwriteai-history.js && node --check dist/plugins/blockwriteai-ai.js && node --check dist/plugins/blockwriteai-signature.js && node --check dist/plugins/blockwriteai-signature-flow.js",
|
|
58
|
+
"pack:preview": "npm pack --dry-run"
|
|
59
|
+
},
|
|
60
|
+
"publishConfig": {
|
|
61
|
+
"access": "public"
|
|
62
|
+
}
|
|
63
|
+
}
|