@aglyn/besigner 1.0.0-beta.143

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.
Files changed (99) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +7 -0
  3. package/package.json +48 -0
  4. package/src/besigner.d.ts +28 -0
  5. package/src/besigner.js +59 -0
  6. package/src/besigner.js.map +1 -0
  7. package/src/index.d.ts +17 -0
  8. package/src/index.js +18 -0
  9. package/src/index.js.map +1 -0
  10. package/src/lib/api/app.api.d.ts +22 -0
  11. package/src/lib/api/app.api.js +59 -0
  12. package/src/lib/api/app.api.js.map +1 -0
  13. package/src/lib/api/besigner.api.d.ts +24 -0
  14. package/src/lib/api/besigner.api.js +39 -0
  15. package/src/lib/api/besigner.api.js.map +1 -0
  16. package/src/lib/clipboard-manager/clipboard-manager.d.ts +89 -0
  17. package/src/lib/clipboard-manager/clipboard-manager.js +241 -0
  18. package/src/lib/clipboard-manager/clipboard-manager.js.map +1 -0
  19. package/src/lib/clipboard-manager/clipboard-mirror.d.ts +52 -0
  20. package/src/lib/clipboard-manager/clipboard-mirror.js +75 -0
  21. package/src/lib/clipboard-manager/clipboard-mirror.js.map +1 -0
  22. package/src/lib/clipboard-manager/index.d.ts +20 -0
  23. package/src/lib/clipboard-manager/index.js +23 -0
  24. package/src/lib/clipboard-manager/index.js.map +1 -0
  25. package/src/lib/clipboard-manager/style-clipboard.d.ts +77 -0
  26. package/src/lib/clipboard-manager/style-clipboard.js +173 -0
  27. package/src/lib/clipboard-manager/style-clipboard.js.map +1 -0
  28. package/src/lib/constants/_internal.d.ts +20 -0
  29. package/src/lib/constants/_internal.js +19 -0
  30. package/src/lib/constants/_internal.js.map +1 -0
  31. package/src/lib/constants/besigner.d.ts +78 -0
  32. package/src/lib/constants/besigner.js +69 -0
  33. package/src/lib/constants/besigner.js.map +1 -0
  34. package/src/lib/controllers/besigner-app.controller.d.ts +33 -0
  35. package/src/lib/controllers/besigner-app.controller.js +57 -0
  36. package/src/lib/controllers/besigner-app.controller.js.map +1 -0
  37. package/src/lib/controllers/besigner-interface.controller.d.ts +44 -0
  38. package/src/lib/controllers/besigner-interface.controller.js +130 -0
  39. package/src/lib/controllers/besigner-interface.controller.js.map +1 -0
  40. package/src/lib/definitions/besigner-app.types.d.ts +41 -0
  41. package/src/lib/definitions/besigner-app.types.js +18 -0
  42. package/src/lib/definitions/besigner-app.types.js.map +1 -0
  43. package/src/lib/definitions/besigner-interface.types.d.ts +106 -0
  44. package/src/lib/definitions/besigner-interface.types.js +18 -0
  45. package/src/lib/definitions/besigner-interface.types.js.map +1 -0
  46. package/src/lib/definitions/emitter.types.d.ts +33 -0
  47. package/src/lib/definitions/emitter.types.js +18 -0
  48. package/src/lib/definitions/emitter.types.js.map +1 -0
  49. package/src/lib/device-preview-width.d.ts +39 -0
  50. package/src/lib/device-preview-width.js +57 -0
  51. package/src/lib/device-preview-width.js.map +1 -0
  52. package/src/lib/dnd-manager/confirm-valid-lineal-relationship.d.ts +54 -0
  53. package/src/lib/dnd-manager/confirm-valid-lineal-relationship.js +109 -0
  54. package/src/lib/dnd-manager/confirm-valid-lineal-relationship.js.map +1 -0
  55. package/src/lib/dnd-manager/dnd-manager.d.ts +75 -0
  56. package/src/lib/dnd-manager/dnd-manager.js +337 -0
  57. package/src/lib/dnd-manager/dnd-manager.js.map +1 -0
  58. package/src/lib/dnd-manager/droppable-region-utils.d.ts +72 -0
  59. package/src/lib/dnd-manager/droppable-region-utils.js +115 -0
  60. package/src/lib/dnd-manager/droppable-region-utils.js.map +1 -0
  61. package/src/lib/dnd-manager/index.d.ts +20 -0
  62. package/src/lib/dnd-manager/index.js +21 -0
  63. package/src/lib/dnd-manager/index.js.map +1 -0
  64. package/src/lib/focus-manager/focus-manager.d.ts +104 -0
  65. package/src/lib/focus-manager/focus-manager.js +353 -0
  66. package/src/lib/focus-manager/focus-manager.js.map +1 -0
  67. package/src/lib/focus-manager/index.d.ts +18 -0
  68. package/src/lib/focus-manager/index.js +19 -0
  69. package/src/lib/focus-manager/index.js.map +1 -0
  70. package/src/lib/is-root-element-id.d.ts +19 -0
  71. package/src/lib/is-root-element-id.js +22 -0
  72. package/src/lib/is-root-element-id.js.map +1 -0
  73. package/src/lib/managers.d.ts +25 -0
  74. package/src/lib/managers.js +26 -0
  75. package/src/lib/managers.js.map +1 -0
  76. package/src/lib/node-move/index.d.ts +17 -0
  77. package/src/lib/node-move/index.js +18 -0
  78. package/src/lib/node-move/index.js.map +1 -0
  79. package/src/lib/node-move/node-move.d.ts +80 -0
  80. package/src/lib/node-move/node-move.js +134 -0
  81. package/src/lib/node-move/node-move.js.map +1 -0
  82. package/src/lib/node-refs/index.d.ts +1 -0
  83. package/src/lib/node-refs/index.js +3 -0
  84. package/src/lib/node-refs/index.js.map +1 -0
  85. package/src/lib/node-refs/node-refs.d.ts +24 -0
  86. package/src/lib/node-refs/node-refs.js +30 -0
  87. package/src/lib/node-refs/node-refs.js.map +1 -0
  88. package/src/lib/pick-manager/index.d.ts +18 -0
  89. package/src/lib/pick-manager/index.js +20 -0
  90. package/src/lib/pick-manager/index.js.map +1 -0
  91. package/src/lib/pick-manager/pick-manager.d.ts +64 -0
  92. package/src/lib/pick-manager/pick-manager.js +116 -0
  93. package/src/lib/pick-manager/pick-manager.js.map +1 -0
  94. package/src/lib/text-entry/index.d.ts +17 -0
  95. package/src/lib/text-entry/index.js +18 -0
  96. package/src/lib/text-entry/index.js.map +1 -0
  97. package/src/lib/text-entry/text-entry.d.ts +71 -0
  98. package/src/lib/text-entry/text-entry.js +103 -0
  99. package/src/lib/text-entry/text-entry.js.map +1 -0
