From 27fac02e994b69417622d009cb69037d99eef10a Mon Sep 17 00:00:00 2001 From: roymondchen Date: Fri, 12 Jun 2026 15:04:45 +0800 Subject: [PATCH] =?UTF-8?q?fix(editor):=20=E4=BB=85=E5=9C=A8=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=20left/top=20=E5=AE=9A=E4=BD=8D=E6=97=B6=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=E8=8A=82=E7=82=B9=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 避免对使用 right/bottom 定位的绝对定位节点误写 left 或 top。 --- packages/editor/src/utils/editor.ts | 17 +++++++--- .../editor/tests/unit/utils/editor.spec.ts | 34 +++++++++++++++++++ 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/packages/editor/src/utils/editor.ts b/packages/editor/src/utils/editor.ts index db15e58f..3e924fc0 100644 --- a/packages/editor/src/utils/editor.ts +++ b/packages/editor/src/utils/editor.ts @@ -375,11 +375,18 @@ export const fixNodePosition = (config: MNode, parent: MContainer, stage: StageC return config.style; } - return { - ...(config.style || {}), - top: getMiddleTop(config, parent, stage), - left: fixNodeLeft(config, parent, stage?.renderer?.contentWindow?.document), - }; + const style = { ...(config.style || {}) }; + const baseStyle = config.style || {}; + + if ('left' in baseStyle && !('right' in baseStyle)) { + style.left = fixNodeLeft(config, parent, stage?.renderer?.contentWindow?.document); + } + + if ('top' in baseStyle && !('bottom' in baseStyle)) { + style.top = getMiddleTop(config, parent, stage); + } + + return style; }; // 序列化配置 diff --git a/packages/editor/tests/unit/utils/editor.spec.ts b/packages/editor/tests/unit/utils/editor.spec.ts index e8748b7f..491c319d 100644 --- a/packages/editor/tests/unit/utils/editor.spec.ts +++ b/packages/editor/tests/unit/utils/editor.spec.ts @@ -1105,6 +1105,40 @@ describe('补充:fixNodeLeft / fixNodePosition / serializeConfig', () => { expect(result).toBeDefined(); }); + test('fixNodePosition - 仅设置 right 时不修正 left', () => { + const style = { position: 'absolute', right: 10 } as any; + const result = editor.fixNodePosition({ id: 'a', style } as any, { id: 'p', items: [] } as any, null); + expect(result).toEqual(style); + expect(result?.left).toBeUndefined(); + }); + + test('fixNodePosition - 仅设置 bottom 时不修正 top', () => { + const style = { position: 'absolute', bottom: 20 } as any; + const result = editor.fixNodePosition({ id: 'a', style } as any, { id: 'p', items: [] } as any, null); + expect(result).toEqual(style); + expect(result?.top).toBeUndefined(); + }); + + test('fixNodePosition - 设置 left 且无 right 时修正 left', () => { + const doc = document.implementation.createHTMLDocument(); + const parent = doc.createElement('div'); + parent.dataset.tmagicId = 'p3'; + Object.defineProperty(parent, 'offsetWidth', { value: 100 }); + const child = doc.createElement('div'); + child.dataset.tmagicId = 'a3'; + Object.defineProperty(child, 'offsetWidth', { value: 80 }); + parent.appendChild(child); + doc.body.appendChild(parent); + + const stage = { renderer: { contentWindow: { document: doc } } } as any; + const result = editor.fixNodePosition( + { id: 'a3', style: { position: 'absolute', left: 50 } } as any, + { id: 'p3', items: [] } as any, + stage, + ); + expect(result?.left).toBe(20); + }); + test('serializeConfig - 输出去掉了 key 引号', () => { const out = editor.serializeConfig({ a: 1 }); expect(out).toContain('a:');