diff --git a/lib/Listener/ShareLinkListener.php b/lib/Listener/ShareLinkListener.php
index facdf5593f..8d0ae95730 100644
--- a/lib/Listener/ShareLinkListener.php
+++ b/lib/Listener/ShareLinkListener.php
@@ -62,7 +62,6 @@ public function handle(Event $event): void {
$this->initialStateService->prepareParams(['userId' => $loggedInUser]);
$this->initialStateService->provideCapabilities();
- Util::addScript('richdocuments', 'richdocuments-files');
Util::addScript('richdocuments', 'richdocuments-viewer', 'viewer');
Util::addScript('richdocuments', 'richdocuments-public', 'viewer');
}
diff --git a/src/files.js b/src/files.js
deleted file mode 100644
index 5546bddcf1..0000000000
--- a/src/files.js
+++ /dev/null
@@ -1,357 +0,0 @@
-import './init-shared.js'
-
-import '../css/filetypes.scss'
-import '../css/files.scss'
-
-import { emit } from '@nextcloud/event-bus'
-import { imagePath, generateOcsUrl, generateUrl, generateFilePath } from '@nextcloud/router'
-import { showError } from '@nextcloud/dialogs'
-import { getDocumentUrlFromTemplate, getDocumentUrlForPublicFile, getDocumentUrlForFile } from './helpers/url.js'
-import PostMessageService from './services/postMessage.tsx'
-import Config from './services/config.tsx'
-import Types from './helpers/types.js'
-import FilesAppIntegration from './view/FilesAppIntegration.js'
-import { splitPath } from './helpers/index.js'
-import { enableScrollLock, disableScrollLock } from './helpers/safariFixer.js'
-import NewFileMenu from './view/NewFileMenu.js'
-
-const FRAME_DOCUMENT = 'FRAME_DOCUMENT'
-const PostMessages = new PostMessageService({
- FRAME_DOCUMENT: () => document.getElementById('richdocumentsframe').contentWindow,
-})
-
-const isDownloadHidden = document.getElementById('hideDownload') && document.getElementById('hideDownload').value === 'true'
-
-const isPublic = document.getElementById('isPublic') && document.getElementById('isPublic').value === '1'
-
-const odfViewer = {
-
- open: false,
- receivedLoading: false,
- isProxyStarting: false,
- isCollaboraConfigured: (
- (OC.getCapabilities().richdocuments.config.wopi_url.indexOf('proxy.php') !== -1)
- || (typeof OC.getCapabilities().richdocuments.collabora === 'object' && OC.getCapabilities().richdocuments.collabora.length !== 0)),
- supportedMimes: OC.getCapabilities().richdocuments.mimetypes.concat(OC.getCapabilities().richdocuments.mimetypesNoDefaultOpen),
- excludeMimeFromDefaultOpen: OC.getCapabilities().richdocuments.mimetypesNoDefaultOpen,
- hideDownloadMimes: OC.getCapabilities().richdocuments.mimetypesSecureView,
-
- onEdit(fileName, context) {
- let fileDir
- let fileId
- let templateId
-
- enableScrollLock()
-
- if (!odfViewer.isCollaboraConfigured) {
- $.get(generateOcsUrl('cloud/capabilities?format=json')).then(
- e => {
- if ((OC.getCapabilities().richdocuments.config.wopi_url.indexOf('proxy.php') !== -1)
- || (typeof e.ocs.data.capabilities.richdocuments.collabora === 'object'
- && e.ocs.data.capabilities.richdocuments.collabora.length !== 0)) {
- odfViewer.isCollaboraConfigured = true
- odfViewer.onEdit(fileName, context)
- } else {
- const setupUrl = generateUrl('/settings/admin/richdocuments')
- const installHint = OC.isUserAdmin()
- ? `Collabora Online is not setup yet.
Click here to configure your own server or connect to a demo server.`
- : t('richdocuments', 'Collabora Online is not setup yet. Please contact your administrator.')
-
- showError(installHint, {
- isHTML: true,
- timeout: 0,
- })
- }
- },
- )
- return
- }
- if (odfViewer.open === true) {
- return
- }
- odfViewer.open = true
- if (context) {
- if (context?.$file?.attr('data-mounttype') === 'external-session') {
- showError(t('richdocuments', 'Opening the file is not supported, since the credentials for the external storage are not available without a session'), {
- timeout: 0,
- })
- odfViewer.open = false
- return
- }
- fileDir = context.dir
- fileId = context.fileId || context.$file?.attr('data-id')
- templateId = context.templateId
- }
- FilesAppIntegration.startLoading()
- odfViewer.receivedLoading = false
-
- let documentUrl = getDocumentUrlForFile(fileDir, fileId)
- if (isPublic) {
- documentUrl = getDocumentUrlForPublicFile(fileName, fileId)
- }
- if (typeof (templateId) !== 'undefined') {
- documentUrl = getDocumentUrlFromTemplate(templateId, fileName, fileDir)
- }
-
- $('head').append($(''))
-
- const $iframe = $('')
- odfViewer.loadingTimeout = setTimeout(odfViewer.onTimeout,
- (OC.getCapabilities().richdocuments.config.timeout * 1000 || 15000))
- $iframe.src = documentUrl
-
- if ((OC.appswebroots.richdocumentscode || OC.appswebroots.richdocumentscode_arm64)
- && OC.getCapabilities().richdocuments.config.wopi_url.indexOf('proxy.php') >= 0) {
- odfViewer.checkProxyStatus()
- }
-
- $('body').css('overscroll-behavior-y', 'none')
- const viewport = document.querySelector('meta[name=viewport]')
- viewport.setAttribute('content', 'width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no')
- if (isPublic) {
- $('body').append($iframe)
- $iframe.addClass('full')
- $('#content').addClass('full-height')
- $('footer').addClass('hidden')
- $('#controls').addClass('hidden')
- $('#content').addClass('loading')
- } else {
- $('body').css('overflow', 'hidden')
- $('body').append($iframe)
- $iframe.addClass('full')
- $iframe.hide()
- }
-
- $('#app-content #controls').addClass('hidden')
- setTimeout(() => {
- FilesAppIntegration.init({
- fileName,
- fileId,
- filePath: fileDir,
- fileList: context ? context.fileList : undefined,
- fileModel: context ? context.fileModel : undefined,
- sendPostMessage: (msgId, values) => {
- PostMessages.sendWOPIPostMessage(FRAME_DOCUMENT, msgId, values)
- },
- })
- emit('richdocuments:file-open:started', {
- ...FilesAppIntegration.loggingContext(),
- })
- })
- },
-
- onReceiveLoading() {
- odfViewer.receivedLoading = true
- $('#richdocumentsframe').prop('title', 'Collabora Online')
- $('#richdocumentsframe').show()
- $('html, body').scrollTop(0)
- $('#content').removeClass('loading')
- FilesAppIntegration.initAfterReady()
- },
-
- onClose() {
- disableScrollLock()
- odfViewer.open = false
- clearTimeout(odfViewer.loadingTimeout)
- odfViewer.receivedLoading = false
- $('link[href*="richdocuments/css/mobile"]').remove()
- $('#app-content #controls').removeClass('hidden')
- $('#richdocumentsframe').remove()
- $('.searchbox').show()
- $('body').css('overflow', 'auto')
-
- if (isPublic) {
- $('#content').removeClass('full-height')
- $('footer').removeClass('hidden')
- $('.directLink').removeClass('hidden')
- $('.directDownload').removeClass('hidden')
- }
-
- OC.Util.History.replaceState()
-
- FilesAppIntegration.close()
- },
-
- onTimeout() {
- if (!odfViewer.receivedLoading && !odfViewer.isProxyStarting) {
- emit('richdocuments:file-open:failed', {
- reason: 'timeout',
- ...FilesAppIntegration.loggingContext(),
- })
- odfViewer.onClose()
- OC.Notification.showTemporary(t('richdocuments', 'Failed to load {productName} - please try again later', { productName: OC.getCapabilities().richdocuments.productName || 'Collabora Online' }))
- } else if (!odfViewer.receivedLoading) {
- odfViewer.loadingTimeout = setTimeout(odfViewer.onTimeout,
- (OC.getCapabilities().richdocuments.config.timeout * 1000 || 15000))
- }
- },
-
- checkProxyStatus() {
- const wopiUrl = OC.getCapabilities().richdocuments.config.wopi_url
- const url = wopiUrl.slice(0, wopiUrl.indexOf('proxy.php') + 'proxy.php'.length)
- $.get(url + '?status').done(function(result) {
- if (result && result.status) {
- if (result.status === 'OK' || result.status === 'error') {
- odfViewer.isProxyStarting = false
- } else if (result.status === 'starting'
- || result.status === 'stopped'
- || result.status === 'restarting') {
- odfViewer.isProxyStarting = true
-
- setTimeout(function() {
- odfViewer.checkProxyStatus()
- }, 1000)
- }
- }
- })
- },
-}
-
-const settings = OC.getCapabilities().richdocuments.config || {}
-Config.update('ooxml', settings.doc_format === 'ooxml')
-
-window.OCA.RichDocuments = {
- config: {
- create: Types.getFileTypes(),
- },
- open: ({ path, fileId, fileModel, fileList = {} }) => {
- const [dir, file] = splitPath(path)
- odfViewer.onEdit(file, {
- fileId,
- dir,
- shareOwnerId: fileModel.get('shareOwnerId'),
- fileList,
- fileModel,
- })
- },
- openWithTemplate: ({ path, fileId, templateId, fileModel, fileList = {} }) => {
- const [dir, file] = splitPath(path)
- odfViewer.onEdit(file, {
- fileId,
- dir,
- templateId,
- shareOwnerId: fileModel.get('shareOwnerId'),
- fileList,
- fileModel,
- })
- },
- FilesAppIntegration: {
- registerHandler: FilesAppIntegration.registerHandler.bind(FilesAppIntegration),
- },
-}
-
-addEventListener('DOMContentLoaded', () => {
- // register file actions and menu
- if (typeof OCA !== 'undefined'
- && typeof OCA.Files !== 'undefined'
- && typeof OCA.Files.fileActions !== 'undefined'
- ) {
- if (isPublic) {
- OC.Plugins.register('OCA.Files.NewFileMenu', NewFileMenu)
- }
- }
-
- OC.MimeType._mimeTypeIcons['application/vnd.oasis.opendocument.graphics'] = imagePath('richdocuments', 'x-office-draw')
-
- // Open documents if a public page is opened for a supported mimetype
- const isSupportedMime = isPublic && odfViewer.supportedMimes.indexOf($('#mimetype').val()) !== -1 && odfViewer.excludeMimeFromDefaultOpen.indexOf($('#mimetype').val()) === -1
- const showSecureView = isPublic && isDownloadHidden && odfViewer.hideDownloadMimes.indexOf($('#mimetype').val()) !== -1
- if (!isSupportedMime && !showSecureView) {
- return
- }
-
- PostMessages.registerPostMessageHandler(({ parsed }) => {
- console.debug('[viewer] Received post message', parsed)
- const { msgId, args, deprecated } = parsed
- if (deprecated) { return }
-
- switch (msgId) {
- case 'NC_ShowNamePicker':
- clearTimeout(odfViewer.loadingTimeout)
- break
- case 'loading':
- odfViewer.onReceiveLoading()
- break
- case 'Action_Load_Resp':
- if (!args?.success) {
- emit('richdocuments:file-open:failed', {
- reason: 'collabora',
- collaboraResponse: parsed?.args?.errorMsg,
- ...FilesAppIntegration.loggingContext(),
- })
- } else {
- emit('richdocuments:file-open:succeeded', {
- ...FilesAppIntegration.loggingContext(),
- })
- }
- break
- case 'App_LoadingStatus':
- if (args.Status === 'Timeout') {
- emit('richdocuments:file-open:failed', {
- reason: 'timeout',
- ...FilesAppIntegration.loggingContext(),
- })
- odfViewer.onClose()
- OC.Notification.showTemporary(t('richdocuments', 'Failed to connect to {productName}. Please try again later or contact your server administrator.',
- { productName: OC.getCapabilities().richdocuments.productName },
- ))
- }
- break
- case 'UI_Share':
- FilesAppIntegration.share()
- break
- case 'UI_CreateFile':
- FilesAppIntegration.createNewFile(args.DocumentType)
- break
- case 'UI_InsertGraphic':
- FilesAppIntegration.insertGraphic((filename, url) => {
- PostMessages.sendWOPIPostMessage(FRAME_DOCUMENT, 'postAsset', { FileName: filename, Url: url })
- })
- break
- case 'File_Rename':
- FilesAppIntegration.rename(args.NewName)
- break
- case 'Action_Save_Resp':
- FilesAppIntegration.saveAs(args.fileName)
- break
- case 'close':
- odfViewer.onClose()
- break
- case 'Get_Views_Resp':
- case 'Views_List':
- FilesAppIntegration.setViews(args)
- break
- case 'UI_FileVersions':
- case 'rev-history':
- FilesAppIntegration.showRevHistory()
- break
- case 'App_VersionRestore':
- if (args.Status === 'Pre_Restore_Ack') {
- FilesAppIntegration.restoreVersionExecute()
- }
- break
- }
-
- // legacy view handling
- if (msgId === 'View_Added') {
- FilesAppIntegration.views[args.ViewId] = args
- FilesAppIntegration.renderAvatars()
- } else if (msgId === 'View_Removed') {
- delete FilesAppIntegration.views[args.ViewId]
- FilesAppIntegration.renderAvatars()
- } else if (msgId === 'FollowUser_Changed') {
- if (args.IsFollowEditor) {
- FilesAppIntegration.followingEditor = true
- } else {
- FilesAppIntegration.followingEditor = false
- }
- if (args.IsFollowUser) {
- FilesAppIntegration.following = args.FollowedViewId
- } else {
- FilesAppIntegration.following = null
- }
- FilesAppIntegration.renderAvatars()
- }
-
- })
-})
diff --git a/src/helpers/index.js b/src/helpers/index.js
index ee740b4569..ee1a29ec9e 100644
--- a/src/helpers/index.js
+++ b/src/helpers/index.js
@@ -90,3 +90,8 @@ export {
splitPath,
getRandomId,
}
+
+export { default as isDocument } from './isDocument.js'
+export { default as isPdf } from './isPdf.js'
+export { default as isPublic } from './isPublicPage.js'
+export { default as isDownloadHidden } from './isDownloadHidden.js'
diff --git a/src/helpers/isDownloadHidden.js b/src/helpers/isDownloadHidden.js
new file mode 100644
index 0000000000..d8a9b38481
--- /dev/null
+++ b/src/helpers/isDownloadHidden.js
@@ -0,0 +1,16 @@
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+/**
+ * Determines if the resource is downloadable
+ * @return {boolean}
+ */
+function isDownloadHidden() {
+ /** @type HTMLInputElement */
+ const downloadHiddenElement = document.getElementById('hideDownload')
+
+ return Boolean(downloadHiddenElement) && downloadHiddenElement.value === 'true'
+}
+
+export default isDownloadHidden
diff --git a/src/helpers/isPdf.js b/src/helpers/isPdf.js
new file mode 100644
index 0000000000..e39b4f1479
--- /dev/null
+++ b/src/helpers/isPdf.js
@@ -0,0 +1,17 @@
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+/**
+ * Determines if the resource is a PDF document
+ * @return {boolean}
+ */
+function isPdf() {
+ /** @type HTMLInputElement */
+ const mimetypeElement = document.getElementById('mimetype')
+
+ return Boolean(mimetypeElement) && (mimetypeElement.value === 'application/pdf')
+}
+
+export default isPdf
diff --git a/src/public.js b/src/public.js
index 8ef79b679e..a04cad6d53 100644
--- a/src/public.js
+++ b/src/public.js
@@ -1,17 +1,28 @@
-import isPublic from './helpers/isPublicPage.js'
-import isDocument from './helpers/isDocument.js'
+import { getCapabilities } from '@nextcloud/capabilities'
+import {
+ isPublic,
+ isPdf,
+ isDocument,
+ isDownloadHidden,
+} from './helpers/index.js'
+import NewFileMenu from './view/NewFileMenu.js'
-document.addEventListener('DOMContentLoaded', () => {
+const optionalMimetypes = getCapabilities().richdocuments.mimetypesNoDefaultOpen
- // Public share, but not a supported mimetype - do nothing
- if (isPublic() && !isDocument()) {
+document.addEventListener('DOMContentLoaded', () => {
+ if (!isPublic() || !OCA.Viewer) {
return
}
- // Public share, and is a supported mimetype - open viewer
- if (isPublic() && isDocument()) {
- if (OCA.Viewer) {
- OCA.Viewer.open({ path: '/' })
- }
+ if (OCA.Files && OCA.Files.fileActions) {
+ OC.Plugins.register('OCA.Files.NewFileMenu', NewFileMenu)
+ }
+
+ const isEnabledFilesPdfViewer = optionalMimetypes.includes('application/pdf')
+
+ if ((isDownloadHidden() || !isEnabledFilesPdfViewer) && isPdf()) {
+ OCA.Viewer.openWith('richdocuments', { path: '/' })
+ } else if (isDocument()) {
+ OCA.Viewer.open({ path: '/' })
}
})
diff --git a/webpack.js b/webpack.js
index d33a405197..547752f778 100644
--- a/webpack.js
+++ b/webpack.js
@@ -6,7 +6,6 @@ const BabelLoaderExcludeNodeModulesExcept = require('babel-loader-exclude-node-m
webpackConfig.entry = {
viewer: path.join(__dirname, 'src', 'viewer.js'),
- files: path.join(__dirname, 'src', 'files.js'),
fileActions: path.join(__dirname, 'src', 'file-actions.js'),
document: path.join(__dirname, 'src', 'document.js'),
admin: path.join(__dirname, 'src', 'admin.js'),