@@ -0,0 +1,71 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * "Is the user typing?" — the single predicate every besigner shortcut that
19
+ * lives on `window`/`document` must consult before it acts (AGL-2211).
20
+ *
21
+ * A global shortcut is registered once and fires wherever focus happens to
22
+ * be. The canvas shortcuts (Cmd+C/V/A) and the picker's Escape are only
23
+ * meaningful when focus is on the element tree; inside a text-entry surface
24
+ * the surface — or the browser — owns the keystroke, and the canvas handler
25
+ * must return without calling `preventDefault()`.
26
+ *
27
+ * The surfaces are enumerated from what the besigner actually mounts, not
28
+ * guessed:
29
+ *
30
+ * - `INPUT` / `TEXTAREA` / `SELECT` — every attributes-panel field, dialog
31
+ * field, and the plugin-settings raw-JSON `TextField`.
32
+ * - `contenteditable` — the inline text and markdown editors' light-DOM
33
+ * halves, and MUI's rich fields.
34
+ * - `role="textbox"` / `role="searchbox"` — ARIA-labelled custom inputs.
35
+ * - **Monaco** (`.monaco-editor`), which is what `Edit -> Raw JSON` is.
36
+ * Monaco 0.52+ ships the `EditContext` API and `editor.editContext`
37
+ * DEFAULTS TO `true` (monaco-editor 0.56 —
38
+ * `esm/vs/editor/common/config/editorOptions.js`), so the focused node is
39
+ * a bare `<div class="native-edit-context" tabindex="0">`: **not** a
40
+ * textarea, **not** contenteditable, no role. Every tag/attribute test
41
+ * above misses it, which is exactly how Cmd+C in the raw JSON editor came
42
+ * to copy canvas ELEMENTS. `.native-edit-context` is matched too so the
43
+ * guard holds even if Monaco is ever mounted without its outer chrome.
44
+ *
45
+ * Deliberately DOM-only and dependency-free: `pick-manager` (this lib) and
46
+ * the designer's clipboard shortcuts (the feature lib) both need it, so it
47
+ * cannot reach for the inline-editor stores — the designer's
48
+ * `isEditingText()` layers those on top.
49
+ */
50
+ /**
51
+ * Ancestors that make everything inside them a text-entry surface. Matched
52
+ * with `closest()`, so a click target deep inside Monaco's view still reads
53
+ * as "the user is typing".
54
+ */
55
+ export declare const TEXT_ENTRY_HOST_SELECTOR: string;
56
+ /**
57
+ * True when `target` is (or sits inside) a surface that owns the keystroke.
58
+ *
59
+ * Accepts an `EventTarget` so a handler can pass `event.target` straight
60
+ * through; anything that is not an element answers `false`.
61
+ */
62
+ export declare function isTextEntryElement(target: EventTarget | Node | null | undefined): boolean;
63
+ /**
64
+ * True when focus currently rests in a text-entry surface.
65
+ *
66
+ * Descends through OPEN shadow roots: `document.activeElement` reports the
67
+ * shadow HOST, so a field inside a web component would otherwise read as
68
+ * "not text". The besigner canvas uses a CLOSED root, which is unreachable
69
+ * by design — the designer's inline-edit stores answer for that surface.
70
+ */
71
+ export declare function isTextEntryFocused(doc?: Document): boolean;
@@ -0,0 +1,103 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ /**
17
+ * "Is the user typing?" — the single predicate every besigner shortcut that
18
+ * lives on `window`/`document` must consult before it acts (AGL-2211).
19
+ *
20
+ * A global shortcut is registered once and fires wherever focus happens to
21
+ * be. The canvas shortcuts (Cmd+C/V/A) and the picker's Escape are only
22
+ * meaningful when focus is on the element tree; inside a text-entry surface
23
+ * the surface — or the browser — owns the keystroke, and the canvas handler
24
+ * must return without calling `preventDefault()`.
25
+ *
26
+ * The surfaces are enumerated from what the besigner actually mounts, not
27
+ * guessed:
28
+ *
29
+ * - `INPUT` / `TEXTAREA` / `SELECT` — every attributes-panel field, dialog
30
+ * field, and the plugin-settings raw-JSON `TextField`.
31
+ * - `contenteditable` — the inline text and markdown editors' light-DOM
32
+ * halves, and MUI's rich fields.
33
+ * - `role="textbox"` / `role="searchbox"` — ARIA-labelled custom inputs.
34
+ * - **Monaco** (`.monaco-editor`), which is what `Edit -> Raw JSON` is.
35
+ * Monaco 0.52+ ships the `EditContext` API and `editor.editContext`
36
+ * DEFAULTS TO `true` (monaco-editor 0.56 —
37
+ * `esm/vs/editor/common/config/editorOptions.js`), so the focused node is
38
+ * a bare `<div class="native-edit-context" tabindex="0">`: **not** a
39
+ * textarea, **not** contenteditable, no role. Every tag/attribute test
40
+ * above misses it, which is exactly how Cmd+C in the raw JSON editor came
41
+ * to copy canvas ELEMENTS. `.native-edit-context` is matched too so the
42
+ * guard holds even if Monaco is ever mounted without its outer chrome.
43
+ *
44
+ * Deliberately DOM-only and dependency-free: `pick-manager` (this lib) and
45
+ * the designer's clipboard shortcuts (the feature lib) both need it, so it
46
+ * cannot reach for the inline-editor stores — the designer's
47
+ * `isEditingText()` layers those on top.
48
+ */ /**
49
+ * Ancestors that make everything inside them a text-entry surface. Matched
50
+ * with `closest()`, so a click target deep inside Monaco's view still reads
51
+ * as "the user is typing".
52
+ */ export const TEXT_ENTRY_HOST_SELECTOR = [
53
+ '.monaco-editor',
54
+ '.native-edit-context',
55
+ '[contenteditable=""]',
56
+ '[contenteditable="true"]',
57
+ '[contenteditable="plaintext-only"]'
58
+ ].join(',');
59
+ /** Element tags that are always text entry. */ const TEXT_ENTRY_TAGS = new Set([
60
+ 'INPUT',
61
+ 'TEXTAREA',
62
+ 'SELECT'
63
+ ]);
64
+ /** ARIA roles that are always text entry. */ const TEXT_ENTRY_ROLES = new Set([
65
+ 'textbox',
66
+ 'searchbox'
67
+ ]);
68
+ /**
69
+ * True when `target` is (or sits inside) a surface that owns the keystroke.
70
+ *
71
+ * Accepts an `EventTarget` so a handler can pass `event.target` straight
72
+ * through; anything that is not an element answers `false`.
73
+ */ export function isTextEntryElement(target) {
74
+ const element = target;
75
+ if (!element || element.nodeType !== 1) return false;
76
+ if (element.isContentEditable) return true;
77
+ if (TEXT_ENTRY_TAGS.has(element.tagName)) return true;
78
+ const role = element.getAttribute == null ? void 0 : element.getAttribute.call(element, 'role');
79
+ if (role && TEXT_ENTRY_ROLES.has(role)) return true;
80
+ return typeof element.closest === 'function' ? !!element.closest(TEXT_ENTRY_HOST_SELECTOR) : false;
81
+ }
82
+ /**
83
+ * True when focus currently rests in a text-entry surface.
84
+ *
85
+ * Descends through OPEN shadow roots: `document.activeElement` reports the
86
+ * shadow HOST, so a field inside a web component would otherwise read as
87
+ * "not text". The besigner canvas uses a CLOSED root, which is unreachable
88
+ * by design — the designer's inline-edit stores answer for that surface.
89
+ */ export function isTextEntryFocused(doc) {
90
+ const root = doc != null ? doc : typeof document === 'undefined' ? null : document;
91
+ if (!root) return false;
92
+ let active = root.activeElement;
93
+ while(active){
94
+ var _active_shadowRoot;
95
+ if (isTextEntryElement(active)) return true;
96
+ const inner = (_active_shadowRoot = active.shadowRoot) == null ? void 0 : _active_shadowRoot.activeElement;
97
+ if (!inner || inner === active) return false;
98
+ active = inner;
99
+ }
100
+ return false;
101
+ }
102
+
103
+ //# sourceMappingURL=text-entry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/besigner/core/src/lib/text-entry/text-entry.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * \"Is the user typing?\" — the single predicate every besigner shortcut that\n * lives on `window`/`document` must consult before it acts (AGL-2211).\n *\n * A global shortcut is registered once and fires wherever focus happens to\n * be. The canvas shortcuts (Cmd+C/V/A) and the picker's Escape are only\n * meaningful when focus is on the element tree; inside a text-entry surface\n * the surface — or the browser — owns the keystroke, and the canvas handler\n * must return without calling `preventDefault()`.\n *\n * The surfaces are enumerated from what the besigner actually mounts, not\n * guessed:\n *\n * - `INPUT` / `TEXTAREA` / `SELECT` — every attributes-panel field, dialog\n * field, and the plugin-settings raw-JSON `TextField`.\n * - `contenteditable` — the inline text and markdown editors' light-DOM\n * halves, and MUI's rich fields.\n * - `role=\"textbox\"` / `role=\"searchbox\"` — ARIA-labelled custom inputs.\n * - **Monaco** (`.monaco-editor`), which is what `Edit -> Raw JSON` is.\n * Monaco 0.52+ ships the `EditContext` API and `editor.editContext`\n * DEFAULTS TO `true` (monaco-editor 0.56 —\n * `esm/vs/editor/common/config/editorOptions.js`), so the focused node is\n * a bare `<div class=\"native-edit-context\" tabindex=\"0\">`: **not** a\n * textarea, **not** contenteditable, no role. Every tag/attribute test\n * above misses it, which is exactly how Cmd+C in the raw JSON editor came\n * to copy canvas ELEMENTS. `.native-edit-context` is matched too so the\n * guard holds even if Monaco is ever mounted without its outer chrome.\n *\n * Deliberately DOM-only and dependency-free: `pick-manager` (this lib) and\n * the designer's clipboard shortcuts (the feature lib) both need it, so it\n * cannot reach for the inline-editor stores — the designer's\n * `isEditingText()` layers those on top.\n */\n\n/**\n * Ancestors that make everything inside them a text-entry surface. Matched\n * with `closest()`, so a click target deep inside Monaco's view still reads\n * as \"the user is typing\".\n */\nexport const TEXT_ENTRY_HOST_SELECTOR = [\n '.monaco-editor',\n '.native-edit-context',\n '[contenteditable=\"\"]',\n '[contenteditable=\"true\"]',\n '[contenteditable=\"plaintext-only\"]',\n].join(',')\n\n/** Element tags that are always text entry. */\nconst TEXT_ENTRY_TAGS = new Set(['INPUT', 'TEXTAREA', 'SELECT'])\n\n/** ARIA roles that are always text entry. */\nconst TEXT_ENTRY_ROLES = new Set(['textbox', 'searchbox'])\n\n/**\n * True when `target` is (or sits inside) a surface that owns the keystroke.\n *\n * Accepts an `EventTarget` so a handler can pass `event.target` straight\n * through; anything that is not an element answers `false`.\n */\nexport function isTextEntryElement(\n target: EventTarget | Node | null | undefined,\n): boolean {\n const element = target as HTMLElement | null\n if (!element || element.nodeType !== 1) return false\n if (element.isContentEditable) return true\n if (TEXT_ENTRY_TAGS.has(element.tagName)) return true\n const role = element.getAttribute?.('role')\n if (role && TEXT_ENTRY_ROLES.has(role)) return true\n return typeof element.closest === 'function'\n ? !!element.closest(TEXT_ENTRY_HOST_SELECTOR)\n : false\n}\n\n/**\n * True when focus currently rests in a text-entry surface.\n *\n * Descends through OPEN shadow roots: `document.activeElement` reports the\n * shadow HOST, so a field inside a web component would otherwise read as\n * \"not text\". The besigner canvas uses a CLOSED root, which is unreachable\n * by design — the designer's inline-edit stores answer for that surface.\n */\nexport function isTextEntryFocused(doc?: Document): boolean {\n const root = doc ?? (typeof document === 'undefined' ? null : document)\n if (!root) return false\n let active: Element | null = root.activeElement\n while (active) {\n if (isTextEntryElement(active)) return true\n const inner = (active as HTMLElement).shadowRoot?.activeElement\n if (!inner || inner === active) return false\n active = inner\n }\n return false\n}\n"],"names":["TEXT_ENTRY_HOST_SELECTOR","join","TEXT_ENTRY_TAGS","Set","TEXT_ENTRY_ROLES","isTextEntryElement","target","element","nodeType","isContentEditable","has","tagName","role","getAttribute","closest","isTextEntryFocused","doc","root","document","active","activeElement","inner","shadowRoot"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgCC,GAED;;;;CAIC,GACD,OAAO,MAAMA,2BAA2B;IACtC;IACA;IACA;IACA;IACA;CACD,CAACC,IAAI,CAAC,KAAI;AAEX,6CAA6C,GAC7C,MAAMC,kBAAkB,IAAIC,IAAI;IAAC;IAAS;IAAY;CAAS;AAE/D,2CAA2C,GAC3C,MAAMC,mBAAmB,IAAID,IAAI;IAAC;IAAW;CAAY;AAEzD;;;;;CAKC,GACD,OAAO,SAASE,mBACdC,MAA6C;IAE7C,MAAMC,UAAUD;IAChB,IAAI,CAACC,WAAWA,QAAQC,QAAQ,KAAK,GAAG,OAAO;IAC/C,IAAID,QAAQE,iBAAiB,EAAE,OAAO;IACtC,IAAIP,gBAAgBQ,GAAG,CAACH,QAAQI,OAAO,GAAG,OAAO;IACjD,MAAMC,OAAOL,QAAQM,YAAY,oBAApBN,QAAQM,YAAY,MAApBN,SAAuB;IACpC,IAAIK,QAAQR,iBAAiBM,GAAG,CAACE,OAAO,OAAO;IAC/C,OAAO,OAAOL,QAAQO,OAAO,KAAK,aAC9B,CAAC,CAACP,QAAQO,OAAO,CAACd,4BAClB;AACN;AAEA;;;;;;;CAOC,GACD,OAAO,SAASe,mBAAmBC,GAAc;IAC/C,MAAMC,OAAOD,cAAAA,MAAQ,OAAOE,aAAa,cAAc,OAAOA;IAC9D,IAAI,CAACD,MAAM,OAAO;IAClB,IAAIE,SAAyBF,KAAKG,aAAa;IAC/C,MAAOD,OAAQ;YAEC;QADd,IAAId,mBAAmBc,SAAS,OAAO;QACvC,MAAME,SAAQ,qBAAA,AAACF,OAAuBG,UAAU,qBAAlC,mBAAoCF,aAAa;QAC/D,IAAI,CAACC,SAASA,UAAUF,QAAQ,OAAO;QACvCA,SAASE;IACX;IACA,OAAO;AACT"}