From 1f164e4526a57ec25c2509d984e671ec411dc1d2 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak <alec@alec.pl> Date: Wed, 09 Jul 2014 02:45:05 -0400 Subject: [PATCH] Revert "Fix bug where compose storage wasn't cleared on page unload (#1489818)" --- program/js/app.js | 234 +++++++++++++++++++++++++++++++--------------------------- 1 files changed, 124 insertions(+), 110 deletions(-) diff --git a/program/js/app.js b/program/js/app.js index b4a2250..31c23dd 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -346,10 +346,10 @@ this.contact_list .addEventListener('initrow', function(o) { ref.triggerEvent('insertrow', { cid:o.uid, row:o }); }) .addEventListener('select', function(o) { ref.compose_recipient_select(o); }) - .addEventListener('dblclick', function(o) { ref.compose_add_recipient('to'); }) + .addEventListener('dblclick', function(o) { ref.compose_add_recipient(); }) .addEventListener('keypress', function(o) { if (o.key_pressed == o.ENTER_KEY) { - if (!ref.compose_add_recipient('to')) { + if (!ref.compose_add_recipient()) { // execute link action on <enter> if not a recipient entry if (o.last_selected && String(o.last_selected).charAt(0) == 'G') { $(o.rows[o.last_selected].obj).find('a').first().click(); @@ -358,6 +358,9 @@ } }) .init(); + + // remember last focused address field + $('#_to,#_cc,#_bcc').focus(function() { ref.env.focused_field = this; }); } if (this.gui_objects.addressbookslist) { @@ -409,6 +412,17 @@ this.update_group_commands(); this.command('list'); + } + + if (this.gui_objects.savedsearchlist) { + this.savedsearchlist = new rcube_treelist_widget(this.gui_objects.savedsearchlist, { + id_prefix: 'rcmli', + id_encode: this.html_identifier_encode, + id_decode: this.html_identifier_decode + }); + + this.savedsearchlist.addEventListener('select', function(node) { + ref.triggerEvent('selectfolder', { folder:node.id, prefix:'rcmli' }); }); } this.set_page_buttons(); @@ -551,6 +565,7 @@ // init treelist widget if (this.gui_objects.folderlist && window.rcube_treelist_widget) { this.treelist = new rcube_treelist_widget(this.gui_objects.folderlist, { + selectable: true, id_prefix: 'rcmli', id_encode: this.html_identifier_encode, id_decode: this.html_identifier_decode, @@ -615,7 +630,7 @@ { var ret, uid, cid, url, flag, aborted = false; - if (obj && obj.blur && !(event || rcube_event.is_keyboard(event))) + if (obj && obj.blur && !(event && rcube_event.is_keyboard(event))) obj.blur(); // do nothing if interface is locked by other command (with exception for searching reset) @@ -649,11 +664,11 @@ // process external commands if (typeof this.command_handlers[command] === 'function') { - ret = this.command_handlers[command](props, obj); + ret = this.command_handlers[command](props, obj, event); return ret !== undefined ? ret : (obj ? false : true); } else if (typeof this.command_handlers[command] === 'string') { - ret = window[this.command_handlers[command]](props, obj); + ret = window[this.command_handlers[command]](props, obj, event); return ret !== undefined ? ret : (obj ? false : true); } @@ -1840,9 +1855,6 @@ return (this.env.mailboxes[id] && !this.env.mailboxes[id].virtual && (this.env.mailboxes[id].id != this.env.mailbox || this.is_multifolder_listing())) ? 1 : 0; - - case 'settings': - return id != this.env.mailbox ? 1 : 0; case 'addressbook': var target; @@ -3485,6 +3497,12 @@ this.compose_add_recipient = function(field) { + // find last focused field name + if (!field) { + field = $(this.env.focused_field).filter(':visible'); + field = field.length ? field.attr('id').replace('_', '') : 'to'; + } + var recipients = [], input = $('#_'+field), delim = this.env.recipients_delimiter; if (this.contact_list && this.contact_list.selection.length) { @@ -3704,10 +3722,7 @@ // submit delete request if (key && confirm(this.get_label('deleteresponseconfirm'))) { this.http_post('settings/delete-response', { _key: key }, false); - return true; } - - return false; }; // updates spellchecker buttons on state change @@ -4062,6 +4077,14 @@ if (upload_id) this.triggerEvent('fileuploaded', {name: name, attachment: att, id: upload_id}); + if (!this.env.attachments) + this.env.attachments = {}; + + if (upload_id && this.env.attachments[upload_id]) + delete this.env.attachments[upload_id]; + + this.env.attachments[name] = att; + if (!this.gui_objects.attachmentlist) return false; @@ -4090,11 +4113,6 @@ // set tabindex attribute var tabindex = $(this.gui_objects.attachmentlist).attr('data-tabindex') || '0'; li.find('a').attr('tabindex', tabindex); - - if (upload_id && this.env.attachments[upload_id]) - delete this.env.attachments[upload_id]; - - this.env.attachments[name] = att; return true; }; @@ -4525,10 +4543,6 @@ this.ksearch_pane = $('<div>').attr('id', 'rcmKSearchpane').attr('role', 'listbox') .css({ position:'absolute', 'z-index':30000 }).append(ul).appendTo(document.body); this.ksearch_pane.__ul = ul[0]; - - // register (delegate) event handlers - ul.on('mouseover', 'li', function(e){ ref.ksearch_select(e.target); }) - .on('mouseup', 'li', function(e){ ref.ksearch_click(e.target); }) } ul = this.ksearch_pane.__ul; @@ -4551,7 +4565,7 @@ // add each result line to list if (results && (len = results.length)) { for (i=0; i < len && maxlen > 0; i++) { - text = typeof results[i] === 'object' ? results[i].name : results[i]; + text = typeof results[i] === 'object' ? (results[i].display || results[i].name) : results[i]; type = typeof results[i] === 'object' ? results[i].type : ''; id = i + this.env.contacts.length; $('<li>').attr('id', 'rcmkSearchItem' + id) @@ -4559,6 +4573,8 @@ .html(this.quote_html(text.replace(new RegExp('('+RegExp.escape(value)+')', 'ig'), '##$1%%')).replace(/##([^%]+)%%/g, '<b>$1</b>')) .addClass(type || '') .appendTo(ul) + .mouseover(function() { ref.ksearch_select(this); }) + .mouseup(function() { ref.ksearch_click(this); }) .get(0)._rcm_id = id; maxlen -= 1; } @@ -4751,7 +4767,8 @@ $(this.gui_objects.addresslist_title).html(this.get_label('contacts')); } - this.select_folder(folder, '', true); + if (!this.env.search_id) + this.select_folder(folder, '', true); // load contacts remotely if (this.gui_objects.contactslist) { @@ -5175,7 +5192,7 @@ // find list (UL) element if (type == 'contactsearch') - ul = this.gui_objects.folderlist; + ul = this.gui_objects.savedsearchlist; else ul = $('ul.groups', this.get_folder_li(this.env.source,'',true)); @@ -5276,7 +5293,7 @@ .html(prop.name); this.env.contactfolders[key] = this.env.contactgroups[key] = prop; - this.treelist.insert({ id:key, html:link, classes:['contactgroup'] }, prop.source, true); + this.treelist.insert({ id:key, html:link, classes:['contactgroup'] }, prop.source, 'contactgroup'); this.triggerEvent('group_insert', { id:prop.id, source:prop.source, name:prop.name, li:this.treelist.get_item(key) }); }; @@ -5558,7 +5575,7 @@ .html(name), prop = { name:name, id:id }; - this.treelist.insert({ id:key, html:link, classes:['contactsearch'] }, null, 'contactsearch'); + this.savedsearchlist.insert({ id:key, html:link, classes:['contactsearch'] }, null, 'contactsearch'); this.select_folder(key,'',true); this.enable_command('search-delete', true); this.env.search_id = id; @@ -5584,7 +5601,7 @@ this.remove_search_item = function(id) { var li, key = 'S'+id; - if (this.treelist.remove(key)) { + if (this.savedsearchlist.remove(key)) { this.triggerEvent('search_delete', { id:id, li:li }); } @@ -5604,7 +5621,13 @@ } this.reset_qsearch(); - this.select_folder('S'+id, '', true); + + if (this.savedsearchlist) { + this.treelist.select(''); + this.savedsearchlist.select('S'+id); + } + else + this.select_folder('S'+id, '', true); // reset vars this.env.current_page = 1; @@ -5674,10 +5697,8 @@ id = this.env.iid ? this.env.iid : selection[0]; // submit request with appended token - if (confirm(this.get_label('deleteidentityconfirm'))) - this.goto_url('delete-identity', { _iid: id, _token: this.env.request_token }, true); - - return true; + if (id && confirm(this.get_label('deleteidentityconfirm'))) + this.http_post('settings/delete-identity', { _iid: id }, true); }; this.update_identity_row = function(id, name, add) @@ -5721,6 +5742,23 @@ frame.location.href = this.env.blankpage; } } + + this.enable_command('delete', false); + }; + + this.remove_identity = function(id) + { + var frame, list = this.identity_list, + rid = this.html_identifier(id); + + if (list && id) { + list.remove_row(rid); + if (this.env.contentframe && (frame = this.get_frame_window(this.env.contentframe))) { + frame.location.href = this.env.blankpage; + } + } + + this.enable_command('delete', false); }; @@ -5734,62 +5772,38 @@ this.last_sub_rx = RegExp('['+delim+']?[^'+delim+']+$'); - this.subscription_list = new rcube_list_widget(this.gui_objects.subscriptionlist, - {multiselect:false, draggable:true, keyboard:true, toggleselect:true}); + this.subscription_list = new rcube_treelist_widget(this.gui_objects.subscriptionlist, { + selectable: true + }); + this.subscription_list - .addEventListener('select', function(o){ ref.subscription_select(o); }) - .addEventListener('dragstart', function(o){ ref.drag_active = true; }) - .addEventListener('dragend', function(o){ ref.subscription_move_folder(o); }) - .addEventListener('initrow', function (row) { - row.obj.onmouseover = function() { ref.focus_subscription(row.id); }; - row.obj.onmouseout = function() { ref.unfocus_subscription(row.id); }; - }) - .init() - .focus(); + .addEventListener('select', function(node) { ref.subscription_select(node.id); }) + .draggable({cancel: '#mailboxroot'}) + .droppable({ + // @todo: find better way, accept callback is executed for every folder + // on the list when dragging starts (and stops), this is slow, but + // I didn't find a method to check droptarget on over event + accept: function(node) { + var source = ref.env.subscriptionrows[$(node).attr('id')], + dest = ref.env.subscriptionrows[this.id], + source_name = source[0], + dest_name = dest[0]; - $('#mailboxroot') - .mouseover(function(){ ref.focus_subscription(this.id); }) - .mouseout(function(){ ref.unfocus_subscription(this.id); }) - }; - - this.focus_subscription = function(id) - { - var row, folder; - - if (this.drag_active && this.env.mailbox && (row = document.getElementById(id))) - if (this.env.subscriptionrows[id] && - (folder = this.env.subscriptionrows[id][0]) !== null - ) { - if (this.check_droptarget(folder) && - !this.env.subscriptionrows[this.get_folder_row_id(this.env.mailbox)][2] && - folder != this.env.mailbox.replace(this.last_sub_rx, '') && - !folder.startsWith(this.env.mailbox + this.env.delimiter) - ) { - this.env.dstfolder = folder; - $(row).addClass('droptarget'); + return !source[2] + && dest_name != source_name.replace(ref.last_sub_rx, '') + && !dest_name.startsWith(source_name + ref.env.delimiter); + }, + drop: function(e, ui) { + ref.subscription_move_folder(ui.draggable.attr('id'), this.id); } - } + }); }; - this.unfocus_subscription = function(id) + this.subscription_select = function(id) { - var row = $('#'+id); + var folder; - this.env.dstfolder = null; - - if (row.length && this.env.subscriptionrows[id]) - row.removeClass('droptarget'); - else - $(this.subscription_list.frame).removeClass('droptarget'); - }; - - this.subscription_select = function(list) - { - var id, folder; - - if (list && (id = list.get_single_selection()) && - (folder = this.env.subscriptionrows['rcmrow'+id]) - ) { + if (id && id != 'mailboxroot' && (folder = this.env.subscriptionrows[id])) { this.env.mailbox = folder[0]; this.show_folder(folder[0]); this.enable_command('delete-folder', !folder[2]); @@ -5801,24 +5815,21 @@ } }; - this.subscription_move_folder = function(list) + this.subscription_move_folder = function(from, to) { - if (this.env.mailbox && this.env.dstfolder !== null && - this.env.dstfolder != this.env.mailbox && - this.env.dstfolder != this.env.mailbox.replace(this.last_sub_rx, '') - ) { - var path = this.env.mailbox.split(this.env.delimiter), - basename = path.pop(), - newname = this.env.dstfolder === '' ? basename : this.env.dstfolder + this.env.delimiter + basename; + var source = this.env.subscriptionrows[from][0]; + dest = this.env.subscriptionrows[to][0]; - if (newname != this.env.mailbox) { - this.http_post('rename-folder', {_folder_oldname: this.env.mailbox, _folder_newname: newname}, this.set_busy(true, 'foldermoving')); - this.subscription_list.draglayer.hide(); + if (source && dest !== null && source != dest && dest != source.replace(this.last_sub_rx, '')) { + var path = source.split(this.env.delimiter), + basename = path.pop(), + newname = dest === '' ? basename : dest + this.env.delimiter + basename; + + if (newname != source) { + this.http_post('rename-folder', {_folder_oldname: source, _folder_newname: newname}, + this.set_busy(true, 'foldermoving')); } } - - this.drag_active = false; - this.unfocus_subscription(this.get_folder_row_id(this.env.dstfolder)); }; // tell server to create and subscribe a new mailbox @@ -5834,8 +5845,7 @@ folder = this.env.subscriptionrows[id][0]; if (folder && confirm(this.get_label('deletefolderconfirm'))) { - var lock = this.set_busy(true, 'folderdeleting'); - this.http_post('delete-folder', {_mbox: folder}, lock); + this.http_post('delete-folder', {_mbox: folder}, this.set_busy(true, 'folderdeleting')); } }; @@ -5847,9 +5857,9 @@ var row, n, tmp, tmp_name, rowid, collator, folders = [], list = [], slist = [], - tbody = this.gui_objects.subscriptionlist.tBodies[0], - refrow = $('tr', tbody).get(1), - id = 'rcmrow'+((new Date).getTime()); + list_element = $(this.gui_objects.subscriptionlist), + refrow = $('li', list_element).get(1), + id = 'rcmli'+((new Date).getTime()); if (!refrow) { // Refresh page if we don't have a table row to clone @@ -5864,7 +5874,7 @@ row.attr({id: id, 'class': class_name}); // set folder name - row.find('td:first').html(display_name); + $('.name', row).html(display_name); // update subscription checkbox $('input[name="_subscribed[]"]', row).val(name) @@ -5935,12 +5945,13 @@ // add row to the table if (rowid) - $('#'+rowid).after(row); + $('#' + rowid).after(row); else - row.appendTo(tbody); + list_element.append(row); // update list widget - this.subscription_list.clear_selection(); + this.subscription_list.select(); + if (!skip_init) this.init_subscription_list(); @@ -5957,11 +5968,11 @@ if (!this.gui_objects.subscriptionlist) { if (this.is_framed) return parent.rcmail.replace_folder_row(oldfolder, newfolder, display_name, is_protected, class_name); + return false; } var i, n, len, name, dispname, oldrow, tmprow, row, level, - tbody = this.gui_objects.subscriptionlist.tBodies[0], folders = this.env.subscriptionrows, id = this.get_folder_row_id(oldfolder), prefix_len = oldfolder.length, @@ -5972,7 +5983,6 @@ // no renaming, only update class_name if (oldfolder == newfolder) { $('#'+id).attr('class', class_name || ''); - this.subscription_list.focus(); return; } @@ -6009,7 +6019,7 @@ for (i=level; i<0; i++) dispname = ' ' + dispname; } - row.find('td:first').html(dispname); + $('.name', row).html(dispname); this.env.subscriptionrows[id][1] = dispname; } } @@ -6037,8 +6047,8 @@ this._remove_folder_row = function(id) { - this.subscription_list.remove_row(id.replace(/^rcmrow/, '')); - $('#'+id).remove(); + this.subscription_list.remove(id.replace(/^rcmli/, '')); + $('#' + id).remove(); delete this.env.subscriptionrows[id]; }; @@ -6469,6 +6479,10 @@ // mark a mailbox as selected and set environment variable this.select_folder = function(name, prefix, encode) { + if (this.savedsearchlist) { + this.savedsearchlist.select(''); + } + if (this.treelist) { this.treelist.select(name); } @@ -7531,7 +7545,7 @@ $(form).attr({ target: frame_name, - action: this.url(action, { _id:this.env.compose_id||'', _uploadid:ts }), + action: this.url(action, {_id: this.env.compose_id || '', _uploadid: ts, _from: this.env.action}), method: 'POST'}) .attr(form.encoding ? 'encoding' : 'enctype', 'multipart/form-data') .submit(); @@ -7594,7 +7608,7 @@ $.ajax({ type: 'POST', dataType: 'json', - url: ref.url(ref.env.filedrop.action||'upload', { _id:ref.env.compose_id||ref.env.cid||'', _uploadid:ts, _remote:1 }), + url: ref.url(ref.env.filedrop.action || 'upload', {_id: ref.env.compose_id||ref.env.cid||'', _uploadid: ts, _remote: 1, _from: ref.env.action}), contentType: formdata ? false : 'multipart/form-data; boundary=' + boundary, processData: false, timeout: 0, // disable default timeout set in ajaxSetup() -- Gitblit v1.9.1