import { getDocumentUrlFromTemplate, getDocumentUrlForPublicFile, getDocumentUrlForFile } from './helpers/url' import PostMessageService from './services/postMessage' import Config from './services/config' import Preload from './services/preload' import Types from './helpers/types' import FilesAppIntegration from './view/FilesAppIntegration' import '../css/viewer.scss' import { splitPath } from './helpers' import NewFileMenu from './view/NewFileMenu' 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, 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: ['image/jpeg', 'image/svg+xml', 'image/cgm', 'image/vnd.dxf', 'image/x-emf', 'image/x-wmf', 'image/x-wpg', 'image/x-freehand', 'image/bmp', 'image/png', 'image/gif', 'image/tiff', 'image/jpg', 'image/jpeg', 'text/plain', 'application/pdf'], registerFileActions() { const EDIT_ACTION_NAME = 'Edit with ' + OC.getCapabilities().richdocuments.productName for (let mime of odfViewer.supportedMimes) { OCA.Files.fileActions.register( mime, EDIT_ACTION_NAME, OC.PERMISSION_READ, OC.imagePath('core', 'actions/rename'), (fileName, context) => { const fileModel = context.fileList.findFile(fileName) const shareOwnerId = fileModel.shareOwnerId return this.onEdit(fileName, { ...context, shareOwnerId }) }, t('richdocuments', 'Edit with {productName}', { productName: OC.getCapabilities().richdocuments.productName }) ) if (odfViewer.excludeMimeFromDefaultOpen.indexOf(mime) === -1 || isDownloadHidden) { OCA.Files.fileActions.setDefault(mime, EDIT_ACTION_NAME) } } }, onEdit: function(fileName, context) { if (!odfViewer.isCollaboraConfigured) { const setupUrl = OC.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.') if (OCP.Toast) { OCP.Toast.error(installHint, { isHTML: true, timeout: 0 }) } else { OC.Notification.showHtml(installHint) } return } if (odfViewer.open === true) { return } odfViewer.open = true if (context) { var fileDir = context.dir var fileId = context.fileId || context.$file.attr('data-id') var 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) } /** * We need to reload the page to set a proper CSP if the file is federated * and the reload didn't happen for the exact same file */ const canAccessCSP = (url, callback) => { let canEmbed = false let frame = document.createElement('iframe') frame.style.display = 'none' frame.onload = () => { canEmbed = true } document.body.appendChild(frame) frame.setAttribute('src', url) setTimeout(() => { if (!canEmbed) { callback() } document.body.removeChild(frame) }, 1000) } // FIXME: Once Nextcloud 16 is minimum requirement we can just pass the allowed domains to initial state // to check then if they are set properly const reloadForFederationCSP = (fileName, shareOwnerId) => { const preloadId = Preload.open ? parseInt(Preload.open.id) : -1 if (typeof shareOwnerId !== 'undefined') { const lastIndex = shareOwnerId.lastIndexOf('@') // only redirect if remote file, not opened though reload and csp blocks the request if (shareOwnerId.substr(lastIndex).indexOf('/') !== -1 && fileId !== preloadId) { canAccessCSP('https://' + shareOwnerId.substr(lastIndex) + '/ocs/v2.php/apps/richdocuments/api/v1/federation', () => { console.debug('Cannot load federated instance though CSP, navigating to ', OC.generateUrl('/apps/richdocuments/open?fileId=' + fileId)) window.location = OC.generateUrl('/apps/richdocuments/open?fileId=' + fileId) }) } } return false } if (context) { reloadForFederationCSP(fileName, context.shareOwnerId) } $('head').append($('')) var $iframe = $('