diff --git a/desktop/src/preview-agent/treeNav.test.ts b/desktop/src/preview-agent/treeNav.test.ts new file mode 100644 index 00000000..e59cb717 --- /dev/null +++ b/desktop/src/preview-agent/treeNav.test.ts @@ -0,0 +1,17 @@ +import { describe, expect, it, beforeEach } from 'vitest' +import { climb, descend } from './treeNav' + +beforeEach(() => { document.body.innerHTML = `

A

` }) + +describe('tree navigation', () => { + it('climb returns parent element, not past body', () => { + const h1 = document.querySelector('h1')! + expect(climb(h1)?.tagName.toLowerCase()).toBe('section') + expect(climb(document.querySelector('main')!)).toBeNull() // body 为界 + }) + it('descend returns first element child', () => { + const section = document.querySelector('section')! + expect(descend(section)?.tagName.toLowerCase()).toBe('h1') + expect(descend(document.querySelector('h1')!)).toBeNull() + }) +}) diff --git a/desktop/src/preview-agent/treeNav.ts b/desktop/src/preview-agent/treeNav.ts new file mode 100644 index 00000000..e6b23cd2 --- /dev/null +++ b/desktop/src/preview-agent/treeNav.ts @@ -0,0 +1,8 @@ +export function climb(el: Element): Element | null { + const p = el.parentElement + if (!p || p.tagName.toLowerCase() === 'body' || p.tagName.toLowerCase() === 'html') return null + return p +} +export function descend(el: Element): Element | null { + return el.firstElementChild +}