summaryrefslogtreecommitdiff
path: root/program/js/app.js
diff options
context:
space:
mode:
Diffstat (limited to 'program/js/app.js')
-rw-r--r--program/js/app.js238
1 files changed, 160 insertions, 78 deletions
diff --git a/program/js/app.js b/program/js/app.js
index e818955bd..b4b125f3f 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -654,7 +654,7 @@ function rcube_webmail()
// check input before leaving compose step
if (this.task == 'mail' && this.env.action == 'compose' && $.inArray(command, this.env.compose_commands) < 0 && !this.env.server_error) {
- if (this.cmp_hash != this.compose_field_hash() && !confirm(this.get_label('notsentwarning')))
+ if (!this.env.is_sent && this.cmp_hash != this.compose_field_hash() && !confirm(this.get_label('notsentwarning')))
return false;
// remove copy from local storage if compose screen is left intentionally
@@ -774,7 +774,7 @@ function rcube_webmail()
case 'list':
if (props && props != '') {
- this.reset_qsearch();
+ this.reset_qsearch(true);
}
if (this.env.action == 'compose' && this.env.extwin) {
window.close();
@@ -894,7 +894,7 @@ function rcube_webmail()
else {
// reload form
if (props == 'reload') {
- form.action += '?_reload=1';
+ form.action += '&_reload=1';
}
else if (this.task == 'settings' && (this.env.identities_level % 2) == 0 &&
(input = $("input[name='_email']", form)) && input.length && !rcube_check_email(input.val())
@@ -1115,7 +1115,7 @@ function rcube_webmail()
break;
case 'send':
- if (!props.nocheck && !this.check_compose_input(command))
+ if (!props.nocheck && !this.env.is_sent && !this.check_compose_input(command))
break;
// Reset the auto-save timer
@@ -1221,17 +1221,16 @@ function rcube_webmail()
// reset quicksearch
case 'reset-search':
- var n, s = this.env.search_request || this.env.qsearch,
- ss = this.gui_objects.qsearchbox && this.gui_objects.qsearchbox.value != '';
+ var n, s = this.env.search_request || this.env.qsearch;
- this.reset_qsearch();
+ this.reset_qsearch(true);
this.select_all_mode = false;
if (s && this.env.action == 'compose') {
if (this.contact_list)
this.list_contacts_clear();
}
- else if (s && ss && this.env.mailbox) {
+ else if (s && this.env.mailbox) {
this.list_mailbox(this.env.mailbox, 1);
}
else if (s && this.task == 'addressbook') {
@@ -1441,7 +1440,7 @@ function rcube_webmail()
else if (delay)
setTimeout(function() { ref.reload(); }, delay);
else if (window.location)
- location.href = this.env.comm_path + (this.env.action ? '&_action='+this.env.action : '');
+ location.href = this.url('', {_extwin: this.env.extwin});
};
// Add variable to GET string, replace old value if exists
@@ -1608,7 +1607,8 @@ function rcube_webmail()
this.folder_collapsed = function(node)
{
- var prefname = this.env.task == 'addressbook' ? 'collapsed_abooks' : 'collapsed_folders';
+ var prefname = this.env.task == 'addressbook' ? 'collapsed_abooks' : 'collapsed_folders',
+ old = this.env[prefname];
if (node.collapsed) {
this.env[prefname] = this.env[prefname] + '&'+urlencode(node.id)+'&';
@@ -1624,7 +1624,8 @@ function rcube_webmail()
}
if (!this.drag_active) {
- this.command('save-pref', { name: prefname, value: this.env[prefname] });
+ if (old !== this.env[prefname])
+ this.command('save-pref', { name: prefname, value: this.env[prefname] });
if (this.env.unread_counts)
this.set_unread_count_display(node.id, false);
@@ -2376,6 +2377,9 @@ function rcube_webmail()
// list messages of a specific mailbox using filter
this.filter_mailbox = function(filter)
{
+ if (this.filter_disabled)
+ return;
+
var lock = this.set_busy(true, 'searching');
this.clear_message_list();
@@ -2409,16 +2413,17 @@ function rcube_webmail()
if (sort)
url._sort = sort;
- // also send search request to get the right messages
- if (this.env.search_request)
- url._search = this.env.search_request;
-
- // set page=1 if changeing to another mailbox
+ // folder change, reset page, search scope, etc.
if (this.env.mailbox != mbox) {
page = 1;
this.env.current_page = page;
+ this.env.search_scope = 'base';
this.select_all_mode = false;
+ this.reset_search_filter();
}
+ // also send search request to get the right messages
+ else if (this.env.search_request)
+ url._search = this.env.search_request;
if (!update_only) {
// unselect selected messages and clear the list and message data
@@ -3344,7 +3349,7 @@ function rcube_webmail()
if (!this.gui_objects.messageform)
return false;
- var i, pos, input_from = $("[name='_from']"),
+ var i, elem, pos, input_from = $("[name='_from']"),
input_to = $("[name='_to']"),
input_subject = $("input[name='_subject']"),
input_message = $("[name='_message']").get(0),
@@ -3379,14 +3384,16 @@ function rcube_webmail()
if (!html_mode) {
pos = this.env.top_posting ? 0 : input_message.value.length;
- this.set_caret_pos(input_message, pos);
// add signature according to selected identity
- // if we have HTML editor, signature is added in callback
+ // if we have HTML editor, signature is added in a callback
if (input_from.prop('type') == 'select-one') {
this.change_identity(input_from[0]);
}
+ // set initial cursor position
+ this.set_caret_pos(input_message, pos);
+
// scroll to the bottom of the textarea (#1490114)
if (pos) {
$(input_message).scrollTop(input_message.scrollHeight);
@@ -3398,11 +3405,14 @@ function rcube_webmail()
this.compose_restore_dialog(0, html_mode)
if (input_to.val() == '')
- input_to.focus();
+ elem = input_to;
else if (input_subject.val() == '')
- input_subject.focus();
+ elem = input_subject;
else if (input_message)
- input_message.focus();
+ elem = input_message;
+
+ // focus first empty element (need to be visible on IE8)
+ $(elem).filter(':visible').focus();
this.env.compose_focus_elem = document.activeElement;
@@ -3489,15 +3499,35 @@ function rcube_webmail()
.attr({ 'autocomplete': 'off', 'aria-autocomplete': 'list', 'aria-expanded': 'false', 'role': 'combobox' });
};
- this.submit_messageform = function(draft)
+ this.submit_messageform = function(draft, saveonly)
{
var form = this.gui_objects.messageform;
if (!form)
return;
+ // the message has been sent but not saved, ask the user what to do
+ if (!saveonly && this.env.is_sent) {
+ return this.show_popup_dialog(this.get_label('messageissent'), '',
+ [{
+ text: this.get_label('save'),
+ 'class': 'mainaction',
+ click: function() {
+ ref.submit_messageform(false, true);
+ $(this).dialog('close');
+ }
+ },
+ {
+ text: this.get_label('cancel'),
+ click: function() {
+ $(this).dialog('close');
+ }
+ }]
+ );
+ }
+
// all checks passed, send message
- var msgid = this.set_busy(true, draft ? 'savingmessage' : 'sendingmessage'),
+ var msgid = this.set_busy(true, draft || saveonly ? 'savingmessage' : 'sendingmessage'),
lang = this.spellcheck_lang(),
files = [];
@@ -3511,6 +3541,10 @@ function rcube_webmail()
form.action = this.add_url(form.action, '_lang', lang);
form.action = this.add_url(form.action, '_framed', 1);
+ if (saveonly) {
+ form.action = this.add_url(form.action, '_saveonly', 1);
+ }
+
// register timer to notify about connection timeout
this.submit_timer = setTimeout(function(){
ref.set_busy(false, null, msgid);
@@ -4306,8 +4340,17 @@ function rcube_webmail()
return url;
};
+ // reset search filter
+ this.reset_search_filter = function()
+ {
+ this.filter_disabled = true;
+ if (this.gui_objects.search_filter)
+ $(this.gui_objects.search_filter).val('ALL').change();
+ this.filter_disabled = false;
+ };
+
// reset quick-search form
- this.reset_qsearch = function()
+ this.reset_qsearch = function(all)
{
if (this.gui_objects.qsearchbox)
this.gui_objects.qsearchbox.value = '';
@@ -4315,6 +4358,11 @@ function rcube_webmail()
if (this.env.qsearch)
this.abort_request(this.env.qsearch);
+ if (all) {
+ this.env.search_scope = 'base';
+ this.reset_search_filter();
+ }
+
this.env.qsearch = null;
this.env.search_request = null;
this.env.search_id = null;
@@ -4358,13 +4406,14 @@ function rcube_webmail()
};
// action executed after mail is sent
- this.sent_successfully = function(type, msg, folders)
+ this.sent_successfully = function(type, msg, folders, save_error)
{
this.display_message(msg, type);
this.compose_skip_unsavedcheck = true;
if (this.env.extwin) {
- this.lock_form(this.gui_objects.messageform);
+ if (!save_error)
+ this.lock_form(this.gui_objects.messageform);
var filter = {task: 'mail', action: ''},
rc = this.opener(false, filter) || this.opener(true, filter);
@@ -4377,12 +4426,16 @@ function rcube_webmail()
}
}
- setTimeout(function() { window.close(); }, 1000);
+ if (!save_error)
+ setTimeout(function() { window.close(); }, 1000);
}
- else {
+ else if (!save_error) {
// before redirect we need to wait some time for Chrome (#1486177)
setTimeout(function() { ref.list_mailbox(); }, 500);
}
+
+ if (save_error)
+ this.env.is_sent = true;
};
@@ -6677,6 +6730,9 @@ function rcube_webmail()
this.env.listcols = listcols;
+ if (!this.env.coltypes)
+ this.env.coltypes = {};
+
// replace old column headers
if (thead) {
if (repl) {
@@ -7168,7 +7224,7 @@ function rcube_webmail()
// compose a valid url with the given parameters
this.url = function(action, query)
{
- var querystring = typeof query === 'string' ? '&' + query : '';
+ var querystring = typeof query === 'string' ? query : '';
if (typeof action !== 'string')
query = action;
@@ -7180,12 +7236,12 @@ function rcube_webmail()
else if (this.env.action)
query._action = this.env.action;
- var base = this.env.comm_path, k, param = {};
+ var url = this.env.comm_path, k, param = {};
// overwrite task name
if (action && action.match(/([a-z0-9_-]+)\/([a-z0-9-_.]+)/)) {
query._action = RegExp.$2;
- base = base.replace(/\_task=[a-z0-9_-]+/, '_task='+RegExp.$1);
+ url = url.replace(/\_task=[a-z0-9_-]+/, '_task=' + RegExp.$1);
}
// remove undefined values
@@ -7194,7 +7250,13 @@ function rcube_webmail()
param[k] = query[k];
}
- return base + (base.indexOf('?') > -1 ? '&' : '?') + $.param(param) + querystring;
+ if (param = $.param(param))
+ url += (url.indexOf('?') > -1 ? '&' : '?') + param;
+
+ if (querystring)
+ url += (url.indexOf('?') > -1 ? '&' : '?') + querystring;
+
+ return url;
};
this.redirect = function(url, lock)
@@ -7247,22 +7309,32 @@ function rcube_webmail()
};
// send a http request to the server
- this.http_request = function(action, query, lock)
+ this.http_request = function(action, data, lock)
{
- var url = this.url(action, query);
+ if (typeof data !== 'object')
+ data = rcube_parse_query(data);
+
+ data._remote = 1;
+ data._unlock = lock ? lock : 0;
// trigger plugin hook
- var result = this.triggerEvent('request'+action, query);
+ var result = this.triggerEvent('request' + action, data);
- if (result !== undefined) {
- // abort if one the handlers returned false
- if (result === false)
- return false;
- else
- url = this.url(action, result);
+ // abort if one of the handlers returned false
+ if (result === false) {
+ if (data._unlock)
+ this.set_busy(false, null, data._unlock);
+ return false;
+ }
+ else if (result !== undefined) {
+ data = result;
+ if (data._action) {
+ action = data._action;
+ delete data._action;
+ }
}
- url += '&_remote=1';
+ var url = this.url(action, data);
// send request
this.log('HTTP GET: ' + url);
@@ -7271,34 +7343,40 @@ function rcube_webmail()
this.start_keepalive();
return $.ajax({
- type: 'GET', url: url, data: { _unlock:(lock?lock:0) }, dataType: 'json',
- success: function(data){ ref.http_response(data); },
+ type: 'GET', url: url, dataType: 'json',
+ success: function(data) { ref.http_response(data); },
error: function(o, status, err) { ref.http_error(o, status, err, lock, action); }
});
};
// send a http POST request to the server
- this.http_post = function(action, postdata, lock)
+ this.http_post = function(action, data, lock)
{
- var url = this.url(action);
+ if (typeof data !== 'object')
+ data = rcube_parse_query(data);
- if (postdata && typeof postdata === 'object') {
- postdata._remote = 1;
- postdata._unlock = (lock ? lock : 0);
- }
- else
- postdata += (postdata ? '&' : '') + '_remote=1' + (lock ? '&_unlock='+lock : '');
+ data._remote = 1;
+ data._unlock = lock ? lock : 0;
// trigger plugin hook
- var result = this.triggerEvent('request'+action, postdata);
- if (result !== undefined) {
- // abort if one of the handlers returned false
- if (result === false)
- return false;
- else
- postdata = result;
+ var result = this.triggerEvent('request'+action, data);
+
+ // abort if one of the handlers returned false
+ if (result === false) {
+ if (data._unlock)
+ this.set_busy(false, null, data._unlock);
+ return false;
+ }
+ else if (result !== undefined) {
+ data = result;
+ if (data._action) {
+ action = data._action;
+ delete data._action;
+ }
}
+ var url = this.url(action);
+
// send request
this.log('HTTP POST: ' + url);
@@ -7306,7 +7384,7 @@ function rcube_webmail()
this.start_keepalive();
return $.ajax({
- type: 'POST', url: url, data: postdata, dataType: 'json',
+ type: 'POST', url: url, data: data, dataType: 'json',
success: function(data){ ref.http_response(data); },
error: function(o, status, err) { ref.http_error(o, status, err, lock, action); }
});
@@ -7422,32 +7500,36 @@ function rcube_webmail()
this.env.qsearch = null;
case 'list':
if (this.task == 'mail') {
- var is_multifolder = this.is_multifolder_listing();
+ var is_multifolder = this.is_multifolder_listing(),
+ list = this.message_list,
+ uid = this.env.list_uid;
+
this.enable_command('show', 'select-all', 'select-none', this.env.messagecount > 0);
this.enable_command('expunge', this.env.exists && !is_multifolder);
this.enable_command('purge', this.purge_mailbox_test() && !is_multifolder);
this.enable_command('import-messages', !is_multifolder);
this.enable_command('expand-all', 'expand-unread', 'collapse-all', this.env.threading && this.env.messagecount && !is_multifolder);
- if ((response.action == 'list' || response.action == 'search') && this.message_list) {
- var list = this.message_list, uid = this.env.list_uid;
-
- // highlight message row when we're back from message page
- if (uid) {
- if (!list.rows[uid])
- uid += '-' + this.env.mailbox;
- if (list.rows[uid]) {
- list.select(uid);
+ if (list) {
+ if (response.action == 'list' || response.action == 'search') {
+ // highlight message row when we're back from message page
+ if (uid) {
+ if (!list.rows[uid])
+ uid += '-' + this.env.mailbox;
+ if (list.rows[uid]) {
+ list.select(uid);
+ }
+ delete this.env.list_uid;
}
- delete this.env.list_uid;
- }
- this.enable_command('set-listmode', this.env.threads && !is_multifolder);
- if (list.rowcount > 0)
- list.focus();
- this.msglist_select(list);
- this.triggerEvent('listupdate', { folder:this.env.mailbox, rowcount:list.rowcount });
+ this.enable_command('set-listmode', this.env.threads && !is_multifolder);
+ if (list.rowcount > 0)
+ list.focus();
+ this.msglist_select(list);
+ }
+ if (response.action != 'getunread')
+ this.triggerEvent('listupdate', { folder:this.env.mailbox, rowcount:list.rowcount });
}
}
else if (this.task == 'addressbook') {