From 4e538df83f53def944b20823679ef04a0b7b5056 Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal Date: Tue, 24 Jun 2025 18:42:56 +0530 Subject: [PATCH] refactor: editor parser --- packages/editor/src/ce/helpers/parser.ts | 19 ++++++++ packages/editor/src/core/helpers/parser.ts | 50 ++++++++++++---------- 2 files changed, 47 insertions(+), 22 deletions(-) create mode 100644 packages/editor/src/ce/helpers/parser.ts diff --git a/packages/editor/src/ce/helpers/parser.ts b/packages/editor/src/ce/helpers/parser.ts new file mode 100644 index 00000000000..5b96c9cfd08 --- /dev/null +++ b/packages/editor/src/ce/helpers/parser.ts @@ -0,0 +1,19 @@ +/** + * @description function to extract all additional assets from HTML content + * @param htmlContent + * @returns {string[]} array of additional asset sources + */ +export const extractAdditionalAssetsFromHTMLContent = (_htmlContent: string): string[] => []; + +/** + * @description function to replace additional assets in HTML content with new IDs + * @param props + * @returns {string} HTML content with replaced additional assets + */ +export const replaceAdditionalAssetsInHTMLContent = (props: { + htmlContent: string; + assetMap: Record; +}): string => { + const { htmlContent } = props; + return htmlContent; +}; diff --git a/packages/editor/src/core/helpers/parser.ts b/packages/editor/src/core/helpers/parser.ts index 844c7b6afd8..13b10532363 100644 --- a/packages/editor/src/core/helpers/parser.ts +++ b/packages/editor/src/core/helpers/parser.ts @@ -1,40 +1,42 @@ // plane imports import { TDocumentPayload, TDuplicateAssetData, TDuplicateAssetResponse } from "@plane/types"; import { TEditorAssetType } from "@plane/types/src/enums"; +// plane web imports +import { + extractAdditionalAssetsFromHTMLContent, + replaceAdditionalAssetsInHTMLContent, +} from "@/plane-editor/helpers/parser"; // local imports import { convertHTMLDocumentToAllFormats } from "./yjs-utils"; /** - * @description function to extract all image assets from HTML content + * @description function to extract all assets from HTML content * @param htmlContent - * @returns {string[]} array of image asset sources + * @returns {string[]} array of asset sources */ -export const extractImageAssetsFromHTMLContent = (htmlContent: string): string[] => { +const extractAssetsFromHTMLContent = (htmlContent: string): string[] => { // create a DOM parser const parser = new DOMParser(); // parse the HTML string into a DOM document const doc = parser.parseFromString(htmlContent, "text/html"); - // get all image components - const imageComponents = doc.querySelectorAll("image-component"); - // collect all unique image sources - const imageSources = new Set(); + // collect all unique asset sources + const assetSources = new Set(); // extract sources from image components + const imageComponents = doc.querySelectorAll("image-component"); imageComponents.forEach((component) => { const src = component.getAttribute("src"); - if (src) imageSources.add(src); + if (src) assetSources.add(src); }); - return Array.from(imageSources); + const additionalAssetIds = extractAdditionalAssetsFromHTMLContent(htmlContent); + return [...Array.from(assetSources), ...additionalAssetIds]; }; /** - * @description function to replace image assets in HTML content with new IDs + * @description function to replace assets in HTML content with new IDs * @param props - * @returns {string} HTML content with replaced image assets + * @returns {string} HTML content with replaced assets */ -export const replaceImageAssetsInHTMLContent = (props: { - htmlContent: string; - assetMap: Record; -}): string => { +const replaceAssetsInHTMLContent = (props: { htmlContent: string; assetMap: Record }): string => { const { htmlContent, assetMap } = props; // create a DOM parser const parser = new DOMParser(); @@ -48,11 +50,15 @@ export const replaceImageAssetsInHTMLContent = (props: { component.setAttribute("src", assetMap[oldSrc]); } }); - // serialize the document back into a string - return doc.body.innerHTML; + // replace additional sources + const replacedHTMLContent = replaceAdditionalAssetsInHTMLContent({ + htmlContent: doc.body.innerHTML, + assetMap, + }); + return replacedHTMLContent; }; -export const getEditorContentWithReplacedImageAssets = async (props: { +export const getEditorContentWithReplacedAssets = async (props: { descriptionHTML: string; entityId: string; entityType: TEditorAssetType; @@ -63,18 +69,18 @@ export const getEditorContentWithReplacedImageAssets = async (props: { const { descriptionHTML, entityId, entityType, projectId, variant, duplicateAssetService } = props; let replacedDescription = descriptionHTML; // step 1: extract image assets from the description - const imageAssets = extractImageAssetsFromHTMLContent(descriptionHTML); - if (imageAssets.length !== 0) { + const assetIds = extractAssetsFromHTMLContent(descriptionHTML); + if (assetIds.length !== 0) { // step 2: duplicate the image assets const duplicateAssetsResponse = await duplicateAssetService({ entity_id: entityId, entity_type: entityType, project_id: projectId, - asset_ids: imageAssets, + asset_ids: assetIds, }); if (Object.keys(duplicateAssetsResponse ?? {}).length > 0) { // step 3: replace the image assets in the description - replacedDescription = replaceImageAssetsInHTMLContent({ + replacedDescription = replaceAssetsInHTMLContent({ htmlContent: descriptionHTML, assetMap: duplicateAssetsResponse, });