feat(web-app-html-editor): add an HTML editor with live preview#13895
Open
dj4oC wants to merge 8 commits into
Open
feat(web-app-html-editor): add an HTML editor with live preview#13895dj4oC wants to merge 8 commits into
dj4oC wants to merge 8 commits into
Conversation
Document how an oCIS editor app actually works before writing code: apps register by file extension (not MIME type), and AppWrapper already provides the WebDAV load/save, dirty tracking, Ctrl+S, unsaved-changes guard and error toasts. Record the editor-library, preview-sandboxing, layout and registration decisions, each citing the Phase 1 file it relies on. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: David Walter <david.walter@kiteworks.com>
Mirror the text-editor package layout (package.json, vitest config, l10n) and add CodeMirror 6 (already resolved in the lockfile via web-pkg) as direct deps. Enable the app by adding "html-editor" to the default and sample-ocis configs; the build auto-discovers it by its web-app-* directory name. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: David Walter <david.walter@kiteworks.com>
…ew modes Register for the html, htm and xhtml extensions and route through AppWrapper, so WebDAV load/save, dirty state, Ctrl+S and the unsaved-changes guard are inherited. App.vue is a thin shell that binds currentContent and emits update:currentContent; it composes a CodeMirror 6 source editor (HTML mode, themed via ODS tokens), a sandboxed srcdoc iframe preview (no allow-same-origin), and a view-mode toolbar (Editor | Split | Preview) laid out with CSS grid. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: David Walter <david.walter@kiteworks.com>
…olbar Cover the app wiring (re-emits edits, switches view mode, debounces the preview), the CodeMirror pane (renders, emits on change, applies external content), the preview pane (srcdoc, sandbox without allow-same-origin, no referrer) and the toolbar (active mode, emits changeMode). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: David Walter <david.walter@kiteworks.com>
…view An adversarial security review (SECURITY-REVIEW.md) confirmed the design is sound against the primary threat (a victim opening an attacker-controlled HTML file): the opaque-origin iframe plus bearer-token-in-JS auth prevent token theft, parent-origin XSS and acting as the victim. This tightens the residual low/info findings: - Reduce the iframe sandbox to "allow-scripts" only. allow-forms and allow-popups added no value for a preview but enabled zero-click phishing / external form-POST beaconing from the opaque-origin frame; dropping them removes the vector. - Inject a strict, self-contained CSP into the preview srcdoc (default-src 'none'; form-action 'none'; base-uri 'none'; inline script/style and data:/blob: only) so the preview is network-isolated and not reliant on the deployment proxy CSP. - Pause the live preview for large files until the user opts in, so a huge or hostile document cannot freeze the tab on open. - Pin the full sandbox contract (exact token set + srcdoc-not-src) in tests so a future change cannot silently loosen the one control everything depends on. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: David Walter <david.walter@kiteworks.com>
|
Thanks for opening this pull request! The maintainers of this repository would appreciate it if you would create a changelog item based on your changes. |
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
#13895 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: David Walter <david.walter@kiteworks.com>
SonarCloud flagged the appInfo.extensions map and the app-switcher menu-item block in index.ts as duplicated against web-app-text-editor (new-code duplication over the 3% gate). Assign the already-typed fileExtensions directly instead of re-mapping them, and drop the app-switcher launcher entry: it was copied boilerplate and is not needed for v1. Users can still create a new HTML file from the Files "New" menu via the extension's newFileMenu. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: David Walter <david.walter@kiteworks.com>
… test The shared unit-test run (vitest projects) went red on web-pkg's @vitest/web-worker tests with timeouts only after this package was added, and the symptom (worker callbacks never firing) matches fake timers being active during real-timer async. Rewrite the debounce assertion to use real timers and a short wait so this test project cannot influence timer state in the shared run. No change to behavior under test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: David Walter <david.walter@kiteworks.com>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
Adds a new core app,
web-app-html-editor, that opens.html/.htm/.xhtmlfiles in a CodeMirror 6 source editor with a live, sandboxed preview. No WOPI and no
extra server: the file is loaded and saved over WebDAV by the standard
AppWrapper,the source is edited in CodeMirror, and the rendered result is shown in a strictly
sandboxed
<iframe srcdoc>.Approach
The app is intentionally thin and idiomatic. It mirrors
web-app-text-editor:defineWebApplicationregisters it by file extension and routes throughAppWrapperRoute. By declaring acurrentContentprop and emittingupdate:currentContent, it inherits the framework's WebDAV load/save, dirtytracking,
Ctrl+S, autosave, the unsaved-changes guard and error notifications, sonone of that is reimplemented. The app itself only composes:
HtmlEditorPane.vue- a CodeMirror 6 wrapper (HTML mode, line numbers, themefollows the active ownCloud theme). CodeMirror 6 is already in the workspace via
md-editor-v3, so the individual@codemirror/*packages are added at theversions already in the lockfile.
HtmlPreviewPane.vue- a sandboxedsrcdociframe.HtmlToolbar.vue- an Editor | Split | Preview view-mode toggle (CSS grid; thefilename, Save and action menu come from
AppTopBar).The app is enabled by default via the
appsarray inconfig/config.json.distandconfig/config.json.sample-ocis.Security
The preview renders attacker-influenceable HTML (a user may open a file shared to
them), so the preview is treated as untrusted:
sandbox="allow-scripts"with noallow-same-origin(opaqueorigin), so the preview cannot read the shell's cookies, storage or OIDC token,
cannot call the oCIS API as the user, and cannot script the parent.
allow-formsand
allow-popupsare deliberately omitted.default-src 'none'; form-action 'none'; base-uri 'none'; inlinescript/style and
data:/blob:only) is injected into thesrcdoc, so thepreview is network-isolated and does not depend on the deployment proxy CSP.
or hostile document cannot freeze the tab on open.
srcdoc-not-src).Trade-off: because the preview is network-isolated, documents that reference
external stylesheets/scripts/images will not load them. This is intentional for
a first version. The package ships
ARCHAEOLOGY.md,DECISIONS.mdandSECURITY-REVIEW.mddocumenting the design rationale and the threat model.Testing
contract,
srcdoc), the toolbar, the CSP-injection helper, and the large-filepreview pause.
pnpm --filter html-editor test:unitis green (27 tests).vue-tsc --noEmit,eslintandprettierare clean..htmlfile (the app ispicked up as the default opener), live edit updating the preview, and saving back
over WebDAV.
Notes
MIME type), matching
web-app-text-editor.