@grida/svg-editor 1.0.0-alpha.16 → 1.0.0-alpha.18
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/README.md +33 -0
- package/dist/{dom-BO2-E9oK.d.ts → dom-BMzX1CXZ.d.ts} +13 -1
- package/dist/{dom-U6ae5fQF.js → dom-DKQ4Vt3z.js} +105 -12
- package/dist/{dom-DOvcMvl4.mjs → dom-OP-kmK8k.mjs} +105 -12
- package/dist/{dom-98AUOfsP.d.mts → dom-TctdgRnn.d.mts} +13 -1
- package/dist/dom.d.mts +2 -2
- package/dist/dom.d.ts +2 -2
- package/dist/dom.js +1 -1
- package/dist/dom.mjs +1 -1
- package/dist/{editor-CYoGJ3Hf.d.ts → editor-BSxTUsW_.d.ts} +246 -4
- package/dist/{editor-C6Lj1In-.js → editor-Be6UrMeV.js} +384 -36
- package/dist/{editor-DKQOIKuU.mjs → editor-BkCbYCz2.mjs} +385 -36
- package/dist/{editor-D2eQe8lB.d.mts → editor-KqpIW1qm.d.mts} +246 -4
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{model-D0nU_EkL.js → model-BLhMJZKJ.js} +373 -27
- package/dist/{model-L3t9ixT_.mjs → model-DU0GOMwM.mjs} +362 -28
- package/dist/presets.d.mts +2 -2
- package/dist/presets.d.ts +2 -2
- package/dist/presets.js +2 -2
- package/dist/presets.mjs +1 -1
- package/dist/react.d.mts +10 -3
- package/dist/react.d.ts +10 -3
- package/dist/react.js +6 -4
- package/dist/react.mjs +6 -4
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -642,6 +642,39 @@ editor.commands.{
|
|
|
642
642
|
// groups with visual state — see TODO §10)
|
|
643
643
|
remove(): void;
|
|
644
644
|
|
|
645
|
+
// clipboard — the payload is a STANDALONE SVG DOCUMENT, not a private
|
|
646
|
+
// format (the file is the IR, so the clipboard is the file format).
|
|
647
|
+
// Copy carries the outbound url(#…)/href reference closure in one
|
|
648
|
+
// <defs> block and declares borrowed xmlns prefixes on the payload
|
|
649
|
+
// shell; ancestor transforms / inherited presentation / viewport are
|
|
650
|
+
// deliberately NOT carried (verbatim policy). Cut = copy + remove as
|
|
651
|
+
// ONE history step labeled "cut"; undo restores the document and the
|
|
652
|
+
// clipboard keeps the payload (cut → undo → paste = move). Paste is
|
|
653
|
+
// synchronous over delivered text (`text ?? internal buffer`) and has
|
|
654
|
+
// a gesture-grade refusal table: non-parseable environment input is a
|
|
655
|
+
// no-op `[]`, never a throw (insert_fragment keeps strict semantics).
|
|
656
|
+
// System-clipboard wiring is the DOM surface's native ClipboardEvent
|
|
657
|
+
// transport (text/plain = the markup itself) plus the optional
|
|
658
|
+
// ClipboardProvider seam. Full contract:
|
|
659
|
+
// https://grida.co/docs/wg/feat-svg-editor/clipboard
|
|
660
|
+
copy(): string | null; // payload | null on empty selection; no history
|
|
661
|
+
cut(): string | null; // one undoable step; buffer secured before delete
|
|
662
|
+
paste(text?: string): NodeId[]; // inserted roots (selected); [] = refusal
|
|
663
|
+
|
|
664
|
+
// duplicate — the clipboard FRD's SECOND extraction operation
|
|
665
|
+
// (subtree clone): in-document, so NO defs closure and NO xmlns
|
|
666
|
+
// shell are carried; subtrees and authored ids clone verbatim
|
|
667
|
+
// (colliding ids resolve first-in-document-order; Tidy dedups).
|
|
668
|
+
// Each clone lands as its origin's next sibling (paints above it);
|
|
669
|
+
// selection moves to the clones; ONE history step. Alt-drag
|
|
670
|
+
// translate-with-clone consumes the same operation. Repeating
|
|
671
|
+
// offset: duplicate → move the copy → duplicate repeats the
|
|
672
|
+
// translate delta (an Alt-drag clone commit arms the same memory);
|
|
673
|
+
// still one undo step, degrades to in-place when the preconditions
|
|
674
|
+
// don't hold. Contract:
|
|
675
|
+
// https://grida.co/docs/wg/feat-svg-editor/subtree-clone
|
|
676
|
+
duplicate(): NodeId[]; // clone ids (selected); [] = refusal
|
|
677
|
+
|
|
645
678
|
// insertion — `tag` is an open string (so paste / RPC can create any element,
|
|
646
679
|
// e.g. "path"); only the closed `InsertableTag` set gets a pointer-driven
|
|
647
680
|
// draw gesture and default paint.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as SvgEditor, p as Gestures, s as SurfaceHandle, w as Camera } from "./editor-
|
|
1
|
+
import { c as SvgEditor, p as Gestures, s as SurfaceHandle, w as Camera } from "./editor-BSxTUsW_.js";
|
|
2
2
|
import cmath from "@grida/cmath";
|
|
3
3
|
//#region src/core/snap/options.d.ts
|
|
4
4
|
type SnapOptions = {
|
|
@@ -48,6 +48,18 @@ type DomSurfaceOptions = {
|
|
|
48
48
|
* carte via `handle.gestures.bind(...)`.
|
|
49
49
|
*/
|
|
50
50
|
gestures?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Wire native ClipboardEvent transport — `copy` / `cut` / `paste`
|
|
53
|
+
* listeners on the owner document, gated by the clipboard attention
|
|
54
|
+
* discipline. Default `true`. Pass `false` to route ALL clipboard
|
|
55
|
+
* traffic through the `ClipboardProvider` seam instead (the
|
|
56
|
+
* configuration under which a host's paste-time screening governs
|
|
57
|
+
* every path) — see docs/wg/feat-svg-editor/clipboard.md §Transport
|
|
58
|
+
* "Host control over the native path". Focus management (the container
|
|
59
|
+
* focusing on pointerdown) stays either way — it is a general canvas
|
|
60
|
+
* mitigation, not a clipboard feature.
|
|
61
|
+
*/
|
|
62
|
+
clipboard?: boolean;
|
|
51
63
|
/**
|
|
52
64
|
* Auto-fit the document into the viewport on initial attach. Default
|
|
53
65
|
* `false`. Mirrors Excalidraw's `initialData.scrollToContent`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_model = require("./model-
|
|
1
|
+
const require_model = require("./model-BLhMJZKJ.js");
|
|
2
2
|
let _grida_cmath = require("@grida/cmath");
|
|
3
3
|
_grida_cmath = require_model.__toESM(_grida_cmath);
|
|
4
4
|
let _grida_svg_parse = require("@grida/svg/parse");
|
|
@@ -1007,15 +1007,18 @@ function create_attention_tracker(container) {
|
|
|
1007
1007
|
};
|
|
1008
1008
|
container.addEventListener("pointerenter", on_enter);
|
|
1009
1009
|
container.addEventListener("pointerleave", on_leave);
|
|
1010
|
-
const
|
|
1010
|
+
const is_focus_within = () => {
|
|
1011
1011
|
const owner = container.ownerDocument;
|
|
1012
|
-
if (!owner) return
|
|
1012
|
+
if (!owner) return false;
|
|
1013
1013
|
const active = owner.activeElement;
|
|
1014
|
-
|
|
1015
|
-
|
|
1014
|
+
return !!active && active !== owner.body && container.contains(active);
|
|
1015
|
+
};
|
|
1016
|
+
const is_attended = () => {
|
|
1017
|
+
return is_focus_within() || pointer_over;
|
|
1016
1018
|
};
|
|
1017
1019
|
return {
|
|
1018
1020
|
is_attended,
|
|
1021
|
+
is_focus_within,
|
|
1019
1022
|
dispose: () => {
|
|
1020
1023
|
container.removeEventListener("pointerenter", on_enter);
|
|
1021
1024
|
container.removeEventListener("pointerleave", on_leave);
|
|
@@ -1707,6 +1710,7 @@ var DomSurface = class DomSurface {
|
|
|
1707
1710
|
this.svg_root = null;
|
|
1708
1711
|
this.teardown = [];
|
|
1709
1712
|
this.element_index = /* @__PURE__ */ new Map();
|
|
1713
|
+
this.rendered_doc_revision = -1;
|
|
1710
1714
|
this.last_pointer = {
|
|
1711
1715
|
x: 0,
|
|
1712
1716
|
y: 0
|
|
@@ -1731,6 +1735,7 @@ var DomSurface = class DomSurface {
|
|
|
1731
1735
|
this.container = options.container;
|
|
1732
1736
|
const container = this.container;
|
|
1733
1737
|
this.fit_on_attach = options.fit === true;
|
|
1738
|
+
this.clipboard_enabled = options.clipboard !== false;
|
|
1734
1739
|
this.attention = create_attention_tracker(container);
|
|
1735
1740
|
this.teardown.push(() => this.attention.dispose());
|
|
1736
1741
|
if (process.env.NODE_ENV !== "production" && container.children.length > 0) console.warn("@grida/svg-editor: surface container is not empty at attach time. Render chrome (toolbars, layer lists, inspectors) as siblings of the container, not children — otherwise clicks on those children will silently break. See README §Surface.");
|
|
@@ -1738,6 +1743,8 @@ var DomSurface = class DomSurface {
|
|
|
1738
1743
|
container.style.overflow = "hidden";
|
|
1739
1744
|
container.style.userSelect = "none";
|
|
1740
1745
|
container.style.webkitUserSelect = "none";
|
|
1746
|
+
container.tabIndex = -1;
|
|
1747
|
+
container.style.outline = "none";
|
|
1741
1748
|
const translate_options = () => {
|
|
1742
1749
|
const style = this.editor.style;
|
|
1743
1750
|
const zoom = this.camera.zoom || 1;
|
|
@@ -1753,7 +1760,9 @@ var DomSurface = class DomSurface {
|
|
|
1753
1760
|
open_preview: (label) => this.editor_internal().history.preview(label),
|
|
1754
1761
|
open_snap: (ids) => this.open_snap_session_for(ids),
|
|
1755
1762
|
options: translate_options,
|
|
1756
|
-
project_delta: (id, d) => this._geometry_provider?.world_delta_to_local(id, d) ?? d
|
|
1763
|
+
project_delta: (id, d) => this._geometry_provider?.world_delta_to_local(id, d) ?? d,
|
|
1764
|
+
set_selection: (ids) => this.editor.commands.select(ids),
|
|
1765
|
+
on_clone_commit: (record) => this.editor_internal().seed_duplication(record)
|
|
1757
1766
|
});
|
|
1758
1767
|
const resize_options = () => {
|
|
1759
1768
|
const style = this.editor.style;
|
|
@@ -1881,7 +1890,7 @@ var DomSurface = class DomSurface {
|
|
|
1881
1890
|
this.current_tool = editor.state.tool;
|
|
1882
1891
|
this.hud.setVectorSelectionMode(this.current_tool.type === "lasso" ? "lasso" : "marquee");
|
|
1883
1892
|
this.hud.setVectorBendMode(this.current_tool.type === "bend" ? "always" : "auto");
|
|
1884
|
-
this.
|
|
1893
|
+
this.flush_dom();
|
|
1885
1894
|
this.sync_surface_selection();
|
|
1886
1895
|
this.hud.setPixelGrid({
|
|
1887
1896
|
enabled: editor.style.pixel_grid,
|
|
@@ -1937,12 +1946,14 @@ var DomSurface = class DomSurface {
|
|
|
1937
1946
|
this.teardown.push(() => internal.set_content_edit_driver(null));
|
|
1938
1947
|
internal.set_computed_resolver({
|
|
1939
1948
|
computed_property: (id, name) => {
|
|
1949
|
+
this.flush_dom();
|
|
1940
1950
|
const el = this.element_index.get(id);
|
|
1941
1951
|
if (!el) return null;
|
|
1942
1952
|
const value = getComputedStyle(el).getPropertyValue(name);
|
|
1943
1953
|
return value === "" ? null : value;
|
|
1944
1954
|
},
|
|
1945
1955
|
computed_paint: (id, channel) => {
|
|
1956
|
+
this.flush_dom();
|
|
1946
1957
|
const el = this.element_index.get(id);
|
|
1947
1958
|
if (!el) return null;
|
|
1948
1959
|
const computed = getComputedStyle(el).getPropertyValue(channel);
|
|
@@ -1959,7 +1970,8 @@ var DomSurface = class DomSurface {
|
|
|
1959
1970
|
root: () => this.svg_root,
|
|
1960
1971
|
camera: () => this.camera,
|
|
1961
1972
|
container: () => this.container,
|
|
1962
|
-
pick_at_world: (p, allow_root) => this._pick_node_at_world(p, allow_root)
|
|
1973
|
+
pick_at_world: (p, allow_root) => this._pick_node_at_world(p, allow_root),
|
|
1974
|
+
flush: () => this.flush_dom()
|
|
1963
1975
|
}), {
|
|
1964
1976
|
subscribe_structure: (cb) => editor.subscribe_with_selector((s) => s.structure_version, () => cb()),
|
|
1965
1977
|
subscribe_geometry: (cb) => editor.subscribe_geometry(cb)
|
|
@@ -2141,6 +2153,25 @@ var DomSurface = class DomSurface {
|
|
|
2141
2153
|
detach_gestures() {
|
|
2142
2154
|
this.gestures._dispose();
|
|
2143
2155
|
}
|
|
2156
|
+
/**
|
|
2157
|
+
* Bring the live DOM up to date with the doc IR iff it is stale.
|
|
2158
|
+
*
|
|
2159
|
+
* Staleness contract: anything that reads the LIVE DOM as a proxy for
|
|
2160
|
+
* document state — the geometry driver (`getBBox` / `getCTM`), the
|
|
2161
|
+
* computed-style resolver — MUST call this first. Doc listeners (the
|
|
2162
|
+
* geometry channel, editor `subscribe`) fire synchronously inside the
|
|
2163
|
+
* mutation, BEFORE the surface's render listener has projected the new
|
|
2164
|
+
* attrs into the DOM; a read in that window returns the PREVIOUS
|
|
2165
|
+
* geometry, and through `MemoizedGeometryProvider` it would be cached as
|
|
2166
|
+
* if current — every later consumer (align, resize_to, snap) then plans
|
|
2167
|
+
* against one-mutation-stale bounds. Same model as CSS layout: reading
|
|
2168
|
+
* `offsetWidth` flushes pending layout; reading `bounds_of` flushes the
|
|
2169
|
+
* pending render.
|
|
2170
|
+
*/
|
|
2171
|
+
flush_dom() {
|
|
2172
|
+
if (this.rendered_doc_revision === this.editor._internal.doc.revision) return;
|
|
2173
|
+
this.render();
|
|
2174
|
+
}
|
|
2144
2175
|
render() {
|
|
2145
2176
|
if (this.text_edit) return;
|
|
2146
2177
|
const owner_doc = this.container.ownerDocument;
|
|
@@ -2167,6 +2198,7 @@ var DomSurface = class DomSurface {
|
|
|
2167
2198
|
for (let c = el.firstElementChild; c; c = c.nextElementSibling) if (c instanceof SVGElement) tag_walk(c);
|
|
2168
2199
|
};
|
|
2169
2200
|
tag_walk(new_svg);
|
|
2201
|
+
this.rendered_doc_revision = doc.revision;
|
|
2170
2202
|
}
|
|
2171
2203
|
sync_canvas_size() {
|
|
2172
2204
|
const cr = this.container.getBoundingClientRect();
|
|
@@ -2761,6 +2793,60 @@ var DomSurface = class DomSurface {
|
|
|
2761
2793
|
});
|
|
2762
2794
|
on(win, "blur", () => this.sync_modifiers(null));
|
|
2763
2795
|
on(this.container, "contextmenu", (e) => e.preventDefault());
|
|
2796
|
+
if (this.clipboard_enabled) {
|
|
2797
|
+
on(owner_doc, "copy", (e) => this.on_copy_or_cut(e, "copy"));
|
|
2798
|
+
on(owner_doc, "cut", (e) => this.on_copy_or_cut(e, "cut"));
|
|
2799
|
+
on(owner_doc, "paste", (e) => this.on_paste(e));
|
|
2800
|
+
}
|
|
2801
|
+
}
|
|
2802
|
+
/**
|
|
2803
|
+
* Gate for claiming a native clipboard gesture. Deliberately STRICTER
|
|
2804
|
+
* than the keyboard attention gate: focus-based only — pointer-over is
|
|
2805
|
+
* a sufficient signal for a keystroke (worst case: a stolen scroll) but
|
|
2806
|
+
* not for clipboard (worst case: destroying what the user believed they
|
|
2807
|
+
* copied, or routing a paste meant for a host text field into the
|
|
2808
|
+
* document). A user with text selected in a sibling panel and the
|
|
2809
|
+
* pointer idly over the canvas must get their text copy.
|
|
2810
|
+
*/
|
|
2811
|
+
claims_clipboard(kind) {
|
|
2812
|
+
if (this.text_edit) return false;
|
|
2813
|
+
if (this.editor.state.mode !== "select") return false;
|
|
2814
|
+
if (!this.attention.is_focus_within()) return false;
|
|
2815
|
+
if (require_model.is_text_input_focused()) return false;
|
|
2816
|
+
if (kind !== "paste") {
|
|
2817
|
+
const sel = this.container.ownerDocument.getSelection();
|
|
2818
|
+
if (sel && !sel.isCollapsed) return false;
|
|
2819
|
+
}
|
|
2820
|
+
return true;
|
|
2821
|
+
}
|
|
2822
|
+
/**
|
|
2823
|
+
* Act-then-claim: an empty selection returns without `preventDefault()`,
|
|
2824
|
+
* leaving the browser default (and the OS clipboard) untouched. The
|
|
2825
|
+
* buffer-only `_internal.clipboard` variants are used here — the event's
|
|
2826
|
+
* DataTransfer is this gesture's ONE external channel (the public
|
|
2827
|
+
* commands would additionally write the provider; one gesture, one
|
|
2828
|
+
* external write — FRD §Transport).
|
|
2829
|
+
*/
|
|
2830
|
+
on_copy_or_cut(e, kind) {
|
|
2831
|
+
if (!this.claims_clipboard(kind)) return;
|
|
2832
|
+
if (!e.clipboardData) return;
|
|
2833
|
+
const internal = this.editor_internal();
|
|
2834
|
+
const payload = kind === "copy" ? internal.clipboard.copy() : internal.clipboard.cut();
|
|
2835
|
+
if (payload === null) return;
|
|
2836
|
+
e.clipboardData.setData("text/plain", payload);
|
|
2837
|
+
e.preventDefault();
|
|
2838
|
+
}
|
|
2839
|
+
/**
|
|
2840
|
+
* Claim-then-act (mirrors the keydown claim doctrine: swallow when the
|
|
2841
|
+
* gesture is aimed at the editor, not just when a handler consumed):
|
|
2842
|
+
* a refused paste — junk text — still claims; the suppressed default is
|
|
2843
|
+
* a no-op on a div anyway.
|
|
2844
|
+
*/
|
|
2845
|
+
on_paste(e) {
|
|
2846
|
+
if (!this.claims_clipboard("paste")) return;
|
|
2847
|
+
e.preventDefault();
|
|
2848
|
+
const text = e.clipboardData?.getData("text/plain");
|
|
2849
|
+
if (text) this.editor.commands.paste(text);
|
|
2764
2850
|
}
|
|
2765
2851
|
/**
|
|
2766
2852
|
* Master signal for modifier-driven UX consumers (measurement, future
|
|
@@ -2782,7 +2868,7 @@ var DomSurface = class DomSurface {
|
|
|
2782
2868
|
kind: "modifiers",
|
|
2783
2869
|
mods: next
|
|
2784
2870
|
});
|
|
2785
|
-
if (prev.shift !== next.shift && this.translate_orchestrator.has_active_session()) this.translate_orchestrator.redrive_modifiers(this.current_translate_modifiers());
|
|
2871
|
+
if ((prev.shift !== next.shift || prev.alt !== next.alt) && this.translate_orchestrator.has_active_session()) this.translate_orchestrator.redrive_modifiers(this.current_translate_modifiers());
|
|
2786
2872
|
if (prev.shift !== next.shift && this.resize_orchestrator.has_active_session()) this.resize_orchestrator.redrive_modifiers(this.current_resize_modifiers());
|
|
2787
2873
|
if (prev.shift !== next.shift && this.rotate_orchestrator.has_active_session()) this.rotate_orchestrator.redrive_modifiers(this.current_rotate_modifiers());
|
|
2788
2874
|
this.redraw();
|
|
@@ -2803,6 +2889,7 @@ var DomSurface = class DomSurface {
|
|
|
2803
2889
|
} else if (kind === "pointer_up") this.text_edit.pointerUp();
|
|
2804
2890
|
return;
|
|
2805
2891
|
}
|
|
2892
|
+
if (kind === "pointer_down") this.container.focus({ preventScroll: true });
|
|
2806
2893
|
const cr = this.container.getBoundingClientRect();
|
|
2807
2894
|
const x = e.clientX - cr.left;
|
|
2808
2895
|
const y = e.clientY - cr.top;
|
|
@@ -3119,13 +3206,15 @@ var DomSurface = class DomSurface {
|
|
|
3119
3206
|
});
|
|
3120
3207
|
if (intent.phase === "commit") this.request_redraw();
|
|
3121
3208
|
}
|
|
3122
|
-
/** Snapshot of HUD modifier state mapped to
|
|
3209
|
+
/** Snapshot of HUD modifier state mapped to the orchestrator's `GestureModifiers`.
|
|
3123
3210
|
* Pull-at-consume: HUD is the canonical store (see `sync_modifiers`),
|
|
3124
3211
|
* read live so mid-drag Shift press/release reflects on the next pass. */
|
|
3125
3212
|
current_translate_modifiers() {
|
|
3213
|
+
const mods = this.hud.modifiers();
|
|
3126
3214
|
return {
|
|
3127
|
-
axis_lock:
|
|
3128
|
-
force_disable_snap: false
|
|
3215
|
+
axis_lock: mods.shift ? "by_dominance" : "off",
|
|
3216
|
+
force_disable_snap: false,
|
|
3217
|
+
clone: mods.alt
|
|
3129
3218
|
};
|
|
3130
3219
|
}
|
|
3131
3220
|
/** Snapshot of HUD modifier state mapped to `ResizeModifiers`. Same
|
|
@@ -4464,6 +4553,7 @@ var SvgGeometryDriver = class {
|
|
|
4464
4553
|
this.accessors = accessors;
|
|
4465
4554
|
}
|
|
4466
4555
|
bounds_of(id) {
|
|
4556
|
+
this.accessors.flush();
|
|
4467
4557
|
const el = this.accessors.element_for(id);
|
|
4468
4558
|
if (!el) return null;
|
|
4469
4559
|
if (el instanceof SVGSVGElement) return svg_viewport_bounds(el);
|
|
@@ -4515,6 +4605,7 @@ var SvgGeometryDriver = class {
|
|
|
4515
4605
|
return out;
|
|
4516
4606
|
}
|
|
4517
4607
|
nodes_in_rect(rect) {
|
|
4608
|
+
this.accessors.flush();
|
|
4518
4609
|
const root = this.accessors.root();
|
|
4519
4610
|
if (!root) return [];
|
|
4520
4611
|
const hits = [];
|
|
@@ -4527,6 +4618,7 @@ var SvgGeometryDriver = class {
|
|
|
4527
4618
|
return hits;
|
|
4528
4619
|
}
|
|
4529
4620
|
node_at_point(p) {
|
|
4621
|
+
this.accessors.flush();
|
|
4530
4622
|
return this.accessors.pick_at_world(p, true);
|
|
4531
4623
|
}
|
|
4532
4624
|
/** World→local delta projection. The frame an element's position is
|
|
@@ -4542,6 +4634,7 @@ var SvgGeometryDriver = class {
|
|
|
4542
4634
|
* the local delta. Identity (→ delta unchanged) for flat frames,
|
|
4543
4635
|
* top-level nodes, and any degenerate / unavailable matrix. */
|
|
4544
4636
|
world_delta_to_local(id, delta) {
|
|
4637
|
+
this.accessors.flush();
|
|
4545
4638
|
const parent = this.accessors.element_for(id)?.parentNode;
|
|
4546
4639
|
const root = this.accessors.root();
|
|
4547
4640
|
if (!(parent instanceof SVGGraphicsElement) || !root) return delta;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { S as is_text_input_focused, a as paint, c as hit_shape_svg, d as NudgeDwellWatcher, f as TranslateOrchestrator, h as transform, i as TOOL_CURSOR, l as RotateOrchestrator, m as group, n as insertions, o as ResizeOrchestrator, s as resize_pipeline, t as PathModel, x as array_shallow_equal } from "./model-DU0GOMwM.mjs";
|
|
2
2
|
import cmath from "@grida/cmath";
|
|
3
3
|
import { svg_parse } from "@grida/svg/parse";
|
|
4
4
|
import { SVGShapes } from "@grida/svg/pathdata";
|
|
@@ -1005,15 +1005,18 @@ function create_attention_tracker(container) {
|
|
|
1005
1005
|
};
|
|
1006
1006
|
container.addEventListener("pointerenter", on_enter);
|
|
1007
1007
|
container.addEventListener("pointerleave", on_leave);
|
|
1008
|
-
const
|
|
1008
|
+
const is_focus_within = () => {
|
|
1009
1009
|
const owner = container.ownerDocument;
|
|
1010
|
-
if (!owner) return
|
|
1010
|
+
if (!owner) return false;
|
|
1011
1011
|
const active = owner.activeElement;
|
|
1012
|
-
|
|
1013
|
-
|
|
1012
|
+
return !!active && active !== owner.body && container.contains(active);
|
|
1013
|
+
};
|
|
1014
|
+
const is_attended = () => {
|
|
1015
|
+
return is_focus_within() || pointer_over;
|
|
1014
1016
|
};
|
|
1015
1017
|
return {
|
|
1016
1018
|
is_attended,
|
|
1019
|
+
is_focus_within,
|
|
1017
1020
|
dispose: () => {
|
|
1018
1021
|
container.removeEventListener("pointerenter", on_enter);
|
|
1019
1022
|
container.removeEventListener("pointerleave", on_leave);
|
|
@@ -1705,6 +1708,7 @@ var DomSurface = class DomSurface {
|
|
|
1705
1708
|
this.svg_root = null;
|
|
1706
1709
|
this.teardown = [];
|
|
1707
1710
|
this.element_index = /* @__PURE__ */ new Map();
|
|
1711
|
+
this.rendered_doc_revision = -1;
|
|
1708
1712
|
this.last_pointer = {
|
|
1709
1713
|
x: 0,
|
|
1710
1714
|
y: 0
|
|
@@ -1729,6 +1733,7 @@ var DomSurface = class DomSurface {
|
|
|
1729
1733
|
this.container = options.container;
|
|
1730
1734
|
const container = this.container;
|
|
1731
1735
|
this.fit_on_attach = options.fit === true;
|
|
1736
|
+
this.clipboard_enabled = options.clipboard !== false;
|
|
1732
1737
|
this.attention = create_attention_tracker(container);
|
|
1733
1738
|
this.teardown.push(() => this.attention.dispose());
|
|
1734
1739
|
if (process.env.NODE_ENV !== "production" && container.children.length > 0) console.warn("@grida/svg-editor: surface container is not empty at attach time. Render chrome (toolbars, layer lists, inspectors) as siblings of the container, not children — otherwise clicks on those children will silently break. See README §Surface.");
|
|
@@ -1736,6 +1741,8 @@ var DomSurface = class DomSurface {
|
|
|
1736
1741
|
container.style.overflow = "hidden";
|
|
1737
1742
|
container.style.userSelect = "none";
|
|
1738
1743
|
container.style.webkitUserSelect = "none";
|
|
1744
|
+
container.tabIndex = -1;
|
|
1745
|
+
container.style.outline = "none";
|
|
1739
1746
|
const translate_options = () => {
|
|
1740
1747
|
const style = this.editor.style;
|
|
1741
1748
|
const zoom = this.camera.zoom || 1;
|
|
@@ -1751,7 +1758,9 @@ var DomSurface = class DomSurface {
|
|
|
1751
1758
|
open_preview: (label) => this.editor_internal().history.preview(label),
|
|
1752
1759
|
open_snap: (ids) => this.open_snap_session_for(ids),
|
|
1753
1760
|
options: translate_options,
|
|
1754
|
-
project_delta: (id, d) => this._geometry_provider?.world_delta_to_local(id, d) ?? d
|
|
1761
|
+
project_delta: (id, d) => this._geometry_provider?.world_delta_to_local(id, d) ?? d,
|
|
1762
|
+
set_selection: (ids) => this.editor.commands.select(ids),
|
|
1763
|
+
on_clone_commit: (record) => this.editor_internal().seed_duplication(record)
|
|
1755
1764
|
});
|
|
1756
1765
|
const resize_options = () => {
|
|
1757
1766
|
const style = this.editor.style;
|
|
@@ -1879,7 +1888,7 @@ var DomSurface = class DomSurface {
|
|
|
1879
1888
|
this.current_tool = editor.state.tool;
|
|
1880
1889
|
this.hud.setVectorSelectionMode(this.current_tool.type === "lasso" ? "lasso" : "marquee");
|
|
1881
1890
|
this.hud.setVectorBendMode(this.current_tool.type === "bend" ? "always" : "auto");
|
|
1882
|
-
this.
|
|
1891
|
+
this.flush_dom();
|
|
1883
1892
|
this.sync_surface_selection();
|
|
1884
1893
|
this.hud.setPixelGrid({
|
|
1885
1894
|
enabled: editor.style.pixel_grid,
|
|
@@ -1935,12 +1944,14 @@ var DomSurface = class DomSurface {
|
|
|
1935
1944
|
this.teardown.push(() => internal.set_content_edit_driver(null));
|
|
1936
1945
|
internal.set_computed_resolver({
|
|
1937
1946
|
computed_property: (id, name) => {
|
|
1947
|
+
this.flush_dom();
|
|
1938
1948
|
const el = this.element_index.get(id);
|
|
1939
1949
|
if (!el) return null;
|
|
1940
1950
|
const value = getComputedStyle(el).getPropertyValue(name);
|
|
1941
1951
|
return value === "" ? null : value;
|
|
1942
1952
|
},
|
|
1943
1953
|
computed_paint: (id, channel) => {
|
|
1954
|
+
this.flush_dom();
|
|
1944
1955
|
const el = this.element_index.get(id);
|
|
1945
1956
|
if (!el) return null;
|
|
1946
1957
|
const computed = getComputedStyle(el).getPropertyValue(channel);
|
|
@@ -1957,7 +1968,8 @@ var DomSurface = class DomSurface {
|
|
|
1957
1968
|
root: () => this.svg_root,
|
|
1958
1969
|
camera: () => this.camera,
|
|
1959
1970
|
container: () => this.container,
|
|
1960
|
-
pick_at_world: (p, allow_root) => this._pick_node_at_world(p, allow_root)
|
|
1971
|
+
pick_at_world: (p, allow_root) => this._pick_node_at_world(p, allow_root),
|
|
1972
|
+
flush: () => this.flush_dom()
|
|
1961
1973
|
}), {
|
|
1962
1974
|
subscribe_structure: (cb) => editor.subscribe_with_selector((s) => s.structure_version, () => cb()),
|
|
1963
1975
|
subscribe_geometry: (cb) => editor.subscribe_geometry(cb)
|
|
@@ -2139,6 +2151,25 @@ var DomSurface = class DomSurface {
|
|
|
2139
2151
|
detach_gestures() {
|
|
2140
2152
|
this.gestures._dispose();
|
|
2141
2153
|
}
|
|
2154
|
+
/**
|
|
2155
|
+
* Bring the live DOM up to date with the doc IR iff it is stale.
|
|
2156
|
+
*
|
|
2157
|
+
* Staleness contract: anything that reads the LIVE DOM as a proxy for
|
|
2158
|
+
* document state — the geometry driver (`getBBox` / `getCTM`), the
|
|
2159
|
+
* computed-style resolver — MUST call this first. Doc listeners (the
|
|
2160
|
+
* geometry channel, editor `subscribe`) fire synchronously inside the
|
|
2161
|
+
* mutation, BEFORE the surface's render listener has projected the new
|
|
2162
|
+
* attrs into the DOM; a read in that window returns the PREVIOUS
|
|
2163
|
+
* geometry, and through `MemoizedGeometryProvider` it would be cached as
|
|
2164
|
+
* if current — every later consumer (align, resize_to, snap) then plans
|
|
2165
|
+
* against one-mutation-stale bounds. Same model as CSS layout: reading
|
|
2166
|
+
* `offsetWidth` flushes pending layout; reading `bounds_of` flushes the
|
|
2167
|
+
* pending render.
|
|
2168
|
+
*/
|
|
2169
|
+
flush_dom() {
|
|
2170
|
+
if (this.rendered_doc_revision === this.editor._internal.doc.revision) return;
|
|
2171
|
+
this.render();
|
|
2172
|
+
}
|
|
2142
2173
|
render() {
|
|
2143
2174
|
if (this.text_edit) return;
|
|
2144
2175
|
const owner_doc = this.container.ownerDocument;
|
|
@@ -2165,6 +2196,7 @@ var DomSurface = class DomSurface {
|
|
|
2165
2196
|
for (let c = el.firstElementChild; c; c = c.nextElementSibling) if (c instanceof SVGElement) tag_walk(c);
|
|
2166
2197
|
};
|
|
2167
2198
|
tag_walk(new_svg);
|
|
2199
|
+
this.rendered_doc_revision = doc.revision;
|
|
2168
2200
|
}
|
|
2169
2201
|
sync_canvas_size() {
|
|
2170
2202
|
const cr = this.container.getBoundingClientRect();
|
|
@@ -2759,6 +2791,60 @@ var DomSurface = class DomSurface {
|
|
|
2759
2791
|
});
|
|
2760
2792
|
on(win, "blur", () => this.sync_modifiers(null));
|
|
2761
2793
|
on(this.container, "contextmenu", (e) => e.preventDefault());
|
|
2794
|
+
if (this.clipboard_enabled) {
|
|
2795
|
+
on(owner_doc, "copy", (e) => this.on_copy_or_cut(e, "copy"));
|
|
2796
|
+
on(owner_doc, "cut", (e) => this.on_copy_or_cut(e, "cut"));
|
|
2797
|
+
on(owner_doc, "paste", (e) => this.on_paste(e));
|
|
2798
|
+
}
|
|
2799
|
+
}
|
|
2800
|
+
/**
|
|
2801
|
+
* Gate for claiming a native clipboard gesture. Deliberately STRICTER
|
|
2802
|
+
* than the keyboard attention gate: focus-based only — pointer-over is
|
|
2803
|
+
* a sufficient signal for a keystroke (worst case: a stolen scroll) but
|
|
2804
|
+
* not for clipboard (worst case: destroying what the user believed they
|
|
2805
|
+
* copied, or routing a paste meant for a host text field into the
|
|
2806
|
+
* document). A user with text selected in a sibling panel and the
|
|
2807
|
+
* pointer idly over the canvas must get their text copy.
|
|
2808
|
+
*/
|
|
2809
|
+
claims_clipboard(kind) {
|
|
2810
|
+
if (this.text_edit) return false;
|
|
2811
|
+
if (this.editor.state.mode !== "select") return false;
|
|
2812
|
+
if (!this.attention.is_focus_within()) return false;
|
|
2813
|
+
if (is_text_input_focused()) return false;
|
|
2814
|
+
if (kind !== "paste") {
|
|
2815
|
+
const sel = this.container.ownerDocument.getSelection();
|
|
2816
|
+
if (sel && !sel.isCollapsed) return false;
|
|
2817
|
+
}
|
|
2818
|
+
return true;
|
|
2819
|
+
}
|
|
2820
|
+
/**
|
|
2821
|
+
* Act-then-claim: an empty selection returns without `preventDefault()`,
|
|
2822
|
+
* leaving the browser default (and the OS clipboard) untouched. The
|
|
2823
|
+
* buffer-only `_internal.clipboard` variants are used here — the event's
|
|
2824
|
+
* DataTransfer is this gesture's ONE external channel (the public
|
|
2825
|
+
* commands would additionally write the provider; one gesture, one
|
|
2826
|
+
* external write — FRD §Transport).
|
|
2827
|
+
*/
|
|
2828
|
+
on_copy_or_cut(e, kind) {
|
|
2829
|
+
if (!this.claims_clipboard(kind)) return;
|
|
2830
|
+
if (!e.clipboardData) return;
|
|
2831
|
+
const internal = this.editor_internal();
|
|
2832
|
+
const payload = kind === "copy" ? internal.clipboard.copy() : internal.clipboard.cut();
|
|
2833
|
+
if (payload === null) return;
|
|
2834
|
+
e.clipboardData.setData("text/plain", payload);
|
|
2835
|
+
e.preventDefault();
|
|
2836
|
+
}
|
|
2837
|
+
/**
|
|
2838
|
+
* Claim-then-act (mirrors the keydown claim doctrine: swallow when the
|
|
2839
|
+
* gesture is aimed at the editor, not just when a handler consumed):
|
|
2840
|
+
* a refused paste — junk text — still claims; the suppressed default is
|
|
2841
|
+
* a no-op on a div anyway.
|
|
2842
|
+
*/
|
|
2843
|
+
on_paste(e) {
|
|
2844
|
+
if (!this.claims_clipboard("paste")) return;
|
|
2845
|
+
e.preventDefault();
|
|
2846
|
+
const text = e.clipboardData?.getData("text/plain");
|
|
2847
|
+
if (text) this.editor.commands.paste(text);
|
|
2762
2848
|
}
|
|
2763
2849
|
/**
|
|
2764
2850
|
* Master signal for modifier-driven UX consumers (measurement, future
|
|
@@ -2780,7 +2866,7 @@ var DomSurface = class DomSurface {
|
|
|
2780
2866
|
kind: "modifiers",
|
|
2781
2867
|
mods: next
|
|
2782
2868
|
});
|
|
2783
|
-
if (prev.shift !== next.shift && this.translate_orchestrator.has_active_session()) this.translate_orchestrator.redrive_modifiers(this.current_translate_modifiers());
|
|
2869
|
+
if ((prev.shift !== next.shift || prev.alt !== next.alt) && this.translate_orchestrator.has_active_session()) this.translate_orchestrator.redrive_modifiers(this.current_translate_modifiers());
|
|
2784
2870
|
if (prev.shift !== next.shift && this.resize_orchestrator.has_active_session()) this.resize_orchestrator.redrive_modifiers(this.current_resize_modifiers());
|
|
2785
2871
|
if (prev.shift !== next.shift && this.rotate_orchestrator.has_active_session()) this.rotate_orchestrator.redrive_modifiers(this.current_rotate_modifiers());
|
|
2786
2872
|
this.redraw();
|
|
@@ -2801,6 +2887,7 @@ var DomSurface = class DomSurface {
|
|
|
2801
2887
|
} else if (kind === "pointer_up") this.text_edit.pointerUp();
|
|
2802
2888
|
return;
|
|
2803
2889
|
}
|
|
2890
|
+
if (kind === "pointer_down") this.container.focus({ preventScroll: true });
|
|
2804
2891
|
const cr = this.container.getBoundingClientRect();
|
|
2805
2892
|
const x = e.clientX - cr.left;
|
|
2806
2893
|
const y = e.clientY - cr.top;
|
|
@@ -3117,13 +3204,15 @@ var DomSurface = class DomSurface {
|
|
|
3117
3204
|
});
|
|
3118
3205
|
if (intent.phase === "commit") this.request_redraw();
|
|
3119
3206
|
}
|
|
3120
|
-
/** Snapshot of HUD modifier state mapped to
|
|
3207
|
+
/** Snapshot of HUD modifier state mapped to the orchestrator's `GestureModifiers`.
|
|
3121
3208
|
* Pull-at-consume: HUD is the canonical store (see `sync_modifiers`),
|
|
3122
3209
|
* read live so mid-drag Shift press/release reflects on the next pass. */
|
|
3123
3210
|
current_translate_modifiers() {
|
|
3211
|
+
const mods = this.hud.modifiers();
|
|
3124
3212
|
return {
|
|
3125
|
-
axis_lock:
|
|
3126
|
-
force_disable_snap: false
|
|
3213
|
+
axis_lock: mods.shift ? "by_dominance" : "off",
|
|
3214
|
+
force_disable_snap: false,
|
|
3215
|
+
clone: mods.alt
|
|
3127
3216
|
};
|
|
3128
3217
|
}
|
|
3129
3218
|
/** Snapshot of HUD modifier state mapped to `ResizeModifiers`. Same
|
|
@@ -4462,6 +4551,7 @@ var SvgGeometryDriver = class {
|
|
|
4462
4551
|
this.accessors = accessors;
|
|
4463
4552
|
}
|
|
4464
4553
|
bounds_of(id) {
|
|
4554
|
+
this.accessors.flush();
|
|
4465
4555
|
const el = this.accessors.element_for(id);
|
|
4466
4556
|
if (!el) return null;
|
|
4467
4557
|
if (el instanceof SVGSVGElement) return svg_viewport_bounds(el);
|
|
@@ -4513,6 +4603,7 @@ var SvgGeometryDriver = class {
|
|
|
4513
4603
|
return out;
|
|
4514
4604
|
}
|
|
4515
4605
|
nodes_in_rect(rect) {
|
|
4606
|
+
this.accessors.flush();
|
|
4516
4607
|
const root = this.accessors.root();
|
|
4517
4608
|
if (!root) return [];
|
|
4518
4609
|
const hits = [];
|
|
@@ -4525,6 +4616,7 @@ var SvgGeometryDriver = class {
|
|
|
4525
4616
|
return hits;
|
|
4526
4617
|
}
|
|
4527
4618
|
node_at_point(p) {
|
|
4619
|
+
this.accessors.flush();
|
|
4528
4620
|
return this.accessors.pick_at_world(p, true);
|
|
4529
4621
|
}
|
|
4530
4622
|
/** World→local delta projection. The frame an element's position is
|
|
@@ -4540,6 +4632,7 @@ var SvgGeometryDriver = class {
|
|
|
4540
4632
|
* the local delta. Identity (→ delta unchanged) for flat frames,
|
|
4541
4633
|
* top-level nodes, and any degenerate / unavailable matrix. */
|
|
4542
4634
|
world_delta_to_local(id, delta) {
|
|
4635
|
+
this.accessors.flush();
|
|
4543
4636
|
const parent = this.accessors.element_for(id)?.parentNode;
|
|
4544
4637
|
const root = this.accessors.root();
|
|
4545
4638
|
if (!(parent instanceof SVGGraphicsElement) || !root) return delta;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as SvgEditor, p as Gestures, s as SurfaceHandle, w as Camera } from "./editor-
|
|
1
|
+
import { c as SvgEditor, p as Gestures, s as SurfaceHandle, w as Camera } from "./editor-KqpIW1qm.mjs";
|
|
2
2
|
import cmath from "@grida/cmath";
|
|
3
3
|
import { guide } from "@grida/cmath/_snap";
|
|
4
4
|
|
|
@@ -50,6 +50,18 @@ type DomSurfaceOptions = {
|
|
|
50
50
|
* carte via `handle.gestures.bind(...)`.
|
|
51
51
|
*/
|
|
52
52
|
gestures?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Wire native ClipboardEvent transport — `copy` / `cut` / `paste`
|
|
55
|
+
* listeners on the owner document, gated by the clipboard attention
|
|
56
|
+
* discipline. Default `true`. Pass `false` to route ALL clipboard
|
|
57
|
+
* traffic through the `ClipboardProvider` seam instead (the
|
|
58
|
+
* configuration under which a host's paste-time screening governs
|
|
59
|
+
* every path) — see docs/wg/feat-svg-editor/clipboard.md §Transport
|
|
60
|
+
* "Host control over the native path". Focus management (the container
|
|
61
|
+
* focusing on pointerdown) stays either way — it is a general canvas
|
|
62
|
+
* mitigation, not a clipboard feature.
|
|
63
|
+
*/
|
|
64
|
+
clipboard?: boolean;
|
|
53
65
|
/**
|
|
54
66
|
* Auto-fit the document into the viewport on initial attach. Default
|
|
55
67
|
* `false`. Mirrors Excalidraw's `initialData.scrollToContent`.
|
package/dist/dom.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { C as BoundsResolver, E as CameraOptions, T as CameraConstraints, d as GestureContext, f as GestureId, g as MemoizedGeometryProvider, h as GeometrySignals, i as DomComputedResolver, m as GeometryProvider, p as Gestures, r as DomComputedPaint, u as GestureBinding, w as Camera } from "./editor-
|
|
2
|
-
import { a as inverse_project_rect, c as DEFAULT_SNAP_OPTIONS, i as install_font_load_geometry_bump, l as SnapOptions, n as DomSurfaceOptions, o as project_delta_inverse_ctm, r as attach_dom_surface, s as project_point_through_ctm, t as DomSurfaceHandle } from "./dom-
|
|
1
|
+
import { C as BoundsResolver, E as CameraOptions, T as CameraConstraints, d as GestureContext, f as GestureId, g as MemoizedGeometryProvider, h as GeometrySignals, i as DomComputedResolver, m as GeometryProvider, p as Gestures, r as DomComputedPaint, u as GestureBinding, w as Camera } from "./editor-KqpIW1qm.mjs";
|
|
2
|
+
import { a as inverse_project_rect, c as DEFAULT_SNAP_OPTIONS, i as install_font_load_geometry_bump, l as SnapOptions, n as DomSurfaceOptions, o as project_delta_inverse_ctm, r as attach_dom_surface, s as project_point_through_ctm, t as DomSurfaceHandle } from "./dom-TctdgRnn.mjs";
|
|
3
3
|
export { type BoundsResolver, Camera, type CameraConstraints, type CameraOptions, DEFAULT_SNAP_OPTIONS, type DomComputedPaint, type DomComputedResolver, DomSurfaceHandle, DomSurfaceOptions, type GeometryProvider, type GeometrySignals, type GestureBinding, type GestureContext, type GestureId, Gestures, MemoizedGeometryProvider, type SnapOptions, attach_dom_surface, install_font_load_geometry_bump, inverse_project_rect, project_delta_inverse_ctm, project_point_through_ctm };
|
package/dist/dom.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { C as BoundsResolver, E as CameraOptions, T as CameraConstraints, d as GestureContext, f as GestureId, g as MemoizedGeometryProvider, h as GeometrySignals, i as DomComputedResolver, m as GeometryProvider, p as Gestures, r as DomComputedPaint, u as GestureBinding, w as Camera } from "./editor-
|
|
2
|
-
import { a as inverse_project_rect, c as DEFAULT_SNAP_OPTIONS, i as install_font_load_geometry_bump, l as SnapOptions, n as DomSurfaceOptions, o as project_delta_inverse_ctm, r as attach_dom_surface, s as project_point_through_ctm, t as DomSurfaceHandle } from "./dom-
|
|
1
|
+
import { C as BoundsResolver, E as CameraOptions, T as CameraConstraints, d as GestureContext, f as GestureId, g as MemoizedGeometryProvider, h as GeometrySignals, i as DomComputedResolver, m as GeometryProvider, p as Gestures, r as DomComputedPaint, u as GestureBinding, w as Camera } from "./editor-BSxTUsW_.js";
|
|
2
|
+
import { a as inverse_project_rect, c as DEFAULT_SNAP_OPTIONS, i as install_font_load_geometry_bump, l as SnapOptions, n as DomSurfaceOptions, o as project_delta_inverse_ctm, r as attach_dom_surface, s as project_point_through_ctm, t as DomSurfaceHandle } from "./dom-BMzX1CXZ.js";
|
|
3
3
|
export { type BoundsResolver, Camera, type CameraConstraints, type CameraOptions, DEFAULT_SNAP_OPTIONS, type DomComputedPaint, type DomComputedResolver, DomSurfaceHandle, DomSurfaceOptions, type GeometryProvider, type GeometrySignals, type GestureBinding, type GestureContext, type GestureId, Gestures, MemoizedGeometryProvider, type SnapOptions, attach_dom_surface, install_font_load_geometry_bump, inverse_project_rect, project_delta_inverse_ctm, project_point_through_ctm };
|
package/dist/dom.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_dom = require("./dom-
|
|
2
|
+
const require_dom = require("./dom-DKQ4Vt3z.js");
|
|
3
3
|
exports.Camera = require_dom.Camera;
|
|
4
4
|
exports.DEFAULT_SNAP_OPTIONS = require_dom.DEFAULT_SNAP_OPTIONS;
|
|
5
5
|
exports.Gestures = require_dom.Gestures;
|
package/dist/dom.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as project_point_through_ctm, c as MemoizedGeometryProvider, i as project_delta_inverse_ctm, l as Camera, n as install_font_load_geometry_bump, o as Gestures, r as inverse_project_rect, s as DEFAULT_SNAP_OPTIONS, t as attach_dom_surface } from "./dom-
|
|
1
|
+
import { a as project_point_through_ctm, c as MemoizedGeometryProvider, i as project_delta_inverse_ctm, l as Camera, n as install_font_load_geometry_bump, o as Gestures, r as inverse_project_rect, s as DEFAULT_SNAP_OPTIONS, t as attach_dom_surface } from "./dom-OP-kmK8k.mjs";
|
|
2
2
|
export { Camera, DEFAULT_SNAP_OPTIONS, Gestures, MemoizedGeometryProvider, attach_dom_surface, install_font_load_geometry_bump, inverse_project_rect, project_delta_inverse_ctm, project_point_through_ctm };
|