@remotion/studio 4.0.517 → 4.0.518
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/components/AssetSelector.js +62 -21
- package/dist/components/AssetSelectorItem.d.ts +2 -1
- package/dist/components/AssetSelectorItem.js +41 -10
- package/dist/components/CaptionTextEditor.js +32 -8
- package/dist/components/CompositionContextButton.js +2 -1
- package/dist/components/CompositionSelector.js +1 -1
- package/dist/components/EditorContent.js +6 -3
- package/dist/components/ElementInstallConfirmation.d.ts +5 -0
- package/dist/components/ElementInstallConfirmation.js +25 -1
- package/dist/components/ElementLibraryModal.js +3 -1
- package/dist/components/InlineCaptionInspector.js +13 -2
- package/dist/components/Modals.js +49 -0
- package/dist/components/PlaybackRateSelector.js +2 -5
- package/dist/components/QuickSwitcher/ExplorerQuickSwitcherTrigger.d.ts +2 -0
- package/dist/components/QuickSwitcher/ExplorerQuickSwitcherTrigger.js +28 -8
- package/dist/components/SelectedOutlineKeyboardControls.d.ts +2 -2
- package/dist/components/SelectedOutlineOverlay.d.ts +1 -3
- package/dist/components/SelectedOutlineOverlay.js +21 -17
- package/dist/components/SelectedOutlineRenderer.d.ts +1 -1
- package/dist/components/SelectedOutlineRenderer.js +9 -78
- package/dist/components/SidebarRenderButton.js +2 -1
- package/dist/components/WebMcp.d.ts +2 -0
- package/dist/components/WebMcp.js +945 -0
- package/dist/components/composition-menu-items.js +26 -0
- package/dist/components/selected-outline-geometry.d.ts +2 -21
- package/dist/components/selected-outline-geometry.js +5 -16
- package/dist/components/selected-outline-measurement.d.ts +1 -29
- package/dist/components/selected-outline-measurement.js +1 -231
- package/dist/components/selected-outline-types.d.ts +2 -15
- package/dist/components/selected-outline-uv.js +3 -106
- package/dist/esm/{chunk-gzqm3g2m.js → chunk-7prjt5n5.js} +4782 -5611
- package/dist/esm/internals.mjs +4782 -5611
- package/dist/esm/previewEntry.mjs +4790 -5619
- package/dist/esm/renderEntry.mjs +1 -1
- package/dist/helpers/create-folder-tree.js +16 -1
- package/dist/helpers/format-file-location.d.ts +8 -0
- package/dist/helpers/format-file-location.js +14 -3
- package/dist/helpers/get-timeline-max-zoom.d.ts +8 -0
- package/dist/helpers/get-timeline-max-zoom.js +17 -6
- package/dist/helpers/hoverable.d.ts +1 -0
- package/dist/helpers/hoverable.js +4 -1
- package/dist/icons/enter.d.ts +4 -0
- package/dist/icons/enter.js +10 -0
- package/dist/state/playbackrate.d.ts +1 -0
- package/dist/state/playbackrate.js +4 -1
- package/package.json +14 -14
- package/dist/components/selected-outline-order.d.ts +0 -12
- package/dist/components/selected-outline-order.js +0 -251
- package/dist/helpers/get-box-quads-polyfill-internals.d.ts +0 -82
- package/dist/helpers/get-box-quads-polyfill-internals.js +0 -2403
- package/dist/helpers/get-box-quads-ponyfill.d.ts +0 -10
- package/dist/helpers/get-box-quads-ponyfill.js +0 -23
package/dist/esm/renderEntry.mjs
CHANGED
|
@@ -213,7 +213,7 @@ var renderContent = (Root) => {
|
|
|
213
213
|
renderToDOM(/* @__PURE__ */ jsx("div", {
|
|
214
214
|
children: /* @__PURE__ */ jsx(DelayedSpinner, {})
|
|
215
215
|
}));
|
|
216
|
-
import("./chunk-
|
|
216
|
+
import("./chunk-7prjt5n5.js").then(({ StudioInternals }) => {
|
|
217
217
|
window.remotion_isStudio = true;
|
|
218
218
|
window.remotion_isReadOnlyStudio = true;
|
|
219
219
|
window.remotion_inputProps = "{}";
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createFolderTree = exports.getKeysToExpand = exports.splitParentIntoNameAndParent = exports.buildAssetFolderStructure = void 0;
|
|
4
4
|
const persist_open_folders_1 = require("./persist-open-folders");
|
|
5
|
+
const sort_by_nonce_history_1 = require("./sort-by-nonce-history");
|
|
5
6
|
const buildAssetFolderStructure = (files, parentFolderName, foldersExpanded) => {
|
|
6
7
|
const notInFolder = files.filter((f) => !f.name.includes('/'));
|
|
7
8
|
const inFolder = files.filter((f) => f.name.includes('/'));
|
|
@@ -152,6 +153,20 @@ const createFolderTree = (comps, folders, foldersExpanded) => {
|
|
|
152
153
|
const list = findItemListToPush(items, item.folderName, item.parentFolderName);
|
|
153
154
|
list.push(toPush);
|
|
154
155
|
}
|
|
155
|
-
|
|
156
|
+
const sortTreeItems = (treeItems) => {
|
|
157
|
+
return (0, sort_by_nonce_history_1.sortItemsByNonceHistory)(treeItems.map((item) => ({
|
|
158
|
+
item,
|
|
159
|
+
nonce: item.type === 'folder' ? item.folder.nonce : item.composition.nonce,
|
|
160
|
+
}))).map(({ item }) => {
|
|
161
|
+
if (item.type === 'composition') {
|
|
162
|
+
return item;
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
...item,
|
|
166
|
+
items: sortTreeItems(item.items),
|
|
167
|
+
};
|
|
168
|
+
});
|
|
169
|
+
};
|
|
170
|
+
return sortTreeItems(items);
|
|
156
171
|
};
|
|
157
172
|
exports.createFolderTree = createFolderTree;
|
|
@@ -2,6 +2,14 @@ type FileLocation = {
|
|
|
2
2
|
readonly source: string | null;
|
|
3
3
|
readonly line: number | null;
|
|
4
4
|
};
|
|
5
|
+
export type RelativeFileLocation = {
|
|
6
|
+
readonly filename: string;
|
|
7
|
+
readonly line: number;
|
|
8
|
+
};
|
|
9
|
+
export declare const getRelativeFileLocation: ({ location, root, }: {
|
|
10
|
+
readonly location: FileLocation | null;
|
|
11
|
+
readonly root: string;
|
|
12
|
+
}) => RelativeFileLocation | null;
|
|
5
13
|
export declare const formatFileLocation: ({ location, root, }: {
|
|
6
14
|
readonly location: FileLocation | null;
|
|
7
15
|
readonly root: string;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.formatContextForAgents = exports.formatFileLocation = void 0;
|
|
3
|
+
exports.formatContextForAgents = exports.formatFileLocation = exports.getRelativeFileLocation = void 0;
|
|
4
4
|
const normalizeSlashes = (path) => path.replace(/\\/g, '/');
|
|
5
5
|
const stripTrailingSlashes = (path) => path.replace(/\/+$/, '');
|
|
6
6
|
const stripLeadingDotSlash = (path) => path.replace(/^\.\/+/, '');
|
|
7
|
-
const
|
|
7
|
+
const getRelativeFileLocation = ({ location, root, }) => {
|
|
8
8
|
if (!(location === null || location === void 0 ? void 0 : location.source) || location.line === null) {
|
|
9
9
|
return null;
|
|
10
10
|
}
|
|
@@ -22,7 +22,18 @@ const formatFileLocation = ({ location, root, }) => {
|
|
|
22
22
|
const relativeSource = sourceIsInsideRoot
|
|
23
23
|
? source.slice(normalizedRoot.length + 1)
|
|
24
24
|
: source;
|
|
25
|
-
return
|
|
25
|
+
return {
|
|
26
|
+
filename: stripLeadingDotSlash(relativeSource),
|
|
27
|
+
line: location.line,
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
exports.getRelativeFileLocation = getRelativeFileLocation;
|
|
31
|
+
const formatFileLocation = ({ location, root, }) => {
|
|
32
|
+
const relativeLocation = (0, exports.getRelativeFileLocation)({ location, root });
|
|
33
|
+
if (relativeLocation === null) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
return `${relativeLocation.filename}:${relativeLocation.line}`;
|
|
26
37
|
};
|
|
27
38
|
exports.formatFileLocation = formatFileLocation;
|
|
28
39
|
const formatContextForAgents = ({ name, location, root, }) => {
|
|
@@ -11,10 +11,18 @@ export declare const clampTimelineZoom: ({ zoom, durationInFrames, }: {
|
|
|
11
11
|
zoom: number;
|
|
12
12
|
durationInFrames: number;
|
|
13
13
|
}) => number;
|
|
14
|
+
export declare const timelineZoomToNormalized: ({ zoom, maxZoom, }: {
|
|
15
|
+
zoom: number;
|
|
16
|
+
maxZoom: number;
|
|
17
|
+
}) => number;
|
|
14
18
|
export declare const timelineZoomToSliderValue: ({ zoom, maxZoom, }: {
|
|
15
19
|
zoom: number;
|
|
16
20
|
maxZoom: number;
|
|
17
21
|
}) => number;
|
|
22
|
+
export declare const normalizedToTimelineZoom: ({ normalized, maxZoom, }: {
|
|
23
|
+
normalized: number;
|
|
24
|
+
maxZoom: number;
|
|
25
|
+
}) => number;
|
|
18
26
|
export declare const sliderValueToTimelineZoom: ({ sliderValue, maxZoom, }: {
|
|
19
27
|
sliderValue: number;
|
|
20
28
|
maxZoom: number;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TIMELINE_ZOOM_SLIDER_PROPS = exports.sliderValueToTimelineZoom = exports.timelineZoomToSliderValue = exports.clampTimelineZoom = exports.getTimelineMaxZoom = exports.TIMELINE_FRAMES_VISIBLE_AT_MAX_ZOOM = exports.TIMELINE_MAX_ZOOM_FLOOR = exports.TIMELINE_MIN_ZOOM = void 0;
|
|
3
|
+
exports.TIMELINE_ZOOM_SLIDER_PROPS = exports.sliderValueToTimelineZoom = exports.normalizedToTimelineZoom = exports.timelineZoomToSliderValue = exports.timelineZoomToNormalized = exports.clampTimelineZoom = exports.getTimelineMaxZoom = exports.TIMELINE_FRAMES_VISIBLE_AT_MAX_ZOOM = exports.TIMELINE_MAX_ZOOM_FLOOR = exports.TIMELINE_MIN_ZOOM = void 0;
|
|
4
4
|
exports.TIMELINE_MIN_ZOOM = 1;
|
|
5
5
|
exports.TIMELINE_MAX_ZOOM_FLOOR = 5;
|
|
6
6
|
/**
|
|
@@ -20,23 +20,34 @@ const clampTimelineZoom = ({ zoom, durationInFrames, }) => {
|
|
|
20
20
|
return Math.round(clamped * 10) / 10;
|
|
21
21
|
};
|
|
22
22
|
exports.clampTimelineZoom = clampTimelineZoom;
|
|
23
|
-
const
|
|
23
|
+
const timelineZoomToNormalized = ({ zoom, maxZoom, }) => {
|
|
24
24
|
if (maxZoom <= exports.TIMELINE_MIN_ZOOM) {
|
|
25
25
|
return 0;
|
|
26
26
|
}
|
|
27
27
|
const clampedZoom = Math.min(maxZoom, Math.max(exports.TIMELINE_MIN_ZOOM, zoom));
|
|
28
|
-
const
|
|
28
|
+
const normalized = Math.log(clampedZoom / exports.TIMELINE_MIN_ZOOM) /
|
|
29
29
|
Math.log(maxZoom / exports.TIMELINE_MIN_ZOOM);
|
|
30
|
-
return Math.round(
|
|
30
|
+
return (Math.round(normalized * TIMELINE_ZOOM_SLIDER_MAX) / TIMELINE_ZOOM_SLIDER_MAX);
|
|
31
|
+
};
|
|
32
|
+
exports.timelineZoomToNormalized = timelineZoomToNormalized;
|
|
33
|
+
const timelineZoomToSliderValue = ({ zoom, maxZoom, }) => {
|
|
34
|
+
return Math.round((0, exports.timelineZoomToNormalized)({ zoom, maxZoom }) * TIMELINE_ZOOM_SLIDER_MAX);
|
|
31
35
|
};
|
|
32
36
|
exports.timelineZoomToSliderValue = timelineZoomToSliderValue;
|
|
33
|
-
const
|
|
37
|
+
const normalizedToTimelineZoom = ({ normalized, maxZoom, }) => {
|
|
34
38
|
if (maxZoom <= exports.TIMELINE_MIN_ZOOM) {
|
|
35
39
|
return exports.TIMELINE_MIN_ZOOM;
|
|
36
40
|
}
|
|
37
|
-
const t =
|
|
41
|
+
const t = Math.min(1, Math.max(0, normalized));
|
|
38
42
|
return exports.TIMELINE_MIN_ZOOM * (maxZoom / exports.TIMELINE_MIN_ZOOM) ** t;
|
|
39
43
|
};
|
|
44
|
+
exports.normalizedToTimelineZoom = normalizedToTimelineZoom;
|
|
45
|
+
const sliderValueToTimelineZoom = ({ sliderValue, maxZoom, }) => {
|
|
46
|
+
return (0, exports.normalizedToTimelineZoom)({
|
|
47
|
+
normalized: sliderValue / TIMELINE_ZOOM_SLIDER_MAX,
|
|
48
|
+
maxZoom,
|
|
49
|
+
});
|
|
50
|
+
};
|
|
40
51
|
exports.sliderValueToTimelineZoom = sliderValueToTimelineZoom;
|
|
41
52
|
exports.TIMELINE_ZOOM_SLIDER_PROPS = {
|
|
42
53
|
min: 0,
|
|
@@ -3,6 +3,7 @@ export declare const HOVERABLE_CLASS_NAME = "__remotion-hoverable";
|
|
|
3
3
|
export declare const HOVER_GROUP_CLASS_NAME = "__remotion-hover-group";
|
|
4
4
|
export declare const HOVER_GROUP_REVEAL_CLASS_NAME = "__remotion-hover-group-reveal";
|
|
5
5
|
export declare const FOCUS_VISIBLE_ONLY_CLASS_NAME = "__remotion-focus-visible-only";
|
|
6
|
+
export declare const NO_HOVER_BACKGROUND_STYLE: React.CSSProperties;
|
|
6
7
|
export declare const hoverableStyle: ({ idleBackground, hoverBackground, idleColor, hoverColor, }: {
|
|
7
8
|
idleBackground: string;
|
|
8
9
|
hoverBackground: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.makeHoverableCSS = exports.hoverableStyle = exports.FOCUS_VISIBLE_ONLY_CLASS_NAME = exports.HOVER_GROUP_REVEAL_CLASS_NAME = exports.HOVER_GROUP_CLASS_NAME = exports.HOVERABLE_CLASS_NAME = void 0;
|
|
3
|
+
exports.makeHoverableCSS = exports.hoverableStyle = exports.NO_HOVER_BACKGROUND_STYLE = exports.FOCUS_VISIBLE_ONLY_CLASS_NAME = exports.HOVER_GROUP_REVEAL_CLASS_NAME = exports.HOVER_GROUP_CLASS_NAME = exports.HOVERABLE_CLASS_NAME = void 0;
|
|
4
4
|
const colors_1 = require("./colors");
|
|
5
5
|
// Purely visual hover styling must be driven by CSS `:hover` rather than
|
|
6
6
|
// React state: When the Studio runs in an <iframe> (like in Browser Studio),
|
|
@@ -16,6 +16,9 @@ const BG_VARIABLE = '--remotion-hoverable-bg';
|
|
|
16
16
|
const HOVER_BG_VARIABLE = '--remotion-hoverable-hover-bg';
|
|
17
17
|
const COLOR_VARIABLE = '--remotion-hoverable-color';
|
|
18
18
|
const HOVER_COLOR_VARIABLE = '--remotion-hoverable-hover-color';
|
|
19
|
+
exports.NO_HOVER_BACKGROUND_STYLE = {
|
|
20
|
+
[HOVER_BG_VARIABLE]: colors_1.TRANSPARENT,
|
|
21
|
+
};
|
|
19
22
|
// To disable the hover effect (e.g. for a disabled control), pass the idle
|
|
20
23
|
// values as the hover values.
|
|
21
24
|
const hoverableStyle = ({ idleBackground, hoverBackground, idleColor, hoverColor, }) => {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EnterIcon = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
// Font Awesome Pro v7.3.1, Copyright 2026 Fonticons, Inc.
|
|
6
|
+
// https://fontawesome.com/license (Commercial License)
|
|
7
|
+
const EnterIcon = ({ color, ...props }) => {
|
|
8
|
+
return (jsx_runtime_1.jsx("svg", { ...props, xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 640 640", children: jsx_runtime_1.jsx("path", { fill: color, d: "M544 144C544 135.2 551.2 128 560 128C568.8 128 576 135.2 576 144L576 240C576 293 533 336 480 336L118.6 336L235.3 452.7C241.5 458.9 241.5 469.1 235.3 475.3C229.1 481.5 218.9 481.5 212.7 475.3L68.7 331.3C65.7 328.3 64 324.2 64 320C64 315.8 65.7 311.7 68.7 308.7L212.7 164.7C218.9 158.5 229.1 158.5 235.3 164.7C241.5 170.9 241.5 181.1 235.3 187.3L118.6 304L480 304C515.3 304 544 275.3 544 240L544 144z" }) }));
|
|
9
|
+
};
|
|
10
|
+
exports.EnterIcon = EnterIcon;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.loadPlaybackRate = exports.persistPlaybackRate = void 0;
|
|
3
|
+
exports.loadPlaybackRate = exports.persistPlaybackRate = exports.commonPlaybackRates = void 0;
|
|
4
4
|
const key = 'remotion.playbackrate';
|
|
5
|
+
exports.commonPlaybackRates = [
|
|
6
|
+
-4, -2, -1, -0.5, -0.25, 0.25, 0.5, 1, 1.5, 2, 4,
|
|
7
|
+
];
|
|
5
8
|
const persistPlaybackRate = (option) => {
|
|
6
9
|
localStorage.setItem(key, String(option));
|
|
7
10
|
};
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/studio"
|
|
4
4
|
},
|
|
5
5
|
"name": "@remotion/studio",
|
|
6
|
-
"version": "4.0.
|
|
6
|
+
"version": "4.0.518",
|
|
7
7
|
"description": "APIs for interacting with the Remotion Studio",
|
|
8
8
|
"main": "dist",
|
|
9
9
|
"scripts": {
|
|
@@ -25,19 +25,19 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@tanstack/react-virtual": "3.14.9",
|
|
28
|
-
"@remotion/canvas": "4.0.
|
|
29
|
-
"@remotion/studio-protocol": "4.0.
|
|
28
|
+
"@remotion/canvas": "4.0.518",
|
|
29
|
+
"@remotion/studio-protocol": "4.0.518",
|
|
30
30
|
"semver": "7.5.3",
|
|
31
|
-
"remotion": "4.0.
|
|
32
|
-
"@remotion/captions": "4.0.
|
|
33
|
-
"@remotion/media": "4.0.
|
|
34
|
-
"@remotion/player": "4.0.
|
|
35
|
-
"@remotion/media-utils": "4.0.
|
|
36
|
-
"@remotion/renderer": "4.0.
|
|
37
|
-
"@remotion/web-renderer": "4.0.
|
|
38
|
-
"@remotion/studio-shared": "4.0.
|
|
39
|
-
"@remotion/timeline-utils": "4.0.
|
|
40
|
-
"@remotion/zod-types": "4.0.
|
|
31
|
+
"remotion": "4.0.518",
|
|
32
|
+
"@remotion/captions": "4.0.518",
|
|
33
|
+
"@remotion/media": "4.0.518",
|
|
34
|
+
"@remotion/player": "4.0.518",
|
|
35
|
+
"@remotion/media-utils": "4.0.518",
|
|
36
|
+
"@remotion/renderer": "4.0.518",
|
|
37
|
+
"@remotion/web-renderer": "4.0.518",
|
|
38
|
+
"@remotion/studio-shared": "4.0.518",
|
|
39
|
+
"@remotion/timeline-utils": "4.0.518",
|
|
40
|
+
"@remotion/zod-types": "4.0.518",
|
|
41
41
|
"@jridgewell/trace-mapping": "0.3.31",
|
|
42
42
|
"mediabunny": "1.55.1",
|
|
43
43
|
"memfs": "3.4.3",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"react": "19.2.3",
|
|
49
49
|
"react-dom": "19.2.3",
|
|
50
50
|
"@types/semver": "7.5.3",
|
|
51
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
51
|
+
"@remotion/eslint-config-internal": "4.0.518",
|
|
52
52
|
"eslint": "9.19.0",
|
|
53
53
|
"@typescript/native-preview": "7.0.0-dev.20260217.1"
|
|
54
54
|
},
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { SelectedOutline } from './selected-outline-geometry';
|
|
2
|
-
import type { SelectedOutlineLayoutTarget } from './selected-outline-types';
|
|
3
|
-
type OutlineSequenceParent = {
|
|
4
|
-
readonly id: string;
|
|
5
|
-
readonly parent: string | null;
|
|
6
|
-
};
|
|
7
|
-
export declare const orderOutlinesForRendering: ({ outlines, sequences, targetsByKey, }: {
|
|
8
|
-
readonly outlines: readonly SelectedOutline[];
|
|
9
|
-
readonly sequences: readonly OutlineSequenceParent[];
|
|
10
|
-
readonly targetsByKey: ReadonlyMap<string, SelectedOutlineLayoutTarget>;
|
|
11
|
-
}) => readonly SelectedOutline[];
|
|
12
|
-
export {};
|
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.orderOutlinesForRendering = void 0;
|
|
4
|
-
const outlinePointEqualityTolerance = 0.5;
|
|
5
|
-
const outlineAreaEqualityTolerance = 0.5;
|
|
6
|
-
const outlineBoundsOverlapTolerance = 0.5;
|
|
7
|
-
const outlinePointsAreEquivalent = (a, b) => {
|
|
8
|
-
return (Math.abs(a.x - b.x) <= outlinePointEqualityTolerance &&
|
|
9
|
-
Math.abs(a.y - b.y) <= outlinePointEqualityTolerance);
|
|
10
|
-
};
|
|
11
|
-
const outlinesHaveEquivalentHitArea = (a, b) => {
|
|
12
|
-
if (a.points.length !== b.points.length) {
|
|
13
|
-
return false;
|
|
14
|
-
}
|
|
15
|
-
for (let startIndex = 0; startIndex < b.points.length; startIndex++) {
|
|
16
|
-
for (const direction of [1, -1]) {
|
|
17
|
-
const pointsMatch = a.points.every((point, index) => {
|
|
18
|
-
const bIndex = (startIndex + direction * index + b.points.length) % b.points.length;
|
|
19
|
-
return outlinePointsAreEquivalent(point, b.points[bIndex]);
|
|
20
|
-
});
|
|
21
|
-
if (pointsMatch) {
|
|
22
|
-
return true;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
return false;
|
|
27
|
-
};
|
|
28
|
-
const getOutlineHitArea = (outline) => {
|
|
29
|
-
let area = 0;
|
|
30
|
-
for (let i = 0; i < outline.points.length; i++) {
|
|
31
|
-
const current = outline.points[i];
|
|
32
|
-
const next = outline.points[(i + 1) % outline.points.length];
|
|
33
|
-
area += current.x * next.y - next.x * current.y;
|
|
34
|
-
}
|
|
35
|
-
return Math.abs(area) / 2;
|
|
36
|
-
};
|
|
37
|
-
const getOutlineBounds = (outline) => {
|
|
38
|
-
const xs = outline.points.map((point) => point.x);
|
|
39
|
-
const ys = outline.points.map((point) => point.y);
|
|
40
|
-
return {
|
|
41
|
-
maxX: Math.max(...xs),
|
|
42
|
-
maxY: Math.max(...ys),
|
|
43
|
-
minX: Math.min(...xs),
|
|
44
|
-
minY: Math.min(...ys),
|
|
45
|
-
};
|
|
46
|
-
};
|
|
47
|
-
const outlineBoundsOverlap = (a, b) => {
|
|
48
|
-
const aBounds = getOutlineBounds(a);
|
|
49
|
-
const bBounds = getOutlineBounds(b);
|
|
50
|
-
return (aBounds.minX <= bBounds.maxX + outlineBoundsOverlapTolerance &&
|
|
51
|
-
aBounds.maxX + outlineBoundsOverlapTolerance >= bBounds.minX &&
|
|
52
|
-
aBounds.minY <= bBounds.maxY + outlineBoundsOverlapTolerance &&
|
|
53
|
-
aBounds.maxY + outlineBoundsOverlapTolerance >= bBounds.minY);
|
|
54
|
-
};
|
|
55
|
-
const getSequenceId = (target) => {
|
|
56
|
-
var _a;
|
|
57
|
-
var _b;
|
|
58
|
-
return (_b = (_a = target === null || target === void 0 ? void 0 : target.sequence) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : null;
|
|
59
|
-
};
|
|
60
|
-
const getParentBySequenceId = ({ sequences, targetsByKey, }) => {
|
|
61
|
-
const parentBySequenceId = new Map();
|
|
62
|
-
for (const sequence of sequences) {
|
|
63
|
-
parentBySequenceId.set(sequence.id, sequence.parent);
|
|
64
|
-
}
|
|
65
|
-
for (const target of targetsByKey.values()) {
|
|
66
|
-
const sequenceId = getSequenceId(target);
|
|
67
|
-
if (sequenceId !== null && !parentBySequenceId.has(sequenceId)) {
|
|
68
|
-
parentBySequenceId.set(sequenceId, target.sequence.parent);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return parentBySequenceId;
|
|
72
|
-
};
|
|
73
|
-
const isAncestorTarget = ({ ancestor, descendant, parentBySequenceId, }) => {
|
|
74
|
-
var _a;
|
|
75
|
-
var _b, _c;
|
|
76
|
-
const ancestorId = getSequenceId(ancestor);
|
|
77
|
-
if (ancestorId === null) {
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
let parentId = (_b = (_a = descendant.sequence) === null || _a === void 0 ? void 0 : _a.parent) !== null && _b !== void 0 ? _b : null;
|
|
81
|
-
while (parentId !== null) {
|
|
82
|
-
if (parentId === ancestorId) {
|
|
83
|
-
return true;
|
|
84
|
-
}
|
|
85
|
-
parentId = (_c = parentBySequenceId.get(parentId)) !== null && _c !== void 0 ? _c : null;
|
|
86
|
-
}
|
|
87
|
-
return false;
|
|
88
|
-
};
|
|
89
|
-
const orderOutlineGroup = ({ outlines, parentBySequenceId, targetsByKey, }) => {
|
|
90
|
-
var _a;
|
|
91
|
-
var _b, _c, _d, _e;
|
|
92
|
-
const incomingEdges = new Map();
|
|
93
|
-
const outgoingEdges = new Map();
|
|
94
|
-
const outlinesByKey = new Map(outlines.map((outline) => [outline.key, outline]));
|
|
95
|
-
for (const outline of outlines) {
|
|
96
|
-
incomingEdges.set(outline.key, new Set());
|
|
97
|
-
outgoingEdges.set(outline.key, new Set());
|
|
98
|
-
}
|
|
99
|
-
const hasPath = ({ fromKey, seen, toKey, }) => {
|
|
100
|
-
var _a;
|
|
101
|
-
if (fromKey === toKey) {
|
|
102
|
-
return true;
|
|
103
|
-
}
|
|
104
|
-
if (seen.has(fromKey)) {
|
|
105
|
-
return false;
|
|
106
|
-
}
|
|
107
|
-
seen.add(fromKey);
|
|
108
|
-
for (const nextKey of (_a = outgoingEdges.get(fromKey)) !== null && _a !== void 0 ? _a : []) {
|
|
109
|
-
if (hasPath({ fromKey: nextKey, seen, toKey })) {
|
|
110
|
-
return true;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
return false;
|
|
114
|
-
};
|
|
115
|
-
const addEdge = (before, after, options) => {
|
|
116
|
-
if (before.key === after.key) {
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
const incoming = incomingEdges.get(after.key);
|
|
120
|
-
const outgoing = outgoingEdges.get(before.key);
|
|
121
|
-
if (incoming === undefined || outgoing === undefined) {
|
|
122
|
-
throw new Error('Expected outline to be registered before adding edge');
|
|
123
|
-
}
|
|
124
|
-
if (outgoing.has(after.key)) {
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
if (hasPath({ fromKey: after.key, seen: new Set(), toKey: before.key })) {
|
|
128
|
-
if (options === null || options === void 0 ? void 0 : options.skipIfCycle) {
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
throw new Error('Could not determine a stable outline rendering order');
|
|
132
|
-
}
|
|
133
|
-
incoming.add(before.key);
|
|
134
|
-
outgoing.add(after.key);
|
|
135
|
-
};
|
|
136
|
-
const addAncestorConstraint = ({ ancestor, descendant, descendantContainsSelection, equivalentHitArea, }) => {
|
|
137
|
-
// Usually, children should be above parents so nested elements are directly
|
|
138
|
-
// selectable. If an unselected child has the same hit area as its parent, put
|
|
139
|
-
// it below the parent so the wrapper can be selected. Once the child or
|
|
140
|
-
// one of its properties is selected, keep it above the parent so it remains
|
|
141
|
-
// directly draggable.
|
|
142
|
-
if (equivalentHitArea && !descendantContainsSelection) {
|
|
143
|
-
addEdge(descendant, ancestor);
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
146
|
-
addEdge(ancestor, descendant);
|
|
147
|
-
}
|
|
148
|
-
};
|
|
149
|
-
const outlineBySequenceId = new Map();
|
|
150
|
-
for (const outline of outlines) {
|
|
151
|
-
const sequenceId = getSequenceId(targetsByKey.get(outline.key));
|
|
152
|
-
if (sequenceId !== null) {
|
|
153
|
-
outlineBySequenceId.set(sequenceId, outline);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
// Only constrain each outline against its nearest rendered ancestor. The
|
|
157
|
-
// resulting graph follows the sequence tree, so pairwise subpixel equivalence
|
|
158
|
-
// cannot introduce contradictory edges across three nested outlines.
|
|
159
|
-
for (const descendant of outlines) {
|
|
160
|
-
const descendantTarget = targetsByKey.get(descendant.key);
|
|
161
|
-
let parentId = (_b = (_a = descendantTarget === null || descendantTarget === void 0 ? void 0 : descendantTarget.sequence) === null || _a === void 0 ? void 0 : _a.parent) !== null && _b !== void 0 ? _b : null;
|
|
162
|
-
while (parentId !== null) {
|
|
163
|
-
const ancestor = outlineBySequenceId.get(parentId);
|
|
164
|
-
if (ancestor !== undefined) {
|
|
165
|
-
addAncestorConstraint({
|
|
166
|
-
ancestor,
|
|
167
|
-
descendant,
|
|
168
|
-
descendantContainsSelection: ((_c = descendantTarget === null || descendantTarget === void 0 ? void 0 : descendantTarget.selected) !== null && _c !== void 0 ? _c : false) ||
|
|
169
|
-
((_d = descendantTarget === null || descendantTarget === void 0 ? void 0 : descendantTarget.containsSelection) !== null && _d !== void 0 ? _d : false),
|
|
170
|
-
equivalentHitArea: outlinesHaveEquivalentHitArea(ancestor, descendant),
|
|
171
|
-
});
|
|
172
|
-
break;
|
|
173
|
-
}
|
|
174
|
-
parentId = (_e = parentBySequenceId.get(parentId)) !== null && _e !== void 0 ? _e : null;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
// For unrelated overlapping outlines, put broader hit targets below
|
|
178
|
-
// smaller ones so a large selected sequence cannot swallow clicks on
|
|
179
|
-
// a more specific element in the same canvas area.
|
|
180
|
-
for (let i = 0; i < outlines.length; i++) {
|
|
181
|
-
for (let j = i + 1; j < outlines.length; j++) {
|
|
182
|
-
const a = outlines[i];
|
|
183
|
-
const b = outlines[j];
|
|
184
|
-
const aTarget = targetsByKey.get(a.key);
|
|
185
|
-
const bTarget = targetsByKey.get(b.key);
|
|
186
|
-
if (aTarget === undefined || bTarget === undefined) {
|
|
187
|
-
continue;
|
|
188
|
-
}
|
|
189
|
-
const aAncestorOfB = isAncestorTarget({
|
|
190
|
-
ancestor: aTarget,
|
|
191
|
-
descendant: bTarget,
|
|
192
|
-
parentBySequenceId,
|
|
193
|
-
});
|
|
194
|
-
const bAncestorOfA = isAncestorTarget({
|
|
195
|
-
ancestor: bTarget,
|
|
196
|
-
descendant: aTarget,
|
|
197
|
-
parentBySequenceId,
|
|
198
|
-
});
|
|
199
|
-
if (aAncestorOfB || bAncestorOfA || !outlineBoundsOverlap(a, b)) {
|
|
200
|
-
continue;
|
|
201
|
-
}
|
|
202
|
-
const aArea = getOutlineHitArea(a);
|
|
203
|
-
const bArea = getOutlineHitArea(b);
|
|
204
|
-
if (Math.abs(aArea - bArea) <= outlineAreaEqualityTolerance) {
|
|
205
|
-
continue;
|
|
206
|
-
}
|
|
207
|
-
if (aArea > bArea) {
|
|
208
|
-
addEdge(a, b, { skipIfCycle: true });
|
|
209
|
-
}
|
|
210
|
-
else {
|
|
211
|
-
addEdge(b, a, { skipIfCycle: true });
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
const emitted = new Set();
|
|
216
|
-
const visiting = new Set();
|
|
217
|
-
const ordered = [];
|
|
218
|
-
const visit = (outline) => {
|
|
219
|
-
var _a;
|
|
220
|
-
if (emitted.has(outline.key)) {
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
if (visiting.has(outline.key)) {
|
|
224
|
-
throw new Error('Could not determine a stable outline rendering order');
|
|
225
|
-
}
|
|
226
|
-
visiting.add(outline.key);
|
|
227
|
-
for (const dependencyKey of (_a = incomingEdges.get(outline.key)) !== null && _a !== void 0 ? _a : []) {
|
|
228
|
-
const dependency = outlinesByKey.get(dependencyKey);
|
|
229
|
-
if (dependency === undefined) {
|
|
230
|
-
throw new Error('Expected outline dependency to exist');
|
|
231
|
-
}
|
|
232
|
-
visit(dependency);
|
|
233
|
-
}
|
|
234
|
-
visiting.delete(outline.key);
|
|
235
|
-
emitted.add(outline.key);
|
|
236
|
-
ordered.push(outline);
|
|
237
|
-
};
|
|
238
|
-
for (const outline of outlines) {
|
|
239
|
-
visit(outline);
|
|
240
|
-
}
|
|
241
|
-
return ordered;
|
|
242
|
-
};
|
|
243
|
-
const orderOutlinesForRendering = ({ outlines, sequences, targetsByKey, }) => {
|
|
244
|
-
const parentBySequenceId = getParentBySequenceId({ sequences, targetsByKey });
|
|
245
|
-
return orderOutlineGroup({
|
|
246
|
-
outlines,
|
|
247
|
-
parentBySequenceId,
|
|
248
|
-
targetsByKey,
|
|
249
|
-
});
|
|
250
|
-
};
|
|
251
|
-
exports.orderOutlinesForRendering = orderOutlinesForRendering;
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @param {globalThis} windowObj?
|
|
3
|
-
* @param {boolean=} force
|
|
4
|
-
*/
|
|
5
|
-
export declare function addPolyfill(windowObj?: globalThis, force?: boolean | undefined): void;
|
|
6
|
-
/**
|
|
7
|
-
* @param {globalThis} windowObj?
|
|
8
|
-
*/
|
|
9
|
-
export declare function patchAdoptNode(windowObj?: globalThis): void;
|
|
10
|
-
/**
|
|
11
|
-
* @param {Node} node
|
|
12
|
-
* @param {DOMQuadInit} quad
|
|
13
|
-
* @param {Element} from
|
|
14
|
-
* @param {{fromBox?: 'margin'|'border'|'padding'|'content', toBox?: 'margin'|'border'|'padding'|'content', iframes?: HTMLIFrameElement[]}=} options
|
|
15
|
-
* @returns {DOMQuad}
|
|
16
|
-
*/
|
|
17
|
-
export declare function convertQuadFromNode(node: Node, quad: DOMQuadInit, from: Element, options?: {
|
|
18
|
-
fromBox?: 'margin' | 'border' | 'padding' | 'content';
|
|
19
|
-
toBox?: 'margin' | 'border' | 'padding' | 'content';
|
|
20
|
-
iframes?: HTMLIFrameElement[];
|
|
21
|
-
} | undefined): DOMQuad;
|
|
22
|
-
/**
|
|
23
|
-
* @param {Node} node
|
|
24
|
-
* @param {{x: number, y: number, width: number, height: number}} rect
|
|
25
|
-
* @param {Element} from
|
|
26
|
-
* @param {{fromBox?: 'margin'|'border'|'padding'|'content', toBox?: 'margin'|'border'|'padding'|'content', iframes?: HTMLIFrameElement[]}=} options
|
|
27
|
-
* @returns {DOMQuad}
|
|
28
|
-
*/
|
|
29
|
-
export declare function convertRectFromNode(node: Node, rect: {
|
|
30
|
-
x: number;
|
|
31
|
-
y: number;
|
|
32
|
-
width: number;
|
|
33
|
-
height: number;
|
|
34
|
-
}, from: Element, options?: {
|
|
35
|
-
fromBox?: 'margin' | 'border' | 'padding' | 'content';
|
|
36
|
-
toBox?: 'margin' | 'border' | 'padding' | 'content';
|
|
37
|
-
iframes?: HTMLIFrameElement[];
|
|
38
|
-
} | undefined): DOMQuad;
|
|
39
|
-
/**
|
|
40
|
-
* @param {Node} node
|
|
41
|
-
* @param {DOMPointInit} point
|
|
42
|
-
* @param {Element} from
|
|
43
|
-
* @param {{fromBox?: 'margin'|'border'|'padding'|'content', toBox?: 'margin'|'border'|'padding'|'content', iframes?: HTMLIFrameElement[]}=} options
|
|
44
|
-
* @returns {DOMPoint}
|
|
45
|
-
*/
|
|
46
|
-
export declare function convertPointFromNode(node: Node, point: DOMPointInit, from: Element, options?: {
|
|
47
|
-
fromBox?: 'margin' | 'border' | 'padding' | 'content';
|
|
48
|
-
toBox?: 'margin' | 'border' | 'padding' | 'content';
|
|
49
|
-
iframes?: HTMLIFrameElement[];
|
|
50
|
-
} | undefined): DOMPoint;
|
|
51
|
-
export declare function clearCache(): void;
|
|
52
|
-
export declare function useCache(): void;
|
|
53
|
-
/**
|
|
54
|
-
* @param {Node} node
|
|
55
|
-
* @param {{box?: 'margin'|'border'|'padding'|'content', relativeTo?: Element, iframes?: HTMLIFrameElement[]}=} options
|
|
56
|
-
* @returns {DOMQuad[]}
|
|
57
|
-
*/
|
|
58
|
-
export declare function getBoxQuads(node: Node, options?: {
|
|
59
|
-
box?: 'margin' | 'border' | 'padding' | 'content';
|
|
60
|
-
relativeTo?: Element;
|
|
61
|
-
iframes?: HTMLIFrameElement[];
|
|
62
|
-
} | undefined): DOMQuad[];
|
|
63
|
-
/**
|
|
64
|
-
* @param {Node} node
|
|
65
|
-
* @param {DOMMatrix=} matrix
|
|
66
|
-
*/
|
|
67
|
-
export declare function getElementSize(node: Node, matrix?: DOMMatrix | undefined): {
|
|
68
|
-
width: number;
|
|
69
|
-
height: number;
|
|
70
|
-
};
|
|
71
|
-
/**
|
|
72
|
-
* @param {Node} node
|
|
73
|
-
* @param {Element} ancestor
|
|
74
|
-
* @param {HTMLIFrameElement[]} iframes
|
|
75
|
-
* @param {boolean=} excludeSelfZoom
|
|
76
|
-
*/
|
|
77
|
-
export declare function getResultingTransformationBetweenElementAndAllAncestors(node: Node, ancestor: Element, iframes: HTMLIFrameElement[], excludeSelfZoom?: boolean | undefined): DOMMatrix;
|
|
78
|
-
/**
|
|
79
|
-
* @param {Node} element
|
|
80
|
-
* @param {HTMLIFrameElement[]=} iframes
|
|
81
|
-
*/
|
|
82
|
-
export declare function getElementCombinedTransform(element: Node, iframes?: HTMLIFrameElement[] | undefined): DOMMatrix;
|