diff --git a/apps/builder/app/shared/html.test.tsx b/apps/builder/app/shared/html.test.tsx index 74cb68aa2178..30fa970f8623 100644 --- a/apps/builder/app/shared/html.test.tsx +++ b/apps/builder/app/shared/html.test.tsx @@ -1,5 +1,5 @@ import { expect, test } from "vitest"; -import { css, renderTemplate, ws } from "@webstudio-is/template"; +import { $, css, renderTemplate, ws } from "@webstudio-is/template"; import { generateFragmentFromHtml } from "./html"; test("generate instances from html", () => { @@ -222,3 +222,25 @@ test("generate style attribute as local styles", () => { ) ); }); + +test("paste svg as html embed", () => { + expect( + generateFragmentFromHtml(` +
+ + + +
+ `) + ).toEqual( + renderTemplate( + + <$.HtmlEmbed + code={` + +`} + /> + + ) + ); +}); diff --git a/apps/builder/app/shared/html.ts b/apps/builder/app/shared/html.ts index c205a787ab88..ea616a027baf 100644 --- a/apps/builder/app/shared/html.ts +++ b/apps/builder/app/shared/html.ts @@ -108,6 +108,38 @@ export const generateFragmentFromHtml = (html: string): WebstudioFragment => { }; const convertElementToInstance = (node: ElementNode) => { + if (node.tagName === "svg" && node.sourceCodeLocation) { + const { startCol, startOffset, endOffset } = node.sourceCodeLocation; + const indent = startCol - 1; + const htmlFragment = html + .slice(startOffset, endOffset) + // try to preserve indentation + .split("\n") + .map((line, index) => { + if (index > 0 && /^\s+$/.test(line.slice(0, indent))) { + return line.slice(indent); + } + return line; + }) + .join("\n"); + const instance: Instance = { + type: "instance", + id: getNewId(), + component: "HtmlEmbed", + children: [], + }; + instances.set(instance.id, instance); + const name = "code"; + const codeProp: Prop = { + id: `${instance.id}:${name}`, + instanceId: instance.id, + name, + type: "string", + value: htmlFragment, + }; + props.push(codeProp); + return { type: "id" as const, value: instance.id }; + } if (!tags.includes(node.tagName)) { return; } @@ -196,7 +228,10 @@ export const generateFragmentFromHtml = (html: string): WebstudioFragment => { return { type: "id" as const, value: instance.id }; }; - const documentFragment = parseFragment(html, { scriptingEnabled: false }); + const documentFragment = parseFragment(html, { + scriptingEnabled: false, + sourceCodeLocationInfo: true, + }); const children: Instance["children"] = []; for (const childNode of documentFragment.childNodes) { if (defaultTreeAdapter.isElementNode(childNode)) {