mirror of
https://github.com/penpot/penpot-exporter-figma-plugin.git
synced 2024-12-22 13:43:03 -05:00
Improve speed at recolect fonts and improve treating modifications (#175)
This commit is contained in:
parent
beb3caa5e0
commit
33d250218c
5 changed files with 71 additions and 14 deletions
5
.changeset/three-hornets-sell.md
Normal file
5
.changeset/three-hornets-sell.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
"penpot-exporter": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Improve detection of changed fonts
|
|
@ -29,6 +29,14 @@ figma.ui.onmessage = message => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let currentPage = figma.currentPage;
|
||||||
|
|
||||||
|
currentPage.on('nodechange', registerChange);
|
||||||
|
|
||||||
figma.on('currentpagechange', () => {
|
figma.on('currentpagechange', () => {
|
||||||
figma.currentPage.once('nodechange', registerChange);
|
currentPage.off('nodechange', registerChange);
|
||||||
|
|
||||||
|
currentPage = figma.currentPage;
|
||||||
|
|
||||||
|
currentPage.on('nodechange', registerChange);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import { isGoogleFont } from '@plugin/translators/text/font/gfonts';
|
import { isGoogleFont } from '@plugin/translators/text/font/gfonts';
|
||||||
import { isLocalFont } from '@plugin/translators/text/font/local';
|
import { isLocalFont } from '@plugin/translators/text/font/local';
|
||||||
|
|
||||||
import { registerChange } from './registerChange';
|
|
||||||
|
|
||||||
export const findAllTextNodes = async () => {
|
export const findAllTextNodes = async () => {
|
||||||
const fonts = new Set<string>();
|
const fonts = new Set<string>();
|
||||||
|
|
||||||
|
@ -20,18 +18,33 @@ export const findAllTextNodes = async () => {
|
||||||
type: 'CUSTOM_FONTS',
|
type: 'CUSTOM_FONTS',
|
||||||
data: Array.from(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<string>) => {
|
const extractMissingFonts = (node: TextNode, fonts: Set<string>) => {
|
||||||
const styledTextSegments = node.getStyledTextSegments(['fontName']);
|
const missingFonts = findMissingFonts(node);
|
||||||
|
|
||||||
styledTextSegments.forEach(segment => {
|
missingFonts.forEach(font => {
|
||||||
if (isGoogleFont(segment.fontName) || isLocalFont(segment.fontName)) {
|
fonts.add(font.family);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fonts.add(segment.fontName.family);
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isKnownFont = (fontName: FontName): boolean => {
|
||||||
|
return isGoogleFont(fontName) || isLocalFont(fontName);
|
||||||
|
};
|
||||||
|
|
|
@ -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' });
|
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;
|
||||||
|
|
|
@ -9,8 +9,9 @@ export const PluginReload = () => {
|
||||||
return (
|
return (
|
||||||
<Stack space="small">
|
<Stack space="small">
|
||||||
<Banner icon={<IconInfo32 />}>
|
<Banner icon={<IconInfo32 />}>
|
||||||
Changes detected. Please reload the plug-in to ensure all modifications are included in the
|
Changes detected in fonts.
|
||||||
exported file.
|
<br />
|
||||||
|
Please reload the plug-in to ensure all modifications are included in the exported file.
|
||||||
</Banner>
|
</Banner>
|
||||||
<Stack space="xsmall" direction="row">
|
<Stack space="xsmall" direction="row">
|
||||||
<Button onClick={reload} fullWidth>
|
<Button onClick={reload} fullWidth>
|
||||||
|
|
Loading…
Reference in a new issue