Skip to content

feat(ui-core,vue): inline same-origin embedding of ZK views (no iframe) - #114

Merged
marioserrano09 merged 1 commit into
mainfrom
feat/113-inline-zk-embed
Sep 30, 2026
Merged

marioserrano09 merged 1 commit into
mainfrom
feat/113-inline-zk-embed

Conversation

@marioserrano09

Copy link
Copy Markdown
Contributor

Closes #113

What

Inline (no-iframe), same-origin embedding of server-rendered ZK views, usable from Vue.

  • ui-core/embed: mountInline(container, src) fetches the ZK response, injects its deduplicated <head> assets (scripts in order, shared between concurrent embeds), appends the body re-creating its <script> nodes, and waits for the desktop announced by the response (dt:'...'). destroy() detaches root pages, calls zAu._rmDesktop and deletes the desktop from zk.Desktop.all.
  • <dynamia-embed mode="inline" src="...">: uses it; content in light DOM (slotted), same-origin only, dynamia-embed:load carries type: 'inline' + desktopIds.
  • @dynamia-tools/vue: <DynamiaZkEmbed src> (load/error events, loading/error slots, remount on src change, cleanup on unmount). Registered by the plugin.
  • Docs: docs/frontend/INLINE_ZK_EMBED.md, READMEs.

Decision worth reviewing

No new backend endpoint. #113 planned a bootstrap endpoint under app/metadata, but the spike showed the response <head> of any ZK view is already a per-page manifest with the versioned asset URLs. /books and /page-embed/<module>/<group>/<page> both work as-is. Nothing changes in the public API of the backend.

Bug found while verifying

Attributing desktops by diffing zk.Desktop.all breaks with overlapping mounts (destroying one embed released the other's desktop). The id is now taken from each response's own dt:'...', unescaped (ZK writes - as \- in the JS source). Covered by tests.

Verification

  • ui-core: 121 tests pass (inline.test.ts added, happy-dom), tsc --noEmit clean, build OK (standalone IIFE grew ~3.5 → 9 kB min).
  • vue: vue-tsc --noEmit clean, build OK, 13 tests pass.
  • Headless Chrome against examples/demo-zk-books (packaged jar), using the built dynamia-embed.global.js: two concurrent inline embeds (/books, /page-embed/library/books) → one desktop each; removing one leaves the other working (AU answers with rid) while the removed one behaves as unknown server-side; changing src replaces the desktop; cross-origin rejected via dynamia-embed:error.

Not verified

  • <DynamiaZkEmbed> in a real browser (only type-checked/built).
  • CSS leak between ZK and the host, WebSocket with several desktops in one window, floating widgets opened at destroy time (only the demo's default views were exercised).
  • Other ZK versions: relies on private client API (zAu._rmDesktop, zk.Desktop.all), every access guarded; verified with ZK 10.3.0.1.

Notes

  • Adds happy-dom as a ui-core devDependency (lockfile changed).
  • Unrelated, seen in passing: MyBookStoreModuleProvider registers Page("htmx", "/htmx.html?v=1"), which 404s (file is served under /static/). Not touched.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GXVz2G6v1fqFdQjRSh9XZF

…frame

- ui-core/embed: mountInline() fetches a server-rendered ZK view, injects its
  deduplicated head assets, appends the body re-creating scripts and tracks the
  desktop id announced by the response (dt:'...'); destroy() releases the
  desktop client- and server-side (zAu._rmDesktop).
- <dynamia-embed mode="inline"> uses it (light DOM, same-origin only).
- @dynamia-tools/vue: <DynamiaZkEmbed> wrapper (load/error events, loading/error slots).
- docs/frontend/INLINE_ZK_EMBED.md; happy-dom devDependency for DOM tests.

No backend endpoint added: the response <head> is already the bootstrap manifest.

Refs #113

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXVz2G6v1fqFdQjRSh9XZF
@marioserrano09
marioserrano09 merged commit 6b71727 into main Sep 30, 2026
1 check passed
@marioserrano09 marioserrano09 mentioned this pull request Sep 30, 2026
1 task done
marioserrano09 added a commit that referenced this pull request Oct 1, 2026
* chore: bump version to 26.10.0

Includes navigation multi-desktop support (#112), inline ZK embed (#114)
and localized navigation labels (#116).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* chore(cli): bump cli.properties versions to 26.10.0

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ui-core/embed + vue: inline (no-iframe) same-origin embedding of ZK pages

1 participant