diff --git a/.travis.yml b/.travis.yml index e2050770..a1a54e9e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: php php: - - 5.6 - 7 env: @@ -50,15 +49,19 @@ matrix: matrix: include: - - php: 5.6 + - php: 7 + env: "DB=sqlite CORE_BRANCH=stable12" + - php: 7 + env: "DB=sqlite CORE_BRANCH=stable13" + - php: 7 env: DB=mysql - - php: 5.6 + - php: 7 env: DB=pgsql - - php: 5.6 + - php: 7 env: DB=mysql;CODECHECK=1 - - php: 5.6 + - php: 7 env: DB=mysql;CODECHECK=2 - - php: 5.6 + - php: 7 env: DB=mysql;JSTESTS=1 allow_failures: - env: DB=mysql;CODECHECK=1 diff --git a/l10n/.tx/config b/.tx/config similarity index 62% rename from l10n/.tx/config rename to .tx/config index 5a679ef2..c628cdd9 100644 --- a/l10n/.tx/config +++ b/.tx/config @@ -3,7 +3,7 @@ host = https://www.transifex.com lang_map = bg_BG: bg, cs_CZ: cs, fi_FI: fi, hu_HU: hu, nb_NO: nb, sk_SK: sk, th_TH: th, ja_JP: ja [nextcloud.richdocuments] -file_filter = /richdocuments.po -source_file = templates/richdocuments.pot +file_filter = translationfiles//richdocuments.po +source_file = translationfiles/templates/richdocuments.pot source_lang = en type = PO diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f4d0a11..f4b3d907 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,18 @@ +**1.12.38 and 1.12.39** +- Bug: fix z-index issue on Nextcloud 13 beta + +**1.12.37** +- Feature: Add support for PutRelativeFile for Save As. + +**1.12.36** +- Feature: Add avatar to UserExtraInfo (from NC 13) +- Feature: Start listening for standard post messages and ignore deprecated ones +- Feature: Add option to enable the app only for users in a specific group +- Updated translations + +**1.12.35** +- Feature: Support for external apps. External apps can now generate a secret token to access richdocuments public API. + **1.12.34** - Bug: Fix editing publicly shared documents - Bug: Delete creator/last modifier name from document templates diff --git a/Makefile b/Makefile index 38a6b585..1659c1d4 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,7 @@ appstore_dir=$(build_dir)/appstore source_dir=$(build_dir)/source package_name=$(app_name) cert_dir=$(HOME)/.nextcloud/certificates +occ=$(CURDIR)/../core/occ appstore: mkdir -p $(sign_dir) @@ -21,7 +22,7 @@ appstore: --exclude=composer.json \ --exclude=composer.lock \ --exclude=composer.phar \ - --exclude=l10n/.tx \ + --exclude=.tx \ --exclude=l10n/no-php \ --exclude=Makefile \ --exclude=nbproject \ @@ -31,6 +32,7 @@ appstore: --exclude=vendor/bin \ $(project_dir) $(sign_dir) @echo "Signing…" + $(occ) integrity:sign-app --privateKey=$(cert_dir)/$(app_name).key --certificate=$(cert_dir)/$(app_name).crt --path=$(sign_dir)/$(app_name) tar -czf $(build_dir)/$(app_name).tar.gz \ -C $(sign_dir) $(app_name) - openssl dgst -sha512 -sign $(cert_dir)/$(app_name).key $(build_dir)/$(app_name).tar.gz | openssl base64 \ No newline at end of file + openssl dgst -sha512 -sign $(cert_dir)/$(app_name).key $(build_dir)/$(app_name).tar.gz | openssl base64 diff --git a/appinfo/app.php b/appinfo/app.php index 6e9249bd..390ff4f6 100644 --- a/appinfo/app.php +++ b/appinfo/app.php @@ -65,7 +65,4 @@ if ($wopiUrl !== '') { $policy = new ContentSecurityPolicy(); $policy->addAllowedFrameDomain($wopiUrl); $manager->addDefaultPolicy($policy); -} - -// Listen to delete file signal -\OCP\Util::connectHook('OC_Filesystem', 'delete', "OCA\Richdocuments\Storage", "onDelete"); +} \ No newline at end of file diff --git a/appinfo/info.xml b/appinfo/info.xml index b92a286c..0b23eba4 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -2,30 +2,31 @@ richdocuments Collabora Online - Collabora Online allows you to to work with all kinds of office documents directly in your browser. This application requires Collabora Cloudsuite to be installed on one of your servers, please read the documentation to learn more about that. Edit office documents directly in your browser. - AGPL - 9999_1.12.36_dontsellme + This application can connect to a Collabora Online server (WOPI Client). Nextcloud is the WOPI Host. Please read the documentation to learn more about that. + 2.0.4 + agpl Collabora Productivity based on work of Frank Karlitschek, Victor Dubiniuk - https://github.com/nextcloud/richdocuments/issues - https://github.com/nextcloud/richdocuments.git - office - integration - - - - - https://nextcloud.com/collaboraonline/ - https://nextcloud.com/collaboraonline/ - + + https://nextcloud.com/collaboraonline/ + https://nextcloud.com/collaboraonline/ + + office + integration + https://collaboraoffice.com/ + https://github.com/nextcloud/richdocuments/issues + https://github.com/nextcloud/richdocuments.git https://nextcloud.com/wp-content/themes/next/assets/img/features/collabora-document.png https://nextcloud.com/wp-content/themes/next/assets/img/features/collabora-presentation.png https://nextcloud.com/wp-content/themes/next/assets/img/features/collabora-spreadsheet.png + + + - \OCA\Richdocuments\Settings\Admin + OCA\Richdocuments\Settings\Admin OCA\Richdocuments\Settings\Section diff --git a/appinfo/routes.php b/appinfo/routes.php index a92dc45d..604f335f 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -25,6 +25,7 @@ return [ ['name' => 'wopi#checkFileInfo', 'url' => 'wopi/files/{fileId}', 'verb' => 'GET'], ['name' => 'wopi#getFile', 'url' => 'wopi/files/{fileId}/contents', 'verb' => 'GET'], ['name' => 'wopi#putFile', 'url' => 'wopi/files/{fileId}/contents', 'verb' => 'POST'], + ['name' => 'wopi#putRelativeFile', 'url' => 'wopi/files/{fileId}', 'verb' => 'POST'], //settings ['name' => 'settings#setSettings', 'url' => 'ajax/admin.php', 'verb' => 'POST'], diff --git a/css/admin.css b/css/admin.css new file mode 100644 index 00000000..6a5d4af2 --- /dev/null +++ b/css/admin.css @@ -0,0 +1,6 @@ +.rd-settings-documentation { + max-width: 50em; +}; +#richdocuments h2 { + display: inline-block; +} \ No newline at end of file diff --git a/js/admin.js b/js/admin.js index 0d5b4a18..616fedfb 100644 --- a/js/admin.js +++ b/js/admin.js @@ -65,7 +65,7 @@ var documentsSettings = { 'external_apps': externalAppsData }; - OC.msg.startAction('#enable-external-apps-section-msg', t('richdocuments', 'Saving...')); + OC.msg.startAction('#enable-external-apps-section-msg', t('richdocuments', 'Saving…')); $.post( OC.filePath('richdocuments', 'ajax', 'admin.php'), data, @@ -73,6 +73,16 @@ var documentsSettings = { ); }, + saveWebroot: function(value) { + var data = { + 'canonical_webroot': value + }; + $.post( + OC.filePath('richdocuments', 'ajax', 'admin.php'), + data + ); + }, + afterSaveExternalApps: function(response) { OC.msg.finishedAction('#enable-external-apps-section-msg', response); }, @@ -234,6 +244,22 @@ var documentsSettings = { $select.change(); }); + $(document).on('change', '#enable_canonical_webroot_cb-richdocuments', function() { + var page = $(this).parent(); + + page.find('#enable-canonical-webroot-section').toggleClass('hidden', !this.checked); + if (!this.checked) { + documentsSettings.saveWebroot(''); + } else { + var val = $('#canonical-webroot').val(); + if (val) + documentsSettings.saveWebroot(); + } + }); + + $(document).on('change', '#canonical-webroot', function() { + documentsSettings.saveWebroot(this.value); + }); } }; diff --git a/js/documents.js b/js/documents.js index 709c6b45..6614044a 100644 --- a/js/documents.js +++ b/js/documents.js @@ -60,8 +60,6 @@ $.widget('oc.documentOverlay', { var documentsMain = { isEditorMode : false, isViewerMode: false, - isGuest : false, - esId : false, ready :false, fileName: null, baseName: null, @@ -72,6 +70,21 @@ var documentsMain = { loadErrorHint : '', renderComplete: false, // false till page is rendered with all required data about the document(s) toolbar : '
', + $deferredVersionRestoreAck: null, + wopiClientFeatures: null, + + // generates docKey for given fileId + _generateDocKey: function(wopiFileId) { + var ocurl = OC.generateUrl('apps/richdocuments/wopi/files/{file_id}', {file_id: wopiFileId}); + if (richdocuments_canonical_webroot) { + if (!richdocuments_canonical_webroot.startsWith('/')) + richdocuments_canonical_webroot = '/' + richdocuments_canonical_webroot; + + ocurl = ocurl.replace(OC.webroot, richdocuments_canonical_webroot); + } + + return ocurl; + }, UI : { /* Editor wrapper HTML */ @@ -107,7 +120,7 @@ var documentsMain = { revisionsStart: 0, init : function(){ - documentsMain.UI.mainTitle = $('title').text(); + documentsMain.UI.mainTitle = parent.document.title; }, showViewer: function(fileId, title){ @@ -249,30 +262,31 @@ var documentsMain = { // close the viewer documentsMain.onCloseViewer(); - // close the editor - documentsMain.UI.hideEditor(); + documentsMain.WOPIPostMessage($('#loleafletframe')[0], 'Host_VersionRestore', {Status: 'Pre_Restore'}); - // If there are changes in the opened editor, we need to wait - // for sometime before these changes can be saved and a revision is created for it, - // before restoring to requested version. - documentsMain.overlay.documentOverlay('show'); - setTimeout(function() { - // restore selected version - $.ajax({ - type: 'GET', - url: e.currentTarget.href, - success: function(response) { - if (response.status === 'error') { - documentsMain.UI.notify(t('richdocuments', 'Failed to revert the document to older version')); + documentsMain.$deferredVersionRestoreAck = $.Deferred(); + jQuery.when(documentsMain.$deferredVersionRestoreAck). + done(function(args) { + // restore selected version + $.ajax({ + type: 'GET', + url: e.currentTarget.href, + success: function(response) { + if (response.status === 'error') { + documentsMain.UI.notify(t('richdocuments', 'Failed to revert the document to older version')); + } + + // load the file again, it should get reverted now + window.location.reload(); + documentsMain.overlay.documentOverlay('hide'); } - - // load the file again, it should get reverted now - window.location = OC.generateUrl('apps/richdocuments/index#{fileid}', {fileid: e.currentTarget.parentElement.dataset.fileid}); - window.location.reload(); - documentsMain.overlay.documentOverlay('hide'); - } + }); }); - }, 1000); + + // resolve the deferred object immediately if client doesn't support version states + if (!documentsMain.wopiClientFeatures || !documentsMain.wopiClientFeatures.VersionStates) { + documentsMain.$deferredVersionRestoreAck.resolve(); + } }); // fake click on first revision (i.e current revision) @@ -280,11 +294,6 @@ var documentsMain = { }, showEditor : function(title, fileId, action){ - if (documentsMain.isGuest){ - // !Login page mess wih WebODF toolbars - $(document.body).attr('id', 'body-user'); - } - if (documentsMain.loadError) { documentsMain.onEditorShutdown(documentsMain.loadErrorMessage + '\n' + documentsMain.loadErrorHint); return; @@ -300,8 +309,7 @@ var documentsMain = { $(document.body).addClass("claro"); $(document.body).prepend(documentsMain.UI.container); - $('title').text(title + ' - ' + documentsMain.UI.mainTitle); - + parent.document.title = title + ' - ' + documentsMain.UI.mainTitle; // WOPISrc - URL that loolwsd will access (ie. pointing to ownCloud) var wopiurl = window.location.protocol + '//' + window.location.host + OC.generateUrl('apps/richdocuments/wopi/files/{file_id}', {file_id: documentsMain.fileId}); @@ -339,6 +347,7 @@ var documentsMain = { var editorInitListener = function(e) { var msg = JSON.parse(e.data); if (msg.MessageId === 'App_LoadingStatus') { + documentsMain.wopiClientFeatures = msg.Values.Features; window.removeEventListener('message', editorInitListener, false); } }; @@ -373,6 +382,42 @@ var documentsMain = { return; documentsMain.UI.showRevHistory(documentsMain.fullPath); + } else if (msgId === 'UI_SaveAs') { + // TODO it's not possible to enter the + // filename into the OC.dialogs.filepicker; so + // it will be necessary to use an own tree + // view or something :-( + //OC.dialogs.filepicker(t('richdocuments', 'Save As'), + // function(val) { + // console.log(val); + // documentsMain.WOPIPostMessage($('#loleafletframe')[0], Action_SaveAs', {'Filename': val}); + // }, false, null, true); + OC.dialogs.prompt(t('richdocuments', 'Please enter the filename to store the document as.'), + t('richdocuments', 'Save As'), + function(result, value) { + if (result === true && value) { + documentsMain.WOPIPostMessage($('#loleafletframe')[0], 'Action_SaveAs', {'Filename': value}); + } + }, + true, + t('richdocuments', 'New filename'), + false).then(function() { + var $dialog = $('.oc-dialog:visible'); + var $buttons = $dialog.find('button'); + $buttons.eq(0).text(t('richdocuments', 'Cancel')); + $buttons.eq(1).text(t('richdocuments', 'Save')); + }); + } else if (msgId === 'App_VersionRestore') { + if (!documentsMain.$deferredVersionRestoreAck) + { + console.warn('No version restore deferred object found.'); + return; + } + + if (args.Status === 'Pre_Restore_Ack') { + // user instructed to restore the version + documentsMain.$deferredVersionRestoreAck.resolve(); + } } }); @@ -392,18 +437,12 @@ var documentsMain = { }, hideEditor : function(){ - if (documentsMain.isGuest){ - // !Login page mess wih WebODF toolbars - $(document.body).attr('id', 'body-login'); - $('footer,nav').show(); - } - // Fade out editor $('#mainContainer').fadeOut('fast', function() { $('#mainContainer').remove(); $('#content-wrapper').fadeIn('fast'); $(document.body).removeClass('claro'); - $('title').text(documentsMain.UI.mainTitle); + parent.document.title = documentsMain.UI.mainTitle; }); }, @@ -467,10 +506,9 @@ var documentsMain = { $('footer,nav').hide(); $(documentsMain.toolbar).appendTo('#header'); - documentsMain.canShare = !documentsMain.isGuest - && typeof OC.Share !== 'undefined' && richdocuments_permissions & OC.PERMISSION_SHARE; + documentsMain.canShare = typeof OC.Share !== 'undefined' && richdocuments_permissions & OC.PERMISSION_SHARE; - // fade out file list and show the cloudsuite + // fade out file list and show the document $('#content-wrapper').fadeOut('fast').promise().done(function() { documentsMain.fileId = richdocuments_fileId; @@ -479,11 +517,6 @@ var documentsMain = { documentsMain.canEdit = Boolean(richdocuments_permissions & OC.PERMISSION_UPDATE); documentsMain.loadDocument(documentsMain.fileName, documentsMain.fileId); - - if (documentsMain.isGuest){ - $('#odf-close').text(t('richdocuments', 'Save') ); - $('#odf-close').removeClass('icon-view-close'); - } }); }, @@ -529,6 +562,7 @@ var documentsMain = { documentsMain.UI.hideEditor(); $('#ocToolbar').remove(); + parent.document.title = documentsMain.UI.mainTitle; parent.postMessage('close', '*'); }, @@ -544,9 +578,6 @@ var documentsMain = { }, show: function(fileId){ - if (documentsMain.isGuest){ - return; - } documentsMain.UI.showProgress(t('richdocuments', 'Loading documents…')); documentsMain.docs.documentGrid('render', fileId); documentsMain.UI.hideProgress(); diff --git a/js/viewer/viewer.js b/js/viewer/viewer.js index 9a314c49..a1ae922c 100644 --- a/js/viewer/viewer.js +++ b/js/viewer/viewer.js @@ -89,7 +89,7 @@ var odfViewer = { FileList.setViewerMode(true); } - var $iframe = $('