tldraw 4.1.0-canary.c62140a07605 → 4.1.0-canary.c9992319dc92
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-cjs/index.d.ts +35 -10
- package/dist-cjs/index.js +3 -1
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/defaultEmbedDefinitions.js +25 -30
- package/dist-cjs/lib/defaultEmbedDefinitions.js.map +2 -2
- package/dist-cjs/lib/defaultExternalContentHandlers.js +9 -32
- package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js +3 -0
- package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +43 -101
- package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/bookmark/bookmarks.js +138 -0
- package/dist-cjs/lib/shapes/bookmark/bookmarks.js.map +7 -0
- package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +25 -3
- package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/line/LineShapeUtil.js +3 -0
- package/dist-cjs/lib/shapes/line/LineShapeUtil.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Cropping.js +20 -4
- package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Cropping.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.js +23 -11
- package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +27 -6
- package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js +21 -9
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingResizeHandle.js +24 -8
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingResizeHandle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingRotateHandle.js +21 -9
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingRotateHandle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +23 -8
- package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js +21 -9
- package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js +26 -11
- package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
- package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +5 -0
- package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/PeopleMenu.js +6 -2
- package/dist-cjs/lib/ui/components/SharePanel/PeopleMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js +1 -1
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +1 -1
- package/dist-cjs/lib/ui/context/actions.js +23 -29
- package/dist-cjs/lib/ui/context/actions.js.map +2 -2
- package/dist-cjs/lib/ui/version.js +3 -3
- package/dist-cjs/lib/ui/version.js.map +1 -1
- package/dist-esm/index.d.mts +35 -10
- package/dist-esm/index.mjs +3 -1
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/defaultEmbedDefinitions.mjs +25 -30
- package/dist-esm/lib/defaultEmbedDefinitions.mjs.map +2 -2
- package/dist-esm/lib/defaultExternalContentHandlers.mjs +9 -32
- package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +3 -0
- package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +46 -101
- package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/bookmark/bookmarks.mjs +124 -0
- package/dist-esm/lib/shapes/bookmark/bookmarks.mjs.map +7 -0
- package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +26 -3
- package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/line/LineShapeUtil.mjs +3 -0
- package/dist-esm/lib/shapes/line/LineShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Cropping.mjs +20 -4
- package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Cropping.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.mjs +23 -11
- package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +29 -7
- package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs +21 -9
- package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/PointingResizeHandle.mjs +24 -8
- package/dist-esm/lib/tools/SelectTool/childStates/PointingResizeHandle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/PointingRotateHandle.mjs +21 -9
- package/dist-esm/lib/tools/SelectTool/childStates/PointingRotateHandle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +23 -8
- package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs +21 -9
- package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs +26 -11
- package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs +5 -0
- package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs.map +2 -2
- package/dist-esm/lib/ui/components/SharePanel/PeopleMenu.mjs +6 -2
- package/dist-esm/lib/ui/components/SharePanel/PeopleMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs +1 -1
- package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +1 -1
- package/dist-esm/lib/ui/context/actions.mjs +23 -29
- package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
- package/dist-esm/lib/ui/version.mjs +3 -3
- package/dist-esm/lib/ui/version.mjs.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +1 -0
- package/src/lib/defaultEmbedDefinitions.ts +20 -24
- package/src/lib/defaultExternalContentHandlers.ts +11 -36
- package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +3 -0
- package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +51 -135
- package/src/lib/shapes/bookmark/bookmarks.ts +170 -0
- package/src/lib/shapes/embed/EmbedShapeUtil.tsx +28 -2
- package/src/lib/shapes/line/LineShapeUtil.tsx +3 -0
- package/src/lib/tools/SelectTool/childStates/Crop/children/Cropping.ts +23 -6
- package/src/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.ts +24 -12
- package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +34 -11
- package/src/lib/tools/SelectTool/childStates/PointingArrowLabel.ts +23 -11
- package/src/lib/tools/SelectTool/childStates/PointingResizeHandle.ts +26 -9
- package/src/lib/tools/SelectTool/childStates/PointingRotateHandle.ts +23 -10
- package/src/lib/tools/SelectTool/childStates/Resizing.ts +24 -9
- package/src/lib/tools/SelectTool/childStates/Rotating.ts +27 -11
- package/src/lib/tools/SelectTool/childStates/Translating.ts +28 -12
- package/src/lib/ui/components/Minimap/MinimapManager.ts +6 -0
- package/src/lib/ui/components/SharePanel/PeopleMenu.tsx +6 -2
- package/src/lib/ui/components/StylePanel/StylePanelButtonPicker.tsx +1 -1
- package/src/lib/ui/context/actions.tsx +27 -31
- package/src/lib/ui/version.ts +3 -3
- package/src/lib/utils/embeds/embeds.test.ts +16 -34
- package/src/test/SelectTool.test.ts +251 -0
- package/src/test/bookmark-shapes.test.ts +129 -7
- package/src/test/customSnapping.test.tsx +55 -11
- package/tldraw.css +7 -2
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var bookmarks_exports = {};
|
|
20
|
+
__export(bookmarks_exports, {
|
|
21
|
+
BOOKMARK_HEIGHT: () => BOOKMARK_HEIGHT,
|
|
22
|
+
BOOKMARK_JUST_URL_HEIGHT: () => BOOKMARK_JUST_URL_HEIGHT,
|
|
23
|
+
BOOKMARK_WIDTH: () => BOOKMARK_WIDTH,
|
|
24
|
+
createBookmarkFromUrl: () => createBookmarkFromUrl,
|
|
25
|
+
getBookmarkHeight: () => getBookmarkHeight,
|
|
26
|
+
getHumanReadableAddress: () => getHumanReadableAddress,
|
|
27
|
+
setBookmarkHeight: () => setBookmarkHeight,
|
|
28
|
+
updateBookmarkAssetOnUrlChange: () => updateBookmarkAssetOnUrlChange
|
|
29
|
+
});
|
|
30
|
+
module.exports = __toCommonJS(bookmarks_exports);
|
|
31
|
+
var import_editor = require("@tldraw/editor");
|
|
32
|
+
const BOOKMARK_WIDTH = 300;
|
|
33
|
+
const BOOKMARK_HEIGHT = 320;
|
|
34
|
+
const BOOKMARK_JUST_URL_HEIGHT = 46;
|
|
35
|
+
const SHORT_BOOKMARK_HEIGHT = 101;
|
|
36
|
+
function getBookmarkHeight(editor, assetId) {
|
|
37
|
+
const asset = assetId ? editor.getAsset(assetId) : null;
|
|
38
|
+
if (asset) {
|
|
39
|
+
if (!asset.props.image) {
|
|
40
|
+
if (!asset.props.title) {
|
|
41
|
+
return BOOKMARK_JUST_URL_HEIGHT;
|
|
42
|
+
} else {
|
|
43
|
+
return SHORT_BOOKMARK_HEIGHT;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return BOOKMARK_HEIGHT;
|
|
48
|
+
}
|
|
49
|
+
function setBookmarkHeight(editor, shape) {
|
|
50
|
+
return {
|
|
51
|
+
...shape,
|
|
52
|
+
props: { ...shape.props, h: getBookmarkHeight(editor, shape.props.assetId) }
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
const getHumanReadableAddress = (url) => {
|
|
56
|
+
try {
|
|
57
|
+
const objUrl = new URL(url);
|
|
58
|
+
return objUrl.hostname.replace(/^www\./, "");
|
|
59
|
+
} catch {
|
|
60
|
+
return url;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
function updateBookmarkAssetOnUrlChange(editor, shape) {
|
|
64
|
+
const { url } = shape.props;
|
|
65
|
+
const assetId = import_editor.AssetRecordType.createId((0, import_editor.getHashForString)(url));
|
|
66
|
+
if (editor.getAsset(assetId)) {
|
|
67
|
+
if (shape.props.assetId !== assetId) {
|
|
68
|
+
editor.updateShapes([
|
|
69
|
+
{
|
|
70
|
+
id: shape.id,
|
|
71
|
+
type: shape.type,
|
|
72
|
+
props: { assetId }
|
|
73
|
+
}
|
|
74
|
+
]);
|
|
75
|
+
}
|
|
76
|
+
} else {
|
|
77
|
+
editor.updateShapes([
|
|
78
|
+
{
|
|
79
|
+
id: shape.id,
|
|
80
|
+
type: shape.type,
|
|
81
|
+
props: { assetId: null }
|
|
82
|
+
}
|
|
83
|
+
]);
|
|
84
|
+
createBookmarkAssetOnUrlChange(editor, shape);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const createBookmarkAssetOnUrlChange = (0, import_editor.debounce)(async (editor, shape) => {
|
|
88
|
+
if (editor.isDisposed) return;
|
|
89
|
+
const { url } = shape.props;
|
|
90
|
+
const asset = await editor.getAssetForExternalContent({ type: "url", url });
|
|
91
|
+
if (!asset) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
editor.run(() => {
|
|
95
|
+
editor.createAssets([asset]);
|
|
96
|
+
editor.updateShapes([
|
|
97
|
+
{
|
|
98
|
+
id: shape.id,
|
|
99
|
+
type: shape.type,
|
|
100
|
+
props: { assetId: asset.id }
|
|
101
|
+
}
|
|
102
|
+
]);
|
|
103
|
+
});
|
|
104
|
+
}, 500);
|
|
105
|
+
async function createBookmarkFromUrl(editor, {
|
|
106
|
+
url,
|
|
107
|
+
center = editor.getViewportPageBounds().center
|
|
108
|
+
}) {
|
|
109
|
+
try {
|
|
110
|
+
const asset = await editor.getAssetForExternalContent({ type: "url", url });
|
|
111
|
+
const shapeId = (0, import_editor.createShapeId)();
|
|
112
|
+
const shapePartial = {
|
|
113
|
+
id: shapeId,
|
|
114
|
+
type: "bookmark",
|
|
115
|
+
x: center.x - BOOKMARK_WIDTH / 2,
|
|
116
|
+
y: center.y - BOOKMARK_HEIGHT / 2,
|
|
117
|
+
rotation: 0,
|
|
118
|
+
opacity: 1,
|
|
119
|
+
props: {
|
|
120
|
+
url,
|
|
121
|
+
assetId: asset?.id || null,
|
|
122
|
+
w: BOOKMARK_WIDTH,
|
|
123
|
+
h: getBookmarkHeight(editor, asset?.id)
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
editor.run(() => {
|
|
127
|
+
if (asset) {
|
|
128
|
+
editor.createAssets([asset]);
|
|
129
|
+
}
|
|
130
|
+
editor.createShapes([shapePartial]);
|
|
131
|
+
});
|
|
132
|
+
const createdShape = editor.getShape(shapeId);
|
|
133
|
+
return import_editor.Result.ok(createdShape);
|
|
134
|
+
} catch (error) {
|
|
135
|
+
return import_editor.Result.err(error instanceof Error ? error.message : "Failed to create bookmark");
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=bookmarks.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/lib/shapes/bookmark/bookmarks.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n\tAssetRecordType,\n\tEditor,\n\tResult,\n\tTLAssetId,\n\tTLBookmarkAsset,\n\tTLBookmarkShape,\n\tTLShapePartial,\n\tcreateShapeId,\n\tdebounce,\n\tgetHashForString,\n} from '@tldraw/editor'\n\nexport const BOOKMARK_WIDTH = 300\nexport const BOOKMARK_HEIGHT = 320\nexport const BOOKMARK_JUST_URL_HEIGHT = 46\nconst SHORT_BOOKMARK_HEIGHT = 101\n\nexport function getBookmarkHeight(editor: Editor, assetId?: TLAssetId | null) {\n\tconst asset = (assetId ? editor.getAsset(assetId) : null) as TLBookmarkAsset | null\n\n\tif (asset) {\n\t\tif (!asset.props.image) {\n\t\t\tif (!asset.props.title) {\n\t\t\t\treturn BOOKMARK_JUST_URL_HEIGHT\n\t\t\t} else {\n\t\t\t\treturn SHORT_BOOKMARK_HEIGHT\n\t\t\t}\n\t\t}\n\t}\n\n\treturn BOOKMARK_HEIGHT\n}\n\nexport function setBookmarkHeight(editor: Editor, shape: TLBookmarkShape) {\n\treturn {\n\t\t...shape,\n\t\tprops: { ...shape.props, h: getBookmarkHeight(editor, shape.props.assetId) },\n\t}\n}\n\n/** @internal */\nexport const getHumanReadableAddress = (url: string) => {\n\ttry {\n\t\tconst objUrl = new URL(url)\n\t\t// we want the hostname without any www\n\t\treturn objUrl.hostname.replace(/^www\\./, '')\n\t} catch {\n\t\treturn url\n\t}\n}\n\nexport function updateBookmarkAssetOnUrlChange(editor: Editor, shape: TLBookmarkShape) {\n\tconst { url } = shape.props\n\n\t// Derive the asset id from the URL\n\tconst assetId: TLAssetId = AssetRecordType.createId(getHashForString(url))\n\n\tif (editor.getAsset(assetId)) {\n\t\t// Existing asset for this URL?\n\t\tif (shape.props.assetId !== assetId) {\n\t\t\teditor.updateShapes<TLBookmarkShape>([\n\t\t\t\t{\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: shape.type,\n\t\t\t\t\tprops: { assetId },\n\t\t\t\t},\n\t\t\t])\n\t\t}\n\t} else {\n\t\t// No asset for this URL?\n\n\t\t// First, clear out the existing asset reference\n\t\teditor.updateShapes<TLBookmarkShape>([\n\t\t\t{\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tprops: { assetId: null },\n\t\t\t},\n\t\t])\n\n\t\t// Then try to asyncronously create a new one\n\t\tcreateBookmarkAssetOnUrlChange(editor, shape)\n\t}\n}\n\nconst createBookmarkAssetOnUrlChange = debounce(async (editor: Editor, shape: TLBookmarkShape) => {\n\tif (editor.isDisposed) return\n\n\tconst { url } = shape.props\n\n\t// Create the asset using the external content manager's createAssetFromUrl method.\n\t// This may be overwritten by the user (for example, we overwrite it on tldraw.com)\n\tconst asset = await editor.getAssetForExternalContent({ type: 'url', url })\n\n\tif (!asset) {\n\t\t// No asset? Just leave the bookmark as a null assetId.\n\t\treturn\n\t}\n\n\teditor.run(() => {\n\t\t// Create the new asset\n\t\teditor.createAssets([asset])\n\n\t\t// And update the shape\n\t\teditor.updateShapes<TLBookmarkShape>([\n\t\t\t{\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tprops: { assetId: asset.id },\n\t\t\t},\n\t\t])\n\t})\n}, 500)\n\n/**\n * Creates a bookmark shape from a URL with unfurled metadata.\n *\n * @returns A Result containing the created bookmark shape or an error\n * @public\n */\n\nexport async function createBookmarkFromUrl(\n\teditor: Editor,\n\t{\n\t\turl,\n\t\tcenter = editor.getViewportPageBounds().center,\n\t}: {\n\t\turl: string\n\t\tcenter?: { x: number; y: number }\n\t}\n): Promise<Result<TLBookmarkShape, string>> {\n\ttry {\n\t\t// Create the bookmark asset with unfurled metadata\n\t\tconst asset = await editor.getAssetForExternalContent({ type: 'url', url })\n\n\t\t// Create the bookmark shape\n\t\tconst shapeId = createShapeId()\n\t\tconst shapePartial: TLShapePartial<TLBookmarkShape> = {\n\t\t\tid: shapeId,\n\t\t\ttype: 'bookmark',\n\t\t\tx: center.x - BOOKMARK_WIDTH / 2,\n\t\t\ty: center.y - BOOKMARK_HEIGHT / 2,\n\t\t\trotation: 0,\n\t\t\topacity: 1,\n\t\t\tprops: {\n\t\t\t\turl,\n\t\t\t\tassetId: asset?.id || null,\n\t\t\t\tw: BOOKMARK_WIDTH,\n\t\t\t\th: getBookmarkHeight(editor, asset?.id),\n\t\t\t},\n\t\t}\n\n\t\teditor.run(() => {\n\t\t\t// Create the asset if we have one\n\t\t\tif (asset) {\n\t\t\t\teditor.createAssets([asset])\n\t\t\t}\n\n\t\t\t// Create the shape\n\t\t\teditor.createShapes([shapePartial])\n\t\t})\n\n\t\t// Get the created shape\n\t\tconst createdShape = editor.getShape(shapeId) as TLBookmarkShape\n\t\treturn Result.ok(createdShape)\n\t} catch (error) {\n\t\treturn Result.err(error instanceof Error ? error.message : 'Failed to create bookmark')\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -25,6 +25,8 @@ var import_jsx_runtime = require("react/jsx-runtime");
|
|
|
25
25
|
var import_editor = require("@tldraw/editor");
|
|
26
26
|
var import_defaultEmbedDefinitions = require("../../defaultEmbedDefinitions");
|
|
27
27
|
var import_embeds = require("../../utils/embeds/embeds");
|
|
28
|
+
var import_BookmarkShapeUtil = require("../bookmark/BookmarkShapeUtil");
|
|
29
|
+
var import_bookmarks = require("../bookmark/bookmarks");
|
|
28
30
|
var import_rotated_box_shadow = require("../shared/rotated-box-shadow");
|
|
29
31
|
const getSandboxPermissions = (permissions) => {
|
|
30
32
|
return Object.entries(permissions).filter(([_perm, isEnabled]) => isEnabled).map(([perm]) => perm).join(" ");
|
|
@@ -69,6 +71,17 @@ class EmbedShapeUtil extends import_editor.BaseBoxShapeUtil {
|
|
|
69
71
|
url: ""
|
|
70
72
|
};
|
|
71
73
|
}
|
|
74
|
+
getGeometry(shape) {
|
|
75
|
+
const embedInfo = this.getEmbedDefinition(shape.props.url);
|
|
76
|
+
if (!embedInfo?.definition) {
|
|
77
|
+
return new import_editor.Rectangle2d({
|
|
78
|
+
width: import_bookmarks.BOOKMARK_WIDTH,
|
|
79
|
+
height: import_bookmarks.BOOKMARK_JUST_URL_HEIGHT,
|
|
80
|
+
isFilled: true
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return super.getGeometry(shape);
|
|
84
|
+
}
|
|
72
85
|
isAspectRatioLocked(shape) {
|
|
73
86
|
const embedInfo = this.getEmbedDefinition(shape.props.url);
|
|
74
87
|
return embedInfo?.definition.isAspectRatioLocked ?? false;
|
|
@@ -167,11 +180,20 @@ class EmbedShapeUtil extends import_editor.BaseBoxShapeUtil {
|
|
|
167
180
|
background: embedInfo?.definition.backgroundColor
|
|
168
181
|
}
|
|
169
182
|
}
|
|
170
|
-
) :
|
|
183
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
184
|
+
import_BookmarkShapeUtil.BookmarkShapeComponent,
|
|
185
|
+
{
|
|
186
|
+
url,
|
|
187
|
+
h,
|
|
188
|
+
rotation: pageRotation,
|
|
189
|
+
assetId: null,
|
|
190
|
+
showImageContainer: false
|
|
191
|
+
}
|
|
192
|
+
) });
|
|
171
193
|
}
|
|
172
194
|
indicator(shape) {
|
|
173
195
|
const embedInfo = this.getEmbedDefinition(shape.props.url);
|
|
174
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
196
|
+
return embedInfo?.definition ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
175
197
|
"rect",
|
|
176
198
|
{
|
|
177
199
|
width: (0, import_editor.toDomPrecision)(shape.props.w),
|
|
@@ -179,7 +201,7 @@ class EmbedShapeUtil extends import_editor.BaseBoxShapeUtil {
|
|
|
179
201
|
rx: embedInfo?.definition.overrideOutlineRadius ?? 8,
|
|
180
202
|
ry: embedInfo?.definition.overrideOutlineRadius ?? 8
|
|
181
203
|
}
|
|
182
|
-
);
|
|
204
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_BookmarkShapeUtil.BookmarkIndicatorComponent, { w: import_bookmarks.BOOKMARK_WIDTH, h: import_bookmarks.BOOKMARK_JUST_URL_HEIGHT });
|
|
183
205
|
}
|
|
184
206
|
getInterpolatedProps(startShape, endShape, t) {
|
|
185
207
|
return {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/shapes/embed/EmbedShapeUtil.tsx"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\n\nimport {\n\tBaseBoxShapeUtil,\n\tHTMLContainer,\n\tTLEmbedShape,\n\tTLEmbedShapeProps,\n\tTLResizeInfo,\n\tembedShapeMigrations,\n\tembedShapeProps,\n\tlerp,\n\tresizeBox,\n\ttoDomPrecision,\n\tuseIsEditing,\n\tuseSvgExportContext,\n\tuseValue,\n} from '@tldraw/editor'\n\nimport {\n\tDEFAULT_EMBED_DEFINITIONS,\n\tEmbedDefinition,\n\tTLEmbedDefinition,\n\tTLEmbedShapePermissions,\n\tembedShapePermissionDefaults,\n} from '../../defaultEmbedDefinitions'\nimport { TLEmbedResult, getEmbedInfo } from '../../utils/embeds/embeds'\nimport { getRotatedBoxShadow } from '../shared/rotated-box-shadow'\n\nconst getSandboxPermissions = (permissions: TLEmbedShapePermissions) => {\n\treturn Object.entries(permissions)\n\t\t.filter(([_perm, isEnabled]) => isEnabled)\n\t\t.map(([perm]) => perm)\n\t\t.join(' ')\n}\n\n/** @public */\nexport class EmbedShapeUtil extends BaseBoxShapeUtil<TLEmbedShape> {\n\tstatic override type = 'embed' as const\n\tstatic override props = embedShapeProps\n\tstatic override migrations = embedShapeMigrations\n\tprivate static embedDefinitions: readonly EmbedDefinition[] = DEFAULT_EMBED_DEFINITIONS\n\n\tstatic setEmbedDefinitions(embedDefinitions: readonly TLEmbedDefinition[]) {\n\t\tEmbedShapeUtil.embedDefinitions = embedDefinitions\n\t}\n\n\tgetEmbedDefinitions(): readonly TLEmbedDefinition[] {\n\t\treturn EmbedShapeUtil.embedDefinitions\n\t}\n\n\tgetEmbedDefinition(url: string): TLEmbedResult {\n\t\treturn getEmbedInfo(EmbedShapeUtil.embedDefinitions, url)\n\t}\n\n\toverride getText(shape: TLEmbedShape) {\n\t\treturn shape.props.url\n\t}\n\n\toverride getAriaDescriptor(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn embedInfo?.definition.title\n\t}\n\n\toverride hideSelectionBoundsFg(shape: TLEmbedShape) {\n\t\treturn !this.canResize(shape)\n\t}\n\toverride canEdit() {\n\t\treturn true\n\t}\n\toverride canResize(shape: TLEmbedShape) {\n\t\treturn !!this.getEmbedDefinition(shape.props.url)?.definition?.doesResize\n\t}\n\toverride canEditInReadonly() {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLEmbedShape['props'] {\n\t\treturn {\n\t\t\tw: 300,\n\t\t\th: 300,\n\t\t\turl: '',\n\t\t}\n\t}\n\n\toverride isAspectRatioLocked(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn embedInfo?.definition.isAspectRatioLocked ?? false\n\t}\n\n\toverride onResize(shape: TLEmbedShape, info: TLResizeInfo<TLEmbedShape>) {\n\t\tconst isAspectRatioLocked = this.isAspectRatioLocked(shape)\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\tlet minWidth = embedInfo?.definition.minWidth ?? 200\n\t\tlet minHeight = embedInfo?.definition.minHeight ?? 200\n\t\tif (isAspectRatioLocked) {\n\t\t\t// Enforce aspect ratio\n\t\t\t// Neither the width or height can be less than 200\n\t\t\tconst aspectRatio = shape.props.w / shape.props.h\n\t\t\tif (aspectRatio > 1) {\n\t\t\t\t// Landscape\n\t\t\t\tminWidth *= aspectRatio\n\t\t\t} else {\n\t\t\t\t// Portrait\n\t\t\t\tminHeight /= aspectRatio\n\t\t\t}\n\t\t}\n\n\t\treturn resizeBox(shape, info, { minWidth, minHeight })\n\t}\n\n\toverride component(shape: TLEmbedShape) {\n\t\tconst svgExport = useSvgExportContext()\n\t\tconst { w, h, url } = shape.props\n\t\tconst isEditing = useIsEditing(shape.id)\n\n\t\tconst embedInfo = this.getEmbedDefinition(url)\n\n\t\tconst isHoveringWhileEditingSameShape = useValue(\n\t\t\t'is hovering',\n\t\t\t() => {\n\t\t\t\tconst { editingShapeId, hoveredShapeId } = this.editor.getCurrentPageState()\n\n\t\t\t\tif (editingShapeId && hoveredShapeId !== editingShapeId) {\n\t\t\t\t\tconst editingShape = this.editor.getShape(editingShapeId)\n\t\t\t\t\tif (editingShape && this.editor.isShapeOfType<TLEmbedShape>(editingShape, 'embed')) {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn false\n\t\t\t},\n\t\t\t[]\n\t\t)\n\n\t\tconst pageRotation = this.editor.getShapePageTransform(shape)!.rotation()\n\n\t\tif (svgExport) {\n\t\t\t// for SVG exports, we show a blank embed\n\t\t\treturn (\n\t\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName=\"tl-embed\"\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tboxShadow: getRotatedBoxShadow(pageRotation),\n\t\t\t\t\t\t\tborderRadius: embedInfo?.definition.overrideOutlineRadius ?? 8,\n\t\t\t\t\t\t\tbackground: embedInfo?.definition.backgroundColor ?? 'var(--tl-color-background)',\n\t\t\t\t\t\t\twidth: w,\n\t\t\t\t\t\t\theight: h,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</HTMLContainer>\n\t\t\t)\n\t\t}\n\n\t\tconst isInteractive = isEditing || isHoveringWhileEditingSameShape\n\n\t\t// Prevent nested embedding of tldraw\n\t\tconst isIframe =\n\t\t\ttypeof window !== 'undefined' && (window !== window.top || window.self !== window.parent)\n\t\tif (isIframe && embedInfo?.definition.type === 'tldraw') return null\n\n\t\tif (embedInfo?.definition.type === 'github_gist') {\n\t\t\tconst idFromGistUrl = embedInfo.url.split('/').pop()\n\t\t\tif (!idFromGistUrl) throw Error('No gist id!')\n\n\t\t\treturn (\n\t\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t\t<Gist\n\t\t\t\t\t\tid={idFromGistUrl}\n\t\t\t\t\t\twidth={toDomPrecision(w)!}\n\t\t\t\t\t\theight={toDomPrecision(h)!}\n\t\t\t\t\t\tisInteractive={isInteractive}\n\t\t\t\t\t\tpageRotation={pageRotation}\n\t\t\t\t\t/>\n\t\t\t\t</HTMLContainer>\n\t\t\t)\n\t\t}\n\n\t\tconst sandbox = getSandboxPermissions({\n\t\t\t...embedShapePermissionDefaults,\n\t\t\t...(embedInfo?.definition.overridePermissions ?? {}),\n\t\t})\n\n\t\treturn (\n\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t{embedInfo?.definition ? (\n\t\t\t\t\t<iframe\n\t\t\t\t\t\tclassName=\"tl-embed\"\n\t\t\t\t\t\tsandbox={sandbox}\n\t\t\t\t\t\tsrc={embedInfo.embedUrl}\n\t\t\t\t\t\twidth={toDomPrecision(w)}\n\t\t\t\t\t\theight={toDomPrecision(h)}\n\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t\t\t\tframeBorder=\"0\"\n\t\t\t\t\t\treferrerPolicy=\"no-referrer-when-downgrade\"\n\t\t\t\t\t\ttabIndex={isEditing ? 0 : -1}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tpointerEvents: isInteractive ? 'auto' : 'none',\n\t\t\t\t\t\t\t// Fix for safari <https://stackoverflow.com/a/49150908>\n\t\t\t\t\t\t\tzIndex: isInteractive ? '' : '-1',\n\t\t\t\t\t\t\tboxShadow: getRotatedBoxShadow(pageRotation),\n\t\t\t\t\t\t\tborderRadius: embedInfo?.definition.overrideOutlineRadius ?? 8,\n\t\t\t\t\t\t\tbackground: embedInfo?.definition.backgroundColor,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t) : null}\n\t\t\t</HTMLContainer>\n\t\t)\n\t}\n\n\toverride indicator(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn (\n\t\t\t<rect\n\t\t\t\twidth={toDomPrecision(shape.props.w)}\n\t\t\t\theight={toDomPrecision(shape.props.h)}\n\t\t\t\trx={embedInfo?.definition.overrideOutlineRadius ?? 8}\n\t\t\t\try={embedInfo?.definition.overrideOutlineRadius ?? 8}\n\t\t\t/>\n\t\t)\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLEmbedShape,\n\t\tendShape: TLEmbedShape,\n\t\tt: number\n\t): TLEmbedShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tw: lerp(startShape.props.w, endShape.props.w, t),\n\t\t\th: lerp(startShape.props.h, endShape.props.h, t),\n\t\t}\n\t}\n}\n\nfunction Gist({\n\tid,\n\tisInteractive,\n\twidth,\n\theight,\n\tstyle,\n\tpageRotation,\n}: {\n\tid: string\n\tisInteractive: boolean\n\twidth: number\n\theight: number\n\tpageRotation: number\n\tstyle?: React.CSSProperties\n}) {\n\t// Security warning:\n\t// Gists allow adding .json extensions to the URL which return JSONP.\n\t// Furthermore, the JSONP can include callbacks that execute arbitrary JavaScript.\n\t// It _is_ sandboxed by the iframe but we still want to disable it nonetheless.\n\t// We restrict the id to only allow hexdecimal characters to prevent this.\n\t// Read more:\n\t// https://github.com/bhaveshk90/Content-Security-Policy-CSP-Bypass-Techniques\n\t// https://github.com/renniepak/CSPBypass\n\tif (!id.match(/^[0-9a-f]+$/)) throw Error('No gist id!')\n\n\treturn (\n\t\t<iframe\n\t\t\tclassName=\"tl-embed\"\n\t\t\tdraggable={false}\n\t\t\twidth={toDomPrecision(width)}\n\t\t\theight={toDomPrecision(height)}\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\tframeBorder=\"0\"\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\tscrolling=\"no\"\n\t\t\treferrerPolicy=\"no-referrer-when-downgrade\"\n\t\t\ttabIndex={isInteractive ? 0 : -1}\n\t\t\tstyle={{\n\t\t\t\t...style,\n\t\t\t\tpointerEvents: isInteractive ? 'all' : 'none',\n\t\t\t\t// Fix for safari <https://stackoverflow.com/a/49150908>\n\t\t\t\tzIndex: isInteractive ? '' : '-1',\n\t\t\t\tboxShadow: getRotatedBoxShadow(pageRotation),\n\t\t\t}}\n\t\t\tsrcDoc={`\n\t\t\t<html>\n\t\t\t\t<head>\n\t\t\t\t\t<base target=\"_blank\">\n\t\t\t\t</head>\n\t\t\t\t<body>\n\t\t\t\t\t<script src=${`https://gist.github.com/${id}.js`}></script>\n\t\t\t\t\t<style type=\"text/css\">\n\t\t\t\t\t\t* { margin: 0px; }\n\t\t\t\t\t\ttable { height: 100%; background-color: red; }\n\t\t\t\t\t\t.gist { background-color: none; height: 100%; }\n\t\t\t\t\t\t.gist .gist-file { height: calc(100vh - 2px); padding: 0px; display: grid; grid-template-rows: 1fr auto; }\n\t\t\t\t\t</style>\n\t\t\t\t</body>\n\t\t\t</html>`}\n\t\t/>\n\t)\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\n\nimport {\n\tBaseBoxShapeUtil,\n\tHTMLContainer,\n\tRectangle2d,\n\tTLEmbedShape,\n\tTLEmbedShapeProps,\n\tTLResizeInfo,\n\tembedShapeMigrations,\n\tembedShapeProps,\n\tlerp,\n\tresizeBox,\n\ttoDomPrecision,\n\tuseIsEditing,\n\tuseSvgExportContext,\n\tuseValue,\n} from '@tldraw/editor'\n\nimport {\n\tDEFAULT_EMBED_DEFINITIONS,\n\tEmbedDefinition,\n\tTLEmbedDefinition,\n\tTLEmbedShapePermissions,\n\tembedShapePermissionDefaults,\n} from '../../defaultEmbedDefinitions'\nimport { TLEmbedResult, getEmbedInfo } from '../../utils/embeds/embeds'\nimport { BookmarkIndicatorComponent, BookmarkShapeComponent } from '../bookmark/BookmarkShapeUtil'\nimport { BOOKMARK_JUST_URL_HEIGHT, BOOKMARK_WIDTH } from '../bookmark/bookmarks'\nimport { getRotatedBoxShadow } from '../shared/rotated-box-shadow'\n\nconst getSandboxPermissions = (permissions: TLEmbedShapePermissions) => {\n\treturn Object.entries(permissions)\n\t\t.filter(([_perm, isEnabled]) => isEnabled)\n\t\t.map(([perm]) => perm)\n\t\t.join(' ')\n}\n\n/** @public */\nexport class EmbedShapeUtil extends BaseBoxShapeUtil<TLEmbedShape> {\n\tstatic override type = 'embed' as const\n\tstatic override props = embedShapeProps\n\tstatic override migrations = embedShapeMigrations\n\tprivate static embedDefinitions: readonly EmbedDefinition[] = DEFAULT_EMBED_DEFINITIONS\n\n\tstatic setEmbedDefinitions(embedDefinitions: readonly TLEmbedDefinition[]) {\n\t\tEmbedShapeUtil.embedDefinitions = embedDefinitions\n\t}\n\n\tgetEmbedDefinitions(): readonly TLEmbedDefinition[] {\n\t\treturn EmbedShapeUtil.embedDefinitions\n\t}\n\n\tgetEmbedDefinition(url: string): TLEmbedResult {\n\t\treturn getEmbedInfo(EmbedShapeUtil.embedDefinitions, url)\n\t}\n\n\toverride getText(shape: TLEmbedShape) {\n\t\treturn shape.props.url\n\t}\n\n\toverride getAriaDescriptor(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn embedInfo?.definition.title\n\t}\n\n\toverride hideSelectionBoundsFg(shape: TLEmbedShape) {\n\t\treturn !this.canResize(shape)\n\t}\n\toverride canEdit() {\n\t\treturn true\n\t}\n\toverride canResize(shape: TLEmbedShape) {\n\t\treturn !!this.getEmbedDefinition(shape.props.url)?.definition?.doesResize\n\t}\n\toverride canEditInReadonly() {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLEmbedShape['props'] {\n\t\treturn {\n\t\t\tw: 300,\n\t\t\th: 300,\n\t\t\turl: '',\n\t\t}\n\t}\n\n\toverride getGeometry(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\tif (!embedInfo?.definition) {\n\t\t\treturn new Rectangle2d({\n\t\t\t\twidth: BOOKMARK_WIDTH,\n\t\t\t\theight: BOOKMARK_JUST_URL_HEIGHT,\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\t\treturn super.getGeometry(shape)\n\t}\n\n\toverride isAspectRatioLocked(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn embedInfo?.definition.isAspectRatioLocked ?? false\n\t}\n\n\toverride onResize(shape: TLEmbedShape, info: TLResizeInfo<TLEmbedShape>) {\n\t\tconst isAspectRatioLocked = this.isAspectRatioLocked(shape)\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\tlet minWidth = embedInfo?.definition.minWidth ?? 200\n\t\tlet minHeight = embedInfo?.definition.minHeight ?? 200\n\t\tif (isAspectRatioLocked) {\n\t\t\t// Enforce aspect ratio\n\t\t\t// Neither the width or height can be less than 200\n\t\t\tconst aspectRatio = shape.props.w / shape.props.h\n\t\t\tif (aspectRatio > 1) {\n\t\t\t\t// Landscape\n\t\t\t\tminWidth *= aspectRatio\n\t\t\t} else {\n\t\t\t\t// Portrait\n\t\t\t\tminHeight /= aspectRatio\n\t\t\t}\n\t\t}\n\n\t\treturn resizeBox(shape, info, { minWidth, minHeight })\n\t}\n\n\toverride component(shape: TLEmbedShape) {\n\t\tconst svgExport = useSvgExportContext()\n\t\tconst { w, h, url } = shape.props\n\t\tconst isEditing = useIsEditing(shape.id)\n\n\t\tconst embedInfo = this.getEmbedDefinition(url)\n\n\t\tconst isHoveringWhileEditingSameShape = useValue(\n\t\t\t'is hovering',\n\t\t\t() => {\n\t\t\t\tconst { editingShapeId, hoveredShapeId } = this.editor.getCurrentPageState()\n\n\t\t\t\tif (editingShapeId && hoveredShapeId !== editingShapeId) {\n\t\t\t\t\tconst editingShape = this.editor.getShape(editingShapeId)\n\t\t\t\t\tif (editingShape && this.editor.isShapeOfType<TLEmbedShape>(editingShape, 'embed')) {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn false\n\t\t\t},\n\t\t\t[]\n\t\t)\n\n\t\tconst pageRotation = this.editor.getShapePageTransform(shape)!.rotation()\n\n\t\tif (svgExport) {\n\t\t\t// for SVG exports, we show a blank embed\n\t\t\treturn (\n\t\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName=\"tl-embed\"\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tboxShadow: getRotatedBoxShadow(pageRotation),\n\t\t\t\t\t\t\tborderRadius: embedInfo?.definition.overrideOutlineRadius ?? 8,\n\t\t\t\t\t\t\tbackground: embedInfo?.definition.backgroundColor ?? 'var(--tl-color-background)',\n\t\t\t\t\t\t\twidth: w,\n\t\t\t\t\t\t\theight: h,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</HTMLContainer>\n\t\t\t)\n\t\t}\n\n\t\tconst isInteractive = isEditing || isHoveringWhileEditingSameShape\n\n\t\t// Prevent nested embedding of tldraw\n\t\tconst isIframe =\n\t\t\ttypeof window !== 'undefined' && (window !== window.top || window.self !== window.parent)\n\t\tif (isIframe && embedInfo?.definition.type === 'tldraw') return null\n\n\t\tif (embedInfo?.definition.type === 'github_gist') {\n\t\t\tconst idFromGistUrl = embedInfo.url.split('/').pop()\n\t\t\tif (!idFromGistUrl) throw Error('No gist id!')\n\n\t\t\treturn (\n\t\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t\t<Gist\n\t\t\t\t\t\tid={idFromGistUrl}\n\t\t\t\t\t\twidth={toDomPrecision(w)!}\n\t\t\t\t\t\theight={toDomPrecision(h)!}\n\t\t\t\t\t\tisInteractive={isInteractive}\n\t\t\t\t\t\tpageRotation={pageRotation}\n\t\t\t\t\t/>\n\t\t\t\t</HTMLContainer>\n\t\t\t)\n\t\t}\n\n\t\tconst sandbox = getSandboxPermissions({\n\t\t\t...embedShapePermissionDefaults,\n\t\t\t...(embedInfo?.definition.overridePermissions ?? {}),\n\t\t})\n\n\t\treturn (\n\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t{embedInfo?.definition ? (\n\t\t\t\t\t<iframe\n\t\t\t\t\t\tclassName=\"tl-embed\"\n\t\t\t\t\t\tsandbox={sandbox}\n\t\t\t\t\t\tsrc={embedInfo.embedUrl}\n\t\t\t\t\t\twidth={toDomPrecision(w)}\n\t\t\t\t\t\theight={toDomPrecision(h)}\n\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t\t\t\tframeBorder=\"0\"\n\t\t\t\t\t\treferrerPolicy=\"no-referrer-when-downgrade\"\n\t\t\t\t\t\ttabIndex={isEditing ? 0 : -1}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tpointerEvents: isInteractive ? 'auto' : 'none',\n\t\t\t\t\t\t\t// Fix for safari <https://stackoverflow.com/a/49150908>\n\t\t\t\t\t\t\tzIndex: isInteractive ? '' : '-1',\n\t\t\t\t\t\t\tboxShadow: getRotatedBoxShadow(pageRotation),\n\t\t\t\t\t\t\tborderRadius: embedInfo?.definition.overrideOutlineRadius ?? 8,\n\t\t\t\t\t\t\tbackground: embedInfo?.definition.backgroundColor,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t) : (\n\t\t\t\t\t<BookmarkShapeComponent\n\t\t\t\t\t\turl={url}\n\t\t\t\t\t\th={h}\n\t\t\t\t\t\trotation={pageRotation}\n\t\t\t\t\t\tassetId={null}\n\t\t\t\t\t\tshowImageContainer={false}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</HTMLContainer>\n\t\t)\n\t}\n\n\toverride indicator(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\n\t\treturn embedInfo?.definition ? (\n\t\t\t<rect\n\t\t\t\twidth={toDomPrecision(shape.props.w)}\n\t\t\t\theight={toDomPrecision(shape.props.h)}\n\t\t\t\trx={embedInfo?.definition.overrideOutlineRadius ?? 8}\n\t\t\t\try={embedInfo?.definition.overrideOutlineRadius ?? 8}\n\t\t\t/>\n\t\t) : (\n\t\t\t<BookmarkIndicatorComponent w={BOOKMARK_WIDTH} h={BOOKMARK_JUST_URL_HEIGHT} />\n\t\t)\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLEmbedShape,\n\t\tendShape: TLEmbedShape,\n\t\tt: number\n\t): TLEmbedShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tw: lerp(startShape.props.w, endShape.props.w, t),\n\t\t\th: lerp(startShape.props.h, endShape.props.h, t),\n\t\t}\n\t}\n}\n\nfunction Gist({\n\tid,\n\tisInteractive,\n\twidth,\n\theight,\n\tstyle,\n\tpageRotation,\n}: {\n\tid: string\n\tisInteractive: boolean\n\twidth: number\n\theight: number\n\tpageRotation: number\n\tstyle?: React.CSSProperties\n}) {\n\t// Security warning:\n\t// Gists allow adding .json extensions to the URL which return JSONP.\n\t// Furthermore, the JSONP can include callbacks that execute arbitrary JavaScript.\n\t// It _is_ sandboxed by the iframe but we still want to disable it nonetheless.\n\t// We restrict the id to only allow hexdecimal characters to prevent this.\n\t// Read more:\n\t// https://github.com/bhaveshk90/Content-Security-Policy-CSP-Bypass-Techniques\n\t// https://github.com/renniepak/CSPBypass\n\tif (!id.match(/^[0-9a-f]+$/)) throw Error('No gist id!')\n\n\treturn (\n\t\t<iframe\n\t\t\tclassName=\"tl-embed\"\n\t\t\tdraggable={false}\n\t\t\twidth={toDomPrecision(width)}\n\t\t\theight={toDomPrecision(height)}\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\tframeBorder=\"0\"\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\tscrolling=\"no\"\n\t\t\treferrerPolicy=\"no-referrer-when-downgrade\"\n\t\t\ttabIndex={isInteractive ? 0 : -1}\n\t\t\tstyle={{\n\t\t\t\t...style,\n\t\t\t\tpointerEvents: isInteractive ? 'all' : 'none',\n\t\t\t\t// Fix for safari <https://stackoverflow.com/a/49150908>\n\t\t\t\tzIndex: isInteractive ? '' : '-1',\n\t\t\t\tboxShadow: getRotatedBoxShadow(pageRotation),\n\t\t\t}}\n\t\t\tsrcDoc={`\n\t\t\t<html>\n\t\t\t\t<head>\n\t\t\t\t\t<base target=\"_blank\">\n\t\t\t\t</head>\n\t\t\t\t<body>\n\t\t\t\t\t<script src=${`https://gist.github.com/${id}.js`}></script>\n\t\t\t\t\t<style type=\"text/css\">\n\t\t\t\t\t\t* { margin: 0px; }\n\t\t\t\t\t\ttable { height: 100%; background-color: red; }\n\t\t\t\t\t\t.gist { background-color: none; height: 100%; }\n\t\t\t\t\t\t.gist .gist-file { height: calc(100vh - 2px); padding: 0px; display: grid; grid-template-rows: 1fr auto; }\n\t\t\t\t\t</style>\n\t\t\t\t</body>\n\t\t\t</html>`}\n\t\t/>\n\t)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/shapes/line/LineShapeUtil.tsx"],
|
|
4
|
-
"sourcesContent": ["import {\n\tGroup2d,\n\tHandleSnapGeometry,\n\tSVGContainer,\n\tShapeUtil,\n\tTLHandle,\n\tTLHandleDragInfo,\n\tTLLineShape,\n\tTLLineShapePoint,\n\tTLResizeInfo,\n\tVec,\n\tWeakCache,\n\tZERO_INDEX_KEY,\n\tassert,\n\tgetColorValue,\n\tgetIndexAbove,\n\tgetIndexBetween,\n\tgetIndices,\n\tlerp,\n\tlineShapeMigrations,\n\tlineShapeProps,\n\tmapObjectMapValues,\n\tmaybeSnapToGrid,\n\tsortByIndex,\n} from '@tldraw/editor'\n\nimport { STROKE_SIZES } from '../arrow/shared'\nimport { PathBuilder, PathBuilderGeometry2d } from '../shared/PathBuilder'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\n\nconst handlesCache = new WeakCache<TLLineShape['props'], TLHandle[]>()\n\n/** @public */\nexport class LineShapeUtil extends ShapeUtil<TLLineShape> {\n\tstatic override type = 'line' as const\n\tstatic override props = lineShapeProps\n\tstatic override migrations = lineShapeMigrations\n\n\toverride hideResizeHandles() {\n\t\treturn true\n\t}\n\toverride hideRotateHandle() {\n\t\treturn true\n\t}\n\toverride hideSelectionBoundsFg() {\n\t\treturn true\n\t}\n\toverride hideSelectionBoundsBg() {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLLineShape['props'] {\n\t\tconst [start, end] = getIndices(2)\n\t\treturn {\n\t\t\tdash: 'draw',\n\t\t\tsize: 'm',\n\t\t\tcolor: 'black',\n\t\t\tspline: 'line',\n\t\t\tpoints: {\n\t\t\t\t[start]: { id: start, index: start, x: 0, y: 0 },\n\t\t\t\t[end]: { id: end, index: end, x: 0.1, y: 0.1 },\n\t\t\t},\n\t\t\tscale: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLLineShape) {\n\t\t// todo: should we have min size?\n\t\tconst geometry = getPathForLineShape(shape).toGeometry()\n\t\tassert(geometry instanceof PathBuilderGeometry2d)\n\t\treturn geometry\n\t}\n\n\toverride getHandles(shape: TLLineShape) {\n\t\treturn handlesCache.get(shape.props, () => {\n\t\t\tconst spline = this.getGeometry(shape)\n\n\t\t\tconst points = linePointsToArray(shape)\n\t\t\tconst results: TLHandle[] = points.map((point) => ({\n\t\t\t\t...point,\n\t\t\t\tid: point.index,\n\t\t\t\ttype: 'vertex',\n\t\t\t\tcanSnap: true,\n\t\t\t}))\n\n\t\t\tfor (let i = 0; i < points.length - 1; i++) {\n\t\t\t\tconst index = getIndexBetween(points[i].index, points[i + 1].index)\n\t\t\t\tconst segment = spline.getSegments()[i]\n\t\t\t\tconst point = segment.interpolateAlongEdge(0.5)\n\t\t\t\tresults.push({\n\t\t\t\t\tid: index,\n\t\t\t\t\ttype: 'create',\n\t\t\t\t\tindex,\n\t\t\t\t\tx: point.x,\n\t\t\t\t\ty: point.y,\n\t\t\t\t\tcanSnap: true,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\treturn results.sort(sortByIndex)\n\t\t})\n\t}\n\n\t// Events\n\n\toverride onResize(shape: TLLineShape, info: TLResizeInfo<TLLineShape>) {\n\t\tconst { scaleX, scaleY } = info\n\n\t\treturn {\n\t\t\tprops: {\n\t\t\t\tpoints: mapObjectMapValues(shape.props.points, (_, { id, index, x, y }) => ({\n\t\t\t\t\tid,\n\t\t\t\t\tindex,\n\t\t\t\t\tx: x * scaleX,\n\t\t\t\t\ty: y * scaleY,\n\t\t\t\t})),\n\t\t\t},\n\t\t}\n\t}\n\n\toverride onBeforeCreate(next: TLLineShape): void | TLLineShape {\n\t\tconst {\n\t\t\tprops: { points },\n\t\t} = next\n\t\tconst pointKeys = Object.keys(points)\n\n\t\tif (pointKeys.length < 2) {\n\t\t\treturn\n\t\t}\n\n\t\tconst firstPoint = points[pointKeys[0]]\n\t\tconst allSame = pointKeys.every((key) => {\n\t\t\tconst point = points[key]\n\t\t\treturn point.x === firstPoint.x && point.y === firstPoint.y\n\t\t})\n\t\tif (allSame) {\n\t\t\tconst lastKey = pointKeys[pointKeys.length - 1]\n\t\t\tpoints[lastKey] = {\n\t\t\t\t...points[lastKey],\n\t\t\t\tx: points[lastKey].x + 0.1,\n\t\t\t\ty: points[lastKey].y + 0.1,\n\t\t\t}\n\t\t\treturn next\n\t\t}\n\t\treturn\n\t}\n\n\toverride onHandleDrag(shape: TLLineShape, { handle }: TLHandleDragInfo<TLLineShape>) {\n\t\tconst newPoint = maybeSnapToGrid(new Vec(handle.x, handle.y), this.editor)\n\t\treturn {\n\t\t\t...shape,\n\t\t\tprops: {\n\t\t\t\t...shape.props,\n\t\t\t\tpoints: {\n\t\t\t\t\t...shape.props.points,\n\t\t\t\t\t[handle.id]: { id: handle.id, index: handle.index, x: newPoint.x, y: newPoint.y },\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t}\n\n\toverride onHandleDragStart(shape: TLLineShape, { handle }: TLHandleDragInfo<TLLineShape>) {\n\t\t// For line shapes, if we're dragging a \"create\" handle, then\n\t\t// create a new vertex handle at that point; and make this handle\n\t\t// the handle that we're dragging.\n\t\tif (handle.type === 'create') {\n\t\t\treturn {\n\t\t\t\t...shape,\n\t\t\t\tprops: {\n\t\t\t\t\t...shape.props,\n\t\t\t\t\tpoints: {\n\t\t\t\t\t\t...shape.props.points,\n\t\t\t\t\t\t[handle.index]: { id: handle.index, index: handle.index, x: handle.x, y: handle.y },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\t\treturn\n\t}\n\n\tcomponent(shape: TLLineShape) {\n\t\treturn (\n\t\t\t<SVGContainer style={{ minWidth: 50, minHeight: 50 }}>\n\t\t\t\t<LineShapeSvg shape={shape} />\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\tindicator(shape: TLLineShape) {\n\t\tconst strokeWidth = STROKE_SIZES[shape.props.size] * shape.props.scale\n\t\tconst path = getPathForLineShape(shape)\n\t\tconst { dash } = shape.props\n\n\t\treturn path.toSvg({\n\t\t\tstyle: dash === 'draw' ? 'draw' : 'solid',\n\t\t\tstrokeWidth: 1,\n\t\t\tpasses: 1,\n\t\t\trandomSeed: shape.id,\n\t\t\toffset: 0,\n\t\t\troundness: strokeWidth * 2,\n\t\t\tprops: { strokeWidth: undefined },\n\t\t})\n\t}\n\n\toverride toSvg(shape: TLLineShape) {\n\t\treturn <LineShapeSvg shouldScale shape={shape} />\n\t}\n\n\toverride getHandleSnapGeometry(shape: TLLineShape): HandleSnapGeometry {\n\t\tconst points = linePointsToArray(shape)\n\t\treturn {\n\t\t\tpoints,\n\t\t\tgetSelfSnapPoints: (handle) => {\n\t\t\t\tconst index = this.getHandles(shape)\n\t\t\t\t\t.filter((h) => h.type === 'vertex')\n\t\t\t\t\t.findIndex((h) => h.id === handle.id)!\n\n\t\t\t\t// We want to skip the current and adjacent handles\n\t\t\t\treturn points.filter((_, i) => Math.abs(i - index) > 1).map(Vec.From)\n\t\t\t},\n\t\t\tgetSelfSnapOutline: (handle) => {\n\t\t\t\t// We want to skip the segments that include the handle, so\n\t\t\t\t// find the index of the handle that shares the same index property\n\t\t\t\t// as the initial dragging handle; this catches a quirk of create handles\n\t\t\t\tconst index = this.getHandles(shape)\n\t\t\t\t\t.filter((h) => h.type === 'vertex')\n\t\t\t\t\t.findIndex((h) => h.id === handle.id)!\n\n\t\t\t\t// Get all the outline segments from the shape that don't include the handle\n\t\t\t\tconst segments = this.getGeometry(shape)\n\t\t\t\t\t.getSegments()\n\t\t\t\t\t.filter((_, i) => i !== index - 1 && i !== index)\n\n\t\t\t\tif (!segments.length) return null\n\t\t\t\treturn new Group2d({ children: segments })\n\t\t\t},\n\t\t}\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLLineShape,\n\t\tendShape: TLLineShape,\n\t\tt: number\n\t): TLLineShape['props'] {\n\t\tconst startPoints = linePointsToArray(startShape)\n\t\tconst endPoints = linePointsToArray(endShape)\n\n\t\tconst pointsToUseStart: TLLineShapePoint[] = []\n\t\tconst pointsToUseEnd: TLLineShapePoint[] = []\n\n\t\tlet index = ZERO_INDEX_KEY\n\n\t\tif (startPoints.length > endPoints.length) {\n\t\t\t// we'll need to expand points\n\t\t\tfor (let i = 0; i < startPoints.length; i++) {\n\t\t\t\tpointsToUseStart[i] = { ...startPoints[i] }\n\t\t\t\tif (endPoints[i] === undefined) {\n\t\t\t\t\tpointsToUseEnd[i] = { ...endPoints[endPoints.length - 1], id: index }\n\t\t\t\t} else {\n\t\t\t\t\tpointsToUseEnd[i] = { ...endPoints[i], id: index }\n\t\t\t\t}\n\t\t\t\tindex = getIndexAbove(index)\n\t\t\t}\n\t\t} else if (endPoints.length > startPoints.length) {\n\t\t\t// we'll need to converge points\n\t\t\tfor (let i = 0; i < endPoints.length; i++) {\n\t\t\t\tpointsToUseEnd[i] = { ...endPoints[i] }\n\t\t\t\tif (startPoints[i] === undefined) {\n\t\t\t\t\tpointsToUseStart[i] = {\n\t\t\t\t\t\t...startPoints[startPoints.length - 1],\n\t\t\t\t\t\tid: index,\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tpointsToUseStart[i] = { ...startPoints[i], id: index }\n\t\t\t\t}\n\t\t\t\tindex = getIndexAbove(index)\n\t\t\t}\n\t\t} else {\n\t\t\t// noop, easy\n\t\t\tfor (let i = 0; i < endPoints.length; i++) {\n\t\t\t\tpointsToUseStart[i] = startPoints[i]\n\t\t\t\tpointsToUseEnd[i] = endPoints[i]\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tpoints: Object.fromEntries(\n\t\t\t\tpointsToUseStart.map((point, i) => {\n\t\t\t\t\tconst endPoint = pointsToUseEnd[i]\n\t\t\t\t\treturn [\n\t\t\t\t\t\tpoint.id,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...point,\n\t\t\t\t\t\t\tx: lerp(point.x, endPoint.x, t),\n\t\t\t\t\t\t\ty: lerp(point.y, endPoint.y, t),\n\t\t\t\t\t\t},\n\t\t\t\t\t]\n\t\t\t\t})\n\t\t\t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\nfunction linePointsToArray(shape: TLLineShape) {\n\treturn Object.values(shape.props.points).sort(sortByIndex)\n}\n\nconst pathCache = new WeakCache<TLLineShape, PathBuilder>()\nfunction getPathForLineShape(shape: TLLineShape): PathBuilder {\n\treturn pathCache.get(shape, () => {\n\t\tconst points = linePointsToArray(shape).map(Vec.From)\n\n\t\tswitch (shape.props.spline) {\n\t\t\tcase 'cubic': {\n\t\t\t\treturn PathBuilder.cubicSplineThroughPoints(points, { endOffsets: 0 })\n\t\t\t}\n\t\t\tcase 'line': {\n\t\t\t\treturn PathBuilder.lineThroughPoints(points, { endOffsets: 0 })\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunction LineShapeSvg({\n\tshape,\n\tshouldScale = false,\n\tforceSolid = false,\n}: {\n\tshape: TLLineShape\n\tshouldScale?: boolean\n\tforceSolid?: boolean\n}) {\n\tconst theme = useDefaultColorTheme()\n\n\tconst path = getPathForLineShape(shape)\n\tconst { dash, color, size } = shape.props\n\n\tconst scaleFactor = 1 / shape.props.scale\n\n\tconst scale = shouldScale ? scaleFactor : 1\n\n\tconst strokeWidth = STROKE_SIZES[size] * shape.props.scale\n\n\treturn path.toSvg({\n\t\tstyle: dash,\n\t\tstrokeWidth,\n\t\tforceSolid,\n\t\trandomSeed: shape.id,\n\t\tprops: {\n\t\t\ttransform: `scale(${scale})`,\n\t\t\tstroke: getColorValue(theme, color, 'solid'),\n\t\t\tfill: 'none',\n\t\t},\n\t})\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["import {\n\tGroup2d,\n\tHandleSnapGeometry,\n\tSVGContainer,\n\tShapeUtil,\n\tTLHandle,\n\tTLHandleDragInfo,\n\tTLLineShape,\n\tTLLineShapePoint,\n\tTLResizeInfo,\n\tVec,\n\tWeakCache,\n\tZERO_INDEX_KEY,\n\tassert,\n\tgetColorValue,\n\tgetIndexAbove,\n\tgetIndexBetween,\n\tgetIndices,\n\tlerp,\n\tlineShapeMigrations,\n\tlineShapeProps,\n\tmapObjectMapValues,\n\tmaybeSnapToGrid,\n\tsortByIndex,\n} from '@tldraw/editor'\n\nimport { STROKE_SIZES } from '../arrow/shared'\nimport { PathBuilder, PathBuilderGeometry2d } from '../shared/PathBuilder'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\n\nconst handlesCache = new WeakCache<TLLineShape['props'], TLHandle[]>()\n\n/** @public */\nexport class LineShapeUtil extends ShapeUtil<TLLineShape> {\n\tstatic override type = 'line' as const\n\tstatic override props = lineShapeProps\n\tstatic override migrations = lineShapeMigrations\n\n\toverride hideResizeHandles() {\n\t\treturn true\n\t}\n\toverride hideRotateHandle() {\n\t\treturn true\n\t}\n\toverride hideSelectionBoundsFg() {\n\t\treturn true\n\t}\n\toverride hideSelectionBoundsBg() {\n\t\treturn true\n\t}\n\toverride hideInMinimap() {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLLineShape['props'] {\n\t\tconst [start, end] = getIndices(2)\n\t\treturn {\n\t\t\tdash: 'draw',\n\t\t\tsize: 'm',\n\t\t\tcolor: 'black',\n\t\t\tspline: 'line',\n\t\t\tpoints: {\n\t\t\t\t[start]: { id: start, index: start, x: 0, y: 0 },\n\t\t\t\t[end]: { id: end, index: end, x: 0.1, y: 0.1 },\n\t\t\t},\n\t\t\tscale: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLLineShape) {\n\t\t// todo: should we have min size?\n\t\tconst geometry = getPathForLineShape(shape).toGeometry()\n\t\tassert(geometry instanceof PathBuilderGeometry2d)\n\t\treturn geometry\n\t}\n\n\toverride getHandles(shape: TLLineShape) {\n\t\treturn handlesCache.get(shape.props, () => {\n\t\t\tconst spline = this.getGeometry(shape)\n\n\t\t\tconst points = linePointsToArray(shape)\n\t\t\tconst results: TLHandle[] = points.map((point) => ({\n\t\t\t\t...point,\n\t\t\t\tid: point.index,\n\t\t\t\ttype: 'vertex',\n\t\t\t\tcanSnap: true,\n\t\t\t}))\n\n\t\t\tfor (let i = 0; i < points.length - 1; i++) {\n\t\t\t\tconst index = getIndexBetween(points[i].index, points[i + 1].index)\n\t\t\t\tconst segment = spline.getSegments()[i]\n\t\t\t\tconst point = segment.interpolateAlongEdge(0.5)\n\t\t\t\tresults.push({\n\t\t\t\t\tid: index,\n\t\t\t\t\ttype: 'create',\n\t\t\t\t\tindex,\n\t\t\t\t\tx: point.x,\n\t\t\t\t\ty: point.y,\n\t\t\t\t\tcanSnap: true,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\treturn results.sort(sortByIndex)\n\t\t})\n\t}\n\n\t// Events\n\n\toverride onResize(shape: TLLineShape, info: TLResizeInfo<TLLineShape>) {\n\t\tconst { scaleX, scaleY } = info\n\n\t\treturn {\n\t\t\tprops: {\n\t\t\t\tpoints: mapObjectMapValues(shape.props.points, (_, { id, index, x, y }) => ({\n\t\t\t\t\tid,\n\t\t\t\t\tindex,\n\t\t\t\t\tx: x * scaleX,\n\t\t\t\t\ty: y * scaleY,\n\t\t\t\t})),\n\t\t\t},\n\t\t}\n\t}\n\n\toverride onBeforeCreate(next: TLLineShape): void | TLLineShape {\n\t\tconst {\n\t\t\tprops: { points },\n\t\t} = next\n\t\tconst pointKeys = Object.keys(points)\n\n\t\tif (pointKeys.length < 2) {\n\t\t\treturn\n\t\t}\n\n\t\tconst firstPoint = points[pointKeys[0]]\n\t\tconst allSame = pointKeys.every((key) => {\n\t\t\tconst point = points[key]\n\t\t\treturn point.x === firstPoint.x && point.y === firstPoint.y\n\t\t})\n\t\tif (allSame) {\n\t\t\tconst lastKey = pointKeys[pointKeys.length - 1]\n\t\t\tpoints[lastKey] = {\n\t\t\t\t...points[lastKey],\n\t\t\t\tx: points[lastKey].x + 0.1,\n\t\t\t\ty: points[lastKey].y + 0.1,\n\t\t\t}\n\t\t\treturn next\n\t\t}\n\t\treturn\n\t}\n\n\toverride onHandleDrag(shape: TLLineShape, { handle }: TLHandleDragInfo<TLLineShape>) {\n\t\tconst newPoint = maybeSnapToGrid(new Vec(handle.x, handle.y), this.editor)\n\t\treturn {\n\t\t\t...shape,\n\t\t\tprops: {\n\t\t\t\t...shape.props,\n\t\t\t\tpoints: {\n\t\t\t\t\t...shape.props.points,\n\t\t\t\t\t[handle.id]: { id: handle.id, index: handle.index, x: newPoint.x, y: newPoint.y },\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t}\n\n\toverride onHandleDragStart(shape: TLLineShape, { handle }: TLHandleDragInfo<TLLineShape>) {\n\t\t// For line shapes, if we're dragging a \"create\" handle, then\n\t\t// create a new vertex handle at that point; and make this handle\n\t\t// the handle that we're dragging.\n\t\tif (handle.type === 'create') {\n\t\t\treturn {\n\t\t\t\t...shape,\n\t\t\t\tprops: {\n\t\t\t\t\t...shape.props,\n\t\t\t\t\tpoints: {\n\t\t\t\t\t\t...shape.props.points,\n\t\t\t\t\t\t[handle.index]: { id: handle.index, index: handle.index, x: handle.x, y: handle.y },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\t\treturn\n\t}\n\n\tcomponent(shape: TLLineShape) {\n\t\treturn (\n\t\t\t<SVGContainer style={{ minWidth: 50, minHeight: 50 }}>\n\t\t\t\t<LineShapeSvg shape={shape} />\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\tindicator(shape: TLLineShape) {\n\t\tconst strokeWidth = STROKE_SIZES[shape.props.size] * shape.props.scale\n\t\tconst path = getPathForLineShape(shape)\n\t\tconst { dash } = shape.props\n\n\t\treturn path.toSvg({\n\t\t\tstyle: dash === 'draw' ? 'draw' : 'solid',\n\t\t\tstrokeWidth: 1,\n\t\t\tpasses: 1,\n\t\t\trandomSeed: shape.id,\n\t\t\toffset: 0,\n\t\t\troundness: strokeWidth * 2,\n\t\t\tprops: { strokeWidth: undefined },\n\t\t})\n\t}\n\n\toverride toSvg(shape: TLLineShape) {\n\t\treturn <LineShapeSvg shouldScale shape={shape} />\n\t}\n\n\toverride getHandleSnapGeometry(shape: TLLineShape): HandleSnapGeometry {\n\t\tconst points = linePointsToArray(shape)\n\t\treturn {\n\t\t\tpoints,\n\t\t\tgetSelfSnapPoints: (handle) => {\n\t\t\t\tconst index = this.getHandles(shape)\n\t\t\t\t\t.filter((h) => h.type === 'vertex')\n\t\t\t\t\t.findIndex((h) => h.id === handle.id)!\n\n\t\t\t\t// We want to skip the current and adjacent handles\n\t\t\t\treturn points.filter((_, i) => Math.abs(i - index) > 1).map(Vec.From)\n\t\t\t},\n\t\t\tgetSelfSnapOutline: (handle) => {\n\t\t\t\t// We want to skip the segments that include the handle, so\n\t\t\t\t// find the index of the handle that shares the same index property\n\t\t\t\t// as the initial dragging handle; this catches a quirk of create handles\n\t\t\t\tconst index = this.getHandles(shape)\n\t\t\t\t\t.filter((h) => h.type === 'vertex')\n\t\t\t\t\t.findIndex((h) => h.id === handle.id)!\n\n\t\t\t\t// Get all the outline segments from the shape that don't include the handle\n\t\t\t\tconst segments = this.getGeometry(shape)\n\t\t\t\t\t.getSegments()\n\t\t\t\t\t.filter((_, i) => i !== index - 1 && i !== index)\n\n\t\t\t\tif (!segments.length) return null\n\t\t\t\treturn new Group2d({ children: segments })\n\t\t\t},\n\t\t}\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLLineShape,\n\t\tendShape: TLLineShape,\n\t\tt: number\n\t): TLLineShape['props'] {\n\t\tconst startPoints = linePointsToArray(startShape)\n\t\tconst endPoints = linePointsToArray(endShape)\n\n\t\tconst pointsToUseStart: TLLineShapePoint[] = []\n\t\tconst pointsToUseEnd: TLLineShapePoint[] = []\n\n\t\tlet index = ZERO_INDEX_KEY\n\n\t\tif (startPoints.length > endPoints.length) {\n\t\t\t// we'll need to expand points\n\t\t\tfor (let i = 0; i < startPoints.length; i++) {\n\t\t\t\tpointsToUseStart[i] = { ...startPoints[i] }\n\t\t\t\tif (endPoints[i] === undefined) {\n\t\t\t\t\tpointsToUseEnd[i] = { ...endPoints[endPoints.length - 1], id: index }\n\t\t\t\t} else {\n\t\t\t\t\tpointsToUseEnd[i] = { ...endPoints[i], id: index }\n\t\t\t\t}\n\t\t\t\tindex = getIndexAbove(index)\n\t\t\t}\n\t\t} else if (endPoints.length > startPoints.length) {\n\t\t\t// we'll need to converge points\n\t\t\tfor (let i = 0; i < endPoints.length; i++) {\n\t\t\t\tpointsToUseEnd[i] = { ...endPoints[i] }\n\t\t\t\tif (startPoints[i] === undefined) {\n\t\t\t\t\tpointsToUseStart[i] = {\n\t\t\t\t\t\t...startPoints[startPoints.length - 1],\n\t\t\t\t\t\tid: index,\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tpointsToUseStart[i] = { ...startPoints[i], id: index }\n\t\t\t\t}\n\t\t\t\tindex = getIndexAbove(index)\n\t\t\t}\n\t\t} else {\n\t\t\t// noop, easy\n\t\t\tfor (let i = 0; i < endPoints.length; i++) {\n\t\t\t\tpointsToUseStart[i] = startPoints[i]\n\t\t\t\tpointsToUseEnd[i] = endPoints[i]\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tpoints: Object.fromEntries(\n\t\t\t\tpointsToUseStart.map((point, i) => {\n\t\t\t\t\tconst endPoint = pointsToUseEnd[i]\n\t\t\t\t\treturn [\n\t\t\t\t\t\tpoint.id,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...point,\n\t\t\t\t\t\t\tx: lerp(point.x, endPoint.x, t),\n\t\t\t\t\t\t\ty: lerp(point.y, endPoint.y, t),\n\t\t\t\t\t\t},\n\t\t\t\t\t]\n\t\t\t\t})\n\t\t\t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\nfunction linePointsToArray(shape: TLLineShape) {\n\treturn Object.values(shape.props.points).sort(sortByIndex)\n}\n\nconst pathCache = new WeakCache<TLLineShape, PathBuilder>()\nfunction getPathForLineShape(shape: TLLineShape): PathBuilder {\n\treturn pathCache.get(shape, () => {\n\t\tconst points = linePointsToArray(shape).map(Vec.From)\n\n\t\tswitch (shape.props.spline) {\n\t\t\tcase 'cubic': {\n\t\t\t\treturn PathBuilder.cubicSplineThroughPoints(points, { endOffsets: 0 })\n\t\t\t}\n\t\t\tcase 'line': {\n\t\t\t\treturn PathBuilder.lineThroughPoints(points, { endOffsets: 0 })\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunction LineShapeSvg({\n\tshape,\n\tshouldScale = false,\n\tforceSolid = false,\n}: {\n\tshape: TLLineShape\n\tshouldScale?: boolean\n\tforceSolid?: boolean\n}) {\n\tconst theme = useDefaultColorTheme()\n\n\tconst path = getPathForLineShape(shape)\n\tconst { dash, color, size } = shape.props\n\n\tconst scaleFactor = 1 / shape.props.scale\n\n\tconst scale = shouldScale ? scaleFactor : 1\n\n\tconst strokeWidth = STROKE_SIZES[size] * shape.props.scale\n\n\treturn path.toSvg({\n\t\tstyle: dash,\n\t\tstrokeWidth,\n\t\tforceSolid,\n\t\trandomSeed: shape.id,\n\t\tprops: {\n\t\t\ttransform: `scale(${scale})`,\n\t\t\tstroke: getColorValue(theme, color, 'solid'),\n\t\t\tfill: 'none',\n\t\t},\n\t})\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -31,6 +31,9 @@ class Cropping extends import_editor.StateNode {
|
|
|
31
31
|
snapshot = {};
|
|
32
32
|
onEnter(info) {
|
|
33
33
|
this.info = info;
|
|
34
|
+
if (typeof info.onInteractionEnd === "string") {
|
|
35
|
+
this.parent.setCurrentToolIdMask(info.onInteractionEnd);
|
|
36
|
+
}
|
|
34
37
|
this.markId = this.editor.markHistoryStoppingPoint("cropping");
|
|
35
38
|
this.snapshot = this.createSnapshot();
|
|
36
39
|
this.updateShapes();
|
|
@@ -53,6 +56,9 @@ class Cropping extends import_editor.StateNode {
|
|
|
53
56
|
onCancel() {
|
|
54
57
|
this.cancel();
|
|
55
58
|
}
|
|
59
|
+
onExit() {
|
|
60
|
+
this.parent.setCurrentToolIdMask(void 0);
|
|
61
|
+
}
|
|
56
62
|
updateCursor() {
|
|
57
63
|
const selectedShape = this.editor.getSelectedShapes()[0];
|
|
58
64
|
if (!selectedShape) return;
|
|
@@ -92,8 +98,13 @@ class Cropping extends import_editor.StateNode {
|
|
|
92
98
|
complete() {
|
|
93
99
|
this.updateShapes();
|
|
94
100
|
(0, import_editor.kickoutOccludedShapes)(this.editor, [this.snapshot.shape.id]);
|
|
95
|
-
|
|
96
|
-
|
|
101
|
+
const { onInteractionEnd } = this.info;
|
|
102
|
+
if (onInteractionEnd) {
|
|
103
|
+
if (typeof onInteractionEnd === "string") {
|
|
104
|
+
this.editor.setCurrentTool(onInteractionEnd, this.info);
|
|
105
|
+
} else {
|
|
106
|
+
onInteractionEnd();
|
|
107
|
+
}
|
|
97
108
|
} else {
|
|
98
109
|
this.editor.setCroppingShape(null);
|
|
99
110
|
this.editor.setCurrentTool("select.idle");
|
|
@@ -101,8 +112,13 @@ class Cropping extends import_editor.StateNode {
|
|
|
101
112
|
}
|
|
102
113
|
cancel() {
|
|
103
114
|
this.editor.bailToMark(this.markId);
|
|
104
|
-
|
|
105
|
-
|
|
115
|
+
const { onInteractionEnd } = this.info;
|
|
116
|
+
if (onInteractionEnd) {
|
|
117
|
+
if (typeof onInteractionEnd === "string") {
|
|
118
|
+
this.editor.setCurrentTool(onInteractionEnd, this.info);
|
|
119
|
+
} else {
|
|
120
|
+
onInteractionEnd();
|
|
121
|
+
}
|
|
106
122
|
} else {
|
|
107
123
|
this.editor.setCroppingShape(null);
|
|
108
124
|
this.editor.setCurrentTool("select.idle");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../../src/lib/tools/SelectTool/childStates/Crop/children/Cropping.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\tSelectionHandle,\n\tShapeWithCrop,\n\tStateNode,\n\tTLPointerEventInfo,\n\tVec,\n\tkickoutOccludedShapes,\n} from '@tldraw/editor'\nimport { getCropBox, getDefaultCrop, getUncroppedSize } from '../../../../../shapes/shared/crop'\nimport { CursorTypeMap } from '../../PointingResizeHandle'\n\ntype Snapshot = ReturnType<Cropping['createSnapshot']>\n\nexport class Cropping extends StateNode {\n\tstatic override id = 'cropping'\n\n\tinfo = {} as TLPointerEventInfo & {\n\t\ttarget: 'selection'\n\t\thandle: SelectionHandle\n\t\tonInteractionEnd?: string\n\t}\n\n\tmarkId = ''\n\n\tprivate snapshot = {} as any as Snapshot\n\n\toverride onEnter(\n\t\tinfo: TLPointerEventInfo & {\n\t\t\ttarget: 'selection'\n\t\t\thandle: SelectionHandle\n\t\t\tonInteractionEnd?: string\n\t\t}\n\t) {\n\t\tthis.info = info\n\t\tthis.markId = this.editor.markHistoryStoppingPoint('cropping')\n\t\tthis.snapshot = this.createSnapshot()\n\t\tthis.updateShapes()\n\t}\n\n\toverride onPointerMove() {\n\t\tthis.updateShapes()\n\t}\n\n\toverride onKeyDown() {\n\t\tthis.updateShapes()\n\t}\n\n\toverride onKeyUp() {\n\t\tthis.updateShapes()\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onComplete() {\n\t\tthis.complete()\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\tprivate updateCursor() {\n\t\tconst selectedShape = this.editor.getSelectedShapes()[0]\n\t\tif (!selectedShape) return\n\n\t\tconst cursorType = CursorTypeMap[this.info.handle!]\n\t\tthis.editor.setCursor({ type: cursorType, rotation: this.editor.getSelectionRotation() })\n\t}\n\n\tprivate updateShapes() {\n\t\tconst { shape, cursorHandleOffset } = this.snapshot\n\n\t\tif (!shape) return\n\t\tconst util = this.editor.getShapeUtil<ShapeWithCrop>(shape.type)\n\t\tif (!util) return\n\n\t\tconst { shiftKey } = this.editor.inputs\n\t\tconst currentPagePoint = this.editor.inputs.currentPagePoint.clone().sub(cursorHandleOffset)\n\t\tconst originPagePoint = this.editor.inputs.originPagePoint.clone().sub(cursorHandleOffset)\n\t\tconst change = currentPagePoint.clone().sub(originPagePoint).rot(-shape.rotation)\n\n\t\tconst crop = shape.props.crop ?? getDefaultCrop()\n\t\tconst uncroppedSize = getUncroppedSize(shape.props, crop)\n\n\t\tconst cropFn = util.onCrop?.bind(util) ?? getCropBox\n\t\tconst partial = cropFn(shape, {\n\t\t\thandle: this.info.handle,\n\t\t\tchange,\n\t\t\tcrop,\n\t\t\tuncroppedSize,\n\t\t\tinitialShape: this.snapshot.shape,\n\t\t\taspectRatioLocked: shiftKey,\n\t\t})\n\t\tif (!partial) return\n\n\t\tthis.editor.updateShapes([\n\t\t\t{\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\t...partial,\n\t\t\t},\n\t\t])\n\t\tthis.updateCursor()\n\t}\n\n\tprivate complete() {\n\t\tthis.updateShapes()\n\t\tkickoutOccludedShapes(this.editor, [this.snapshot.shape.id])\n\t\
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAOO;AACP,kBAA6D;AAC7D,kCAA8B;AAIvB,MAAM,iBAAiB,wBAAU;AAAA,EACvC,OAAgB,KAAK;AAAA,EAErB,OAAO,CAAC;AAAA,EAMR,SAAS;AAAA,EAED,WAAW,CAAC;AAAA,EAEX,QACR,MAKC;AACD,SAAK,OAAO;AACZ,SAAK,SAAS,KAAK,OAAO,yBAAyB,UAAU;AAC7D,SAAK,WAAW,KAAK,eAAe;AACpC,SAAK,aAAa;AAAA,EACnB;AAAA,EAES,gBAAgB;AACxB,SAAK,aAAa;AAAA,EACnB;AAAA,EAES,YAAY;AACpB,SAAK,aAAa;AAAA,EACnB;AAAA,EAES,UAAU;AAClB,SAAK,aAAa;AAAA,EACnB;AAAA,EAES,cAAc;AACtB,SAAK,SAAS;AAAA,EACf;AAAA,EAES,aAAa;AACrB,SAAK,SAAS;AAAA,EACf;AAAA,EAES,WAAW;AACnB,SAAK,OAAO;AAAA,EACb;AAAA,EAEQ,eAAe;AACtB,UAAM,gBAAgB,KAAK,OAAO,kBAAkB,EAAE,CAAC;AACvD,QAAI,CAAC,cAAe;AAEpB,UAAM,aAAa,0CAAc,KAAK,KAAK,MAAO;AAClD,SAAK,OAAO,UAAU,EAAE,MAAM,YAAY,UAAU,KAAK,OAAO,qBAAqB,EAAE,CAAC;AAAA,EACzF;AAAA,EAEQ,eAAe;AACtB,UAAM,EAAE,OAAO,mBAAmB,IAAI,KAAK;AAE3C,QAAI,CAAC,MAAO;AACZ,UAAM,OAAO,KAAK,OAAO,aAA4B,MAAM,IAAI;AAC/D,QAAI,CAAC,KAAM;AAEX,UAAM,EAAE,SAAS,IAAI,KAAK,OAAO;AACjC,UAAM,mBAAmB,KAAK,OAAO,OAAO,iBAAiB,MAAM,EAAE,IAAI,kBAAkB;AAC3F,UAAM,kBAAkB,KAAK,OAAO,OAAO,gBAAgB,MAAM,EAAE,IAAI,kBAAkB;AACzF,UAAM,SAAS,iBAAiB,MAAM,EAAE,IAAI,eAAe,EAAE,IAAI,CAAC,MAAM,QAAQ;AAEhF,UAAM,OAAO,MAAM,MAAM,YAAQ,4BAAe;AAChD,UAAM,oBAAgB,8BAAiB,MAAM,OAAO,IAAI;AAExD,UAAM,SAAS,KAAK,QAAQ,KAAK,IAAI,KAAK;AAC1C,UAAM,UAAU,OAAO,OAAO;AAAA,MAC7B,QAAQ,KAAK,KAAK;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA,cAAc,KAAK,SAAS;AAAA,MAC5B,mBAAmB;AAAA,IACpB,CAAC;AACD,QAAI,CAAC,QAAS;AAEd,SAAK,OAAO,aAAa;AAAA,MACxB;AAAA,QACC,IAAI,MAAM;AAAA,QACV,MAAM,MAAM;AAAA,QACZ,GAAG;AAAA,MACJ;AAAA,IACD,CAAC;AACD,SAAK,aAAa;AAAA,EACnB;AAAA,EAEQ,WAAW;AAClB,SAAK,aAAa;AAClB,6CAAsB,KAAK,QAAQ,CAAC,KAAK,SAAS,MAAM,EAAE,CAAC;AAC3D,
|
|
4
|
+
"sourcesContent": ["import {\n\tSelectionHandle,\n\tShapeWithCrop,\n\tStateNode,\n\tTLPointerEventInfo,\n\tVec,\n\tkickoutOccludedShapes,\n} from '@tldraw/editor'\nimport { getCropBox, getDefaultCrop, getUncroppedSize } from '../../../../../shapes/shared/crop'\nimport { CursorTypeMap } from '../../PointingResizeHandle'\n\ntype Snapshot = ReturnType<Cropping['createSnapshot']>\n\nexport class Cropping extends StateNode {\n\tstatic override id = 'cropping'\n\n\tinfo = {} as TLPointerEventInfo & {\n\t\ttarget: 'selection'\n\t\thandle: SelectionHandle\n\t\tonInteractionEnd?: string | (() => void)\n\t}\n\n\tmarkId = ''\n\n\tprivate snapshot = {} as any as Snapshot\n\n\toverride onEnter(\n\t\tinfo: TLPointerEventInfo & {\n\t\t\ttarget: 'selection'\n\t\t\thandle: SelectionHandle\n\t\t\tonInteractionEnd?: string | (() => void)\n\t\t}\n\t) {\n\t\tthis.info = info\n\t\tif (typeof info.onInteractionEnd === 'string') {\n\t\t\tthis.parent.setCurrentToolIdMask(info.onInteractionEnd)\n\t\t}\n\t\tthis.markId = this.editor.markHistoryStoppingPoint('cropping')\n\t\tthis.snapshot = this.createSnapshot()\n\t\tthis.updateShapes()\n\t}\n\n\toverride onPointerMove() {\n\t\tthis.updateShapes()\n\t}\n\n\toverride onKeyDown() {\n\t\tthis.updateShapes()\n\t}\n\n\toverride onKeyUp() {\n\t\tthis.updateShapes()\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onComplete() {\n\t\tthis.complete()\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\toverride onExit() {\n\t\tthis.parent.setCurrentToolIdMask(undefined)\n\t}\n\n\tprivate updateCursor() {\n\t\tconst selectedShape = this.editor.getSelectedShapes()[0]\n\t\tif (!selectedShape) return\n\n\t\tconst cursorType = CursorTypeMap[this.info.handle!]\n\t\tthis.editor.setCursor({ type: cursorType, rotation: this.editor.getSelectionRotation() })\n\t}\n\n\tprivate updateShapes() {\n\t\tconst { shape, cursorHandleOffset } = this.snapshot\n\n\t\tif (!shape) return\n\t\tconst util = this.editor.getShapeUtil<ShapeWithCrop>(shape.type)\n\t\tif (!util) return\n\n\t\tconst { shiftKey } = this.editor.inputs\n\t\tconst currentPagePoint = this.editor.inputs.currentPagePoint.clone().sub(cursorHandleOffset)\n\t\tconst originPagePoint = this.editor.inputs.originPagePoint.clone().sub(cursorHandleOffset)\n\t\tconst change = currentPagePoint.clone().sub(originPagePoint).rot(-shape.rotation)\n\n\t\tconst crop = shape.props.crop ?? getDefaultCrop()\n\t\tconst uncroppedSize = getUncroppedSize(shape.props, crop)\n\n\t\tconst cropFn = util.onCrop?.bind(util) ?? getCropBox\n\t\tconst partial = cropFn(shape, {\n\t\t\thandle: this.info.handle,\n\t\t\tchange,\n\t\t\tcrop,\n\t\t\tuncroppedSize,\n\t\t\tinitialShape: this.snapshot.shape,\n\t\t\taspectRatioLocked: shiftKey,\n\t\t})\n\t\tif (!partial) return\n\n\t\tthis.editor.updateShapes([\n\t\t\t{\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\t...partial,\n\t\t\t},\n\t\t])\n\t\tthis.updateCursor()\n\t}\n\n\tprivate complete() {\n\t\tthis.updateShapes()\n\t\tkickoutOccludedShapes(this.editor, [this.snapshot.shape.id])\n\t\tconst { onInteractionEnd } = this.info\n\t\tif (onInteractionEnd) {\n\t\t\tif (typeof onInteractionEnd === 'string') {\n\t\t\t\tthis.editor.setCurrentTool(onInteractionEnd, this.info)\n\t\t\t} else {\n\t\t\t\tonInteractionEnd()\n\t\t\t}\n\t\t} else {\n\t\t\tthis.editor.setCroppingShape(null)\n\t\t\tthis.editor.setCurrentTool('select.idle')\n\t\t}\n\t}\n\n\tprivate cancel() {\n\t\tthis.editor.bailToMark(this.markId)\n\t\tconst { onInteractionEnd } = this.info\n\t\tif (onInteractionEnd) {\n\t\t\tif (typeof onInteractionEnd === 'string') {\n\t\t\t\tthis.editor.setCurrentTool(onInteractionEnd, this.info)\n\t\t\t} else {\n\t\t\t\tonInteractionEnd()\n\t\t\t}\n\t\t} else {\n\t\t\tthis.editor.setCroppingShape(null)\n\t\t\tthis.editor.setCurrentTool('select.idle')\n\t\t}\n\t}\n\n\tprivate createSnapshot() {\n\t\tconst selectionRotation = this.editor.getSelectionRotation()\n\t\tconst {\n\t\t\tinputs: { originPagePoint },\n\t\t} = this.editor\n\n\t\tconst shape = this.editor.getOnlySelectedShape() as ShapeWithCrop\n\n\t\tconst selectionBounds = this.editor.getSelectionRotatedPageBounds()!\n\n\t\tconst dragHandlePoint = Vec.RotWith(\n\t\t\tselectionBounds.getHandlePoint(this.info.handle!),\n\t\t\tselectionBounds.point,\n\t\t\tselectionRotation\n\t\t)\n\n\t\tconst cursorHandleOffset = Vec.Sub(originPagePoint, dragHandlePoint)\n\n\t\treturn {\n\t\t\tshape,\n\t\t\tcursorHandleOffset,\n\t\t}\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -28,7 +28,9 @@ class PointingCropHandle extends import_editor.StateNode {
|
|
|
28
28
|
info = {};
|
|
29
29
|
onEnter(info) {
|
|
30
30
|
this.info = info;
|
|
31
|
-
|
|
31
|
+
if (typeof info.onInteractionEnd === "string") {
|
|
32
|
+
this.parent.setCurrentToolIdMask(info.onInteractionEnd);
|
|
33
|
+
}
|
|
32
34
|
const selectedShape = this.editor.getSelectedShapes()[0];
|
|
33
35
|
if (!selectedShape) return;
|
|
34
36
|
const cursorType = import_PointingResizeHandle.CursorTypeMap[this.info.handle];
|
|
@@ -55,12 +57,17 @@ class PointingCropHandle extends import_editor.StateNode {
|
|
|
55
57
|
});
|
|
56
58
|
}
|
|
57
59
|
onPointerUp() {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
const { onInteractionEnd } = this.info;
|
|
61
|
+
if (onInteractionEnd) {
|
|
62
|
+
if (typeof onInteractionEnd === "string") {
|
|
63
|
+
this.editor.setCurrentTool(onInteractionEnd, this.info);
|
|
64
|
+
} else {
|
|
65
|
+
onInteractionEnd();
|
|
66
|
+
}
|
|
67
|
+
return;
|
|
63
68
|
}
|
|
69
|
+
this.editor.setCroppingShape(null);
|
|
70
|
+
this.editor.setCurrentTool("select.idle");
|
|
64
71
|
}
|
|
65
72
|
onCancel() {
|
|
66
73
|
this.cancel();
|
|
@@ -72,12 +79,17 @@ class PointingCropHandle extends import_editor.StateNode {
|
|
|
72
79
|
this.cancel();
|
|
73
80
|
}
|
|
74
81
|
cancel() {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
82
|
+
const { onInteractionEnd } = this.info;
|
|
83
|
+
if (onInteractionEnd) {
|
|
84
|
+
if (typeof onInteractionEnd === "string") {
|
|
85
|
+
this.editor.setCurrentTool(onInteractionEnd, this.info);
|
|
86
|
+
} else {
|
|
87
|
+
onInteractionEnd();
|
|
88
|
+
}
|
|
89
|
+
return;
|
|
80
90
|
}
|
|
91
|
+
this.editor.setCroppingShape(null);
|
|
92
|
+
this.editor.setCurrentTool("select.idle");
|
|
81
93
|
}
|
|
82
94
|
}
|
|
83
95
|
//# sourceMappingURL=PointingCropHandle.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../../src/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.ts"],
|
|
4
|
-
"sourcesContent": ["import { StateNode, TLPointerEventInfo } from '@tldraw/editor'\nimport { CursorTypeMap } from '../../PointingResizeHandle'\n\ntype TLPointingCropHandleInfo = TLPointerEventInfo & {\n\ttarget: 'selection'\n} & {\n\tonInteractionEnd?: string\n}\n\nexport class PointingCropHandle extends StateNode {\n\tstatic override id = 'pointing_crop_handle'\n\n\tprivate info = {} as TLPointingCropHandleInfo\n\n\toverride onEnter(info: TLPointingCropHandleInfo) {\n\t\tthis.info = info\n\t\tthis.parent.setCurrentToolIdMask(info.onInteractionEnd)\n\t\tconst selectedShape = this.editor.getSelectedShapes()[0]\n\t\tif (!selectedShape) return\n\n\t\tconst cursorType = CursorTypeMap[this.info.handle!]\n\t\tthis.editor.setCursor({ type: cursorType, rotation: this.editor.getSelectionRotation() })\n\t\tthis.editor.setCroppingShape(selectedShape.id)\n\t}\n\n\toverride onExit() {\n\t\tthis.editor.setCursor({ type: 'default', rotation: 0 })\n\t\tthis.parent.setCurrentToolIdMask(undefined)\n\t}\n\n\toverride onPointerMove() {\n\t\tif (this.editor.inputs.isDragging) {\n\t\t\tthis.startCropping()\n\t\t}\n\t}\n\n\toverride onLongPress() {\n\t\tthis.startCropping()\n\t}\n\n\tprivate startCropping() {\n\t\tif (this.editor.getIsReadonly()) return\n\t\tthis.parent.transition('cropping', {\n\t\t\t...this.info,\n\t\t\tonInteractionEnd: this.info.onInteractionEnd,\n\t\t})\n\t}\n\n\toverride onPointerUp() {\n\t\
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA8C;AAC9C,kCAA8B;AAQvB,MAAM,2BAA2B,wBAAU;AAAA,EACjD,OAAgB,KAAK;AAAA,EAEb,OAAO,CAAC;AAAA,EAEP,QAAQ,MAAgC;AAChD,SAAK,OAAO;AACZ,
|
|
4
|
+
"sourcesContent": ["import { StateNode, TLPointerEventInfo } from '@tldraw/editor'\nimport { CursorTypeMap } from '../../PointingResizeHandle'\n\ntype TLPointingCropHandleInfo = TLPointerEventInfo & {\n\ttarget: 'selection'\n} & {\n\tonInteractionEnd?: string | (() => void)\n}\n\nexport class PointingCropHandle extends StateNode {\n\tstatic override id = 'pointing_crop_handle'\n\n\tprivate info = {} as TLPointingCropHandleInfo\n\n\toverride onEnter(info: TLPointingCropHandleInfo) {\n\t\tthis.info = info\n\t\tif (typeof info.onInteractionEnd === 'string') {\n\t\t\tthis.parent.setCurrentToolIdMask(info.onInteractionEnd)\n\t\t}\n\t\tconst selectedShape = this.editor.getSelectedShapes()[0]\n\t\tif (!selectedShape) return\n\n\t\tconst cursorType = CursorTypeMap[this.info.handle!]\n\t\tthis.editor.setCursor({ type: cursorType, rotation: this.editor.getSelectionRotation() })\n\t\tthis.editor.setCroppingShape(selectedShape.id)\n\t}\n\n\toverride onExit() {\n\t\tthis.editor.setCursor({ type: 'default', rotation: 0 })\n\t\tthis.parent.setCurrentToolIdMask(undefined)\n\t}\n\n\toverride onPointerMove() {\n\t\tif (this.editor.inputs.isDragging) {\n\t\t\tthis.startCropping()\n\t\t}\n\t}\n\n\toverride onLongPress() {\n\t\tthis.startCropping()\n\t}\n\n\tprivate startCropping() {\n\t\tif (this.editor.getIsReadonly()) return\n\t\tthis.parent.transition('cropping', {\n\t\t\t...this.info,\n\t\t\tonInteractionEnd: this.info.onInteractionEnd,\n\t\t})\n\t}\n\n\toverride onPointerUp() {\n\t\tconst { onInteractionEnd } = this.info\n\t\tif (onInteractionEnd) {\n\t\t\tif (typeof onInteractionEnd === 'string') {\n\t\t\t\tthis.editor.setCurrentTool(onInteractionEnd, this.info)\n\t\t\t} else {\n\t\t\t\tonInteractionEnd()\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tthis.editor.setCroppingShape(null)\n\t\tthis.editor.setCurrentTool('select.idle')\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\toverride onComplete() {\n\t\tthis.cancel()\n\t}\n\n\toverride onInterrupt() {\n\t\tthis.cancel()\n\t}\n\n\tprivate cancel() {\n\t\tconst { onInteractionEnd } = this.info\n\t\tif (onInteractionEnd) {\n\t\t\tif (typeof onInteractionEnd === 'string') {\n\t\t\t\tthis.editor.setCurrentTool(onInteractionEnd, this.info)\n\t\t\t} else {\n\t\t\t\tonInteractionEnd()\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tthis.editor.setCroppingShape(null)\n\t\tthis.editor.setCurrentTool('select.idle')\n\t}\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA8C;AAC9C,kCAA8B;AAQvB,MAAM,2BAA2B,wBAAU;AAAA,EACjD,OAAgB,KAAK;AAAA,EAEb,OAAO,CAAC;AAAA,EAEP,QAAQ,MAAgC;AAChD,SAAK,OAAO;AACZ,QAAI,OAAO,KAAK,qBAAqB,UAAU;AAC9C,WAAK,OAAO,qBAAqB,KAAK,gBAAgB;AAAA,IACvD;AACA,UAAM,gBAAgB,KAAK,OAAO,kBAAkB,EAAE,CAAC;AACvD,QAAI,CAAC,cAAe;AAEpB,UAAM,aAAa,0CAAc,KAAK,KAAK,MAAO;AAClD,SAAK,OAAO,UAAU,EAAE,MAAM,YAAY,UAAU,KAAK,OAAO,qBAAqB,EAAE,CAAC;AACxF,SAAK,OAAO,iBAAiB,cAAc,EAAE;AAAA,EAC9C;AAAA,EAES,SAAS;AACjB,SAAK,OAAO,UAAU,EAAE,MAAM,WAAW,UAAU,EAAE,CAAC;AACtD,SAAK,OAAO,qBAAqB,MAAS;AAAA,EAC3C;AAAA,EAES,gBAAgB;AACxB,QAAI,KAAK,OAAO,OAAO,YAAY;AAClC,WAAK,cAAc;AAAA,IACpB;AAAA,EACD;AAAA,EAES,cAAc;AACtB,SAAK,cAAc;AAAA,EACpB;AAAA,EAEQ,gBAAgB;AACvB,QAAI,KAAK,OAAO,cAAc,EAAG;AACjC,SAAK,OAAO,WAAW,YAAY;AAAA,MAClC,GAAG,KAAK;AAAA,MACR,kBAAkB,KAAK,KAAK;AAAA,IAC7B,CAAC;AAAA,EACF;AAAA,EAES,cAAc;AACtB,UAAM,EAAE,iBAAiB,IAAI,KAAK;AAClC,QAAI,kBAAkB;AACrB,UAAI,OAAO,qBAAqB,UAAU;AACzC,aAAK,OAAO,eAAe,kBAAkB,KAAK,IAAI;AAAA,MACvD,OAAO;AACN,yBAAiB;AAAA,MAClB;AACA;AAAA,IACD;AACA,SAAK,OAAO,iBAAiB,IAAI;AACjC,SAAK,OAAO,eAAe,aAAa;AAAA,EACzC;AAAA,EAES,WAAW;AACnB,SAAK,OAAO;AAAA,EACb;AAAA,EAES,aAAa;AACrB,SAAK,OAAO;AAAA,EACb;AAAA,EAES,cAAc;AACtB,SAAK,OAAO;AAAA,EACb;AAAA,EAEQ,SAAS;AAChB,UAAM,EAAE,iBAAiB,IAAI,KAAK;AAClC,QAAI,kBAAkB;AACrB,UAAI,OAAO,qBAAqB,UAAU;AACzC,aAAK,OAAO,eAAe,kBAAkB,KAAK,IAAI;AAAA,MACvD,OAAO;AACN,yBAAiB;AAAA,MAClB;AACA;AAAA,IACD;AACA,SAAK,OAAO,iBAAiB,IAAI;AACjC,SAAK,OAAO,eAAe,aAAa;AAAA,EACzC;AACD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -40,7 +40,9 @@ class DraggingHandle extends import_editor.StateNode {
|
|
|
40
40
|
onEnter(info) {
|
|
41
41
|
const { shape, isCreating, creatingMarkId, handle } = info;
|
|
42
42
|
this.info = info;
|
|
43
|
-
|
|
43
|
+
if (typeof info.onInteractionEnd === "string") {
|
|
44
|
+
this.parent.setCurrentToolIdMask(info.onInteractionEnd);
|
|
45
|
+
}
|
|
44
46
|
this.shapeId = shape.id;
|
|
45
47
|
this.markId = "";
|
|
46
48
|
if (isCreating) {
|
|
@@ -175,9 +177,16 @@ class DraggingHandle extends import_editor.StateNode {
|
|
|
175
177
|
}
|
|
176
178
|
}
|
|
177
179
|
const { onInteractionEnd } = this.info;
|
|
178
|
-
if (
|
|
179
|
-
|
|
180
|
-
|
|
180
|
+
if (onInteractionEnd) {
|
|
181
|
+
if (typeof onInteractionEnd === "string") {
|
|
182
|
+
if (this.editor.getInstanceState().isToolLocked && onInteractionEnd) {
|
|
183
|
+
this.editor.setCurrentTool(onInteractionEnd, { shapeId: this.shapeId });
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
} else {
|
|
187
|
+
onInteractionEnd?.();
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
181
190
|
}
|
|
182
191
|
this.parent.transition("idle");
|
|
183
192
|
}
|
|
@@ -197,7 +206,11 @@ class DraggingHandle extends import_editor.StateNode {
|
|
|
197
206
|
this.editor.snaps.clearIndicators();
|
|
198
207
|
const { onInteractionEnd } = this.info;
|
|
199
208
|
if (onInteractionEnd) {
|
|
200
|
-
|
|
209
|
+
if (typeof onInteractionEnd === "string") {
|
|
210
|
+
this.editor.setCurrentTool(onInteractionEnd, { shapeId: this.shapeId });
|
|
211
|
+
} else {
|
|
212
|
+
onInteractionEnd?.();
|
|
213
|
+
}
|
|
201
214
|
return;
|
|
202
215
|
}
|
|
203
216
|
this.parent.transition("idle");
|
|
@@ -224,7 +237,15 @@ class DraggingHandle extends import_editor.StateNode {
|
|
|
224
237
|
}
|
|
225
238
|
editor.snaps.clearIndicators();
|
|
226
239
|
let nextHandle = { ...initialHandle, x: point.x, y: point.y };
|
|
227
|
-
|
|
240
|
+
let canSnap = false;
|
|
241
|
+
if (initialHandle.canSnap && initialHandle.snapType) {
|
|
242
|
+
(0, import_editor.warnOnce)(
|
|
243
|
+
"canSnap is deprecated. Cannot use both canSnap and snapType together - snapping disabled. Please use only snapType."
|
|
244
|
+
);
|
|
245
|
+
} else {
|
|
246
|
+
canSnap = initialHandle.canSnap || initialHandle.snapType !== void 0;
|
|
247
|
+
}
|
|
248
|
+
if (canSnap && (isSnapMode ? !ctrlKey : ctrlKey)) {
|
|
228
249
|
const pageTransform = editor.getShapePageTransform(shape.id);
|
|
229
250
|
if (!pageTransform) throw Error("Expected a page transform");
|
|
230
251
|
const snap = snaps.handles.snapHandle({ currentShapeId: shapeId, handle: nextHandle });
|