diff --git a/packages/core/src/clipboard.ts b/packages/core/src/clipboard.ts index 97c9f9e37..e16acc0bb 100644 --- a/packages/core/src/clipboard.ts +++ b/packages/core/src/clipboard.ts @@ -8,7 +8,7 @@ import { sortChildren } from '@open-pencil/fig/node-change' import { initCodec, getCompiledSchema, getSchemaBytes } from '@open-pencil/kiwi/fig/codec' -import type { NodeChange as KiwiNodeChange } from '@open-pencil/kiwi/fig/codec' +import type { GUID, NodeChange as KiwiNodeChange } from '@open-pencil/kiwi/fig/codec' import { decodeBinarySchema, compileSchema, ByteBuffer } from '@open-pencil/kiwi/schema-runtime' import type { SceneGraph, SceneNode } from '@open-pencil/scene-graph' @@ -283,7 +283,9 @@ export function importClipboardNodes( remapComponentIds(created, graph) - populateAndApplyOverrides(graph, guidMap as Map, created, blobs) + graph.preserveSourceMetadataDuring(() => { + populateAndApplyOverrides(graph, guidMap as Map, created, blobs) + }) for (const figmaId of internalTopLevel) { const ourId = created.get(figmaId) @@ -321,6 +323,8 @@ export async function buildFigmaClipboardHTML( } } + const nodeIdToGuid = new Map() + const assignedGuidValues = new Set() const blobs: Uint8Array[] = [] for (let i = 0; i < nodes.length; i++) { collectTextNodes(nodes[i]) @@ -332,8 +336,12 @@ export async function buildFigmaClipboardHTML( localIdCounter, graph, blobs, + nodeIdToGuid, + fontDigestMap, undefined, - fontDigestMap + undefined, + undefined, + assignedGuidValues ) ) } diff --git a/tests/engine/clipboard/figma/html.test.ts b/tests/engine/clipboard/figma/html.test.ts index f8625026d..5800b52ff 100644 --- a/tests/engine/clipboard/figma/html.test.ts +++ b/tests/engine/clipboard/figma/html.test.ts @@ -141,6 +141,37 @@ describe('buildFigmaClipboardHTML', () => { expect(html).toContain('figmeta') }) + it('preserves source metadata while importing instance overrides', async () => { + const source = new SceneGraph() + const sourcePage = source.getPages()[0] + const component = source.createNode('COMPONENT', sourcePage.id, { name: 'Button' }) + source.createNode('TEXT', component.id, { name: 'Label', text: 'Effective label' }) + const instance = source.createNode('INSTANCE', sourcePage.id, { + name: 'Button instance', + componentId: component.id + }) + source.populateInstanceChildren(instance.id, component.id) + + const html = await buildFigmaClipboardHTML([component, instance], source) + const parsed = await parseFigmaClipboard(expectDefined(html, 'Figma clipboard html')) + const clipboard = expectDefined(parsed, 'Figma clipboard') + const target = new SceneGraph() + const targetPage = target.getPages()[0] + importClipboardNodes(clipboard.nodes, target, targetPage.id) + const importedInstance = [...target.getAllNodes()].find( + (node) => node.type === 'INSTANCE' && node.name === 'Button instance' + ) + const importedLabel = importedInstance + ? [...target.getAllNodes()].find( + (node) => node.type === 'TEXT' && node.parentId === importedInstance.id + ) + : undefined + + expect(importedInstance).toBeDefined() + expect(importedLabel?.text).toBe('Effective label') + expect(importedLabel?.source.editedFields).toEqual([]) + }) + it('roundtrips: encode then decode back', async () => { const graph = new SceneGraph() const page = graph.getPages()[0]