From 33d250218cb9e68f7aa7afd854bf73c3d85a7ead Mon Sep 17 00:00:00 2001 From: Jordi Sala Morales Date: Tue, 18 Jun 2024 13:20:09 +0200 Subject: [PATCH] Improve speed at recolect fonts and improve treating modifications (#175) --- .changeset/three-hornets-sell.md | 5 +++++ plugin-src/code.ts | 10 ++++++++- plugin-src/findAllTextnodes.ts | 33 +++++++++++++++++++++--------- plugin-src/registerChange.ts | 32 ++++++++++++++++++++++++++++- ui-src/components/PluginReload.tsx | 5 +++-- 5 files changed, 71 insertions(+), 14 deletions(-) create mode 100644 .changeset/three-hornets-sell.md diff --git a/.changeset/three-hornets-sell.md b/.changeset/three-hornets-sell.md new file mode 100644 index 0000000..6b61fe4 --- /dev/null +++ b/.changeset/three-hornets-sell.md @@ -0,0 +1,5 @@ +--- +"penpot-exporter": patch +--- + +Improve detection of changed fonts diff --git a/plugin-src/code.ts b/plugin-src/code.ts index 0d1a310..2df40cb 100644 --- a/plugin-src/code.ts +++ b/plugin-src/code.ts @@ -29,6 +29,14 @@ figma.ui.onmessage = message => { } }; +let currentPage = figma.currentPage; + +currentPage.on('nodechange', registerChange); + figma.on('currentpagechange', () => { - figma.currentPage.once('nodechange', registerChange); + currentPage.off('nodechange', registerChange); + + currentPage = figma.currentPage; + + currentPage.on('nodechange', registerChange); }); diff --git a/plugin-src/findAllTextnodes.ts b/plugin-src/findAllTextnodes.ts index 564407b..c1c1696 100644 --- a/plugin-src/findAllTextnodes.ts +++ b/plugin-src/findAllTextnodes.ts @@ -1,8 +1,6 @@ import { isGoogleFont } from '@plugin/translators/text/font/gfonts'; import { isLocalFont } from '@plugin/translators/text/font/local'; -import { registerChange } from './registerChange'; - export const findAllTextNodes = async () => { const fonts = new Set(); @@ -20,18 +18,33 @@ export const findAllTextNodes = async () => { type: 'CUSTOM_FONTS', data: Array.from(fonts) }); +}; - figma.currentPage.once('nodechange', registerChange); +export const findMissingFonts = (node: TextNode): FontName[] => { + if (node.fontName !== figma.mixed) { + return isKnownFont(node.fontName) ? [] : [node.fontName]; + } + + const missingFonts: FontName[] = []; + const styledTextSegments = node.getStyledTextSegments(['fontName']); + + styledTextSegments.map(segment => { + if (isKnownFont(segment.fontName)) return; + + missingFonts.push(segment.fontName); + }); + + return missingFonts; }; const extractMissingFonts = (node: TextNode, fonts: Set) => { - const styledTextSegments = node.getStyledTextSegments(['fontName']); + const missingFonts = findMissingFonts(node); - styledTextSegments.forEach(segment => { - if (isGoogleFont(segment.fontName) || isLocalFont(segment.fontName)) { - return; - } - - fonts.add(segment.fontName.family); + missingFonts.forEach(font => { + fonts.add(font.family); }); }; + +const isKnownFont = (fontName: FontName): boolean => { + return isGoogleFont(fontName) || isLocalFont(fontName); +}; diff --git a/plugin-src/registerChange.ts b/plugin-src/registerChange.ts index ffe6354..203e766 100644 --- a/plugin-src/registerChange.ts +++ b/plugin-src/registerChange.ts @@ -1,3 +1,33 @@ -export const registerChange = () => { +import { findMissingFonts } from './findAllTextnodes'; + +export const registerChange = (event: NodeChangeEvent) => { + if (!changesAreRelevant(event.nodeChanges)) return; + figma.ui.postMessage({ type: 'CHANGES_DETECTED' }); }; + +const changesAreRelevant = (changes: NodeChange[]): boolean => { + for (const change of changes) { + if (changeIsRelevant(change)) return true; + } + + return false; +}; + +const changeIsRelevant = (change: NodeChange): boolean => { + const node = change.node; + + if (!isTextNode(node) || change.type === 'DELETE') return false; + + return ( + (change.type === 'CREATE' || + (change.type === 'PROPERTY_CHANGE' && + change.properties.some( + property => property === 'fontName' || property === 'styledTextSegments' + ))) && + findMissingFonts(node).length > 0 + ); +}; + +const isTextNode = (node: SceneNode | RemovedNode): node is TextNode => + node.type === 'TEXT' && 'name' in node; diff --git a/ui-src/components/PluginReload.tsx b/ui-src/components/PluginReload.tsx index eddd03d..ab0c184 100644 --- a/ui-src/components/PluginReload.tsx +++ b/ui-src/components/PluginReload.tsx @@ -9,8 +9,9 @@ export const PluginReload = () => { return ( }> - Changes detected. Please reload the plug-in to ensure all modifications are included in the - exported file. + Changes detected in fonts. +
+ Please reload the plug-in to ensure all modifications are included in the exported file.