Repository navigation
fix(viewer): migrate to @nextcloud/viewer for Nextcloud 36 - #375
Open
AndyScherzinger wants to merge 9 commits into
Open
AndyScherzinger wants to merge 9 commits into
AndyScherzinger wants to merge 9 commits into
Conversation
Nextcloud 36 dropped array access on the server container, so \OC::$server[...] fails with "Cannot use object of type OC\Server as array" and the viewer iframe returns a 500. OCP\Server::get() is the public API for this and works on all supported versions. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
Nextcloud 36 removes the viewer app. OCA.Viewer.registerHandler() and setRootElement() are gone and the LoadViewer event is never dispatched, so mind maps no longer open at all. - Register the handler with @nextcloud/viewer from an init script loaded on BeforeTemplateRenderedEvent. - Render the editor iframe from a native custom element instead of a Vue 2 component built on the viewer mixin. - Open and close the viewer through getViewer(). The edit file action is only registered on Nextcloud 32, from 33 on the viewer registers the actions for its handlers itself. - Mount the element directly into the public share page instead of pointing the viewer at it. Closes #353 Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
The custom renderBuiltUrl emitted a bare OC.filePath(), which a minified top-level function named OC can shadow. With the viewer library bundled, lazy chunks then fail to load wherever this app's copy of the viewer is the one mounted, e.g. on Nextcloud 32. @nextcloud/vite-config already emits window.OC.filePath() itself. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
The toast was handed the Error object, which made it throw and hid the actual error. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
On Nextcloud 32 and later the public share page is rendered by the Files app and opens single-file shares through the default file action, so the #files-public-content container public.js waited for does not exist on any supported version. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
The handler registration runs on every page, but pulled in the whole editor logic with it: dialogs, axios, jszip, and @nextcloud/files-legacy with its WebDAV client and Node polyfills, about 1 MB. - Register the handler from constants and the element only, and load mindmap.js when a mind map is first shown. - Load the Nextcloud 32 file action from its own chunk, only on 32. What every page loads drops from 1062 kB (301 kB gzip) to 169 kB (61 kB gzip), most of it the @nextcloud/viewer entry itself. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
AndyScherzinger
force-pushed
the
fix/viewer-library
branch
from
October 10, 2026 15:35
61ddb91 to
099c9c1
Compare
Where no newer copy is on the page, this app's copy is the viewer that gets mounted, so ship the current one. Its breaking changes do not affect this app: open() is called without callbacks, and compare() and canCompare are not used. The 'default' theme now follows the user's theme again, as it did with the viewer app. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
None of the rules in css/style.css apply on a supported version: - the #body-public rules styled the old public share page, which the Files app renders since at least Nextcloud 32 - the .ie rule targeted Internet Explorer - nothing renders a #mmframe element - .icon-mindmap was only the template creator's fallback for servers without setIconSvgInline(), which exists since Nextcloud 29 Drop it together with LoadAdditionalListener, which only added it to the Files app, its link in the editor iframe, and the fallback. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
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.
Closes #353
Mind maps no longer open on Nextcloud 36. Two independent problems cause it, fixed in separate commits:
templates/viewer.phpused\OC::$server[...], and array access on the server container is gone in 36 (Cannot use object of type OC\Server as array). It now usesOCP\Server::get().LoadVieweris no longer dispatched, andOCA.Viewer.registerHandler()/setRootElement()no longer exist.Changes for the second part:
@nextcloud/viewer(^2.0.0-beta.18) from an init script loaded onBeforeTemplateRenderedEvent.src/views/MindMap.jsis now a native custom element rendering the editor iframe, instead of a Vue 2 component built on the viewer mixin.OCA.FilesMindMap.close()→getViewer().close().@nextcloud/files4 passes a context object toenabled()/exec(), it was never enabled on 33+ anyway; the viewer now registers the actions for its handlers itself.max-versionraised to 36.mindmap.js, with dialogs, axios and jszip) loads when a mind map is first shown, and the 32-only file action loads from its own chunk on 32 only. What every page loads goes from 1062 kB (301 kB gzip) to 169 kB (61 kB gzip), most of it the@nextcloud/viewerentry itself.Found while testing on 32:
renderBuiltUrlinvite.config.tsemitted a bareOC.filePath(), which a minified top-levelfunction OCin the bundle shadows (OC.filePath is not a function). This only surfaces where this app's copy of the viewer is the one mounted (no newer copy on the page, e.g. 32). Dropped the override;@nextcloud/vite-configalready emitswindow.OC.filePath().Errorobject and threw, hiding the real error.public.jsandLoadPublicViewerListenerare removed: on 32, 34 and 36 the public share page is rendered by the Files app and opens single-file shares through the default file action, so the#files-public-contentcontainer it waited for does not exist on any supported version.css/style.cssis removed, withLoadAdditionalListenerthat only added it to Files, its link in the editor iframe, and the template creator'sicon-mindmapfallback. None of its rules apply on 32+: the#body-publicrules styled that old share page,.ietargeted Internet Explorer, nothing renders#mmframe, andicon-mindmapwas only used withoutsetIconSvgInline(), which exists since 29.Testing
Tested with a browser on Nextcloud 36 (master), 34.0.4 (viewer 7.0.0-dev from
stable34) and 32.0.15 (viewer 5.0.0):Vitest suite passes. The table was run with
@nextcloud/viewer2.0.0-beta.14; 32 and 36 were re-run after the init script split. After the bump to 2.0.0-beta.18, 36 was re-run (open, save, public share); there this app's copy is elected over the server's 2.0.0-beta.15, so it exercises the bundled viewer and its styles. 32 and 34 were not re-run on beta.18. On 32 and 34 the old viewer app keeps itsOCA.Viewerglobal while the library registry only holds this handler, so both coexist:@nextcloud/vieweronly useswindow._nc_viewer_scope, never touchesOCA.Viewer, and no default handlers are registered. 33 and 35 not tested separately.Notes
defaulttheme follows the user's theme, but on a light theme the viewer header title stays light (rgb(235, 235, 235)on white), so it is barely readable. The viewer's CSS is bundled and applied; its header rules only cover the non-default themes, so this looks like a library issue rather than this app.src/__tests__/MindMap.spec.jsis replaced bymindmapElement.spec.js. Besides testing the removed Vue component, it collided withmindmap.spec.json case-insensitive filesystems.🤖 AI (if applicable)