@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.
@@ -0,0 +1,178 @@
1
+ /*!
2
+ * BlockWriteAI Drawing Plugin
3
+ * Adds the licensed freehand drawing block.
4
+ */
5
+ (function (global) {
6
+ "use strict";
7
+
8
+ var BlockWriteAI = global.BlockWriteAI;
9
+ if (!BlockWriteAI || BlockWriteAI.__drawingPluginInstalled) return;
10
+ BlockWriteAI.__drawingPluginInstalled = 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 { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" }[ch];
17
+ });
18
+ };
19
+ var faIcon = H.faIcon || function (name, label) {
20
+ return '<i class="fa-solid fa-' + esc(name) + '" aria-hidden="true"></i><span class="rbe-sr-only">' + esc(label || name) + "</span>";
21
+ };
22
+
23
+ function injectStyles() {
24
+ if (document.querySelector("style[data-blockwriteai-drawing]")) return;
25
+ var style = document.createElement("style");
26
+ style.dataset.blockwriteaiDrawing = "true";
27
+ style.textContent =
28
+ ".rbe-drawing-block{border:1px solid var(--rbe-border,#d7dee8);border-radius:8px;background:#fff;padding:12px;display:grid;gap:12px;}" +
29
+ ".rbe-drawing-block .rbe-plugin-toolbar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;}" +
30
+ ".rbe-drawing-block .rbe-plugin-toolbar label{display:inline-flex;align-items:center;gap:7px;font-size:12px;font-weight:750;color:#667085;}" +
31
+ ".rbe-drawing-block .rbe-plugin-toolbar input{border:1px solid var(--rbe-border,#d7dee8);border-radius:7px;background:#fff;color:#172033;font:14px/1.4 Arial,sans-serif;padding:8px 9px;}" +
32
+ ".rbe-drawing-block .rbe-plugin-toolbar input[type='color']{width:40px;min-width:40px;height:34px;padding:3px;}" +
33
+ ".rbe-drawing-text-input{min-width:220px;flex:1 1 260px;}" +
34
+ ".rbe-drawing-text-apply{min-width:38px;}" +
35
+ ".rbe-drawing-shell{display:grid;gap:10px;}" +
36
+ ".rbe-drawing-canvas{width:100%;height:260px;border:1px solid #cbd5e1;border-radius:8px;background:#fff;touch-action:none;}" +
37
+ ".rbe-output-drawing{margin:0 0 15px;}" +
38
+ ".rbe-output-drawing img{max-width:100%;border:1px solid #d7dee8;border-radius:8px;background:#fff;}" +
39
+ "@media (max-width:640px){.rbe-drawing-block{padding:10px;gap:10px;}.rbe-drawing-block .rbe-plugin-toolbar{display:grid;grid-template-columns:1fr;align-items:stretch;}.rbe-drawing-block .rbe-plugin-toolbar label{width:100%;justify-content:space-between;}.rbe-drawing-block .rbe-plugin-toolbar input{width:100%;}.rbe-drawing-canvas{height:220px;}}";
40
+ document.head.appendChild(style);
41
+ }
42
+
43
+ function drawingTextSvgDataUri(text, color) {
44
+ var safeColor = /^#[0-9a-f]{3}([0-9a-f]{3})?$/i.test(color || "") ? color : "#2f1830";
45
+ var words = String(text || "Signature text").trim().split(/\s+/);
46
+ var lineOne = words.slice(0, Math.ceil(words.length / 2)).join(" ");
47
+ var lineTwo = words.slice(Math.ceil(words.length / 2)).join(" ");
48
+ var hasTwoLines = !!lineTwo;
49
+ var svg = [
50
+ '<svg xmlns="http://www.w3.org/2000/svg" width="900" height="320" viewBox="0 0 900 320">',
51
+ '<rect width="900" height="320" rx="16" fill="#ffffff"/>',
52
+ '<text x="450" y="' + (hasTwoLines ? "138" : "176") + '" text-anchor="middle" font-family="Mabriella, \'Brush Script MT\', \'Segoe Script\', \'Lucida Handwriting\', cursive" font-size="' + (hasTwoLines ? "104" : "118") + '" font-weight="400" fill="' + esc(safeColor) + '">' + esc(lineOne) + "</text>",
53
+ hasTwoLines ? '<text x="450" y="244" text-anchor="middle" font-family="Mabriella, \'Brush Script MT\', \'Segoe Script\', \'Lucida Handwriting\', cursive" font-size="104" font-weight="400" fill="' + esc(safeColor) + '">' + esc(lineTwo) + "</text>" : "",
54
+ "</svg>"
55
+ ].join("");
56
+ return "data:image/svg+xml;charset=UTF-8," + encodeURIComponent(svg);
57
+ }
58
+
59
+ BlockWriteAI.registerTool("drawing", {
60
+ label: "Drawing",
61
+ hint: "Freehand sketch canvas",
62
+ icon: "pen-nib",
63
+ premiumFeature: "drawing",
64
+ defaultData: { image: "", color: "#172033", size: 4, text: "" },
65
+ render: function (body, data) {
66
+ injectStyles();
67
+ var editor = this;
68
+ data = data || {};
69
+ var wrap = el("div", "rbe-drawing-block");
70
+ wrap.dataset.initialImage = data.image || data.url || data.src || "";
71
+ if (!wrap.dataset.initialImage && data.text) {
72
+ wrap.dataset.initialImage = drawingTextSvgDataUri(data.text, data.color || "#2f1830");
73
+ }
74
+ wrap.dataset.drawingDirty = "false";
75
+ wrap.innerHTML =
76
+ '<div class="rbe-plugin-toolbar">' +
77
+ '<label>Pen <input class="rbe-drawing-color" type="color"></label>' +
78
+ '<label>Size <input class="rbe-drawing-size" type="range" min="1" max="24"></label>' +
79
+ '<input class="rbe-drawing-text-input" type="text" placeholder="Type name or text">' +
80
+ '<button type="button" class="rbe-small-btn rbe-drawing-text-apply" title="Convert text to Mabriella style" aria-label="Convert text to Mabriella style">' + faIcon("wand-magic-sparkles", "Convert text") + "</button>" +
81
+ '<button type="button" class="rbe-small-btn rbe-drawing-clear">' + faIcon("eraser", "Clear drawing") + "</button>" +
82
+ '</div><div class="rbe-drawing-shell"><canvas class="rbe-drawing-canvas" width="900" height="320"></canvas></div>';
83
+ body.appendChild(wrap);
84
+
85
+ var canvas = wrap.querySelector("canvas");
86
+ var ctx = canvas.getContext("2d");
87
+ wrap.querySelector(".rbe-drawing-color").value = data.color || "#172033";
88
+ wrap.querySelector(".rbe-drawing-size").value = data.size || 4;
89
+ wrap.querySelector(".rbe-drawing-text-input").value = data.text || "";
90
+
91
+ function loadImage(source) {
92
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
93
+ if (!source) return;
94
+ var image = new Image();
95
+ image.onload = function () { ctx.drawImage(image, 0, 0, canvas.width, canvas.height); };
96
+ image.src = source;
97
+ }
98
+
99
+ if (wrap.dataset.initialImage) loadImage(wrap.dataset.initialImage);
100
+
101
+ var drawing = false;
102
+ function point(event) {
103
+ var rect = canvas.getBoundingClientRect();
104
+ return { x: ((event.clientX - rect.left) / rect.width) * canvas.width, y: ((event.clientY - rect.top) / rect.height) * canvas.height };
105
+ }
106
+
107
+ canvas.addEventListener("pointerdown", function (event) {
108
+ drawing = true;
109
+ wrap.dataset.drawingDirty = "true";
110
+ canvas.setPointerCapture(event.pointerId);
111
+ var p = point(event);
112
+ ctx.beginPath();
113
+ ctx.moveTo(p.x, p.y);
114
+ });
115
+ canvas.addEventListener("pointermove", function (event) {
116
+ if (!drawing) return;
117
+ var p = point(event);
118
+ ctx.strokeStyle = wrap.querySelector(".rbe-drawing-color").value;
119
+ ctx.lineWidth = Number(wrap.querySelector(".rbe-drawing-size").value || 4);
120
+ ctx.lineCap = "round";
121
+ ctx.lineJoin = "round";
122
+ ctx.lineTo(p.x, p.y);
123
+ ctx.stroke();
124
+ });
125
+ canvas.addEventListener("pointerup", function () {
126
+ drawing = false;
127
+ editor.changed(true);
128
+ });
129
+ wrap.querySelector(".rbe-drawing-text-apply").addEventListener("click", function () {
130
+ var input = wrap.querySelector(".rbe-drawing-text-input");
131
+ var text = (input.value || "").trim();
132
+ if (!text) {
133
+ input.focus();
134
+ return;
135
+ }
136
+ wrap.dataset.initialImage = drawingTextSvgDataUri(text, wrap.querySelector(".rbe-drawing-color").value || "#2f1830");
137
+ wrap.dataset.drawingDirty = "false";
138
+ loadImage(wrap.dataset.initialImage);
139
+ editor.changed(true);
140
+ });
141
+ wrap.querySelector(".rbe-drawing-clear").addEventListener("click", function () {
142
+ wrap.dataset.initialImage = "";
143
+ wrap.dataset.drawingDirty = "true";
144
+ wrap.querySelector(".rbe-drawing-text-input").value = "";
145
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
146
+ editor.changed(true);
147
+ });
148
+ },
149
+ serialize: function (block) {
150
+ var canvas = block.querySelector(".rbe-drawing-canvas");
151
+ var drawingBlock = block.querySelector(".rbe-drawing-block") || block;
152
+ var initialImage = drawingBlock.dataset.initialImage || "";
153
+ var payload = {
154
+ image: "",
155
+ color: (block.querySelector(".rbe-drawing-color") || {}).value || "#172033",
156
+ size: Number((block.querySelector(".rbe-drawing-size") || {}).value || 4),
157
+ text: (block.querySelector(".rbe-drawing-text-input") || {}).value || ""
158
+ };
159
+ if (initialImage && drawingBlock.dataset.drawingDirty !== "true") {
160
+ payload.image = initialImage;
161
+ return payload;
162
+ }
163
+ payload.image = canvas ? canvas.toDataURL("image/png") : "";
164
+ return payload;
165
+ },
166
+ toHTML: function (data) {
167
+ data = data || {};
168
+ var image = data.image || data.url || data.src || (data.diagram && data.diagram.image) || "";
169
+ if (!image && data.text) image = drawingTextSvgDataUri(data.text, data.color || "#2f1830");
170
+ return image ? '<figure class="rbe-output-drawing"><img src="' + esc(image) + '" alt="Drawing"></figure>' : "";
171
+ },
172
+ toMarkdown: function () {
173
+ return "![Drawing](drawing.png)";
174
+ }
175
+ });
176
+
177
+ injectStyles();
178
+ })(typeof window !== "undefined" ? window : this);
@@ -0,0 +1,23 @@
1
+ /*!
2
+ * BlockWriteAI History Plugin
3
+ * Enables the optional History dropdown for BlockWriteAI editors loaded after this file.
4
+ */
5
+ (function (global, factory) {
6
+ if (typeof module === "object" && module.exports) {
7
+ module.exports = factory(require("../blockwriteai"));
8
+ } else {
9
+ factory(global.BlockWriteAI);
10
+ }
11
+ })(typeof window !== "undefined" ? window : this, function (BlockWriteAI) {
12
+ "use strict";
13
+
14
+ if (!BlockWriteAI || typeof BlockWriteAI.configure !== "function") return null;
15
+
16
+ BlockWriteAI.configure({ historyPanel: true });
17
+ BlockWriteAI.enableHistoryPanel = function () {
18
+ BlockWriteAI.configure({ historyPanel: true });
19
+ return BlockWriteAI;
20
+ };
21
+
22
+ return BlockWriteAI;
23
+ });