From 690842d2f5fa0790b6a8a58ee9c30616abc5a42e Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Tue, 27 May 2025 18:21:03 +0300 Subject: [PATCH] fix: paste markdown Async in html paste broke markdown because await was missing in onPaste. --- .../app/shared/copy-paste/init-copy-paste.ts | 9 ++++---- .../app/shared/copy-paste/plugin-html.ts | 4 +++- .../app/shared/copy-paste/plugin-instance.ts | 2 ++ .../app/shared/copy-paste/plugin-markdown.ts | 21 +++++++++++-------- .../plugin-webflow/plugin-webflow.ts | 11 +++++++--- 5 files changed, 30 insertions(+), 17 deletions(-) diff --git a/apps/builder/app/shared/copy-paste/init-copy-paste.ts b/apps/builder/app/shared/copy-paste/init-copy-paste.ts index af4dcb0e9edc..2226ee32d2f0 100644 --- a/apps/builder/app/shared/copy-paste/init-copy-paste.ts +++ b/apps/builder/app/shared/copy-paste/init-copy-paste.ts @@ -5,8 +5,8 @@ import { } from "../nano-states"; import { instanceText, instanceJson } from "./plugin-instance"; import { html } from "./plugin-html"; -import * as markdown from "./plugin-markdown"; -import * as webflow from "./plugin-webflow/plugin-webflow"; +import { markdown } from "./plugin-markdown"; +import { webflow } from "./plugin-webflow/plugin-webflow"; import { builderApi } from "../builder-api"; const isTextEditing = (event: ClipboardEvent) => { @@ -64,6 +64,7 @@ const validateClipboardEvent = (event: ClipboardEvent) => { }; export type Plugin = { + name: string; mimeType: string; onCopy?: () => undefined | string; onCut?: () => undefined | string; @@ -109,7 +110,7 @@ const initPlugins = ({ } }; - const handlePaste = (event: ClipboardEvent) => { + const handlePaste = async (event: ClipboardEvent) => { if (validateClipboardEvent(event) === false) { return; } @@ -118,7 +119,7 @@ const initPlugins = ({ // this shouldn't matter, but just in case event.preventDefault(); const data = event.clipboardData?.getData(mimeType).trim(); - if (data && onPaste?.(data)) { + if (data && (await onPaste?.(data))) { break; } } diff --git a/apps/builder/app/shared/copy-paste/plugin-html.ts b/apps/builder/app/shared/copy-paste/plugin-html.ts index 48b70745599f..e9b5c32ad8fd 100644 --- a/apps/builder/app/shared/copy-paste/plugin-html.ts +++ b/apps/builder/app/shared/copy-paste/plugin-html.ts @@ -4,10 +4,12 @@ import { denormalizeSrcProps } from "./asset-upload"; import type { Plugin } from "./init-copy-paste"; export const html: Plugin = { + name: "html", mimeType: "text/plain", onPaste: async (html: string) => { let fragment = generateFragmentFromHtml(html); fragment = await denormalizeSrcProps(fragment); - return insertWebstudioFragmentAt(fragment); + const result = insertWebstudioFragmentAt(fragment); + return result; }, }; diff --git a/apps/builder/app/shared/copy-paste/plugin-instance.ts b/apps/builder/app/shared/copy-paste/plugin-instance.ts index 9006b09df7e5..6d13ede37d38 100644 --- a/apps/builder/app/shared/copy-paste/plugin-instance.ts +++ b/apps/builder/app/shared/copy-paste/plugin-instance.ts @@ -225,6 +225,7 @@ const onCut = () => { }; export const instanceText: Plugin = { + name: "instance-text", mimeType: "text/plain", onCopy, onCut, @@ -232,6 +233,7 @@ export const instanceText: Plugin = { }; export const instanceJson: Plugin = { + name: "instance-json", mimeType: "application/json", onPaste, }; diff --git a/apps/builder/app/shared/copy-paste/plugin-markdown.ts b/apps/builder/app/shared/copy-paste/plugin-markdown.ts index 909817804483..b915a0291156 100644 --- a/apps/builder/app/shared/copy-paste/plugin-markdown.ts +++ b/apps/builder/app/shared/copy-paste/plugin-markdown.ts @@ -3,8 +3,7 @@ import { micromark } from "micromark"; import { insertWebstudioFragmentAt } from "../instance-utils"; import { denormalizeSrcProps } from "./asset-upload"; import { generateFragmentFromHtml } from "../html"; - -export const mimeType = "text/plain"; +import type { Plugin } from "./init-copy-paste"; const parse = (clipboardData: string) => { const html = micromark(clipboardData, "utf-8", { @@ -23,13 +22,17 @@ const parse = (clipboardData: string) => { return fragment; }; -export const onPaste = async (clipboardData: string) => { - let fragment = parse(clipboardData); - if (fragment === undefined) { - return false; - } - fragment = await denormalizeSrcProps(fragment); - return insertWebstudioFragmentAt(fragment); +export const markdown: Plugin = { + name: "markdown", + mimeType: "text/plain", + onPaste: async (clipboardData: string) => { + let fragment = parse(clipboardData); + if (fragment === undefined) { + return false; + } + fragment = await denormalizeSrcProps(fragment); + return insertWebstudioFragmentAt(fragment); + }, }; export const __testing__ = { diff --git a/apps/builder/app/shared/copy-paste/plugin-webflow/plugin-webflow.ts b/apps/builder/app/shared/copy-paste/plugin-webflow/plugin-webflow.ts index 40292b5c1c7f..bd4f5873b80b 100644 --- a/apps/builder/app/shared/copy-paste/plugin-webflow/plugin-webflow.ts +++ b/apps/builder/app/shared/copy-paste/plugin-webflow/plugin-webflow.ts @@ -19,11 +19,10 @@ import { builderApi } from "~/shared/builder-api"; import { denormalizeSrcProps } from "../asset-upload"; import { nanoHash } from "~/shared/nano-hash"; import { findAvailableVariables } from "~/shared/data-variables"; +import type { Plugin } from "../init-copy-paste"; const { toast } = builderApi; -export const mimeType = "application/json"; - const toWebstudioFragment = async (wfData: WfData) => { const fragment: WebstudioFragment = { children: [], @@ -165,7 +164,7 @@ const parse = (clipboardData: string) => { console.error(result.error.message); }; -export const onPaste = async (clipboardData: string) => { +const onPaste = async (clipboardData: string) => { const project = $project.get(); const wfData = parse(clipboardData); if (wfData === undefined || project === undefined) { @@ -211,6 +210,12 @@ export const onPaste = async (clipboardData: string) => { return true; }; +export const webflow: Plugin = { + name: "webflow", + mimeType: "application/json", + onPaste, +}; + export const __testing__ = { toWebstudioFragment, };