Files
nextcloud-server-mirror/dist/core-viewer-init.mjs.map
2026-10-07 08:58:40 +00:00

1 line
19 KiB
Plaintext

{"version":3,"file":"core-viewer-init.mjs","sources":["../build/frontend/apps/viewer/src/legacy.ts","../build/frontend/core/src/viewer-init.ts"],"sourcesContent":["/*!\n * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport type { IFile, NodeData } from '@nextcloud/files'\nimport type { FileStat, ResponseDataDetailed } from 'webdav'\n\nimport { getCurrentUser } from '@nextcloud/auth'\nimport { File, Permission } from '@nextcloud/files'\nimport { getClient, getDefaultPropfind, getRemoteURL, getRootPath, resultToNode } from '@nextcloud/files/dav'\nimport { getLoggerBuilder } from '@nextcloud/logger'\nimport { canView, getViewer } from '@nextcloud/viewer'\n\n/**\n * The release this shim goes away in.\n *\n * Named in every warning so that an app author reading a log knows how long\n * they have rather than only that something is deprecated.\n */\nconst REMOVED_IN = 39\n\nconst logger = getLoggerBuilder()\n\t.setApp('viewer')\n\t.detectUser()\n\t.build()\n\n/**\n * The shape apps passed around before the viewer took nodes.\n *\n * Loose on purpose: this came from callers rather than from us, and most of\n * them filled in only the few fields they had.\n */\ninterface LegacyFileInfo {\n\tfileid?: number | string\n\tfilename?: string\n\tbasename?: string\n\tsource?: string\n\tmime?: string\n\tetag?: string\n\thasPreview?: boolean\n\tsize?: number\n\tmtime?: number\n\tpermissions?: number\n}\n\ninterface LegacyOpenOptions {\n\tpath?: string\n\tfileInfo?: LegacyFileInfo\n\tlist?: LegacyFileInfo[]\n\tenableSidebar?: boolean\n\tloadMore?: () => LegacyFileInfo[] | Promise<LegacyFileInfo[]>\n\tcanLoop?: boolean\n\tstartSlideshow?: boolean\n\tonPrev?: (file: IFile) => void\n\tonNext?: (file: IFile) => void\n\tonClose?: () => void\n}\n\n/** What the getters answer with, kept from the last call to open */\ninterface LegacyState {\n\tfile: string\n\tfiles: LegacyFileInfo[]\n\tenableSidebar: boolean\n\tcanLoop: boolean\n\tstartSlideshow: boolean\n\tloadMore: () => LegacyFileInfo[] | Promise<LegacyFileInfo[]>\n\tonPrev: (file: IFile) => void\n\tonNext: (file: IFile) => void\n\tonClose: () => void\n\toverrideHandlerId: string | null\n}\n\n/** The state of a viewer with nothing open */\nfunction emptyState(): LegacyState {\n\treturn {\n\t\tfile: '',\n\t\tfiles: [],\n\t\tenableSidebar: true,\n\t\tcanLoop: true,\n\t\tstartSlideshow: false,\n\t\tloadMore: () => [],\n\t\tonPrev: () => {},\n\t\tonNext: () => {},\n\t\tonClose: () => {},\n\t\toverrideHandlerId: null,\n\t}\n}\n\nlet state: LegacyState = emptyState()\n\n/**\n * Say that something reached for the old API, and what to reach for instead.\n *\n * Warned on every access rather than once per caller: these end up in the\n * logs an administrator sends with a bug report, and one line at the top of\n * a session is the one that scrolls away.\n *\n * @param member - the property or method that was used\n * @param replacement - what to call instead\n */\nfunction deprecated(member: string, replacement: string): void {\n\tlogger.warn(`OCA.Viewer.${member} is deprecated and will be removed in Nextcloud ${REMOVED_IN}. Use ${replacement} from the @nextcloud/viewer package instead.`)\n}\n\n/**\n * Look a path up on the dav endpoint so the viewer can be handed a node.\n *\n * @param path - an absolute path in the user's files\n */\nasync function nodeFromPath(path: string): Promise<IFile> {\n\tconst result = await getClient().stat(getRootPath() + path, {\n\t\tdetails: true,\n\t\tdata: getDefaultPropfind(),\n\t}) as ResponseDataDetailed<FileStat>\n\treturn resultToNode(result.data) as IFile\n}\n\n/**\n * The last part of a path, for a caller that did not say what the file is\n * called.\n *\n * @param source - the address the file is served from\n */\nfunction basenameOf(source: string): string {\n\tconst name = source.split('/').pop() ?? ''\n\ttry {\n\t\treturn decodeURIComponent(name)\n\t} catch {\n\t\treturn name\n\t}\n}\n\n/**\n * The folder part of an address, as a path.\n *\n * @param source - the address the file is served from\n */\nfunction directoryOf(source: string): string {\n\ttry {\n\t\tconst { pathname } = new URL(source, window.location.origin)\n\t\treturn pathname.slice(0, pathname.lastIndexOf('/')) || '/'\n\t} catch {\n\t\treturn '/'\n\t}\n}\n\n/**\n * Build a node out of what an app handed over.\n *\n * Callers filled in what they had, so most of this is defaulting. A file\n * with a `source` of its own is served from somewhere that is not dav, and\n * keeps it; everything else is addressed under the user's files.\n *\n * @param info - the file info an app passed to open\n */\nfunction nodeFromFileInfo(info: LegacyFileInfo): IFile {\n\tconst owner = getCurrentUser()?.uid ?? null\n\t// A node is addressed by URL. What apps passed here was a path inside the\n\t// user's files, so it needs the dav endpoint in front of it.\n\tconst davSource = info.filename\n\t\t? getRemoteURL() + getRootPath() + info.filename\n\t\t: undefined\n\tconst source = info.source ?? davSource\n\n\tif (source === undefined) {\n\t\tthrow new Error('Viewer file info needs either a source or a filename')\n\t}\n\n\tconst data: NodeData = {\n\t\tsource,\n\t\t// A file under the user's files is relative to their dav home. One\n\t\t// served from somewhere else has no home, so the folder it sits in\n\t\t// stands in for it and the node still knows its own name.\n\t\troot: info.source === undefined ? getRootPath() : directoryOf(info.source),\n\t\tdisplayname: info.basename ?? basenameOf(source),\n\t\tmime: info.mime ?? 'application/octet-stream',\n\t\towner,\n\t\tpermissions: info.permissions ?? Permission.READ,\n\t\tattributes: {\n\t\t\tetag: info.etag,\n\t\t\thasPreview: info.hasPreview,\n\t\t},\n\t}\n\n\t// Set apart rather than defaulted: a node is not allowed to carry these\n\t// as undefined, and a caller that did not know them leaves them out\n\tif (info.fileid !== undefined) {\n\t\tdata.id = Number(info.fileid)\n\t}\n\tif (info.size !== undefined) {\n\t\tdata.size = info.size\n\t}\n\tif (info.mtime !== undefined) {\n\t\tdata.mtime = new Date(info.mtime)\n\t}\n\n\treturn new File(data)\n}\n\n/**\n * Whether any handler would take a file of this type.\n *\n * The answer is worked out by asking the handlers about a file that has\n * nothing but the type, because a handler is asked about nodes rather than\n * about types. One that looks at more than the type, at whether a preview\n * exists say, can answer differently here than it would for a real file.\n *\n * @param mime - the type to ask about\n */\nfunction canOpenMime(mime: string): boolean {\n\ttry {\n\t\treturn canView(new File({\n\t\t\tsource: `${getRemoteURL()}${getRootPath()}/.viewer-mime-probe`,\n\t\t\troot: getRootPath(),\n\t\t\tmime,\n\t\t\towner: getCurrentUser()?.uid ?? null,\n\t\t\tpermissions: Permission.READ,\n\t\t\tattributes: { hasPreview: true },\n\t\t}))\n\t} catch (error) {\n\t\tlogger.debug('Could not work out whether the viewer handles this type', { mime, error })\n\t\treturn false\n\t}\n}\n\n/**\n * A stand-in for the list of types the viewer used to publish.\n *\n * Handlers no longer carry a list of types, they answer about a file, so\n * there is nothing left to enumerate. Every caller we know of asks whether\n * one type is in the list, so that is what this answers; anything that reads\n * it as a list sees an empty one rather than a wrong one.\n */\nconst mimetypes = new Proxy([] as string[], {\n\tget(target, property, receiver) {\n\t\tif (property === 'includes') {\n\t\t\treturn (mime: string) => canOpenMime(mime)\n\t\t}\n\t\tif (property === 'indexOf') {\n\t\t\treturn (mime: string) => (canOpenMime(mime) ? 0 : -1)\n\t\t}\n\t\treturn Reflect.get(target, property, receiver)\n\t},\n})\n\n/**\n * Open a file, the way the viewer app used to be asked to.\n *\n * @param options - what to open, and how\n */\nasync function open(options: LegacyOpenOptions = {}): Promise<void> {\n\tdeprecated('open()', 'getViewer().open()')\n\n\tconst {\n\t\tpath,\n\t\tfileInfo,\n\t\tlist = [],\n\t\tenableSidebar = true,\n\t\tloadMore = () => [],\n\t\tcanLoop = true,\n\t\tstartSlideshow = false,\n\t\tonPrev = () => {},\n\t\tonNext = () => {},\n\t\tonClose = () => {},\n\t} = options\n\n\t// Kept from the old implementation: these were thrown rather than logged,\n\t// and an app relying on the throw should keep getting it\n\tif (!path && !fileInfo) {\n\t\tthrow new Error('Viewer needs either an URL or path to open. None given')\n\t}\n\tif (path && !path.startsWith('/')) {\n\t\tthrow new Error('Please use an absolute path')\n\t}\n\tif (!Array.isArray(list)) {\n\t\tthrow new Error('The files list must be an array')\n\t}\n\tif (typeof loadMore !== 'function') {\n\t\tthrow new Error('The loadMore method must be a function')\n\t}\n\n\tconst handlerId = state.overrideHandlerId ?? undefined\n\tstate = {\n\t\t...emptyState(),\n\t\tfile: path ?? fileInfo?.filename ?? '',\n\t\tfiles: list,\n\t\tenableSidebar,\n\t\tcanLoop,\n\t\tstartSlideshow,\n\t\tloadMore,\n\t\tonPrev,\n\t\tonNext,\n\t\tonClose,\n\t}\n\n\tlet target = path ? await nodeFromPath(path) : nodeFromFileInfo(fileInfo!)\n\tconst nodes = list.map(nodeFromFileInfo)\n\n\t// The file to show has to be one of the nodes handed over, and the list\n\t// the caller gave usually already holds it under a different object\n\tconst known = nodes.find((node) => (\n\t\t(target.fileid !== undefined && node.fileid === target.fileid)\n\t\t|| node.source === target.source\n\t))\n\tif (known) {\n\t\ttarget = known\n\t} else {\n\t\tnodes.push(target)\n\t}\n\n\tawait getViewer().open(nodes, target, {\n\t\tenableSidebar,\n\t\tcanLoop,\n\t\tstartSlideshow,\n\t\tonPrev,\n\t\tonNext,\n\t\t// The viewer being closed from the inside has to clear what the\n\t\t// getters answer with, or the file stays open as far as they know\n\t\tonClose: () => {\n\t\t\tstate = emptyState()\n\t\t\tonClose()\n\t\t},\n\t\tloadMore: async () => (await loadMore()).map(nodeFromFileInfo),\n\t}, handlerId)\n}\n\n/**\n * What the viewer app used to put on the page.\n *\n * @deprecated since 36, removed in 39. Use the `@nextcloud/viewer` package.\n */\nexport interface LegacyViewerApi {\n\topen(options?: LegacyOpenOptions): Promise<void>\n\topenWith(handlerId: string, options?: LegacyOpenOptions): Promise<void>\n\tcompare(fileInfo: LegacyFileInfo, compareFileInfo: LegacyFileInfo): Promise<void>\n\tclose(): void\n\treadonly file: string\n\treadonly files: LegacyFileInfo[]\n\treadonly list: LegacyFileInfo[]\n\treadonly mimetypes: string[]\n\treadonly enableSidebar: boolean\n\treadonly canLoop: boolean\n\treadonly startSlideshow: boolean\n\treadonly loadMore: () => LegacyFileInfo[] | Promise<LegacyFileInfo[]>\n\treadonly onPrev: (file: IFile) => void\n\treadonly onNext: (file: IFile) => void\n\treadonly onClose: () => void\n\treadonly overrideHandlerId: string | null\n}\n\n/**\n * Install the old global on the page.\n *\n * Nothing in the server calls it any more. It is here for apps that have not\n * moved over yet, and goes away in Nextcloud {@link REMOVED_IN}.\n */\nexport function installLegacyViewerApi(): void {\n\twindow.OCA ??= {} as typeof window.OCA\n\n\tconst api: LegacyViewerApi = {\n\t\topen,\n\n\t\topenWith(handlerId: string, options: LegacyOpenOptions = {}): Promise<void> {\n\t\t\tdeprecated('openWith()', 'the handler argument of getViewer().open()')\n\t\t\tstate.overrideHandlerId = handlerId\n\t\t\treturn open(options)\n\t\t},\n\n\t\tcompare(fileInfo: LegacyFileInfo, compareFileInfo: LegacyFileInfo): Promise<void> {\n\t\t\tdeprecated('compare()', 'getViewer().compare()')\n\t\t\treturn getViewer().compare(nodeFromFileInfo(fileInfo), nodeFromFileInfo(compareFileInfo))\n\t\t},\n\n\t\tclose(): void {\n\t\t\tdeprecated('close()', 'getViewer().close()')\n\t\t\tstate = emptyState()\n\t\t\tgetViewer().close()\n\t\t},\n\n\t\tget file(): string {\n\t\t\tdeprecated('file', 'the node you passed to getViewer().open()')\n\t\t\treturn state.file\n\t\t},\n\n\t\tget files(): LegacyFileInfo[] {\n\t\t\tdeprecated('files', 'the nodes you passed to getViewer().open()')\n\t\t\treturn state.files\n\t\t},\n\n\t\t// Never a getter on the viewer app, so this always read as undefined.\n\t\t// Kept as the list it was meant to be rather than as the mistake.\n\t\tget list(): LegacyFileInfo[] {\n\t\t\tdeprecated('list', 'the nodes you passed to getViewer().open()')\n\t\t\treturn state.files\n\t\t},\n\n\t\tget mimetypes(): string[] {\n\t\t\tdeprecated('mimetypes', 'canView()')\n\t\t\treturn mimetypes\n\t\t},\n\n\t\tget enableSidebar(): boolean {\n\t\t\tdeprecated('enableSidebar', 'the options you passed to getViewer().open()')\n\t\t\treturn state.enableSidebar\n\t\t},\n\n\t\tget canLoop(): boolean {\n\t\t\tdeprecated('canLoop', 'the options you passed to getViewer().open()')\n\t\t\treturn state.canLoop\n\t\t},\n\n\t\tget startSlideshow(): boolean {\n\t\t\tdeprecated('startSlideshow', 'the options you passed to getViewer().open()')\n\t\t\treturn state.startSlideshow\n\t\t},\n\n\t\tget loadMore() {\n\t\t\tdeprecated('loadMore', 'the options you passed to getViewer().open()')\n\t\t\treturn state.loadMore\n\t\t},\n\n\t\tget onPrev() {\n\t\t\tdeprecated('onPrev', 'the options you passed to getViewer().open()')\n\t\t\treturn state.onPrev\n\t\t},\n\n\t\tget onNext() {\n\t\t\tdeprecated('onNext', 'the options you passed to getViewer().open()')\n\t\t\treturn state.onNext\n\t\t},\n\n\t\tget onClose() {\n\t\t\tdeprecated('onClose', 'the options you passed to getViewer().open()')\n\t\t\treturn state.onClose\n\t\t},\n\n\t\tget overrideHandlerId(): string | null {\n\t\t\tdeprecated('overrideHandlerId', 'the handler argument of getViewer().open()')\n\t\t\treturn state.overrideHandlerId\n\t\t},\n\t}\n\n\twindow.OCA.Viewer = api\n}\n","/*!\n * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport { registerDefaultHandlers } from '@nextcloud/viewer'\nimport { installLegacyViewerApi } from '../../apps/viewer/src/legacy.ts'\n\n// Registers the handlers for images, video and audio, and offers this copy of\n// the viewer to the page. Nothing of the viewer itself is loaded until a file\n// is opened.\n//\n// This runs from an init script so those handlers, and the file actions they\n// register, are in place before the Files list takes its first snapshot of the\n// available actions.\nregisterDefaultHandlers()\n\n// Nothing here calls OCA.Viewer any more. It stays on the page for apps that\n// have not moved over, warns whenever it is touched, and goes in Nextcloud 39\n// with the rest of apps/viewer.\ninstallLegacyViewerApi()\n"],"names":["REMOVED_IN","logger","getLoggerBuilder","emptyState","state","deprecated","member","replacement","nodeFromPath","path","result","getClient","getRootPath","getDefaultPropfind","resultToNode","basenameOf","source","name","directoryOf","pathname","nodeFromFileInfo","info","owner","getCurrentUser","davSource","getRemoteURL","data","Permission","File","canOpenMime","mime","canView","error","mimetypes","target","property","receiver","open","options","fileInfo","list","enableSidebar","loadMore","canLoop","startSlideshow","onPrev","onNext","onClose","handlerId","nodes","known","node","getViewer","installLegacyViewerApi","api","compareFileInfo","registerDefaultHandlers"],"mappings":"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"}