Initial import: open-design source for helix-mind.ai distribution
Some checks failed
ci / Validate workspace (push) Successful in 12m32s
landing-page-ci / Validate landing page (push) Successful in 9m41s
landing-page-deploy / Deploy landing page (push) Failing after 5m23s
refresh-contributors-wall / Refresh contributors wall cache bust (push) Failing after 12s
github-metrics / Generate repository metrics SVG (push) Failing after 2m8s
Some checks failed
ci / Validate workspace (push) Successful in 12m32s
landing-page-ci / Validate landing page (push) Successful in 9m41s
landing-page-deploy / Deploy landing page (push) Failing after 5m23s
refresh-contributors-wall / Refresh contributors wall cache bust (push) Failing after 12s
github-metrics / Generate repository metrics SVG (push) Failing after 2m8s
This repository contains the open-design daemon CLI source code, built and packaged at https://helix-mind.ai/cli/open-design/latest.tgz for use by the HelixMind /design slash command. Licenses: Apache-2.0 (root) + MIT (skills/*)
This commit is contained in:
69
apps/web/tests/edit-mode/bridge.test.ts
Normal file
69
apps/web/tests/edit-mode/bridge.test.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { JSDOM } from 'jsdom';
|
||||
import {
|
||||
buildManualEditBridge,
|
||||
isMeaningfulManualEditElement,
|
||||
isManualEditHostNode,
|
||||
isSourceMappableManualEditElement,
|
||||
manualEditDomPathForElement,
|
||||
manualEditStableIdForElement,
|
||||
} from '../../src/edit-mode/bridge';
|
||||
|
||||
describe('manual edit bridge target normalization', () => {
|
||||
it('prefers explicit data-od-id over generated ids', () => {
|
||||
const dom = new JSDOM('<main><h1 data-od-id="hero">Title</h1></main>');
|
||||
const target = dom.window.document.querySelector('h1')!;
|
||||
|
||||
expect(manualEditStableIdForElement(target)).toBe('hero');
|
||||
expect(target.getAttribute('data-od-runtime-id')).toBeNull();
|
||||
});
|
||||
|
||||
it('generates stable DOM path ids for unannotated elements', () => {
|
||||
const dom = new JSDOM('<main><section><p>First</p><p>Second</p></section></main>');
|
||||
const target = dom.window.document.querySelectorAll('p')[1]!;
|
||||
|
||||
expect(manualEditDomPathForElement(target)).toBe('path-0-0-1');
|
||||
expect(manualEditStableIdForElement(target)).toBe('path-0-0-1');
|
||||
expect(manualEditStableIdForElement(target)).toBe('path-0-0-1');
|
||||
expect(target.getAttribute('data-od-runtime-id')).toBe('path-0-0-1');
|
||||
});
|
||||
|
||||
it('generates DOM path ids against source-shaped children, ignoring host shim nodes', () => {
|
||||
const dom = new JSDOM(
|
||||
'<script data-od-sandbox-shim></script><main><section><p>First</p><p>Second</p></section></main><script data-od-edit-bridge></script>',
|
||||
);
|
||||
const target = dom.window.document.querySelectorAll('p')[1]!;
|
||||
|
||||
expect(isManualEditHostNode(dom.window.document.querySelector('[data-od-sandbox-shim]')!)).toBe(true);
|
||||
expect(manualEditDomPathForElement(target)).toBe('path-0-0-1');
|
||||
});
|
||||
|
||||
it('discovers meaningful elements and ignores tiny or irrelevant elements', () => {
|
||||
const dom = new JSDOM('<main><h1 data-od-source-path="path-0-0">Title</h1><script>1</script></main>');
|
||||
const title = dom.window.document.querySelector('h1')!;
|
||||
const script = dom.window.document.querySelector('script')!;
|
||||
|
||||
expect(isMeaningfulManualEditElement(title, { width: 80, height: 24 })).toBe(true);
|
||||
expect(isMeaningfulManualEditElement(title, { width: 3, height: 24 })).toBe(false);
|
||||
expect(isMeaningfulManualEditElement(script, { width: 80, height: 24 })).toBe(false);
|
||||
});
|
||||
|
||||
it('does not expose path targets unless they carry a source path marker', () => {
|
||||
const dom = new JSDOM('<main><h1>Runtime title</h1><p data-od-source-path="path-0-1">Source text</p></main>');
|
||||
const runtimeTitle = dom.window.document.querySelector('h1')!;
|
||||
const sourceText = dom.window.document.querySelector('p')!;
|
||||
|
||||
expect(isSourceMappableManualEditElement(runtimeTitle)).toBe(false);
|
||||
expect(isSourceMappableManualEditElement(sourceText)).toBe(true);
|
||||
expect(isMeaningfulManualEditElement(runtimeTitle, { width: 80, height: 24 })).toBe(false);
|
||||
});
|
||||
|
||||
it('omits selected outerHTML from bulk target posts but includes it for selected targets', () => {
|
||||
const bridge = buildManualEditBridge(true);
|
||||
|
||||
expect(bridge).toContain('targets.push(targetFrom(nodes[i], false))');
|
||||
expect(bridge).toContain("target: targetFrom(el, true)");
|
||||
expect(bridge).toContain('if (!isSourceMappable(nodes[i])) continue;');
|
||||
expect(bridge).toContain('if (isPrimaryTarget(el)) return el;');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user