diff --git a/apps/vscode/editor/src/app.tsx b/apps/vscode/editor/src/app.tsx index f255aee1a358..9ef6ef3202b5 100644 --- a/apps/vscode/editor/src/app.tsx +++ b/apps/vscode/editor/src/app.tsx @@ -12,6 +12,7 @@ import { TLComponents, Tldraw, ViewSubmenu, + hardReset, setRuntimeOverrides, } from 'tldraw' import 'tldraw/tldraw.css' @@ -44,7 +45,7 @@ setRuntimeOverrides({ }) }, hardReset: async () => { - await (window as any).__tldraw__hardReset?.() + await hardReset({ shouldReload: false }) vscode.postMessage({ type: 'vscode:hard-reset', }) diff --git a/assets/embed-icons/canva.png b/assets/embed-icons/canva.png new file mode 100644 index 000000000000..8274ac54d77c Binary files /dev/null and b/assets/embed-icons/canva.png differ diff --git a/packages/assets/imports.js b/packages/assets/imports.js index 7dbc68beec6b..4b093dca7ac2 100644 --- a/packages/assets/imports.js +++ b/packages/assets/imports.js @@ -1,6 +1,7 @@ // This file is automatically generated by internal/scripts/refresh-assets.ts. // Do not edit manually. Or do, I'm a comment, not a cop. +import embedIconsCanvaPng from './embed-icons/canva.png' import embedIconsCodepenPng from './embed-icons/codepen.png' import embedIconsCodesandboxPng from './embed-icons/codesandbox.png' import embedIconsDesmosPng from './embed-icons/desmos.png' @@ -338,6 +339,7 @@ export function getAssetUrlsByImport(opts) { 'zh-tw': formatAssetUrl(translationsZhTwJson, opts), }, embedIcons: { + canva: formatAssetUrl(embedIconsCanvaPng, opts), codepen: formatAssetUrl(embedIconsCodepenPng, opts), codesandbox: formatAssetUrl(embedIconsCodesandboxPng, opts), desmos: formatAssetUrl(embedIconsDesmosPng, opts), diff --git a/packages/assets/imports.vite.js b/packages/assets/imports.vite.js index 8864cb11360d..90d0494025ec 100644 --- a/packages/assets/imports.vite.js +++ b/packages/assets/imports.vite.js @@ -1,6 +1,7 @@ // This file is automatically generated by internal/scripts/refresh-assets.ts. // Do not edit manually. Or do, I'm a comment, not a cop. +import embedIconsCanvaPngUrl from './embed-icons/canva.png?url' import embedIconsCodepenPngUrl from './embed-icons/codepen.png?url' import embedIconsCodesandboxPngUrl from './embed-icons/codesandbox.png?url' import embedIconsDesmosPngUrl from './embed-icons/desmos.png?url' @@ -338,6 +339,7 @@ export function getAssetUrlsByImport(opts) { 'zh-tw': formatAssetUrl(translationsZhTwJsonUrl, opts), }, embedIcons: { + canva: formatAssetUrl(embedIconsCanvaPngUrl, opts), codepen: formatAssetUrl(embedIconsCodepenPngUrl, opts), codesandbox: formatAssetUrl(embedIconsCodesandboxPngUrl, opts), desmos: formatAssetUrl(embedIconsDesmosPngUrl, opts), diff --git a/packages/assets/selfHosted.js b/packages/assets/selfHosted.js index 242d2b0da9f3..c14920d60f93 100644 --- a/packages/assets/selfHosted.js +++ b/packages/assets/selfHosted.js @@ -256,6 +256,7 @@ export function getAssetUrls(opts) { 'zh-tw': formatAssetUrl('./translations/zh-tw.json', opts), }, embedIcons: { + canva: formatAssetUrl('./embed-icons/canva.png', opts), codepen: formatAssetUrl('./embed-icons/codepen.png', opts), codesandbox: formatAssetUrl('./embed-icons/codesandbox.png', opts), desmos: formatAssetUrl('./embed-icons/desmos.png', opts), diff --git a/packages/assets/types.d.ts b/packages/assets/types.d.ts index e91fe0779182..54bb63271859 100644 --- a/packages/assets/types.d.ts +++ b/packages/assets/types.d.ts @@ -242,6 +242,7 @@ export type AssetUrls = { 'zh-tw': string } embedIcons: { + canva: string codepen: string codesandbox: string desmos: string diff --git a/packages/assets/urls.js b/packages/assets/urls.js index 5e50a59b3825..313682e0151c 100644 --- a/packages/assets/urls.js +++ b/packages/assets/urls.js @@ -304,6 +304,7 @@ export function getAssetUrlsByMetaUrl(opts) { 'zh-tw': formatAssetUrl(new URL('./translations/zh-tw.json', import.meta.url).href, opts), }, embedIcons: { + canva: formatAssetUrl(new URL('./embed-icons/canva.png', import.meta.url).href, opts), codepen: formatAssetUrl(new URL('./embed-icons/codepen.png', import.meta.url).href, opts), codesandbox: formatAssetUrl( new URL('./embed-icons/codesandbox.png', import.meta.url).href, diff --git a/packages/editor/src/lib/utils/runtime.ts b/packages/editor/src/lib/utils/runtime.ts index 9c83ecd0ed9f..f08ae889b60d 100644 --- a/packages/editor/src/lib/utils/runtime.ts +++ b/packages/editor/src/lib/utils/runtime.ts @@ -1,3 +1,5 @@ +import { hardReset } from './sync/hardReset' + /** @public */ export const runtime: { openWindow(url: string, target: string, allowReferrer?: boolean): void @@ -11,7 +13,7 @@ export const runtime: { window.location.reload() }, async hardReset() { - return await (window as any).__tldraw__hardReset?.() + return await hardReset({ shouldReload: true }) }, } diff --git a/packages/editor/src/lib/utils/sync/hardReset.ts b/packages/editor/src/lib/utils/sync/hardReset.ts index 41db22514072..a9c2dedb0603 100644 --- a/packages/editor/src/lib/utils/sync/hardReset.ts +++ b/packages/editor/src/lib/utils/sync/hardReset.ts @@ -19,11 +19,3 @@ export async function hardReset({ shouldReload = true } = {}) { window.location.reload() } } - -if (typeof window !== 'undefined') { - if (process.env.NODE_ENV === 'development') { - ;(window as any).hardReset = hardReset - } - // window.__tldraw__hardReset is used to inject the logic into the tldraw library - ;(window as any).__tldraw__hardReset = hardReset -} diff --git a/packages/tldraw/api-report.api.md b/packages/tldraw/api-report.api.md index 97ac89b2d732..b06557b22e5e 100644 --- a/packages/tldraw/api-report.api.md +++ b/packages/tldraw/api-report.api.md @@ -738,6 +738,16 @@ export const DEFAULT_EMBED_DEFINITIONS: readonly [{ readonly toEmbedUrl: (url: string) => string | undefined; readonly type: "figma"; readonly width: 720; +}, { + readonly doesResize: true; + readonly embedOnPaste: true; + readonly fromEmbedUrl: (url: string) => string | undefined; + readonly height: 500; + readonly hostnames: readonly ["canva.com"]; + readonly title: "Canva"; + readonly toEmbedUrl: (url: string) => string | undefined; + readonly type: "canva"; + readonly width: 720; }, { readonly doesResize: true; readonly embedOnPaste: true; diff --git a/packages/tldraw/src/lib/defaultEmbedDefinitions.ts b/packages/tldraw/src/lib/defaultEmbedDefinitions.ts index de01392731bc..24d3b481e9ee 100644 --- a/packages/tldraw/src/lib/defaultEmbedDefinitions.ts +++ b/packages/tldraw/src/lib/defaultEmbedDefinitions.ts @@ -68,6 +68,39 @@ export const DEFAULT_EMBED_DEFINITIONS = [ }, embedOnPaste: true, }, + { + type: 'canva', + title: 'Canva', + hostnames: ['canva.com'], + width: 720, + height: 500, + doesResize: true, + toEmbedUrl: (url) => { + const urlObj = safeParseUrl(url) + if ( + urlObj && + urlObj.pathname.match(/^\/design\/([^/]+)\/.+/) && + !urlObj.searchParams.has('embed') + ) { + urlObj.searchParams.set('embed', '') + return urlObj.href + } + return + }, + fromEmbedUrl: (url) => { + const urlObj = safeParseUrl(url) + if ( + urlObj && + urlObj.pathname.match(/^\/design\/([^/]+)\/.+/) && + urlObj.searchParams.has('embed') + ) { + urlObj.searchParams.delete('embed') + return urlObj.href + } + return + }, + embedOnPaste: true, + }, { type: 'google_maps', title: 'Google Maps', diff --git a/packages/tldraw/src/lib/utils/embeds/embeds.test.ts b/packages/tldraw/src/lib/utils/embeds/embeds.test.ts index b4e8e4c8e351..1b2d2fca2b67 100644 --- a/packages/tldraw/src/lib/utils/embeds/embeds.test.ts +++ b/packages/tldraw/src/lib/utils/embeds/embeds.test.ts @@ -219,6 +219,31 @@ const MATCH_URL_TEST_URLS: (MatchUrlTestNoMatchDef | MatchUrlTestMatchDef)[] = [ url: 'https://www.figma.com/foobar', match: false, }, + // canva + { + url: 'https://www.canva.com/design/DAFrLlkQu3Q/view', + match: true, + output: { + type: 'canva', + embedUrl: 'https://www.canva.com/design/DAFrLlkQu3Q/view?embed=', + }, + }, + { + url: 'https://www.canva.com/design/DAFrLlkQu3Q/some-slug', + match: true, + output: { + type: 'canva', + embedUrl: 'https://www.canva.com/design/DAFrLlkQu3Q/some-slug?embed=', + }, + }, + { + url: 'https://www.canva.com/design/DAFrLlkQu3Q', + match: false, + }, + { + url: 'https://www.canva.com/templates', + match: false, + }, // google_maps { url: 'https://www.google.com/maps/@52.2449313,0.0813192,14z', @@ -556,6 +581,27 @@ const MATCH_EMBED_TEST_URLS: (MatchEmbedTestMatchDef | MatchEmbedTestNoMatchDef) embedUrl: 'https://www.figma.com/embed?foobar=baz', match: false, }, + // canva + { + embedUrl: 'https://www.canva.com/design/DAFrLlkQu3Q/view?embed=', + match: true, + output: { + type: 'canva', + url: 'https://www.canva.com/design/DAFrLlkQu3Q/view', + }, + }, + { + embedUrl: 'https://www.canva.com/design/DAFrLlkQu3Q/some-slug?embed=', + match: true, + output: { + type: 'canva', + url: 'https://www.canva.com/design/DAFrLlkQu3Q/some-slug', + }, + }, + { + embedUrl: 'https://www.canva.com/templates', + match: false, + }, // google_maps { embedUrl: `https://google.com/maps/embed/v1/view?key=${process.env.NEXT_PUBLIC_GC_API_KEY}¢er=52.2449313,0.0813192&zoom=14`,