@node-edit-utils/core 2.0.8 → 2.1.0
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/dist/lib/node-tools/select/helpers/isLocked.d.ts +1 -0
- package/dist/node-edit-utils.cjs.js +28 -20
- package/dist/node-edit-utils.esm.js +28 -20
- package/dist/node-edit-utils.umd.js +28 -20
- package/dist/node-edit-utils.umd.min.js +1 -1
- package/package.json +1 -1
- package/src/lib/node-tools/highlight/updateHighlightFrameVisibility.ts +2 -2
- package/src/lib/node-tools/select/helpers/isLocked.ts +4 -0
- package/src/lib/node-tools/select/selectNode.ts +12 -1
- package/src/lib/node-tools/text/nodeText.ts +2 -4
- package/src/lib/post-message/processPostMessage.ts +14 -7
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const isLocked: (node: HTMLElement | null) => boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Markup Canvas
|
|
3
3
|
* High-performance markup canvas with zoom and pan capabilities
|
|
4
|
-
* @version 2.0
|
|
4
|
+
* @version 2.1.0
|
|
5
5
|
*/
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
@@ -97,16 +97,24 @@ const bindToWindow = (key, value) => {
|
|
|
97
97
|
}
|
|
98
98
|
};
|
|
99
99
|
|
|
100
|
+
const isLocked = (node) => {
|
|
101
|
+
return node?.classList.contains("select-none") ?? false;
|
|
102
|
+
};
|
|
103
|
+
|
|
100
104
|
const processPostMessage = (event, onNodeSelected) => {
|
|
101
|
-
if (event.data.source === "markup-canvas" && event.data.canvasName === "canvas") {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
105
|
+
// if (event.data.source === "markup-canvas" && event.data.canvasName === "canvas") {
|
|
106
|
+
// if (event.data.action === "zoom") {
|
|
107
|
+
// // Zoom handling can be implemented here if needed
|
|
108
|
+
// }
|
|
109
|
+
// }
|
|
106
110
|
if (event.data.source === "application") {
|
|
107
111
|
if (event.data.action === "selectedNodeChanged") {
|
|
108
112
|
const nodeId = event.data.data;
|
|
109
113
|
const selectedNode = document.querySelector(`[data-node-id="${nodeId}"]`);
|
|
114
|
+
if (isLocked(selectedNode)) {
|
|
115
|
+
onNodeSelected?.(null);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
110
118
|
if (selectedNode) {
|
|
111
119
|
onNodeSelected?.(selectedNode);
|
|
112
120
|
}
|
|
@@ -153,13 +161,19 @@ const selectNode = (event, editableNode) => {
|
|
|
153
161
|
const clickX = event.clientX;
|
|
154
162
|
const clickY = event.clientY;
|
|
155
163
|
const clickThrough = event.metaKey || event.ctrlKey;
|
|
156
|
-
const candidates = getElementsFromPoint(clickX, clickY).filter((element) => !IGNORED_DOM_ELEMENTS.includes(element.tagName.toLowerCase())
|
|
164
|
+
const candidates = getElementsFromPoint(clickX, clickY).filter((element) => !IGNORED_DOM_ELEMENTS.includes(element.tagName.toLowerCase()));
|
|
157
165
|
if (editableNode && candidates.includes(editableNode)) {
|
|
166
|
+
if (isLocked(editableNode)) {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
158
169
|
return editableNode;
|
|
159
170
|
}
|
|
160
171
|
if (clickThrough) {
|
|
161
172
|
candidateCache = [];
|
|
162
173
|
selectedNode = candidates[0];
|
|
174
|
+
if (isLocked(selectedNode)) {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
163
177
|
return selectedNode;
|
|
164
178
|
}
|
|
165
179
|
if (targetSameCandidates(candidateCache, candidates)) {
|
|
@@ -171,6 +185,9 @@ const selectNode = (event, editableNode) => {
|
|
|
171
185
|
const nodeIndex = candidates.length - 1 - attempt;
|
|
172
186
|
selectedNode = candidates[nodeIndex];
|
|
173
187
|
candidateCache = candidates;
|
|
188
|
+
if (isLocked(selectedNode)) {
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
174
191
|
return selectedNode;
|
|
175
192
|
};
|
|
176
193
|
|
|
@@ -306,20 +323,11 @@ const updateHighlightFrameVisibility = (node, nodeProvider) => {
|
|
|
306
323
|
const frame = getHighlightFrameElement(nodeProvider);
|
|
307
324
|
if (!frame)
|
|
308
325
|
return;
|
|
309
|
-
const
|
|
326
|
+
const className = node.className;
|
|
327
|
+
const hasHiddenClass = /\bhidden\b/.test(className) || node.classList.contains("select-none");
|
|
310
328
|
frame.style.display = hasHiddenClass ? "none" : "";
|
|
311
329
|
};
|
|
312
330
|
|
|
313
|
-
const disableCanvasTextMode = () => {
|
|
314
|
-
const disableTextEditMode = getCanvasWindowValue(["keyboard", "disableTextEditMode"]);
|
|
315
|
-
disableTextEditMode?.();
|
|
316
|
-
};
|
|
317
|
-
|
|
318
|
-
const enableCanvasTextMode = () => {
|
|
319
|
-
const enableTextEditMode = getCanvasWindowValue(["keyboard", "enableTextEditMode"]);
|
|
320
|
-
enableTextEditMode?.();
|
|
321
|
-
};
|
|
322
|
-
|
|
323
331
|
const insertLineBreak = () => {
|
|
324
332
|
const selection = window.getSelection();
|
|
325
333
|
if (selection && selection.rangeCount > 0) {
|
|
@@ -413,7 +421,7 @@ const nodeText = () => {
|
|
|
413
421
|
if (editable) {
|
|
414
422
|
editableNode = node;
|
|
415
423
|
makeNodeEditable(node);
|
|
416
|
-
enableCanvasTextMode();
|
|
424
|
+
//enableCanvasTextMode();
|
|
417
425
|
cleanup = setupNodeListeners(node, nodeProvider, blurEditMode);
|
|
418
426
|
}
|
|
419
427
|
};
|
|
@@ -430,7 +438,7 @@ const nodeText = () => {
|
|
|
430
438
|
blurInProgress = true;
|
|
431
439
|
const nodeToCleanup = editableNode;
|
|
432
440
|
makeNodeNonEditable(nodeToCleanup);
|
|
433
|
-
disableCanvasTextMode();
|
|
441
|
+
//disableCanvasTextMode();
|
|
434
442
|
cleanup?.();
|
|
435
443
|
editableNode = null;
|
|
436
444
|
blurInProgress = false;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Markup Canvas
|
|
3
3
|
* High-performance markup canvas with zoom and pan capabilities
|
|
4
|
-
* @version 2.0
|
|
4
|
+
* @version 2.1.0
|
|
5
5
|
*/
|
|
6
6
|
// biome-ignore lint/suspicious/noExplicitAny: generic constraint requires flexibility
|
|
7
7
|
function withRAFThrottle(func) {
|
|
@@ -95,16 +95,24 @@ const bindToWindow = (key, value) => {
|
|
|
95
95
|
}
|
|
96
96
|
};
|
|
97
97
|
|
|
98
|
+
const isLocked = (node) => {
|
|
99
|
+
return node?.classList.contains("select-none") ?? false;
|
|
100
|
+
};
|
|
101
|
+
|
|
98
102
|
const processPostMessage = (event, onNodeSelected) => {
|
|
99
|
-
if (event.data.source === "markup-canvas" && event.data.canvasName === "canvas") {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
103
|
+
// if (event.data.source === "markup-canvas" && event.data.canvasName === "canvas") {
|
|
104
|
+
// if (event.data.action === "zoom") {
|
|
105
|
+
// // Zoom handling can be implemented here if needed
|
|
106
|
+
// }
|
|
107
|
+
// }
|
|
104
108
|
if (event.data.source === "application") {
|
|
105
109
|
if (event.data.action === "selectedNodeChanged") {
|
|
106
110
|
const nodeId = event.data.data;
|
|
107
111
|
const selectedNode = document.querySelector(`[data-node-id="${nodeId}"]`);
|
|
112
|
+
if (isLocked(selectedNode)) {
|
|
113
|
+
onNodeSelected?.(null);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
108
116
|
if (selectedNode) {
|
|
109
117
|
onNodeSelected?.(selectedNode);
|
|
110
118
|
}
|
|
@@ -151,13 +159,19 @@ const selectNode = (event, editableNode) => {
|
|
|
151
159
|
const clickX = event.clientX;
|
|
152
160
|
const clickY = event.clientY;
|
|
153
161
|
const clickThrough = event.metaKey || event.ctrlKey;
|
|
154
|
-
const candidates = getElementsFromPoint(clickX, clickY).filter((element) => !IGNORED_DOM_ELEMENTS.includes(element.tagName.toLowerCase())
|
|
162
|
+
const candidates = getElementsFromPoint(clickX, clickY).filter((element) => !IGNORED_DOM_ELEMENTS.includes(element.tagName.toLowerCase()));
|
|
155
163
|
if (editableNode && candidates.includes(editableNode)) {
|
|
164
|
+
if (isLocked(editableNode)) {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
156
167
|
return editableNode;
|
|
157
168
|
}
|
|
158
169
|
if (clickThrough) {
|
|
159
170
|
candidateCache = [];
|
|
160
171
|
selectedNode = candidates[0];
|
|
172
|
+
if (isLocked(selectedNode)) {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
161
175
|
return selectedNode;
|
|
162
176
|
}
|
|
163
177
|
if (targetSameCandidates(candidateCache, candidates)) {
|
|
@@ -169,6 +183,9 @@ const selectNode = (event, editableNode) => {
|
|
|
169
183
|
const nodeIndex = candidates.length - 1 - attempt;
|
|
170
184
|
selectedNode = candidates[nodeIndex];
|
|
171
185
|
candidateCache = candidates;
|
|
186
|
+
if (isLocked(selectedNode)) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
172
189
|
return selectedNode;
|
|
173
190
|
};
|
|
174
191
|
|
|
@@ -304,20 +321,11 @@ const updateHighlightFrameVisibility = (node, nodeProvider) => {
|
|
|
304
321
|
const frame = getHighlightFrameElement(nodeProvider);
|
|
305
322
|
if (!frame)
|
|
306
323
|
return;
|
|
307
|
-
const
|
|
324
|
+
const className = node.className;
|
|
325
|
+
const hasHiddenClass = /\bhidden\b/.test(className) || node.classList.contains("select-none");
|
|
308
326
|
frame.style.display = hasHiddenClass ? "none" : "";
|
|
309
327
|
};
|
|
310
328
|
|
|
311
|
-
const disableCanvasTextMode = () => {
|
|
312
|
-
const disableTextEditMode = getCanvasWindowValue(["keyboard", "disableTextEditMode"]);
|
|
313
|
-
disableTextEditMode?.();
|
|
314
|
-
};
|
|
315
|
-
|
|
316
|
-
const enableCanvasTextMode = () => {
|
|
317
|
-
const enableTextEditMode = getCanvasWindowValue(["keyboard", "enableTextEditMode"]);
|
|
318
|
-
enableTextEditMode?.();
|
|
319
|
-
};
|
|
320
|
-
|
|
321
329
|
const insertLineBreak = () => {
|
|
322
330
|
const selection = window.getSelection();
|
|
323
331
|
if (selection && selection.rangeCount > 0) {
|
|
@@ -411,7 +419,7 @@ const nodeText = () => {
|
|
|
411
419
|
if (editable) {
|
|
412
420
|
editableNode = node;
|
|
413
421
|
makeNodeEditable(node);
|
|
414
|
-
enableCanvasTextMode();
|
|
422
|
+
//enableCanvasTextMode();
|
|
415
423
|
cleanup = setupNodeListeners(node, nodeProvider, blurEditMode);
|
|
416
424
|
}
|
|
417
425
|
};
|
|
@@ -428,7 +436,7 @@ const nodeText = () => {
|
|
|
428
436
|
blurInProgress = true;
|
|
429
437
|
const nodeToCleanup = editableNode;
|
|
430
438
|
makeNodeNonEditable(nodeToCleanup);
|
|
431
|
-
disableCanvasTextMode();
|
|
439
|
+
//disableCanvasTextMode();
|
|
432
440
|
cleanup?.();
|
|
433
441
|
editableNode = null;
|
|
434
442
|
blurInProgress = false;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Markup Canvas
|
|
3
3
|
* High-performance markup canvas with zoom and pan capabilities
|
|
4
|
-
* @version 2.0
|
|
4
|
+
* @version 2.1.0
|
|
5
5
|
*/
|
|
6
6
|
(function (global, factory) {
|
|
7
7
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
@@ -101,16 +101,24 @@
|
|
|
101
101
|
}
|
|
102
102
|
};
|
|
103
103
|
|
|
104
|
+
const isLocked = (node) => {
|
|
105
|
+
return node?.classList.contains("select-none") ?? false;
|
|
106
|
+
};
|
|
107
|
+
|
|
104
108
|
const processPostMessage = (event, onNodeSelected) => {
|
|
105
|
-
if (event.data.source === "markup-canvas" && event.data.canvasName === "canvas") {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
109
|
+
// if (event.data.source === "markup-canvas" && event.data.canvasName === "canvas") {
|
|
110
|
+
// if (event.data.action === "zoom") {
|
|
111
|
+
// // Zoom handling can be implemented here if needed
|
|
112
|
+
// }
|
|
113
|
+
// }
|
|
110
114
|
if (event.data.source === "application") {
|
|
111
115
|
if (event.data.action === "selectedNodeChanged") {
|
|
112
116
|
const nodeId = event.data.data;
|
|
113
117
|
const selectedNode = document.querySelector(`[data-node-id="${nodeId}"]`);
|
|
118
|
+
if (isLocked(selectedNode)) {
|
|
119
|
+
onNodeSelected?.(null);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
114
122
|
if (selectedNode) {
|
|
115
123
|
onNodeSelected?.(selectedNode);
|
|
116
124
|
}
|
|
@@ -157,13 +165,19 @@
|
|
|
157
165
|
const clickX = event.clientX;
|
|
158
166
|
const clickY = event.clientY;
|
|
159
167
|
const clickThrough = event.metaKey || event.ctrlKey;
|
|
160
|
-
const candidates = getElementsFromPoint(clickX, clickY).filter((element) => !IGNORED_DOM_ELEMENTS.includes(element.tagName.toLowerCase())
|
|
168
|
+
const candidates = getElementsFromPoint(clickX, clickY).filter((element) => !IGNORED_DOM_ELEMENTS.includes(element.tagName.toLowerCase()));
|
|
161
169
|
if (editableNode && candidates.includes(editableNode)) {
|
|
170
|
+
if (isLocked(editableNode)) {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
162
173
|
return editableNode;
|
|
163
174
|
}
|
|
164
175
|
if (clickThrough) {
|
|
165
176
|
candidateCache = [];
|
|
166
177
|
selectedNode = candidates[0];
|
|
178
|
+
if (isLocked(selectedNode)) {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
167
181
|
return selectedNode;
|
|
168
182
|
}
|
|
169
183
|
if (targetSameCandidates(candidateCache, candidates)) {
|
|
@@ -175,6 +189,9 @@
|
|
|
175
189
|
const nodeIndex = candidates.length - 1 - attempt;
|
|
176
190
|
selectedNode = candidates[nodeIndex];
|
|
177
191
|
candidateCache = candidates;
|
|
192
|
+
if (isLocked(selectedNode)) {
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
178
195
|
return selectedNode;
|
|
179
196
|
};
|
|
180
197
|
|
|
@@ -310,20 +327,11 @@
|
|
|
310
327
|
const frame = getHighlightFrameElement(nodeProvider);
|
|
311
328
|
if (!frame)
|
|
312
329
|
return;
|
|
313
|
-
const
|
|
330
|
+
const className = node.className;
|
|
331
|
+
const hasHiddenClass = /\bhidden\b/.test(className) || node.classList.contains("select-none");
|
|
314
332
|
frame.style.display = hasHiddenClass ? "none" : "";
|
|
315
333
|
};
|
|
316
334
|
|
|
317
|
-
const disableCanvasTextMode = () => {
|
|
318
|
-
const disableTextEditMode = getCanvasWindowValue(["keyboard", "disableTextEditMode"]);
|
|
319
|
-
disableTextEditMode?.();
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
const enableCanvasTextMode = () => {
|
|
323
|
-
const enableTextEditMode = getCanvasWindowValue(["keyboard", "enableTextEditMode"]);
|
|
324
|
-
enableTextEditMode?.();
|
|
325
|
-
};
|
|
326
|
-
|
|
327
335
|
const insertLineBreak = () => {
|
|
328
336
|
const selection = window.getSelection();
|
|
329
337
|
if (selection && selection.rangeCount > 0) {
|
|
@@ -417,7 +425,7 @@
|
|
|
417
425
|
if (editable) {
|
|
418
426
|
editableNode = node;
|
|
419
427
|
makeNodeEditable(node);
|
|
420
|
-
enableCanvasTextMode();
|
|
428
|
+
//enableCanvasTextMode();
|
|
421
429
|
cleanup = setupNodeListeners(node, nodeProvider, blurEditMode);
|
|
422
430
|
}
|
|
423
431
|
};
|
|
@@ -434,7 +442,7 @@
|
|
|
434
442
|
blurInProgress = true;
|
|
435
443
|
const nodeToCleanup = editableNode;
|
|
436
444
|
makeNodeNonEditable(nodeToCleanup);
|
|
437
|
-
disableCanvasTextMode();
|
|
445
|
+
//disableCanvasTextMode();
|
|
438
446
|
cleanup?.();
|
|
439
447
|
editableNode = null;
|
|
440
448
|
blurInProgress = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).MarkupCanvas={})}(this,function(e){"use strict";function t(e){let t=null,n=null;const o=(...o)=>{n=o,null===t&&(t=requestAnimationFrame(()=>{n&&e(...n),t=null,n=null}))};return o.cleanup=()=>{null!==t&&(cancelAnimationFrame(t),t=null,n=null)},o}const n=e=>{const t=window.canvas;return e.reduce((e,t)=>e?.[t],t)};
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).MarkupCanvas={})}(this,function(e){"use strict";function t(e){let t=null,n=null;const o=(...o)=>{n=o,null===t&&(t=requestAnimationFrame(()=>{n&&e(...n),t=null,n=null}))};return o.cleanup=()=>{null!==t&&(cancelAnimationFrame(t),t=null,n=null)},o}const n=e=>{const t=window.canvas;return e.reduce((e,t)=>e?.[t],t)};const o=e=>e?.classList.contains("select-none")??!1;function r(e){return e.querySelector(".highlight-frame")}const s=e=>{if(!e)return;const t=r(e);t&&t.remove()},a=["path","rect","circle","ellipse","polygon","line","polyline","text","text-noci"];let i=[],l=0;const d=(e,t)=>{let n=null;const r=e.clientX,s=e.clientY,d=e.metaKey||e.ctrlKey,c=((e,t)=>{const n=document.elementsFromPoint(e,t);return Array.from(n).reduce((e,t)=>e.found?e:"node-provider"===t.getAttribute("data-role")?(e.found=!0,e):(e.elements.push(t),e),{elements:[],found:!1}).elements})(r,s).filter(e=>!a.includes(e.tagName.toLowerCase()));if(t&&c.includes(t))return o(t)?null:t;if(d)return i=[],n=c[0],o(n)?null:n;var u,m;m=c,(u=i).length===m.length&&u.every((e,t)=>e===m[t])?l<=c.length&&l++:l=0;return n=c[c.length-1-l],i=c,o(n)?null:n},c=(e,t,n,r)=>{const a=e=>{((e,t)=>{if("application"===e.data.source&&"selectedNodeChanged"===e.data.action){const n=e.data.data,r=document.querySelector(`[data-node-id="${n}"]`);if(o(r))return void t?.(null);r&&t?.(r)}})(e,t)},i=n=>{((e,t,n,o)=>{if(e.preventDefault(),e.stopPropagation(),t&&!t.contains(e.target))return s(t),void o(null);o(d(e,n))})(n,e,r(),t)},l=e=>{console.log("Esacpe Handler",e),"Escape"===e.key&&(e.preventDefault(),e.stopPropagation(),n?.())};return window.addEventListener("message",a),document.addEventListener("click",i),document.addEventListener("keydown",l),()=>{window.removeEventListener("message",a),document.removeEventListener("click",i),document.removeEventListener("keydown",l)}};function u(e,t){const o=e.getBoundingClientRect(),r=t.getBoundingClientRect(),s=o.top-r.top,a=o.left-r.left,i=n(["zoom","current"])??1;return{top:parseFloat((s/i).toFixed(5)),left:parseFloat((a/i).toFixed(5)),width:Math.max(4,parseFloat((o.width/i).toFixed(5))),height:parseFloat((o.height/i).toFixed(5))}}const m=(e,t)=>{const n=document.createElement("div");n.className="node-tools",t.appendChild(n),((e,t)=>{const n=document.createElement("div");n.className="tag-label",n.textContent=e.tagName.toLowerCase(),t.appendChild(n)})(e,n)},p=(e,t)=>{if(!e)return;const o=r(t);o&&o.remove();const s=((e,t)=>{const{top:o,left:r,width:s,height:a}=u(e,t),i=n(["zoom","current"])??1;document.body.style.setProperty("--zoom",i.toString()),document.body.style.setProperty("--stroke-width",(2/i).toFixed(3));const l=document.createElement("div");l.classList.add("highlight-frame"),l.style.setProperty("--frame-top",`${o}px`),l.style.setProperty("--frame-left",`${r}px`),l.style.setProperty("--frame-width",`${s}px`),l.style.setProperty("--frame-height",`${a}px`);const d=document.createElementNS("http://www.w3.org/2000/svg","svg");d.classList.add("highlight-frame-svg");const c=document.createElementNS("http://www.w3.org/2000/svg","rect");return c.setAttribute("x","0"),c.setAttribute("y","0"),c.setAttribute("width","100%"),c.setAttribute("height","100%"),c.classList.add("highlight-frame-rect"),d.appendChild(c),l.appendChild(d),l})(e,t);"true"===e.contentEditable&&s.classList.add("is-editable"),m(e,s),t.appendChild(s)},v=(e,t)=>{const o=r(t),s=n(["zoom","current"])??1;if(!o)return;s>=.3?t.style.setProperty("--tool-opacity","1"):t.style.setProperty("--tool-opacity","0");const{top:a,left:i,width:l,height:d}=u(e,t);o.style.setProperty("--frame-top",`${a}px`),o.style.setProperty("--frame-left",`${i}px`),o.style.setProperty("--frame-width",`${l}px`),o.style.setProperty("--frame-height",`${d}px`)},h=(e,t)=>{const n=r(t);if(!n)return;const o=e.className,s=/\bhidden\b/.test(o)||e.classList.contains("select-none");n.style.display=s?"none":""},f=e=>{const t=e=>{"Enter"===e.key&&(e.preventDefault(),e.stopPropagation(),(()=>{const e=window.getSelection();if(e&&e.rangeCount>0){const t=e.getRangeAt(0);t.deleteContents();const n=document.createElement("br");t.insertNode(n),t.setStartAfter(n),t.setEndAfter(n),e.removeAllRanges(),e.addRange(t)}})())};return e.addEventListener("keydown",t),()=>{e.removeEventListener("keydown",t)}},y=(e,t)=>{const n=((e,t)=>{const n=new MutationObserver(e=>{t(e)});return n.observe(e,{subtree:!0,childList:!0,characterData:!0}),n})(e,()=>{v(e,t)});return()=>n.disconnect()},g=()=>{let e=null,t=!1,n=null;const o=()=>{if(t||!e)return;t=!0;var o;(o=e).contentEditable="false",o.classList.remove("is-editable"),o.style.outline="none",n?.(),e=null,t=!1};return{enableEditMode:(t,r)=>{if(e===t)return;e&&e!==t&&o();const s=(e=>Array.from(e.childNodes).some(e=>e.nodeType===Node.TEXT_NODE&&e.textContent?.trim()))(t);s&&(e=t,(e=>{e.contentEditable="true",e.classList.add("is-editable"),e.style.outline="none"})(t),n=((e,t,n)=>{if(!t)return()=>{};e.addEventListener("blur",n);const o=f(e),r=y(e,t);return()=>{e.removeEventListener("blur",n),o(),r?.()}})(t,r,o))},blurEditMode:o,getEditableNode:()=>e,isEditing:()=>null!==e}},b=320,w=1680,E=[{name:"Mobile",rawValue:390,value:"320px"},{name:"Tablet Portrait",rawValue:768,value:"768px"},{name:"Tablet Landscape",rawValue:1024,value:"1024px"},{name:"Notebook",rawValue:1280,value:"1280px"},{name:"Desktop",rawValue:1680,value:"1680px"}],x=(e,t,n)=>{const o=parseFloat(document.body.dataset.zoom||"1"),r=((e,t)=>{const n=e+Math.round(t);return Math.max(b,Math.min(w,n))})(n,(e.clientX-t)/o);return r},L=(e,t)=>{e.style.setProperty("--container-width",`${t}px`),((e,t)=>{e.querySelectorAll(".resize-preset-button").forEach((e,n)=>{n<E.length&&(E[n].rawValue===t?e.classList.add("is-active"):e.classList.remove("is-active"))})})(e,t)};e.createCanvasObserver=function(){const e=document.querySelector(".transform-layer");if(!e)return{disconnect:()=>{}};const o=t(()=>{(()=>{const e=n(["zoom","current"]);document.body.style.setProperty("--zoom",e.toFixed(5)),document.body.style.setProperty("--stroke-width",(2/e).toFixed(3)),document.body.dataset.zoom=e.toFixed(5),document.body.dataset.strokeWidth=(2/e).toFixed(3)})()}),r=new MutationObserver(()=>{o()});return r.observe(e,{attributes:!0,attributeOldValue:!0,subtree:!0,childList:!0}),{disconnect:function(){o.cleanup(),r.disconnect()}}},e.createNodeTools=e=>{const n=e;let o=null,r=null,a=null;const i=g(),l=t(v),d=e=>{if(a!==e){if(a=e,i.isEditing()){const t=i.getEditableNode();t&&t!==e&&i.blurEditMode()}var t,s;o?.disconnect(),r?.disconnect(),e&&n&&(i.enableEditMode(e,n),o=((e,t)=>{const n=new ResizeObserver(e=>{t(e)});return n.observe(e),n})(n,()=>{l(e,n)}),r=new MutationObserver(()=>{l(e,n),h(e,n)}),r.observe(e,{attributes:!0,attributeFilter:["class"]})),t="selectedNodeChanged",s=e?.getAttribute("data-node-id")??null,window.parent.postMessage({source:"node-edit-utils",action:t,data:s,timestamp:Date.now()},"*"),p(e,n),e&&n&&h(e,n)}},u=c(n,d,()=>{i.isEditing()&&i.blurEditMode(),a&&n&&(s(n),a=null,o?.disconnect(),r?.disconnect())},i.getEditableNode),m={selectNode:d,getSelectedNode:()=>a,refreshHighlightFrame:()=>{l(a,n)},clearSelectedNode:()=>{s(n),a=null,o?.disconnect(),r?.disconnect()},getEditableNode:()=>i.getEditableNode(),cleanup:()=>{u(),o?.disconnect(),r?.disconnect(),i.blurEditMode(),l.cleanup()}};var f,y;return f="nodeTools",y=m,"undefined"!=typeof window&&(window[f]=y),m},e.createViewport=e=>{const n=document.querySelector(".canvas-container"),o=e.querySelector(".resize-handle");o&&o.remove();const r=(e=>{const t=document.createElement("div");return t.className="resize-handle",e.appendChild(t),t})(e);e.style.setProperty("--container-width","400px"),((e,t,n)=>{const o=document.createElement("div");o.className="resize-presets",E.forEach(e=>{const r=document.createElement("button");r.textContent=e.name,r.className="resize-preset-button",r.addEventListener("click",()=>{n(t,e.rawValue)}),o.appendChild(r)}),e.appendChild(o)})(r,e,L);let s=!1,a=0,i=0;const l=t(t=>{if(!s)return;n&&(n.style.cursor="ew-resize");const o=x(t,a,i);L(e,o)}),d=((e,t,n,o,r)=>(e.addEventListener("mousedown",t),document.addEventListener("mousemove",n),document.addEventListener("mouseup",o),window.addEventListener("blur",r),()=>{e.removeEventListener("mousedown",t),document.removeEventListener("mousemove",n),document.removeEventListener("mouseup",o),window.removeEventListener("blur",r)}))(r,t=>{t.preventDefault(),t.stopPropagation(),s=!0,a=t.clientX,i=e.offsetWidth},l,e=>{e.preventDefault(),e.stopPropagation(),n&&(n.style.cursor="default"),s=!1},()=>{s=!1});return{setWidth:t=>{L(e,t)},cleanup:()=>{s=!1,l?.cleanup(),d(),r.remove()}}}});
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@ export const updateHighlightFrameVisibility = (node: HTMLElement, nodeProvider:
|
|
|
4
4
|
const frame = getHighlightFrameElement(nodeProvider);
|
|
5
5
|
if (!frame) return;
|
|
6
6
|
|
|
7
|
-
const
|
|
7
|
+
const className = node.className;
|
|
8
|
+
const hasHiddenClass = /\bhidden\b/.test(className) || node.classList.contains("select-none");
|
|
8
9
|
frame.style.display = hasHiddenClass ? "none" : "";
|
|
9
10
|
};
|
|
10
|
-
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { IGNORED_DOM_ELEMENTS } from "./constants";
|
|
2
2
|
import { getElementsFromPoint } from "./helpers/getElementsFromPoint";
|
|
3
|
+
import { isLocked } from "./helpers/isLocked";
|
|
3
4
|
import { targetSameCandidates } from "./helpers/targetSameCandidates";
|
|
4
5
|
|
|
5
6
|
let candidateCache: Element[] = [];
|
|
@@ -14,10 +15,13 @@ export const selectNode = (event: MouseEvent, editableNode: HTMLElement | null):
|
|
|
14
15
|
const clickThrough = event.metaKey || event.ctrlKey;
|
|
15
16
|
|
|
16
17
|
const candidates = getElementsFromPoint(clickX, clickY).filter(
|
|
17
|
-
(element) => !IGNORED_DOM_ELEMENTS.includes(element.tagName.toLowerCase())
|
|
18
|
+
(element) => !IGNORED_DOM_ELEMENTS.includes(element.tagName.toLowerCase())
|
|
18
19
|
);
|
|
19
20
|
|
|
20
21
|
if (editableNode && candidates.includes(editableNode)) {
|
|
22
|
+
if (isLocked(editableNode)) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
21
25
|
return editableNode;
|
|
22
26
|
}
|
|
23
27
|
|
|
@@ -25,6 +29,9 @@ export const selectNode = (event: MouseEvent, editableNode: HTMLElement | null):
|
|
|
25
29
|
candidateCache = [];
|
|
26
30
|
|
|
27
31
|
selectedNode = candidates[0] as HTMLElement;
|
|
32
|
+
if (isLocked(selectedNode)) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
28
35
|
return selectedNode;
|
|
29
36
|
}
|
|
30
37
|
|
|
@@ -40,5 +47,9 @@ export const selectNode = (event: MouseEvent, editableNode: HTMLElement | null):
|
|
|
40
47
|
|
|
41
48
|
candidateCache = candidates;
|
|
42
49
|
|
|
50
|
+
if (isLocked(selectedNode)) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
|
|
43
54
|
return selectedNode;
|
|
44
55
|
};
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { disableCanvasTextMode } from "../../canvas/disableCanvasTextMode";
|
|
2
|
-
import { enableCanvasTextMode } from "../../canvas/enableCanvasTextMode";
|
|
3
1
|
import { setupNodeListeners } from "./events/setupNodeListeners";
|
|
4
2
|
import { hasTextContent } from "./helpers/hasTextContent";
|
|
5
3
|
import { makeNodeEditable } from "./helpers/makeNodeEditable";
|
|
@@ -26,7 +24,7 @@ export const nodeText = (): NodeText => {
|
|
|
26
24
|
editableNode = node;
|
|
27
25
|
|
|
28
26
|
makeNodeEditable(node);
|
|
29
|
-
enableCanvasTextMode();
|
|
27
|
+
//enableCanvasTextMode();
|
|
30
28
|
|
|
31
29
|
cleanup = setupNodeListeners(node, nodeProvider, blurEditMode);
|
|
32
30
|
}
|
|
@@ -50,7 +48,7 @@ export const nodeText = (): NodeText => {
|
|
|
50
48
|
const nodeToCleanup = editableNode;
|
|
51
49
|
|
|
52
50
|
makeNodeNonEditable(nodeToCleanup);
|
|
53
|
-
disableCanvasTextMode();
|
|
51
|
+
//disableCanvasTextMode();
|
|
54
52
|
cleanup?.();
|
|
55
53
|
|
|
56
54
|
editableNode = null;
|
|
@@ -1,17 +1,24 @@
|
|
|
1
|
+
import { isLocked } from "../node-tools/select/helpers/isLocked";
|
|
2
|
+
|
|
1
3
|
export const processPostMessage = (event: MessageEvent, onNodeSelected?: (node: HTMLElement | null) => void) => {
|
|
2
|
-
if (event.data.source === "markup-canvas" && event.data.canvasName === "canvas") {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
4
|
+
// if (event.data.source === "markup-canvas" && event.data.canvasName === "canvas") {
|
|
5
|
+
// if (event.data.action === "zoom") {
|
|
6
|
+
// // Zoom handling can be implemented here if needed
|
|
7
|
+
// }
|
|
8
|
+
// }
|
|
7
9
|
|
|
8
10
|
if (event.data.source === "application") {
|
|
9
11
|
if (event.data.action === "selectedNodeChanged") {
|
|
10
12
|
const nodeId = event.data.data;
|
|
11
|
-
const selectedNode = document.querySelector(`[data-node-id="${nodeId}"]`);
|
|
13
|
+
const selectedNode = document.querySelector(`[data-node-id="${nodeId}"]`) as HTMLElement | null;
|
|
14
|
+
|
|
15
|
+
if (isLocked(selectedNode)) {
|
|
16
|
+
onNodeSelected?.(null);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
12
19
|
|
|
13
20
|
if (selectedNode) {
|
|
14
|
-
onNodeSelected?.(selectedNode
|
|
21
|
+
onNodeSelected?.(selectedNode);
|
|
15
22
|
}
|
|
16
23
|
}
|
|
17
24
|
}
|