diff --git a/plugins/kolab_notes/notes.js b/plugins/kolab_notes/notes.js index 2af79ef9..fa12d9f6 100644 --- a/plugins/kolab_notes/notes.js +++ b/plugins/kolab_notes/notes.js @@ -1,1493 +1,1493 @@ /** * Client scripts for the Kolab Notes plugin * * @author Thomas Bruederli * @author Aleksander Machniak * * @licstart The following is the entire license notice for the * JavaScript code in this file. * * Copyright (C) 2014-2017, 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. */ function rcube_kolab_notes_ui(settings) { /* private vars */ var ui_loading = false; var saving_lock; var search_query; var folder_drop_target; var notebookslist; var noteslist; var notesdata = {}; var taglist; var search_request; var search_query; var render_no_focus; var me = this; /* public members */ this.selected_list = null; this.selected_note = null; this.notebooks = rcmail.env.kolab_notebooks || {}; this.list_set_sort = list_set_sort; this.settings = settings; /** * initialize the notes UI */ function init() { // register button commands rcmail.register_command('createnote', function(){ warn_unsaved_changes(function(){ edit_note(null, 'new'); }); }, false); rcmail.register_command('list-create', function(){ list_edit_dialog(null); }, true); rcmail.register_command('list-edit', function(){ list_edit_dialog(me.selected_list); }, false); rcmail.register_command('list-delete', function(){ list_delete(me.selected_list); }, false); rcmail.register_command('list-remove', function(){ list_remove(me.selected_list); }, false); rcmail.register_command('list-sort', list_set_sort, true); rcmail.register_command('save', save_note, true); rcmail.register_command('delete', delete_notes, false); rcmail.register_command('search', quicksearch, true); rcmail.register_command('reset-search', reset_search, true); rcmail.register_command('sendnote', send_note, false); rcmail.register_command('print', print_note, false); rcmail.register_command('history', show_history_dialog, false); // register server callbacks rcmail.addEventListener('plugin.data_ready', data_ready); rcmail.addEventListener('plugin.render_note', render_note); rcmail.addEventListener('plugin.update_note', update_note); rcmail.addEventListener('plugin.update_list', list_update); rcmail.addEventListener('plugin.destroy_list', list_destroy); rcmail.addEventListener('plugin.unlock_saving', function() { if (saving_lock) { rcmail.set_busy(false, null, saving_lock); } if (rcmail.gui_objects.noteseditform) { rcmail.lock_form(rcmail.gui_objects.noteseditform, false); } }); rcmail.addEventListener('plugin.close_history_dialog', close_history_dialog); rcmail.addEventListener('plugin.note_render_changelog', render_changelog); rcmail.addEventListener('plugin.note_show_revision', render_revision); rcmail.addEventListener('plugin.note_show_diff', show_diff); // initialize folder selectors if (settings.selected_list && !me.notebooks[settings.selected_list]) { settings.selected_list = null; } for (var id in me.notebooks) { if (me.notebooks[id].editable && !settings.selected_list) { settings.selected_list = id; } } var widget_class = window.kolab_folderlist || rcube_treelist_widget; notebookslist = new widget_class(rcmail.gui_objects.notebooks, { id_prefix: 'rcmliknb', save_state: true, selectable: true, keyboard: true, searchbox: '#notebooksearch', search_action: 'notes/list', search_sources: [ 'folders', 'users' ], search_title: rcmail.gettext('listsearchresults','kolab_notes'), check_droptarget: function(node) { var list = me.notebooks[node.id]; return !node.virtual && list.editable && node.id != me.selected_list; } }); notebookslist.addEventListener('select', function(node) { var id = node.id; if (me.notebooks[id] && id != me.selected_list) { warn_unsaved_changes(function(){ rcmail.enable_command('createnote', has_permission(me.notebooks[id], 'i')); rcmail.enable_command('list-edit', has_permission(me.notebooks[id], 'a')); rcmail.enable_command('list-delete', has_permission(me.notebooks[id], 'xa')); rcmail.enable_command('list-remove', !me.notebooks[id]['default']); fetch_notes(id); // sets me.selected_list rcmail.triggerEvent('show-list', {title: me.notebooks[id].listname}); // Elastic }, function(){ // restore previous selection notebookslist.select(me.selected_list); }); } // unfocus clicked list item $(notebookslist.get_item(id)).find('a.listname').first().blur(); }); notebookslist.addEventListener('subscribe', function(p) { var list; if ((list = me.notebooks[p.id])) { list.subscribed = p.subscribed || false; rcmail.http_post('list', { _do:'subscribe', _list:{ id:p.id, permanent:list.subscribed?1:0 } }); } }); notebookslist.addEventListener('remove', function(p) { if (me.notebooks[p.id] && !me.notebooks[p.id]['default']) { list_remove(p.id); } }); notebookslist.addEventListener('insert-item', function(p) { var list = p.data; if (list && list.id && !list.virtual) { me.notebooks[list.id] = list; if (list.subscribed) rcmail.http_post('list', { _do:'subscribe', _list:{ id:p.id, permanent:1 } }); } }); notebookslist.addEventListener('click-item', function(p) { // avoid link execution return false; }); notebookslist.addEventListener('search-complete', function(data) { if (data.length) rcmail.display_message(rcmail.gettext('nrnotebooksfound','kolab_notes').replace('$nr', data.length), 'voice'); else rcmail.display_message(rcmail.gettext('nonotebooksfound','kolab_notes'), 'notice'); }); // Make Elastic checkboxes pretty if (window.UI && UI.pretty_checkbox) { notebookslist.addEventListener('add-item', function(prop) { UI.pretty_checkbox($(prop.li).find('input')); }); } $(rcmail.gui_objects.notebooks).on('click', 'div.folder > a.listname', function(e) { var id = String($(this).closest('li').attr('id')).replace(/^rcmliknb/, ''); notebookslist.select(id); e.preventDefault(); return false; }); // register dbl-click handler to open list edit dialog $(rcmail.gui_objects.notebooks).on('dblclick', 'li:not(.virtual) a', function(e) { var id = String($(this).closest('li').attr('id')).replace(/^rcmliknb/, ''); if (me.notebooks[id] && has_permission(me.notebooks[id], 'a')) { list_edit_dialog(id); } // clear text selection (from dbl-clicking) var sel = window.getSelection ? window.getSelection() : document.selection; if (sel && sel.removeAllRanges) { sel.removeAllRanges(); } else if (sel && sel.empty) { sel.empty(); } e.preventDefault(); return false; }); // initialize notes list widget if (rcmail.gui_objects.noteslist) { rcmail.noteslist = noteslist = new rcube_list_widget(rcmail.gui_objects.noteslist, { multiselect:true, draggable:true, keyboard:true }); noteslist.addEventListener('select', function(list) { render_no_focus = rcube_event._last_keyboard_event && $(list.list).has(rcube_event._last_keyboard_event.target); var selection_changed = list.selection.length != 1 || !me.selected_note || list.selection[0] != me.selected_note.id; selection_changed && warn_unsaved_changes(function(){ var note; if (!list.multi_selecting && noteslist.selection.length == 1 && (note = notesdata[noteslist.selection[0]])) { edit_note(note.uid, 'edit'); } else { reset_view(true); } }, function(){ // TODO: previous restore selection list.select(me.selected_note.id); }); rcmail.enable_command('delete', me.notebooks[me.selected_list] && has_permission(me.notebooks[me.selected_list], 'td') && list.selection.length > 0); rcmail.enable_command('sendnote', list.selection.length > 0); rcmail.enable_command('print', 'history', list.selection.length == 1); }) .addEventListener('dragstart', function(e) { folder_drop_target = null; notebookslist.drag_start(); }) .addEventListener('dragmove', function(e) { folder_drop_target = notebookslist.intersects(rcube_event.get_mouse_pos(e), true); }) .addEventListener('dragend', function(e) { notebookslist.drag_end(); // move dragged notes to this folder if (folder_drop_target) { noteslist.draglayer.hide(); // check unsaved changes first var new_folder_id = folder_drop_target; warn_unsaved_changes( // ok function() { move_notes(new_folder_id); reset_view(); noteslist.clear_selection(); }, // nok undefined, // beforesave function(savedata) { savedata.list = new_folder_id; // remove from list and thus avoid being moved (again) var id = me.selected_note.id; noteslist.remove_row(id); delete notesdata[id]; } ); } folder_drop_target = null; }) .init().focus(); } if (settings.sort_col) { $('#notessortmenu a.by-' + settings.sort_col).addClass('selected'); } init_editor(); if (settings.selected_list) { notebookslist.select(settings.selected_list) } rcmail.addEventListener('kolab-tags-search', filter_notes) .addEventListener('kolab-tags-drop-data', function(e) { return notesdata[e.id]; }) .addEventListener('kolab-tags-drop', function(e) { if ($(e.list).is('#kolabnoteslist')) { return; } var rec = notesdata[e.id]; if (rec && rec.id && e.tag) { savedata = me.selected_note && rec.uid == me.selected_note.uid ? get_save_data() : $.extend({}, rec); if (savedata.id) delete savedata.id; if (savedata.html) delete savedata.html; if (!savedata.tags) savedata.tags = []; savedata.tags.push(e.tag); rcmail.lock_form(rcmail.gui_objects.noteseditform, true); saving_lock = rcmail.set_busy(true, 'kolab_notes.savingdata'); rcmail.http_post('action', { _data: savedata, _do: 'edit' }, true); } }); rcmail.triggerEvent('kolab-notes-init'); } this.init = init; /** * */ function init_dialog() { rcmail.register_command('save', save_note, true); rcmail.addEventListener('plugin.render_note', render_note); rcmail.addEventListener('plugin.update_note', function(data){ data.id = rcmail.html_identifier_encode(data.uid); notesdata[data.id] = data; render_note(data); }); rcmail.addEventListener('plugin.unlock_saving', function(){ if (saving_lock) { rcmail.set_busy(false, null, saving_lock); } if (rcmail.gui_objects.noteseditform) { rcmail.lock_form(rcmail.gui_objects.noteseditform, false); } if (rcmail.is_framed()) { parent.$(parent.kolab_note_dialog_element).dialog('destroy'); } }); var id, callback = function() { if (settings.selected_uid) { me.selected_list = settings.selected_list; edit_note(settings.selected_uid); } else { me.selected_note = $.extend({ list: me.selected_list, uid: null, title: rcmail.gettext('newnote','kolab_notes'), description: '', tags: [], created: rcmail.gettext('now', 'kolab_notes'), changed: rcmail.gettext('now', 'kolab_notes') }, rcmail.env.kolab_notes_template || {}); render_note(me.selected_note); } }; for (id in me.notebooks) { if (me.notebooks[id].editable) { me.selected_list = id; break; } } init_editor(callback); } this.init_dialog = init_dialog; /** * Initialize TinyMCE editor */ function init_editor(callback) { if (callback) { rcmail.addEventListener('editor-load', callback); } // initialize HTML editor var config = $.extend(rcmail.env.editor_config, {disabled_plugins: ['image', 'media']}); rcmail.editor_init(config, 'notecontent'); // register click handler for message links $(rcmail.gui_objects.notesattachmentslist).on('click', 'li a.messagelink', function() { rcmail.open_window(this.href); return false; }); } /** * Quote HTML entities */ function Q(str) { return String(str).replace(//g, '>').replace(/"/g, '"'); } /** * Check permissions on the given list object */ function has_permission(list, perm) { // multiple chars means "either of" if (String(perm).length > 1) { for (var i=0; i < perm.length; i++) { if (has_permission(list, perm[i])) { return true; } } } if (list.rights && String(list.rights).indexOf(perm) >= 0) { return true; } return (perm == 'i' && list.editable); } /** * */ function edit_note(uid, action) { if (!uid) { me.selected_note = null; if (noteslist) noteslist.clear_selection(); me.selected_note = { list: me.selected_list, uid: null, title: rcmail.gettext('newnote','kolab_notes'), description: '', tags: [], created: rcmail.gettext('now', 'kolab_notes'), changed: rcmail.gettext('now', 'kolab_notes') } render_note(me.selected_note); } else { ui_loading = rcmail.set_busy(true, 'loading'); rcmail.http_request('get', { _list:me.selected_list, _id:uid }, true); } } /** * */ function list_edit_dialog(id) { var list = me.notebooks[id] || { name:'', editable:true, rights: 'riwta' }, title = rcmail.gettext((list.id ? 'editlist' : 'newnotebook'), 'kolab_notes'), params = {_do: (list.id ? 'form-edit' : 'form-new'), _list: {id: list.id}, _framed: 1}, $dialog = $('