From 5b242b8e2604d3f9eb98494c8ea3ff34a3ceec54 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Mon, 19 Mar 2018 13:52:58 +0100 Subject: [PATCH] Merge audittrail.js and kolabfolders.js code into libkolab.js ... which includes also attachments handling code and will include more shared functionality in the future. --- plugins/calendar/lib/calendar_ui.php | 7 +- .../lib/kolab_addressbook_ui.php | 2 +- plugins/kolab_notes/kolab_notes_ui.php | 7 +- plugins/libkolab/js/audittrail.js | 269 ------------------ .../{js/folderlist.js => libkolab.js} | 262 ++++++++++++++++- plugins/libkolab/libkolab.php | 2 +- .../skins/elastic/templates/attachment.html | 19 -- .../skins/larry/templates/attachment.html | 17 -- plugins/tasklist/tasklist_ui.php | 7 +- 9 files changed, 265 insertions(+), 327 deletions(-) delete mode 100644 plugins/libkolab/js/audittrail.js rename plugins/libkolab/{js/folderlist.js => libkolab.js} (59%) diff --git a/plugins/calendar/lib/calendar_ui.php b/plugins/calendar/lib/calendar_ui.php index eac0523f..f99c658c 100644 --- a/plugins/calendar/lib/calendar_ui.php +++ b/plugins/calendar/lib/calendar_ui.php @@ -119,12 +119,7 @@ class calendar_ui $this->cal->include_script('calendar_ui.js'); $this->cal->include_script('lib/js/fullcalendar.js'); $this->rc->output->include_script('treelist.js'); - - // include kolab folderlist widget if available - if (in_array('libkolab', $this->cal->api->loaded_plugins())) { - $this->cal->api->include_script('libkolab/js/folderlist.js'); - $this->cal->api->include_script('libkolab/js/audittrail.js'); - } + $this->cal->api->include_script('libkolab/libkolab.js'); jqueryui::miniColors(); } diff --git a/plugins/kolab_addressbook/lib/kolab_addressbook_ui.php b/plugins/kolab_addressbook/lib/kolab_addressbook_ui.php index 726b66cf..a9f6aad5 100644 --- a/plugins/kolab_addressbook/lib/kolab_addressbook_ui.php +++ b/plugins/kolab_addressbook/lib/kolab_addressbook_ui.php @@ -126,7 +126,7 @@ class kolab_addressbook_ui if ($this->plugin->bonnie_api) { $this->rc->output->set_env('kolab_audit_trail', true); - $this->plugin->api->include_script('libkolab/js/audittrail.js'); + $this->plugin->api->include_script('libkolab/libkolab.js'); $this->rc->output->add_label( 'kolab_addressbook.showhistory', diff --git a/plugins/kolab_notes/kolab_notes_ui.php b/plugins/kolab_notes/kolab_notes_ui.php index d1cbb759..28e17e8b 100644 --- a/plugins/kolab_notes/kolab_notes_ui.php +++ b/plugins/kolab_notes/kolab_notes_ui.php @@ -53,12 +53,7 @@ class kolab_notes_ui $this->rc->output->include_script('list.js'); $this->rc->output->include_script('treelist.js'); $this->plugin->include_script('notes.js'); - - // include kolab folderlist widget if available - if (in_array('libkolab', $this->plugin->api->loaded_plugins())) { - $this->plugin->api->include_script('libkolab/js/folderlist.js'); - $this->plugin->api->include_script('libkolab/js/audittrail.js'); - } + $this->plugin->api->include_script('libkolab/libkolab.js'); // load config options and user prefs relevant for the UI $settings = array( diff --git a/plugins/libkolab/js/audittrail.js b/plugins/libkolab/js/audittrail.js deleted file mode 100644 index 404fc098..00000000 --- a/plugins/libkolab/js/audittrail.js +++ /dev/null @@ -1,269 +0,0 @@ -/** - * Kolab groupware audit trail utilities - * - * @author Thomas Bruederli - * - * @licstart The following is the entire license notice for the - * JavaScript code in this file. - * - * Copyright (C) 2015, Kolab Systems AG - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - * @licend The above is the entire license notice - * for the JavaScript code in this file. - */ - -var libkolab_audittrail = {} - -libkolab_audittrail.quote_html = function(str) -{ - return String(str).replace(//g, '>').replace(/"/g, '"'); -}; - - -// show object changelog in a dialog -libkolab_audittrail.object_history_dialog = function(p) -{ - // render dialog - var $dialog = $(p.container); - - // close show dialog first - if ($dialog.is(':ui-dialog')) - $dialog.dialog('close'); - - // hide and reset changelog table - $dialog.find('div.notfound-message').remove(); - $dialog.find('.changelog-table').show().children('tbody') - .html('' + rcmail.gettext('loading') + ''); - - // open jquery UI dialog - $dialog.dialog({ - modal: true, - resizable: true, - closeOnEscape: true, - title: p.title, - open: function() { - $dialog.attr('aria-hidden', 'false'); - }, - close: function() { - $dialog.dialog('destroy').attr('aria-hidden', 'true').hide(); - }, - buttons: [ - { - text: rcmail.gettext('close'), - click: function() { $dialog.dialog('close'); }, - 'class': 'cancel', - autofocus: true - } - ], - minWidth: 450, - width: 650, - height: 350, - minHeight: 200 - }) - .show().children('.compare-button').hide(); - - // initialize event handlers for history dialog UI elements - if (!$dialog.data('initialized')) { - // compare button - $dialog.find('.compare-button input').click(function(e) { - var rev1 = $dialog.find('.changelog-table input.diff-rev1:checked').val(), - rev2 = $dialog.find('.changelog-table input.diff-rev2:checked').val(); - - if (rev1 && rev2 && rev1 != rev2) { - // swap revisions if the user got it wrong - if (rev1 > rev2) { - var tmp = rev2; - rev2 = rev1; - rev1 = tmp; - } - - if (p.comparefunc) { - p.comparefunc(rev1, rev2); - } - } - else { - alert('Invalid selection!') - } - - if (!rcube_event.is_keyboard(e) && this.blur) { - this.blur(); - } - return false; - }); - - // delegate handlers for list actions - $dialog.find('.changelog-table tbody').on('click', 'td.actions a', function(e) { - var link = $(this), - action = link.hasClass('restore') ? 'restore' : 'show', - event = $('#eventhistory').data('event'), - rev = link.attr('data-rev'); - - // ignore clicks on first row (current revision) - if (link.closest('tr').hasClass('first')) { - return false; - } - - // let the user confirm the restore action - if (action == 'restore' && !confirm(rcmail.gettext('revisionrestoreconfirm', p.module).replace('$rev', rev))) { - return false; - } - - if (p.listfunc) { - p.listfunc(action, rev); - } - - if (!rcube_event.is_keyboard(e) && this.blur) { - this.blur(); - } - return false; - }) - .on('click', 'input.diff-rev1', function(e) { - if (!this.checked) return true; - - var rev1 = this.value, selection_valid = false; - $dialog.find('.changelog-table input.diff-rev2').each(function(i, elem) { - $(elem).prop('disabled', elem.value <= rev1); - if (elem.checked && elem.value > rev1) { - selection_valid = true; - } - }); - if (!selection_valid) { - $dialog.find('.changelog-table input.diff-rev2:not([disabled])').last().prop('checked', true); - } - }); - - $dialog.addClass('changelog-dialog').data('initialized', true); - } - - return $dialog; -}; - -// callback from server with changelog data -libkolab_audittrail.render_changelog = function(data, object, folder) -{ - var Q = libkolab_audittrail.quote_html; - - var $dialog = $('.changelog-dialog') - if (data === false || !data.length) { - return false; - } - - var i, change, accessible, op_append, - first = data.length - 1, last = 0, - is_writeable = !!folder.editable, - op_labels = { - RECEIVE: 'actionreceive', - APPEND: 'actionappend', - MOVE: 'actionmove', - DELETE: 'actiondelete', - READ: 'actionread', - FLAGSET: 'actionflagset', - FLAGCLEAR: 'actionflagclear' - }, - actions = ' ' + - (is_writeable ? '' : ''), - tbody = $dialog.find('.changelog-table tbody').html(''); - - for (i=first; i >= 0; i--) { - change = data[i]; - accessible = change.date && change.user; - - if (change.op == 'MOVE' && change.mailbox) { - op_append = ' ⇢ ' + change.mailbox; - } - else if ((change.op == 'FLAGSET' || change.op == 'FLAGCLEAR') && change.flags) { - op_append = ': ' + change.flags; - } - else { - op_append = ''; - } - - $('') - .append('' + (accessible && change.op != 'DELETE' ? - ' '+ - '' - : '')) - .append('' + Q(i+1) + '') - .append('' + Q(change.date || '') + '') - .append('' + Q(change.user || 'undisclosed') + '') - .append('' + Q(rcmail.gettext(op_labels[change.op] || '', 'libkolab') + op_append) + '') - .append('' + (accessible && change.op != 'DELETE' ? actions.replace(/\{rev\}/g, change.rev) : '') + '') - .appendTo(tbody); - } - - if (first > 0) { - $dialog.find('.compare-button').fadeIn(200); - $dialog.find('.changelog-table tr.last input.diff-rev1').click(); - } - - // set dialog size according to content - libkolab_audittrail.dialog_resize($dialog.get(0), $dialog.height() + 15, 600); - - return $dialog; -}; - -// resize and reposition (center) the dialog window -libkolab_audittrail.dialog_resize = function(id, height, width) -{ - var win = $(window), w = win.width(), h = win.height(); - $(id).dialog('option', { height: Math.min(h-20, height+130), width: Math.min(w-20, width+50) }); -}; - - -// register handlers for mail message history -window.rcmail && rcmail.addEventListener('init', function(e) { - var loading_lock; - - if (rcmail.env.task == 'mail') { - rcmail.register_command('kolab-mail-history', function() { - var dialog, uid = rcmail.get_single_uid(), rec = { uid: uid, mbox: rcmail.get_message_mailbox(uid) }; - if (!uid || !window.libkolab_audittrail) { - return false; - } - - // render dialog - $dialog = libkolab_audittrail.object_history_dialog({ - module: 'libkolab', - container: '#mailmessagehistory', - title: rcmail.gettext('objectchangelog','libkolab') - }); - - $dialog.data('rec', rec); - - // fetch changelog data - loading_lock = rcmail.set_busy(true, 'loading', loading_lock); - rcmail.http_post('plugin.message-changelog', { _uid: rec.uid, _mbox: rec.mbox }, loading_lock); - - }, rcmail.env.action == 'show'); - - rcmail.addEventListener('plugin.message_render_changelog', function(data) { - var $dialog = $('#mailmessagehistory'), - rec = $dialog.data('rec'); - - if (data === false || !data.length || !rec) { - // display 'unavailable' message - $('
' + rcmail.gettext('objectchangelognotavailable','libkolab') + '
') - .insertBefore($dialog.find('.changelog-table').hide()); - return; - } - - data.module = 'libkolab'; - libkolab_audittrail.render_changelog(data, rec, {}); - }); - - rcmail.env.message_commands.push('kolab-mail-history'); - } -}); diff --git a/plugins/libkolab/js/folderlist.js b/plugins/libkolab/libkolab.js similarity index 59% rename from plugins/libkolab/js/folderlist.js rename to plugins/libkolab/libkolab.js index 00dcc475..56c8dee7 100644 --- a/plugins/libkolab/js/folderlist.js +++ b/plugins/libkolab/libkolab.js @@ -1,12 +1,12 @@ /** - * Kolab groupware folders treelist widget + * Kolab groupware utilities * * @author Thomas Bruederli * * @licstart The following is the entire license notice for the * JavaScript code in this file. * - * Copyright (C) 2014, Kolab Systems AG + * Copyright (C) 2015-2018, Kolab Systems AG * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -25,6 +25,202 @@ * for the JavaScript code in this file. */ +var libkolab_audittrail = {} + +libkolab_audittrail.quote_html = function(str) +{ + return String(str).replace(//g, '>').replace(/"/g, '"'); +}; + +// show object changelog in a dialog +libkolab_audittrail.object_history_dialog = function(p) +{ + // render dialog + var $dialog = $(p.container); + + // close show dialog first + if ($dialog.is(':ui-dialog')) + $dialog.dialog('close'); + + // hide and reset changelog table + $dialog.find('div.notfound-message').remove(); + $dialog.find('.changelog-table').show().children('tbody') + .html('' + rcmail.gettext('loading') + ''); + + // open jquery UI dialog + $dialog.dialog({ + modal: true, + resizable: true, + closeOnEscape: true, + title: p.title, + open: function() { + $dialog.attr('aria-hidden', 'false'); + }, + close: function() { + $dialog.dialog('destroy').attr('aria-hidden', 'true').hide(); + }, + buttons: [ + { + text: rcmail.gettext('close'), + click: function() { $dialog.dialog('close'); }, + 'class': 'cancel', + autofocus: true + } + ], + minWidth: 450, + width: 650, + height: 350, + minHeight: 200 + }) + .show().children('.compare-button').hide(); + + // initialize event handlers for history dialog UI elements + if (!$dialog.data('initialized')) { + // compare button + $dialog.find('.compare-button input').click(function(e) { + var rev1 = $dialog.find('.changelog-table input.diff-rev1:checked').val(), + rev2 = $dialog.find('.changelog-table input.diff-rev2:checked').val(); + + if (rev1 && rev2 && rev1 != rev2) { + // swap revisions if the user got it wrong + if (rev1 > rev2) { + var tmp = rev2; + rev2 = rev1; + rev1 = tmp; + } + + if (p.comparefunc) { + p.comparefunc(rev1, rev2); + } + } + else { + alert('Invalid selection!') + } + + if (!rcube_event.is_keyboard(e) && this.blur) { + this.blur(); + } + return false; + }); + + // delegate handlers for list actions + $dialog.find('.changelog-table tbody').on('click', 'td.actions a', function(e) { + var link = $(this), + action = link.hasClass('restore') ? 'restore' : 'show', + event = $('#eventhistory').data('event'), + rev = link.attr('data-rev'); + + // ignore clicks on first row (current revision) + if (link.closest('tr').hasClass('first')) { + return false; + } + + // let the user confirm the restore action + if (action == 'restore' && !confirm(rcmail.gettext('revisionrestoreconfirm', p.module).replace('$rev', rev))) { + return false; + } + + if (p.listfunc) { + p.listfunc(action, rev); + } + + if (!rcube_event.is_keyboard(e) && this.blur) { + this.blur(); + } + return false; + }) + .on('click', 'input.diff-rev1', function(e) { + if (!this.checked) return true; + + var rev1 = this.value, selection_valid = false; + $dialog.find('.changelog-table input.diff-rev2').each(function(i, elem) { + $(elem).prop('disabled', elem.value <= rev1); + if (elem.checked && elem.value > rev1) { + selection_valid = true; + } + }); + if (!selection_valid) { + $dialog.find('.changelog-table input.diff-rev2:not([disabled])').last().prop('checked', true); + } + }); + + $dialog.addClass('changelog-dialog').data('initialized', true); + } + + return $dialog; +}; + +// callback from server with changelog data +libkolab_audittrail.render_changelog = function(data, object, folder) +{ + var Q = libkolab_audittrail.quote_html; + + var $dialog = $('.changelog-dialog') + if (data === false || !data.length) { + return false; + } + + var i, change, accessible, op_append, + first = data.length - 1, last = 0, + is_writeable = !!folder.editable, + op_labels = { + RECEIVE: 'actionreceive', + APPEND: 'actionappend', + MOVE: 'actionmove', + DELETE: 'actiondelete', + READ: 'actionread', + FLAGSET: 'actionflagset', + FLAGCLEAR: 'actionflagclear' + }, + actions = '
' + + (is_writeable ? '' : ''), + tbody = $dialog.find('.changelog-table tbody').html(''); + + for (i=first; i >= 0; i--) { + change = data[i]; + accessible = change.date && change.user; + + if (change.op == 'MOVE' && change.mailbox) { + op_append = ' ⇢ ' + change.mailbox; + } + else if ((change.op == 'FLAGSET' || change.op == 'FLAGCLEAR') && change.flags) { + op_append = ': ' + change.flags; + } + else { + op_append = ''; + } + + $('') + .append('' + (accessible && change.op != 'DELETE' ? + ' '+ + '' + : '')) + .append('' + Q(i+1) + '') + .append('' + Q(change.date || '') + '') + .append('' + Q(change.user || 'undisclosed') + '') + .append('' + Q(rcmail.gettext(op_labels[change.op] || '', 'libkolab') + op_append) + '') + .append('' + (accessible && change.op != 'DELETE' ? actions.replace(/\{rev\}/g, change.rev) : '') + '') + .appendTo(tbody); + } + + if (first > 0) { + $dialog.find('.compare-button').fadeIn(200); + $dialog.find('.changelog-table tr.last input.diff-rev1').click(); + } + + // set dialog size according to content + libkolab_audittrail.dialog_resize($dialog.get(0), $dialog.height() + 15, 600); + + return $dialog; +}; + +// resize and reposition (center) the dialog window +libkolab_audittrail.dialog_resize = function(id, height, width) +{ + var win = $(window), w = win.width(), h = win.height(); + $(id).dialog('option', { height: Math.min(h-20, height+130), width: Math.min(w-20, width+50) }); +}; + function kolab_folderlist(node, p) { // extends treelist.js @@ -357,3 +553,65 @@ function kolab_folderlist(node, p) // link prototype from base class kolab_folderlist.prototype = rcube_treelist_widget.prototype; + + +window.rcmail && rcmail.addEventListener('init', function(e) { + var loading_lock; + + if (rcmail.env.task == 'mail') { + rcmail.register_command('kolab-mail-history', function() { + var dialog, uid = rcmail.get_single_uid(), rec = { uid: uid, mbox: rcmail.get_message_mailbox(uid) }; + if (!uid || !window.libkolab_audittrail) { + return false; + } + + // render dialog + $dialog = libkolab_audittrail.object_history_dialog({ + module: 'libkolab', + container: '#mailmessagehistory', + title: rcmail.gettext('objectchangelog','libkolab') + }); + + $dialog.data('rec', rec); + + // fetch changelog data + loading_lock = rcmail.set_busy(true, 'loading', loading_lock); + rcmail.http_post('plugin.message-changelog', { _uid: rec.uid, _mbox: rec.mbox }, loading_lock); + + }, rcmail.env.action == 'show'); + + rcmail.addEventListener('plugin.message_render_changelog', function(data) { + var $dialog = $('#mailmessagehistory'), + rec = $dialog.data('rec'); + + if (data === false || !data.length || !rec) { + // display 'unavailable' message + $('
' + rcmail.gettext('objectchangelognotavailable','libkolab') + '
') + .insertBefore($dialog.find('.changelog-table').hide()); + return; + } + + data.module = 'libkolab'; + libkolab_audittrail.render_changelog(data, rec, {}); + }); + + rcmail.env.message_commands.push('kolab-mail-history'); + } + + if (rcmail.env.action == 'get-attachment') { + if (rcmail.rcmail.gui_objects.attachmentframe) { + rcmail.gui_objects.messagepartframe = rcmail.gui_objects.attachmentframe; + rcmail.enable_command('image-scale', 'image-rotate', !!/^image\//.test(rcmail.env.mimetype)); + rcmail.register_command('print-attachment', function() { + var frame = rcmail.get_frame_window(rcmail.gui_objects.attachmentframe.id); + if (frame) frame.print(); + }, true); + } + + if (rcmail.env.attachment_download_url) { + rcmail.register_command('download-attachment', function() { + rcmail.location_href(rcmail.env.attachment_download_url, window); + }, true); + } + } +}); diff --git a/plugins/libkolab/libkolab.php b/plugins/libkolab/libkolab.php index cee2df9c..27691fd5 100644 --- a/plugins/libkolab/libkolab.php +++ b/plugins/libkolab/libkolab.php @@ -65,7 +65,7 @@ class libkolab extends rcube_plugin if ($rcmail->task == 'mail' && self::get_bonnie_api()) { if ($rcmail->output->type == 'html') { $this->add_hook('render_page', array($this, 'bonnie_render_page')); - $this->include_script('js/audittrail.js'); + $this->include_script('libkolab.js'); // add 'Show history' item to message menu $this->api->add_content(html::tag('li', null, diff --git a/plugins/libkolab/skins/elastic/templates/attachment.html b/plugins/libkolab/skins/elastic/templates/attachment.html index eb4d6950..e81fabe4 100644 --- a/plugins/libkolab/skins/elastic/templates/attachment.html +++ b/plugins/libkolab/skins/elastic/templates/attachment.html @@ -64,23 +64,4 @@ - - diff --git a/plugins/libkolab/skins/larry/templates/attachment.html b/plugins/libkolab/skins/larry/templates/attachment.html index 664d5f7c..4acc2e7b 100644 --- a/plugins/libkolab/skins/larry/templates/attachment.html +++ b/plugins/libkolab/skins/larry/templates/attachment.html @@ -59,23 +59,6 @@ $(document).ready(function() { } }); -window.rcmail && rcmail.addEventListener('init', function(evt) { - if (rcmail.gui_objects.attachmentframe) { - rcmail.gui_objects.messagepartframe = rcmail.gui_objects.attachmentframe; - rcmail.enable_command('image-scale', 'image-rotate', !!/^image\//.test(rcmail.env.mimetype)); - rcmail.register_command('print-attachment', function() { - var frame = rcmail.get_frame_window(rcmail.gui_objects.attachmentframe.id); - if (frame) frame.print(); - }, true); - } - - if (rcmail.env.attachment_download_url) { - rcmail.register_command('download-attachment', function() { - rcmail.location_href(rcmail.env.attachment_download_url, window); - }, true); - } -}); - diff --git a/plugins/tasklist/tasklist_ui.php b/plugins/tasklist/tasklist_ui.php index 48b0c425..a8bfb170 100644 --- a/plugins/tasklist/tasklist_ui.php +++ b/plugins/tasklist/tasklist_ui.php @@ -160,12 +160,7 @@ class tasklist_ui $this->plugin->include_script('tasklist.js'); $this->rc->output->include_script('treelist.js'); - - // include kolab folderlist widget if available - if (in_array('libkolab', $this->plugin->api->loaded_plugins())) { - $this->plugin->api->include_script('libkolab/js/folderlist.js'); - $this->plugin->api->include_script('libkolab/js/audittrail.js'); - } + $this->plugin->api->include_script('libkolab/libkolab.js'); } /**