From 7574f16316fb654d02aa3364a43d309e7602ef07 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Mon, 5 Oct 2026 20:17:06 +0200 Subject: [PATCH 1/9] fix(viewer): resolve services through OCP\Server in the template 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 --- templates/viewer.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/templates/viewer.php b/templates/viewer.php index 4b926aa..5ef64e8 100644 --- a/templates/viewer.php +++ b/templates/viewer.php @@ -9,8 +9,9 @@ /** @var array $_ */ use OCP\App\IAppManager; use OCP\IURLGenerator; - $urlGenerator = \OC::$server->get(IURLGenerator::class); - $version = \OC::$server[IAppManager::class]->getAppVersion('files_mindmap'); + use OCP\Server; + $urlGenerator = Server::get(IURLGenerator::class); + $version = Server::get(IAppManager::class)->getAppVersion('files_mindmap'); $lang = $_['lang']; $nonce = $_['cspNonce'] ?? ''; ?> From e154b58517338914bcca3532030d78e7195ea4cd Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Mon, 5 Oct 2026 20:20:30 +0200 Subject: [PATCH 2/9] fix(viewer): register the handler with @nextcloud/viewer 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 --- lib/AppInfo/Application.php | 3 +- lib/Listener/LoadViewerListener.php | 20 +- package-lock.json | 1117 +++++++++++++++++++++++--- package.json | 1 + src/__tests__/MindMap.spec.js | 108 --- src/__tests__/mindmap.spec.js | 10 +- src/__tests__/mindmapElement.spec.js | 72 ++ src/mindmap.js | 38 +- src/mindmapviewer.js | 25 +- src/public.js | 42 +- src/viewer.js | 4 +- src/views/MindMap.js | 89 +- 12 files changed, 1197 insertions(+), 332 deletions(-) delete mode 100644 src/__tests__/MindMap.spec.js create mode 100644 src/__tests__/mindmapElement.spec.js diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 4718e91..8e571b5 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -18,7 +18,6 @@ use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\IMimeTypeDetector; use OCP\Security\CSP\AddContentSecurityPolicyEvent; -use OCA\Viewer\Event\LoadViewer; use OCA\Files_MindMap\Listener\LoadAdditionalListener; use OCA\Files_MindMap\Listener\LoadViewerListener; use OCA\Files_MindMap\Listener\LoadPublicViewerListener; @@ -48,7 +47,7 @@ public function registerProvider() { public function register(IRegistrationContext $context): void { $context->registerEventListener(LoadAdditionalScriptsEvent::class, LoadAdditionalListener::class); $context->registerEventListener(BeforeTemplateRenderedEvent::class, LoadPublicViewerListener::class); - $context->registerEventListener(LoadViewer::class, LoadViewerListener::class); + $context->registerEventListener(BeforeTemplateRenderedEvent::class, LoadViewerListener::class); $context->registerEventListener(RegisterTemplateCreatorEvent::class, RegisterTemplateCreatorListener::class); } diff --git a/lib/Listener/LoadViewerListener.php b/lib/Listener/LoadViewerListener.php index e79cfe1..107e7d6 100644 --- a/lib/Listener/LoadViewerListener.php +++ b/lib/Listener/LoadViewerListener.php @@ -9,19 +9,27 @@ namespace OCA\Files_MindMap\Listener; -use OCA\Viewer\Event\LoadViewer; +use OCA\Files_MindMap\AppInfo\Application; +use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent; +use OCP\AppFramework\Http\TemplateResponse; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use OCP\Util; -/** @template-implements IEventListener */ +/** @template-implements IEventListener */ class LoadViewerListener implements IEventListener { public function handle(Event $event): void { - if (!$event instanceof LoadViewer) { + if (!$event instanceof BeforeTemplateRenderedEvent) { return; } - - Util::addScript('files_mindmap', 'files_mindmap-mindmapviewer', 'viewer'); + + if ($event->getResponse()->getRenderAs() === TemplateResponse::RENDER_AS_ERROR) { + return; + } + + // The viewer reads its handlers when the first file is opened, so the + // handler has to be registered from an init script + Util::addInitScript(Application::APPNAME, 'files_mindmap-mindmapviewer'); } -} \ No newline at end of file +} diff --git a/package-lock.json b/package-lock.json index a79fda1..429dcb3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "@nextcloud/paths": "^3.1.0", "@nextcloud/router": "^3.2.0", "@nextcloud/sharing": "^0.4.0", + "@nextcloud/viewer": "^2.0.0-beta.14", "jszip": "^3.10.2" }, "devDependencies": { @@ -1102,6 +1103,19 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "license": "ISC", + "optional": true, + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -1651,6 +1665,24 @@ "@nextcloud/files": "^3.12.0" } }, + "node_modules/@nextcloud/image-editor": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@nextcloud/image-editor/-/image-editor-1.0.0-beta.7.tgz", + "integrity": "sha512-JZG4HCX3XMm2hc54xvEs8xPo60q4g+qvevJu7WWEAqeGTK3erl6q70224OhGC7gDijMZE+kC753WKpJLnYBMwA==", + "license": "AGPL-3.0-or-later", + "dependencies": { + "@nextcloud/l10n": "^3.4.0", + "konva": "~10.3.2" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || ^24.0.0" + }, + "peerDependencies": { + "@nextcloud/dialogs": "^7.0.0", + "@nextcloud/vue": "^9.0.0", + "vue": "^3.5.0" + } + }, "node_modules/@nextcloud/initial-state": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@nextcloud/initial-state/-/initial-state-3.0.0.tgz", @@ -1737,6 +1769,39 @@ "node": "^20.0.0 || ^22.0.0 || ^24.0.0" } }, + "node_modules/@nextcloud/viewer": { + "version": "2.0.0-beta.14", + "resolved": "https://registry.npmjs.org/@nextcloud/viewer/-/viewer-2.0.0-beta.14.tgz", + "integrity": "sha512-1we9o780BP/HQBZhcz+czM76yq8Df1smWLj5JhKPQXs+jcAuAeaK5u490qwdZKHr4n4Voqsz0H6sdVU+3vG+VQ==", + "license": "AGPL-3.0-or-later", + "dependencies": { + "@mdi/svg": "^7.4.47", + "@nextcloud/image-editor": "^1.0.0-beta.6", + "@nextcloud/logger": "^3.0.3", + "@skjnldsv/vue-plyr": "^7.5.0", + "debounce": "^3.0.0", + "dompurify": "^3.4.14", + "opensheetmusicdisplay": "^2.1.3", + "vue-material-design-icons": "^5.3.1", + "webdav": "^5.10.0" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || ^24.0.0" + }, + "peerDependencies": { + "@nextcloud/axios": "^2.5.2", + "@nextcloud/capabilities": "^1.2.1", + "@nextcloud/dialogs": "^7.5.0", + "@nextcloud/event-bus": "^3.3.3", + "@nextcloud/files": "^4.0.0", + "@nextcloud/l10n": "^3.4.1", + "@nextcloud/paths": "^3.1.0", + "@nextcloud/router": "^3.1.0", + "@nextcloud/sharing": "^0.4.0 || ^1.0.0-beta.2", + "@nextcloud/vue": "^9.13.0", + "vue": "^3.5.0" + } + }, "node_modules/@nextcloud/vite-config": { "version": "2.5.4", "resolved": "https://registry.npmjs.org/@nextcloud/vite-config/-/vite-config-2.5.4.tgz", @@ -1767,9 +1832,9 @@ } }, "node_modules/@nextcloud/vue": { - "version": "9.11.0", - "resolved": "https://registry.npmjs.org/@nextcloud/vue/-/vue-9.11.0.tgz", - "integrity": "sha512-LRsyU9Mxs0b2xWqbxygps8O7/i1z4QhNQD9/QDni+VqFY3V0N95mAgmKJm6vfoFuxTAMXERp9bjqFn3UV542gw==", + "version": "9.13.1", + "resolved": "https://registry.npmjs.org/@nextcloud/vue/-/vue-9.13.1.tgz", + "integrity": "sha512-6ZeHm+coHJ6wsavulll4CVl3tk5ehjh7p6pW9GU1BgfDkOsbx5Pv4U8/uVk7yOTn4oAo695XTHhFN17pyI1peQ==", "license": "AGPL-3.0-or-later", "dependencies": { "@ckpack/vue-color": "^1.6.0", @@ -1782,7 +1847,7 @@ "@nextcloud/initial-state": "^3.0.0", "@nextcloud/l10n": "^3.4.1", "@nextcloud/logger": "^3.0.3", - "@nextcloud/router": "^3.1.0", + "@nextcloud/router": "^3.2.0", "@nextcloud/sharing": "^0.4.0", "@nextcloud/vue-select": "^4.1.0", "@vuepic/vue-datepicker": "^11.0.3", @@ -1791,7 +1856,7 @@ "blurhash": "^2.0.5", "clone": "^2.1.2", "debounce": "^3.0.0", - "dompurify": "^3.4.14", + "dompurify": "^3.4.15", "emoji-mart-vue-fast": "^15.0.5", "escape-html": "^1.0.3", "floating-vue": "^5.2.2", @@ -1815,10 +1880,22 @@ "unist-builder": "^4.0.0", "unist-util-visit-parents": "^6.0.2", "vue": "^3.5.18", - "vue-router": "^5.2.0" + "vue-router": "^5.3.1" }, "engines": { "node": "^20.11.0 || ^22 || ^24" + }, + "peerDependencies": { + "@nextcloud/dialogs": "^7.4.0", + "@nextcloud/files": "^4.1.0" + }, + "peerDependenciesMeta": { + "@nextcloud/dialogs": { + "optional": true + }, + "@nextcloud/files": { + "optional": true + } } }, "node_modules/@nextcloud/vue-select": { @@ -1834,101 +1911,101 @@ } }, "node_modules/@nextcloud/vue/node_modules/@vue/compiler-core": { - "version": "3.5.42", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.42.tgz", - "integrity": "sha512-2Ye1ilMtKXxl8qZUrQ5j0CdgenFp/HFQmta6rfRyfEsTG69L6Wk+tWuNoHYHMx9E8tF2Slvdg1FuwDvAXdy1LQ==", + "version": "3.5.43", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.43.tgz", + "integrity": "sha512-zdiLhnbe1QQqgDT8xZMpNmyqZ3qlI+/Q/FHQco57Kwl/b05HhCzN6eVGN9QU9rbga4CrS0H5SYY8VGHZCt/1Hg==", "license": "MIT", "dependencies": { "@babel/parser": "^7.29.8", - "@vue/shared": "3.5.42", + "@vue/shared": "3.5.43", "entities": "^7.0.1", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "node_modules/@nextcloud/vue/node_modules/@vue/compiler-dom": { - "version": "3.5.42", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.42.tgz", - "integrity": "sha512-qbhQZEFmycr+ni/qyuccS4sucNN7VAbDfbkvNxWOX2VfgFm90MNs3/UhRNKoPMEIVn0F8gdlYjLPvqxHwHeQOA==", + "version": "3.5.43", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.43.tgz", + "integrity": "sha512-PEZoAk3NQmsn/ejMzSOCyTYqwGqczrWm70PuhBKjjv1+TCoQAaO/zOqNwjV+honlNstT5ILxtc+8r8UUfj+iEQ==", "license": "MIT", "dependencies": { - "@vue/compiler-core": "3.5.42", - "@vue/shared": "3.5.42" + "@vue/compiler-core": "3.5.43", + "@vue/shared": "3.5.43" } }, "node_modules/@nextcloud/vue/node_modules/@vue/compiler-sfc": { - "version": "3.5.42", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.42.tgz", - "integrity": "sha512-fkCAFB4okcAANGMThboWnScp/gzWjU0ZSkVnjTIiplmMDq2uq0tIB3j+xVu4rhv5rvOgBySCysudmbMd6xRRqw==", + "version": "3.5.43", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.43.tgz", + "integrity": "sha512-FCbrG3XNCRl+js3huuKx4IVHBLTvMkJhVepjbxSPu1gn4yWLaYtGNQdjJGZaMytXB6qb76qQDDmDSLy/vkmleQ==", "license": "MIT", "dependencies": { "@babel/parser": "^7.29.8", - "@vue/compiler-core": "3.5.42", - "@vue/compiler-dom": "3.5.42", - "@vue/compiler-ssr": "3.5.42", - "@vue/shared": "3.5.42", + "@vue/compiler-core": "3.5.43", + "@vue/compiler-dom": "3.5.43", + "@vue/compiler-ssr": "3.5.43", + "@vue/shared": "3.5.43", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", - "postcss": "^8.5.19", + "postcss": "^8.5.28", "source-map-js": "^1.2.1" } }, "node_modules/@nextcloud/vue/node_modules/@vue/compiler-ssr": { - "version": "3.5.42", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.42.tgz", - "integrity": "sha512-xmLk3wLkbizPAiLyomjgFFosf2ys9b5Ghb+oh/k2tnvipNz8OFrQOiTcWCzyK7MpBp9KkyGtfvgfLUivbmuGYA==", + "version": "3.5.43", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.43.tgz", + "integrity": "sha512-GF62orf7KiJX9RqrHNGrYBudsQGD0OhJ5nDs90O8UiDuS40+YMYomiXu6w6EuvtXuRDc3MSNis3EaaSKAVSWpg==", "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.42", - "@vue/shared": "3.5.42" + "@vue/compiler-dom": "3.5.43", + "@vue/shared": "3.5.43" } }, "node_modules/@nextcloud/vue/node_modules/@vue/reactivity": { - "version": "3.5.42", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.42.tgz", - "integrity": "sha512-TzNNfKpb7hDxbQltwAut8VDQA5YP+BuRlxntHUuRjyKwlMvmAPbs3unhCvieijifY6vFfVBwsS7wG/C7uq+bEQ==", + "version": "3.5.43", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.43.tgz", + "integrity": "sha512-G/c9GyOZNI2jVaaS6OX1EF1SSFSv7H0ERqNTl4+DTFMlZmB5eVAB53aLQNam/7NL2NPtaDD7RdVrzf8uJzMuOA==", "license": "MIT", "dependencies": { - "@vue/shared": "3.5.42" + "@vue/shared": "3.5.43" } }, "node_modules/@nextcloud/vue/node_modules/@vue/runtime-core": { - "version": "3.5.42", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.42.tgz", - "integrity": "sha512-9uACtuHs7vJGkm5Bp3xu4xRDLFTIYy5DgxpToVjqGIAhAEKwQfsaLvKINhM6nFVp6bZPRFGdDqd1g52MqKsotA==", + "version": "3.5.43", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.43.tgz", + "integrity": "sha512-hU6U6VnVhBGQDpvlnnDlIB8ZGJBiOcgk2lh/0InltHiz3D8oSkluvuvY+do1G2H3+udeKFsmaBlgVYP7gXQzEw==", "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.42", - "@vue/shared": "3.5.42" + "@vue/reactivity": "3.5.43", + "@vue/shared": "3.5.43" } }, "node_modules/@nextcloud/vue/node_modules/@vue/runtime-dom": { - "version": "3.5.42", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.42.tgz", - "integrity": "sha512-rsCmhiWLaRxGltLwhlCWyYkFn7WAbKRh0q17eZ1A6Dq6eqc2ACQ61IIryxz0LrsvCzHSilLA9JHovVwM8CNE2g==", + "version": "3.5.43", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.43.tgz", + "integrity": "sha512-Bb2Jc0YjjJdMt1SJmb9b2L/IWd3I8lIT9x9eS/xvvP9CiVgna0ffua74xKRmt4/uSJ+0r4iN8ex1jrqkhQGWQw==", "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.42", - "@vue/runtime-core": "3.5.42", - "@vue/shared": "3.5.42", + "@vue/reactivity": "3.5.43", + "@vue/runtime-core": "3.5.43", + "@vue/shared": "3.5.43", "csstype": "^3.2.3" } }, "node_modules/@nextcloud/vue/node_modules/@vue/server-renderer": { - "version": "3.5.42", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.42.tgz", - "integrity": "sha512-2++5dUyYS4gvo7xQXSECUDhB7TS0aOl5SeVfC5qSq1Jgfhjvegw1zqhwTIR3imZ+QYPJQw9gfcFvXGAjGZ7ajQ==", + "version": "3.5.43", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.43.tgz", + "integrity": "sha512-l2Ygjv9NehV94PSBxNWsAHC0j/eIIKbn92mBuWXAPGLnn6HfJ6MH5ubsd+Nk0YoZ5FRuxWI1P2VSoh+dbPQhCQ==", "license": "MIT", "dependencies": { - "@vue/compiler-ssr": "3.5.42", - "@vue/runtime-dom": "3.5.42", - "@vue/shared": "3.5.42" + "@vue/compiler-ssr": "3.5.43", + "@vue/runtime-dom": "3.5.43", + "@vue/shared": "3.5.43" } }, "node_modules/@nextcloud/vue/node_modules/@vue/shared": { - "version": "3.5.42", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.42.tgz", - "integrity": "sha512-2rPxex1jQf4jvl9MOHl6YaXCPcrNqz/FstMOEh3QWY+/OME9nQTvl9WYeCwhW7AFjaR0SnngZGlp/wkR6rkI6g==", + "version": "3.5.43", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.43.tgz", + "integrity": "sha512-uksS7YGMR5NZyr4JNq0Rp+QyLns0ueaz20KwzIPW9R0LH1Vnt4E+XUM29PNseEbf1www2gOuhuDi5AKOIXag9Q==", "license": "MIT" }, "node_modules/@nextcloud/vue/node_modules/chokidar": { @@ -1946,6 +2023,12 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/@nextcloud/vue/node_modules/confbox": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.3.1.tgz", + "integrity": "sha512-cKUSoKa8YxFZZSmraVi7onONx3amu77ngK3kGpsYHDH7drPwCRkQE1RYMPlLRrMtnciRj274XNRxcHxnKmDSnA==", + "license": "MIT" + }, "node_modules/@nextcloud/vue/node_modules/readdirp": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.1.1.tgz", @@ -1960,16 +2043,16 @@ } }, "node_modules/@nextcloud/vue/node_modules/vue": { - "version": "3.5.42", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.42.tgz", - "integrity": "sha512-4RyHQTbQvOPs3MfvUO1Sg0YRrKNnA0mAVtvpd12Tg1fKDN7OHBUl1IqSn8zGJjK9nI3NkNp8cgTpVrSZC5TTcA==", + "version": "3.5.43", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.43.tgz", + "integrity": "sha512-o5qZoksdnjIKvW1srZ3ab7pcDNYAerBjRe54D0LBLfRdCYFrSgBHVXokMas35czQc0//lmx4/tuY4ZNQ+Rf2Ng==", "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.42", - "@vue/compiler-sfc": "3.5.42", - "@vue/runtime-dom": "3.5.42", - "@vue/server-renderer": "3.5.42", - "@vue/shared": "3.5.42" + "@vue/compiler-dom": "3.5.43", + "@vue/compiler-sfc": "3.5.43", + "@vue/runtime-dom": "3.5.43", + "@vue/server-renderer": "3.5.43", + "@vue/shared": "3.5.43" }, "peerDependencies": { "typescript": "*" @@ -1981,26 +2064,26 @@ } }, "node_modules/@nextcloud/vue/node_modules/vue-router": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-5.3.0.tgz", - "integrity": "sha512-a2PBXX9yfkS58JzSJALUffgDa09lEzKmCcEnLaepoIr88L+9hEnsgEQkcadJGID+vtHa0gFpVo064zmylA9fcg==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-5.4.0.tgz", + "integrity": "sha512-pFvcYcxinDHjZUlf7AzFBrT8r8Xqvv4uMHoJnjc+EqPawXQvHTkF8S4tfSmQLpriVHUGfkaKlI7Et0KRjTMTdw==", "license": "MIT", "dependencies": { "@vue-macros/common": "^3.1.3", "@vue/devtools-api": "^8.1.5", - "ast-walker-scope": "^0.9.0", + "ast-walker-scope": "^0.10.0", "chokidar": "^5.0.0", - "confbox": "^0.2.4", + "confbox": "^0.3.1", "local-pkg": "^1.2.1", - "magic-string": "^0.30.21", + "magic-string": "^1.4.3", "mlly": "^1.8.2", "muggle-string": "^0.4.1", - "nostics": "^1.1.4", + "nostics": "^1.3.0", "pathe": "^2.0.3", - "picomatch": "^4.0.5", + "picomatch": "^4.0.7", "scule": "^1.3.0", "tinyglobby": "^0.2.17", - "unplugin": "^3.3.0", + "unplugin": "^3.4.0", "unplugin-utils": "^0.3.2" }, "funding": { @@ -2028,6 +2111,15 @@ } } }, + "node_modules/@nextcloud/vue/node_modules/vue-router/node_modules/magic-string": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.4.3.tgz", + "integrity": "sha512-z12OxmaPGE0F4xlpGdjuAUckipLpQlTAuAmyGhNoD7ODpYUzvDfvtxUbjM/jwznyP178oju/KDdyi220wNJ0RQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.6.0" + } + }, "node_modules/@nodable/entities": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-3.0.0.tgz", @@ -2943,6 +3035,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@skjnldsv/vue-plyr": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@skjnldsv/vue-plyr/-/vue-plyr-7.5.0.tgz", + "integrity": "sha512-JmbKPe8Eh0yTP+7w4VYeqGhrUqDKM4qSsCn37CbADAvvwMvceBwYC0IBXil0RBtyzStxwXPtOj1oI//lQ5DeTw==", + "license": "MIT", + "dependencies": { + "plyr": "^3.7.8", + "vue": "^3.3.4" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0", + "npm": "^9.0.0 || ^10.0.0" + } + }, "node_modules/@stylistic/eslint-plugin": { "version": "5.10.0", "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.10.0.tgz", @@ -3098,6 +3204,12 @@ "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", "license": "MIT" }, + "node_modules/@types/vexflow": { + "version": "1.2.42", + "resolved": "https://registry.npmjs.org/@types/vexflow/-/vexflow-1.2.42.tgz", + "integrity": "sha512-bj3If1sm1FYJN0tJMV2BJNrwoeQ6xfrTt+rbmFvUytyxUhklLlW79MR4uwQ+upzrNJLVy012TnC7oZqSpEglSw==", + "license": "MIT" + }, "node_modules/@types/web-bluetooth": { "version": "0.0.21", "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz", @@ -3641,7 +3753,6 @@ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.33.tgz", "integrity": "sha512-p8UfIqyIhb0rYGlSgSBV+lPhF2iUSBcRy7enhTmPqKWadHy9kcOFYF1AejYBP9P+avnd3OBbD49DU4pLWX/94A==", "license": "MIT", - "peer": true, "dependencies": { "@vue/shared": "3.5.33" } @@ -3651,7 +3762,6 @@ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.33.tgz", "integrity": "sha512-UpFF45RI9//a7rvq7RdOQblb4tup7hHG9QsmIrxkFQLzQ7R8/iNQ5LE15NhLZ1/WcHMU2b47u6P33CPUelHyIQ==", "license": "MIT", - "peer": true, "dependencies": { "@vue/reactivity": "3.5.33", "@vue/shared": "3.5.33" @@ -3662,7 +3772,6 @@ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.33.tgz", "integrity": "sha512-IOxMsAOwquhfITgmOgaPYl7/j8gKUxUFoflRc+u4LxyD3+783xne8vNta1PONVCvCV9A0w7hkyEepINDqfO0tw==", "license": "MIT", - "peer": true, "dependencies": { "@vue/reactivity": "3.5.33", "@vue/runtime-core": "3.5.33", @@ -3675,7 +3784,6 @@ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.33.tgz", "integrity": "sha512-0xylq/8/h44lVG0pZFknv1XIdEgymq2E9n59uTWJBG+dIgiT0TMCSsxrN7nO16Z0MU0MPjFcguBbZV8Itk52Hw==", "license": "MIT", - "peer": true, "dependencies": { "@vue/compiler-ssr": "3.5.33", "@vue/shared": "3.5.33" @@ -4016,22 +4124,94 @@ } }, "node_modules/ast-walker-scope": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/ast-walker-scope/-/ast-walker-scope-0.9.0.tgz", - "integrity": "sha512-IJdzo2vLiElBxKzwS36VsCue/62d6IdWjnPB2v3nuPKeWGynp6FF/CYoLa5i/3jXH/z97ZDdsXz6abpgM6w07A==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/ast-walker-scope/-/ast-walker-scope-0.10.0.tgz", + "integrity": "sha512-KzvoxDfXNz2Gm8KYLh47K3qcY3Zza3WKOuh2xoqa7LBu6MDKWAZLovJtU9DuAd/Er+rhQHCRn619lHS5U+qmhw==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.29.2", - "@babel/types": "^7.29.0", - "ast-kit": "^2.2.0" + "@babel/parser": "^8.0.0", + "@babel/types": "^8.0.0", + "ast-kit": "^3.0.0" }, "engines": { - "node": ">=20.19.0" + "node": "^22.18.0 || >=24.11.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, + "node_modules/ast-walker-scope/node_modules/@babel/helper-string-parser": { + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-8.0.6.tgz", + "integrity": "sha512-+6HYEBnsDRZHJtUTAEfMQd0zMDqdFHS7C+5vAsEZqBUr3vEMWOWlHJ0Jz1gS8jJIlCvLsuA6ivmeoqzH936YcA==", + "license": "MIT", + "engines": { + "node": "^22.18.0 || >=24.11.0" + } + }, + "node_modules/ast-walker-scope/node_modules/@babel/helper-validator-identifier": { + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-8.0.6.tgz", + "integrity": "sha512-HYx0YmuchRxRSpnjvcNffnPS8DCauKNmnumIuHG3jnQAVewRA7kfJGwF13ayEpSZs7s4R/oBH4eppuXcAQd5JQ==", + "license": "MIT", + "engines": { + "node": "^22.18.0 || >=24.11.0" + } + }, + "node_modules/ast-walker-scope/node_modules/@babel/parser": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-8.0.7.tgz", + "integrity": "sha512-UkDwEbPO1px2JQSrdh4qIgaH1JgG7GO/pFeJkpxhDxIETkT/QvGpnigXIw75ViHYPtIgKITmVUJqLjiO+JuWjA==", + "license": "MIT", + "dependencies": { + "@babel/types": "^8.0.6" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": "^22.18.0 || >=24.11.0" + } + }, + "node_modules/ast-walker-scope/node_modules/@babel/types": { + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-8.0.6.tgz", + "integrity": "sha512-c+xgSWboV2pdwXP67BUWDVRHi2BO5Q3KwxyFVs7taVTY+fsK47/L51ZXQoV9rozHJDNHvJ4v4WEsI/IlxV2l2A==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^8.0.6", + "@babel/helper-validator-identifier": "^8.0.6" + }, + "engines": { + "node": "^22.18.0 || >=24.11.0" + } + }, + "node_modules/ast-walker-scope/node_modules/ast-kit": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ast-kit/-/ast-kit-3.0.0.tgz", + "integrity": "sha512-8OG92q3R35qjC/4i6BLBMg8IB+fClWu/1PEwg2Z9Rn+BuNaiEgJzpzn+pxWOdHJWDCAwu2JP0wCDTozAM4QirQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^8.0.0", + "estree-walker": "^3.0.3", + "pathe": "^2.0.3" + }, + "engines": { + "node": "^22.18.0 || >=24.11.0" }, "funding": { "url": "https://github.com/sponsors/sxzz" } }, + "node_modules/ast-walker-scope/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -4104,7 +4284,7 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, + "devOptional": true, "funding": [ { "type": "github", @@ -4157,6 +4337,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, "node_modules/birpc": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.9.0.tgz", @@ -4166,6 +4356,40 @@ "url": "https://github.com/sponsors/antfu" } }, + "node_modules/bit-twiddle": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bit-twiddle/-/bit-twiddle-1.0.2.tgz", + "integrity": "sha512-B9UhK0DKFZhoTFcfvAzhqsjStvGJp9vYWf3+6SNTtdSQnvIgfkHbgHrg/e4+TH71N2GDu8tpmCVoyfrL1d7ntA==", + "license": "MIT", + "optional": true + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "optional": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/blurhash": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/blurhash/-/blurhash-2.0.5.tgz", @@ -4410,7 +4634,7 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, + "devOptional": true, "funding": [ { "type": "github", @@ -4613,6 +4837,16 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "license": "BlueOak-1.0.0", + "optional": true, + "engines": { + "node": ">=18" + } + }, "node_modules/cipher-base": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.7.tgz", @@ -4917,6 +5151,12 @@ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", "license": "MIT" }, + "node_modules/custom-event-polyfill": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/custom-event-polyfill/-/custom-event-polyfill-1.0.7.tgz", + "integrity": "sha512-TDDkd5DkaZxZFM8p+1I3yAlvM3rSr1wbrOliG4yJiwinMZN8z/iGL7BTlDkrJcYTmgUSb4ywVCc3ZaUtOtC76w==", + "license": "MIT" + }, "node_modules/data-uri-to-buffer": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", @@ -5006,6 +5246,32 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -5098,7 +5364,6 @@ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "license": "Apache-2.0", "optional": true, - "peer": true, "engines": { "node": ">=8" } @@ -5295,6 +5560,16 @@ "vue": ">2.0.0" } }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "license": "MIT", + "optional": true, + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/entities": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", @@ -5307,6 +5582,16 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -5856,6 +6141,16 @@ "safe-buffer": "^5.1.1" } }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "license": "(MIT OR WTFPL)", + "optional": true, + "engines": { + "node": ">=6" + } + }, "node_modules/expect-type": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", @@ -5866,7 +6161,14 @@ "node": ">=12.0.0" } }, - "node_modules/exsolve": { + "node_modules/exponential-backoff": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", + "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", + "license": "Apache-2.0", + "optional": true + }, + "node_modules/exsolve": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz", "integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==", @@ -6026,6 +6328,13 @@ "node": ">=16.0.0" } }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "license": "MIT", + "optional": true + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -6180,6 +6489,13 @@ "node": ">=12.20.0" } }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "license": "MIT", + "optional": true + }, "node_modules/fs-extra": { "version": "11.3.6", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.6.tgz", @@ -6275,6 +6591,32 @@ "url": "https://github.com/fisker/git-hooks-list?sponsor=1" } }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "license": "MIT", + "optional": true + }, + "node_modules/gl": { + "version": "9.0.0-rc.10", + "resolved": "https://registry.npmjs.org/gl/-/gl-9.0.0-rc.10.tgz", + "integrity": "sha512-G6lYaWoan0d2d8UO0UmaSS8zqyyZwYt6q2dFVJ2hD62sRWUwkMIH+Jp7gEoQesLlo28Nzelh+GIYz1qOUa5WmQ==", + "hasInstallScript": true, + "license": "BSD-2-Clause", + "optional": true, + "dependencies": { + "bindings": "^1.5.0", + "bit-twiddle": "^1.0.2", + "glsl-tokenizer": "^2.1.5", + "nan": "^2.26.2", + "node-gyp": "^12.2.0", + "prebuild-install": "^7.1.3" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/glob": { "version": "13.0.6", "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", @@ -6359,6 +6701,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/glsl-tokenizer": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/glsl-tokenizer/-/glsl-tokenizer-2.1.5.tgz", + "integrity": "sha512-XSZEJ/i4dmz3Pmbnpsy3cKh7cotvFlBiZnDOwnj/05EwNp2XrhQ4XKJxT7/pDt4kp4YcpRSKz8eTV7S+mwV6MA==", + "license": "MIT", + "optional": true, + "dependencies": { + "through2": "^0.6.3" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -6375,7 +6727,7 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/has-flag": { @@ -6652,7 +7004,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, + "devOptional": true, "funding": [ { "type": "github", @@ -6725,7 +7077,7 @@ "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/inline-style-parser": { @@ -7205,6 +7557,38 @@ "dev": true, "license": "MIT" }, + "node_modules/konva": { + "version": "10.3.3", + "resolved": "https://registry.npmjs.org/konva/-/konva-10.3.3.tgz", + "integrity": "sha512-j3Rrn504bYFwJ0zV0ZbSOQRsM9KMBLOpEq6xZuyIjbaKeFbBXwgiM5SA4IDq4nwM1l49GVKs66Mo+sl7+4G7PQ==", + "funding": [ + { + "type": "patreon", + "url": "https://www.patreon.com/lavrton" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/konva" + }, + { + "type": "github", + "url": "https://github.com/sponsors/lavrton" + } + ], + "license": "MIT", + "peerDependencies": { + "canvas": "^3.0.0", + "skia-canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + }, + "skia-canvas": { + "optional": true + } + } + }, "node_modules/layerr": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/layerr/-/layerr-3.0.0.tgz", @@ -7240,6 +7624,12 @@ "integrity": "sha512-P8aEP5U/D1/IlTY2OeYsErdwh9bGuLE30NcXtKEjgdHcahveQoQwM2yZNsioQHsWFz0P7KKudisbrzCgR0sDHg==", "license": "MIT" }, + "node_modules/loadjs": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loadjs/-/loadjs-4.3.0.tgz", + "integrity": "sha512-vNX4ZZLJBeDEOBvdr2v/F+0aN5oMuPu7JTqrMwp+DtgK+AryOlpy6Xtm2/HpNr+azEa828oQjOtWsB6iDtSfSQ==", + "license": "MIT" + }, "node_modules/local-pkg": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.2.1.tgz", @@ -7280,6 +7670,19 @@ "dev": true, "license": "MIT" }, + "node_modules/loglevel": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz", + "integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, "node_modules/longest-streak": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", @@ -8090,6 +8493,19 @@ "node": ">= 0.6" } }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -8119,16 +8535,46 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "optional": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/minipass": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", - "dev": true, + "devOptional": true, "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" } }, + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "license": "MIT", + "optional": true, + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "license": "MIT", + "optional": true + }, "node_modules/mlly": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz", @@ -8180,10 +8626,17 @@ "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", "license": "MIT" }, + "node_modules/nan": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.29.0.tgz", + "integrity": "sha512-GlGk3HIvitbvs+LT3g6XUP1kpirKNvmDFwF/bmo6XNWSb/eYEs/O4bfgIEIXCZ+lIOTS5xNwDvSGMw6FJdAhtA==", + "license": "MIT", + "optional": true + }, "node_modules/nanoid": { - "version": "3.3.18", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", - "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", + "version": "3.3.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.20.tgz", + "integrity": "sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==", "funding": [ { "type": "github", @@ -8198,6 +8651,13 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/napi-build-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", + "license": "MIT", + "optional": true + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -8221,6 +8681,19 @@ "integrity": "sha512-yFehXNWRs4cM0+dz7QxCd06hTbWbSkV0ISsqBfkntU6TOY4Qm3Q88fRRLOddkGh2Qq6dZvnKVAahfhjcUvLnyA==", "license": "MIT" }, + "node_modules/node-abi": { + "version": "3.98.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.98.0.tgz", + "integrity": "sha512-Llh8noNw7s15m+rmIrZnZQbe4gLyasL9loT74rC92PkmwWKeEedKvc7o6pjp8B3MhrYT/Cl846NOYZbz1wmddw==", + "license": "MIT", + "optional": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/node-addon-api": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", @@ -8267,6 +8740,93 @@ "url": "https://opencollective.com/node-fetch" } }, + "node_modules/node-gyp": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-12.4.0.tgz", + "integrity": "sha512-OMcPNvqTCFUnNaBlmdgq+lfNqY7gTiSmNRDjY3uAXRyudeKZEZxu3CLtjMQrx4zZxCX2b/mpNqTtwuCJgXhHkw==", + "license": "MIT", + "optional": true, + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "graceful-fs": "^4.2.6", + "nopt": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "tar": "^7.5.4", + "tinyglobby": "^0.2.12", + "undici": "^6.25.0", + "which": "^6.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/node-gyp/node_modules/abbrev": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-4.0.0.tgz", + "integrity": "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==", + "license": "ISC", + "optional": true, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", + "license": "BlueOak-1.0.0", + "optional": true, + "engines": { + "node": ">=20" + } + }, + "node_modules/node-gyp/node_modules/nopt": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-9.0.0.tgz", + "integrity": "sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==", + "license": "ISC", + "optional": true, + "dependencies": { + "abbrev": "^4.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/node-gyp/node_modules/undici": { + "version": "6.29.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.29.0.tgz", + "integrity": "sha512-R+RODBqp6i2pPflGdq+xIOUkl+RNfGgHwoinecKu/JCuf2uO06cOKoDbI2P7Dn6KcswdKwrczbU6IYJ6K8X+wg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18.17" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", + "license": "ISC", + "optional": true, + "dependencies": { + "isexe": "^4.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, "node_modules/node-releases": { "version": "2.0.54", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.54.tgz", @@ -8365,9 +8925,9 @@ } }, "node_modules/nostics": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/nostics/-/nostics-1.2.0.tgz", - "integrity": "sha512-FGqEfhQjrvo1lL8KFifdTQiNwwQHJxC1jtYE1Rc54qF/jxONUNL+kC9gS1krX8Q65PgrQ5fCqH/I4NhWBvdSqg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/nostics/-/nostics-1.3.0.tgz", + "integrity": "sha512-wzRsrJwNlFbqIRQt8aCeL2WE8USip/uuvGSOZV1D02CxX8ABTMbw8IywKjH7yWHETMXbWJI4OBpihg9rmz2Vyg==", "license": "MIT" }, "node_modules/nth-check": { @@ -8465,6 +9025,44 @@ "node": ">=12.20.0" } }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "optional": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/opensheetmusicdisplay": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/opensheetmusicdisplay/-/opensheetmusicdisplay-2.2.0.tgz", + "integrity": "sha512-KUJ1OXhjGZP3n1ZTkLoEotL7+g4pQts9jSICY1I1WvShPI7F4Lr6G9Hqmmaoo1jNAaQB89Zy2yOC+mEquv6OuQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@types/vexflow": "^1.2.38", + "jszip": "3.10.1", + "loglevel": "^1.8.0", + "typescript-collections": "^1.3.3", + "vexflow": "1.2.93" + }, + "optionalDependencies": { + "gl": "^9.0.0-rc.10" + } + }, + "node_modules/opensheetmusicdisplay/node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "license": "(MIT OR GPL-3.0-or-later)", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -8855,6 +9453,23 @@ "pathe": "^2.0.3" } }, + "node_modules/plyr": { + "version": "3.8.5", + "resolved": "https://registry.npmjs.org/plyr/-/plyr-3.8.5.tgz", + "integrity": "sha512-SqGU1s76fq4lI8ABYhi1uxwrcLGYqmyiMazFAUIOQKKwt6S7FfflEMljLaM3SV8HUUb1KdZ04FY/SNFRpPZHUw==", + "deprecated": "Plyr is deprecated and receives security updates only. Use Video.js 10 for new projects. Migration guide: https://videojs.org/docs/framework/html/guides/migrate-from-plyr", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "custom-event-polyfill": "^1.0.7", + "loadjs": "^4.3.0", + "rangetouch": "^2.0.1", + "url-polyfill": "^1.1.14" + }, + "engines": { + "node": "^22.18.0 || >=24.11.0" + } + }, "node_modules/possible-typed-array-names": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", @@ -8866,9 +9481,9 @@ } }, "node_modules/postcss": { - "version": "8.5.26", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz", - "integrity": "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==", + "version": "8.5.29", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.29.tgz", + "integrity": "sha512-49cGhUbXj8Qenv0iTMxA1cFBzxXoctpC9Ujd77t1WcbJIr6nF/eI7g/8MgxrYldFRuAXvja7xQRwavoW7kgrxQ==", "funding": [ { "type": "opencollective", @@ -8885,9 +9500,9 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.17", + "nanoid": "^3.3.19", "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" + "source-map-js": "^1.2.2" }, "engines": { "node": "^10 || ^12 || >=14" @@ -8907,6 +9522,34 @@ "node": ">=4" } }, + "node_modules/prebuild-install": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", + "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", + "deprecated": "No longer maintained. Please contact the author of the relevant native addon; alternatives are available.", + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^2.0.0", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -8917,6 +9560,16 @@ "node": ">= 0.8.0" } }, + "node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "license": "ISC", + "optional": true, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -8981,6 +9634,17 @@ "dev": true, "license": "MIT" }, + "node_modules/pump": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", + "license": "MIT", + "optional": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -9060,6 +9724,28 @@ "safe-buffer": "^5.1.0" } }, + "node_modules/rangetouch": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/rangetouch/-/rangetouch-2.0.1.tgz", + "integrity": "sha512-sln+pNSc8NGaHoLzwNBssFSf/rSYkqeBXzX1AtJlkJiUaVSJSbRAWJk+4omsXkN+EJalzkZhWQ3th1m0FpR5xA==", + "license": "MIT" + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "optional": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, "node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", @@ -9691,6 +10377,53 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, "node_modules/sort-object-keys": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/sort-object-keys/-/sort-object-keys-2.1.0.tgz", @@ -9961,6 +10694,16 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/striptags": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/striptags/-/striptags-3.2.0.tgz", @@ -10051,6 +10794,113 @@ "integrity": "sha512-wieBHXygIm7OyQOu5hQlkk62/WyCFYGlWg7L6/ZCUZwx0o398Zkn4pVmMyfYhfMG8kGrj/Krt8eIk6UKC6VzwA==", "license": "MIT" }, + "node_modules/tar": { + "version": "7.5.22", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.22.tgz", + "integrity": "sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA==", + "license": "BlueOak-1.0.0", + "optional": true, + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tar-fs": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.5.tgz", + "integrity": "sha512-OboTd8mmMhZDNPV+UjQcK9yKAatXu2aJ+r1w4im1Otd4M4fl2hwvdoXUxIYHFTHWK/3y3FarBP70v3vwmGlOxw==", + "license": "MIT", + "optional": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "license": "ISC", + "optional": true + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha512-RkK/CCESdTKQZHdmKICijdKKsCRVHs5KsLZ6pACAmF/1GPUQhonHSXWNERctxEp7RmvjdNbZTL5z9V7nSCXKcg==", + "license": "MIT", + "optional": true, + "dependencies": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + }, + "node_modules/through2/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "license": "MIT", + "optional": true + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "license": "MIT", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/through2/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "license": "MIT", + "optional": true + }, "node_modules/timers-browserify": { "version": "2.0.12", "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", @@ -10274,6 +11124,19 @@ "dev": true, "license": "MIT" }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -10316,6 +11179,12 @@ "node": ">=14.17" } }, + "node_modules/typescript-collections": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/typescript-collections/-/typescript-collections-1.3.3.tgz", + "integrity": "sha512-7sI4e/bZijOzyURng88oOFZCISQPTHozfE2sUu5AviFYk5QV7fYGb6YiDl+vKjF/pICA354JImBImL9XJWUvdQ==", + "license": "MIT" + }, "node_modules/typescript-eslint": { "version": "8.62.1", "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.62.1.tgz", @@ -10487,13 +11356,13 @@ } }, "node_modules/unplugin": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-3.3.0.tgz", - "integrity": "sha512-qa66K+crbfyE6JK10GjvbJeRrOsuC/JpbnHctfyp/i4oBTxWOzJfRZyDiOk1PtErMFRu8JhsU/wPvOdBNWe5Rg==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-3.4.0.tgz", + "integrity": "sha512-9skdIFlCsPdFV7wUfZxNsFInlW+7nJmGu2gkTu0OUhF56aXGsHab9x52/QhdJ4lC7ZDPWTxbiC4ANqVlsuaW3w==", "license": "MIT", "dependencies": { "@jridgewell/remapping": "^2.3.5", - "picomatch": "^4.0.4", + "picomatch": "^4.0.7", "webpack-virtual-modules": "^0.6.2" }, "engines": { @@ -10501,6 +11370,7 @@ }, "peerDependencies": { "@farmfe/core": "*", + "@rsbuild/core": "*", "@rspack/core": "*", "bun-types-no-globals": "*", "esbuild": "*", @@ -10514,6 +11384,9 @@ "@farmfe/core": { "optional": true }, + "@rsbuild/core": { + "optional": true + }, "@rspack/core": { "optional": true }, @@ -10631,6 +11504,12 @@ "requires-port": "^1.0.0" } }, + "node_modules/url-polyfill": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/url-polyfill/-/url-polyfill-1.1.14.tgz", + "integrity": "sha512-p4f3TTAG6ADVF3mwbXw7hGw+QJyw5CnNGvYh5fCuQQZIiuKUswqcznyV3pGDP9j0TSmC4UvRKm8kl1QsX1diiQ==", + "license": "MIT" + }, "node_modules/url/node_modules/punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", @@ -10658,6 +11537,12 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, + "node_modules/vexflow": { + "version": "1.2.93", + "resolved": "https://registry.npmjs.org/vexflow/-/vexflow-1.2.93.tgz", + "integrity": "sha512-LwHQDCc257Lwju35BhyZuPYcVWu0hIUqEdM7j9+B+bq91bSelssnAG5JR8odTUtgGuwwvGwLhXw37wtmHNCS6Q==", + "license": "MIT" + }, "node_modules/vfile": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", @@ -11499,7 +12384,6 @@ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.33.tgz", "integrity": "sha512-1AgChhx5w3ALgT4oK3acm2Es/7jyZhWSVUfs3rOBlGQC0rjEDkS7G4lWlJJGGNQD+BV3reCwbQrOe1mPNwKHBQ==", "license": "MIT", - "peer": true, "dependencies": { "@vue/compiler-dom": "3.5.33", "@vue/compiler-sfc": "3.5.33", @@ -11548,6 +12432,12 @@ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0" } }, + "node_modules/vue-material-design-icons": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/vue-material-design-icons/-/vue-material-design-icons-5.3.1.tgz", + "integrity": "sha512-6UNEyhlTzlCeT8ZeX5WbpUGFTTPSbOoTQeoASTv7X4Ylh0pe8vltj+36VMK56KM0gG8EQVoMK/Qw/6evalg8lA==", + "license": "MIT" + }, "node_modules/vue-resize": { "version": "2.0.0-alpha.1", "resolved": "https://registry.npmjs.org/vue-resize/-/vue-resize-2.0.0-alpha.1.tgz", @@ -11730,6 +12620,13 @@ "node": ">=0.10.0" } }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC", + "optional": true + }, "node_modules/xml-name-validator": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", @@ -11766,12 +12663,22 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=0.4" } }, + "node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "license": "BlueOak-1.0.0", + "optional": true, + "engines": { + "node": ">=18" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 6d9ea3a..1690616 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "@nextcloud/paths": "^3.1.0", "@nextcloud/router": "^3.2.0", "@nextcloud/sharing": "^0.4.0", + "@nextcloud/viewer": "^2.0.0-beta.14", "jszip": "^3.10.2" }, "peerDependencies": { diff --git a/src/__tests__/MindMap.spec.js b/src/__tests__/MindMap.spec.js deleted file mode 100644 index 507ef3f..0000000 --- a/src/__tests__/MindMap.spec.js +++ /dev/null @@ -1,108 +0,0 @@ -/** - * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -import { shallowMount } from '@vue/test-utils' -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import MindMap from '../views/MindMap.js' - -vi.mock('@nextcloud/l10n', () => ({ getLanguage: () => 'en' })) -vi.mock('@nextcloud/router', () => ({ - generateUrl: (path, params = {}) => Object.entries(params).reduce( - (acc, [k, v]) => acc.replace(`{${k}}`, v ?? ''), - path, - ), -})) -vi.mock('@nextcloud/sharing/public', () => ({ - isPublicShare: vi.fn(() => false), - getSharingToken: () => '', -})) - -// Viewer mixin that supplies the props/methods the component expects -const viewerMixin = { - data() { - return { - fileList: [], - fileid: null, - source: null, - davPath: null, - } - }, - methods: { - doneLoading() {}, - }, -} - -function mountMindMap(dataOverrides = {}) { - return shallowMount(MindMap, { - global: { - mixins: [ - { - ...viewerMixin, - data() { - return { ...viewerMixin.data(), ...dataOverrides } - }, - }, - ], - }, - }) -} - -describe('MindMap', () => { - beforeEach(() => { - window.OCA = { FilesMindMap: { setFile: vi.fn() } } - }) - - afterEach(() => { - delete window.OCA - }) - - it('renders an iframe element', () => { - const wrapper = mountMindMap() - expect(wrapper.find('iframe').exists()).toBe(true) - }) - - describe('iframeSrc computed property', () => { - it('uses source when available', () => { - const wrapper = mountMindMap({ - source: '/remote.php/dav/files/user/test.km', - }) - expect(wrapper.vm.iframeSrc).toContain('/remote.php/dav/files/user/test.km') - }) - - it('falls back to davPath when source is null', () => { - const wrapper = mountMindMap({ - source: null, - davPath: '/dav/path/test.km', - }) - expect(wrapper.vm.iframeSrc).toContain('/dav/path/test.km') - }) - }) - - describe('file computed property', () => { - it('returns the file whose fileid matches the current fileid', () => { - const file = { fileid: 7, name: 'test.km' } - const wrapper = mountMindMap({ fileList: [file], fileid: 7 }) - expect(wrapper.vm.file).toStrictEqual(file) - }) - - it('returns undefined when no file matches', () => { - const wrapper = mountMindMap({ - fileList: [{ fileid: 1, name: 'other.km' }], - fileid: 99, - }) - expect(wrapper.vm.file).toBeUndefined() - }) - }) - - describe('lifecycle hooks', () => { - it('calls OCA.FilesMindMap.setFile on mount', () => { - mountMindMap({ - fileList: [{ fileid: 3, name: 'test.km' }], - fileid: 3, - }) - expect(window.OCA.FilesMindMap.setFile).toHaveBeenCalled() - }) - }) -}) diff --git a/src/__tests__/mindmap.spec.js b/src/__tests__/mindmap.spec.js index 63fd161..292aaf1 100644 --- a/src/__tests__/mindmap.spec.js +++ b/src/__tests__/mindmap.spec.js @@ -55,6 +55,10 @@ vi.mock('@nextcloud/files', () => ({ getUniqueName: vi.fn((name) => name), })) +vi.mock('@nextcloud/viewer', () => ({ + getViewer: vi.fn(() => ({ open: vi.fn(), close: vi.fn() })), +})) + vi.mock('@nextcloud/axios', () => { const fn = vi.fn() fn.get = vi.fn() @@ -189,19 +193,19 @@ describe('FilesMindMap', () => { describe('setFile', () => { it('sets name, dir, and fullName from file object', () => { - FilesMindMap.setFile({ filename: '/documents/test.km', basename: 'test.km' }) + FilesMindMap.setFile({ path: '/documents/test.km', basename: 'test.km' }) expect(FilesMindMap._file.name).toBe('test.km') expect(FilesMindMap._file.dir).toBe('/documents') expect(FilesMindMap._file.fullName).toBe('/documents/test.km') }) it('sets dir to "/" for top-level files', () => { - FilesMindMap.setFile({ filename: '/test.km', basename: 'test.km' }) + FilesMindMap.setFile({ path: '/test.km', basename: 'test.km' }) expect(FilesMindMap._file.dir).toBe('/') }) it('sets _currentContext from the resolved dir', () => { - FilesMindMap.setFile({ filename: '/docs/sub/test.km', basename: 'test.km' }) + FilesMindMap.setFile({ path: '/docs/sub/test.km', basename: 'test.km' }) expect(FilesMindMap._currentContext).toEqual(expect.objectContaining({ dir: '/docs/sub' })) }) }) diff --git a/src/__tests__/mindmapElement.spec.js b/src/__tests__/mindmapElement.spec.js new file mode 100644 index 0000000..75c2982 --- /dev/null +++ b/src/__tests__/mindmapElement.spec.js @@ -0,0 +1,72 @@ +/** + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import MindMap from '../views/MindMap.js' + +vi.mock('@nextcloud/router', () => ({ + generateUrl: (path, params = {}) => Object.entries(params).reduce( + (acc, [k, v]) => acc.replace(`{${k}}`, v ?? ''), + path, + ), +})) + +window.customElements.define('test-mindmap-viewer', MindMap) + +const file = { path: '/docs/test.km', basename: 'test.km' } + +/** + * Create the element the way the viewer does: properties and attributes + * first, then insert it. + * + * @param {object} attributes attributes to set before inserting + */ +function mount(attributes = {}) { + const element = document.createElement('test-mindmap-viewer') + element.file = file + Object.entries(attributes).forEach(([key, value]) => element.setAttribute(key, value)) + document.body.appendChild(element) + return element +} + +describe('MindMap element', () => { + beforeEach(() => { + window.OCA = { FilesMindMap: { setFile: vi.fn() } } + }) + + afterEach(() => { + document.body.replaceChildren() + delete window.OCA + }) + + it('hands the file to FilesMindMap', () => { + mount() + expect(window.OCA.FilesMindMap.setFile).toHaveBeenCalledWith(file) + }) + + it('renders the editor iframe for the file', () => { + const iframe = mount().querySelector('iframe') + expect(iframe.getAttribute('src')).toBe('/apps/files_mindmap/?file=/docs/test.km') + }) + + it('sizes the iframe from the viewer attributes', () => { + const element = mount({ 'max-width': '800', 'max-height': '600' }) + const iframe = element.querySelector('iframe') + expect(iframe.style.width).toBe('800px') + expect(iframe.style.height).toBe('600px') + + element.setAttribute('max-height', '400') + expect(iframe.style.height).toBe('400px') + }) + + it('emits loaded once the iframe has loaded', () => { + const element = mount() + const loaded = vi.fn() + element.addEventListener('loaded', loaded) + + element.querySelector('iframe').dispatchEvent(new Event('load')) + expect(loaded).toHaveBeenCalledOnce() + }) +}) diff --git a/src/mindmap.js b/src/mindmap.js index 46313c3..ac8bbb1 100644 --- a/src/mindmap.js +++ b/src/mindmap.js @@ -8,11 +8,7 @@ import SvgPencil from '@mdi/svg/svg/pencil.svg?raw' import { getCurrentUser } from '@nextcloud/auth' import axios from '@nextcloud/axios' import { showMessage as showToast } from '@nextcloud/dialogs' -import { - DefaultType, - Permission, - registerFileAction, -} from '@nextcloud/files' +import { DefaultType, Permission } from '@nextcloud/files' import { FileAction, registerFileAction as legacyRegisterFileAction, @@ -21,6 +17,7 @@ import { translate as t } from '@nextcloud/l10n' import { dirname } from '@nextcloud/paths' import { generateUrl } from '@nextcloud/router' import { getSharingToken, isPublicShare } from '@nextcloud/sharing/public' +import { getViewer } from '@nextcloud/viewer' import logger from './logger.js' import freemind from './plugins/freemind.js' import km from './plugins/km.js' @@ -29,6 +26,9 @@ import util from './util.js' const version = Number.parseInt((window.OC?.config?.version ?? '0').split('.')[0]) +export const HANDLER_ID = 'files_mindmap' +export const TAG_NAME = 'files-mindmap-viewer' + const FilesMindMap = { _currentContext: null, _file: {}, @@ -175,9 +175,16 @@ const FilesMindMap = { }, /** + * Register the edit action on Nextcloud 32 and older. From 33 on the + * viewer registers the actions for its handlers itself. + * * @private */ registerFileActions() { + if (version >= 33) { + return + } + const mimes = this.getSupportedMimetypes() const _self = this @@ -194,7 +201,7 @@ const FilesMindMap = { async exec(node) { try { - OCA.Viewer.openWith('mindmap', { path: node.path }) + await getViewer().open([node], node, {}, HANDLER_ID) return true } catch (error) { _self.showMessage(error) @@ -205,21 +212,18 @@ const FilesMindMap = { default: DefaultType.HIDDEN, } - if (version >= 33) { - registerFileAction(actionConfig) - } else { - legacyRegisterFileAction(new FileAction(actionConfig)) - } + legacyRegisterFileAction(new FileAction(actionConfig)) }, - setFile(file) { - const filename = file.filename + '' - const basename = file.basename + '' + close() { + getViewer().close() + }, - this._file.name = basename + setFile(node) { + this._file.name = node.basename this._file.root = '/files/' + getCurrentUser()?.uid - this._file.dir = dirname(filename) - this._file.fullName = filename + this._file.dir = dirname(node.path) + this._file.fullName = node.path this._currentContext = { dir: this._file.dir, root: this._file.root, diff --git a/src/mindmapviewer.js b/src/mindmapviewer.js index 822e119..1067d53 100644 --- a/src/mindmapviewer.js +++ b/src/mindmapviewer.js @@ -4,7 +4,9 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -import FilesMindMap from './mindmap.js' +import { translate as t } from '@nextcloud/l10n' +import { registerHandler } from '@nextcloud/viewer' +import FilesMindMap, { HANDLER_ID, TAG_NAME } from './mindmap.js' import MindMap from './views/MindMap.js' OCA.FilesMindMap = FilesMindMap @@ -12,15 +14,16 @@ OCA.FilesMindMap = FilesMindMap FilesMindMap.init() FilesMindMap.registerFileActions() -const supportedMimes = OCA.FilesMindMap.getSupportedMimetypes() +const supportedMimes = FilesMindMap.getSupportedMimetypes() -if (OCA.Viewer) { - OCA.Viewer.registerHandler({ - id: 'mindmap', - group: null, - mimes: supportedMimes, - component: MindMap, - theme: 'default', - canCompare: true, - }) +if (!window.customElements.get(TAG_NAME)) { + window.customElements.define(TAG_NAME, MindMap) } + +registerHandler({ + id: HANDLER_ID, + displayName: t('files_mindmap', 'Mind map'), + tagName: TAG_NAME, + enabled: (nodes) => nodes.every((node) => supportedMimes.includes(node.mime)), + theme: 'default', +}) diff --git a/src/public.js b/src/public.js index 614a7d0..04a703f 100644 --- a/src/public.js +++ b/src/public.js @@ -6,37 +6,23 @@ import { isPublicShare } from '@nextcloud/sharing/public' import logger from './logger.js' -import FilesMindMap from './mindmap.js' +import FilesMindMap, { TAG_NAME } from './mindmap.js' -if (isPublicShare()) { - OCA.FilesMindMap = FilesMindMap - FilesMindMap.init() +if (isPublicShare() && FilesMindMap.isMindmapPublic()) { + window.addEventListener('DOMContentLoaded', function() { + const contentElmt = document.getElementById('files-public-content') + const footerElmt = document.querySelector('body > footer') || document.querySelector('#app-content > footer') + if (contentElmt) { + const name = document.getElementById('filename')?.value ?? '' + const element = document.createElement(TAG_NAME) + element.file = { basename: name, path: '/' + name } + contentElmt.replaceChildren(element) - if (FilesMindMap.isMindmapPublic()) { - window.addEventListener('DOMContentLoaded', function() { - const contentElmt = document.getElementById('files-public-content') - const footerElmt = document.querySelector('body > footer') || document.querySelector('#app-content > footer') - if (contentElmt) { - if (OCA.Viewer) { - contentElmt.innerHTML = '' - OCA.Viewer.setRootElement('#files-public-content') - OCA.Viewer.open({ path: '/' }) - - footerElmt.style.display = 'none' - - // This is an ugly implementation, need to remove the top margin after viewer creates the iframe - setTimeout(() => { - const frameElmt = document.querySelector('#viewer > iframe') - if (frameElmt) { - frameElmt.style.marginTop = '0' - } - }, 1000) - } else { - logger.error('Viewer is not available, cannot preview mindmap') - } + if (footerElmt) { + footerElmt.style.display = 'none' } - }) - } + } + }) logger.debug('files_mindmap public.js loaded') } diff --git a/src/viewer.js b/src/viewer.js index 3bb0480..37074db 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -105,7 +105,7 @@ redirectIfNotDisplayedInFrame(); if (self._autoSaveTimer !== null) { clearInterval(self._autoSaveTimer) } - window.parent.OCA.Viewer.close() + window.parent.OCA.FilesMindMap.close() } if (this._changed && window.parent.OCA.FilesMindMap._file.supportedWrite) { const result = window.confirm(t('The file has not been saved. Is it saved?')) @@ -239,7 +239,7 @@ redirectIfNotDisplayedInFrame(); }, function(msg) { self._loadStatus = false window.alert(t('Load file fail!') + msg) - window.parent.OCA.Viewer.close() + window.parent.OCA.FilesMindMap.close() }) }, isDataSchema(url) { diff --git a/src/views/MindMap.js b/src/views/MindMap.js index b314c21..0dce88c 100644 --- a/src/views/MindMap.js +++ b/src/views/MindMap.js @@ -5,55 +5,44 @@ */ import { generateUrl } from '@nextcloud/router' -import { h as _h } from 'vue' -import logger from '../logger.js' - -logger.debug('MindMap Vue Loading') - -// Plain Options API component — intentionally NOT a Vue SFC. -// The viewer app (Vue 2.7) renders this component; using a compiled SFC would -// bundle Vue 3 render helpers (createElementBlock, openBlock) that are -// incompatible with the Vue 2.7 runtime. The render(h) signature receives -// Vue 2.7's h function directly from the runtime, keeping VNodes compatible. -// The viewer also injects its Mime mixin (providing doneLoading, source, -// davPath, fileList, fileid etc.) via component.mixins — that merge only -// works for plain Options API objects, not