From 7c26dbd36fdfa4f2f70d878d420ee59ad5c2aaac Mon Sep 17 00:00:00 2001 From: Aleksander Machniak <alec@alec.pl> Date: Fri, 16 Jan 2015 03:50:40 -0500 Subject: [PATCH] Fix javascript error in "IE 8.0/Tablet PC" browser (#1490210) --- program/js/app.js | 195 ++++++++++++++++++++++++++++++------------------ 1 files changed, 123 insertions(+), 72 deletions(-) diff --git a/program/js/app.js b/program/js/app.js index eca1fd3..123f1fe 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -187,6 +187,11 @@ if (this.env.permaurl) this.enable_command('permaurl', 'extwin', true); + // initialize html editor + if (this.env.html_editor_init && window.rcmail_editor_init) { + rcmail_editor_init(this.env.html_editor_init); + } + switch (this.task) { case 'mail': @@ -978,12 +983,9 @@ url = {}; if (this.task == 'mail') { - url._mbox = this.env.mailbox; + url = {_mbox: this.env.mailbox, _search: this.env.search_request}; if (props) - url._to = props; - // also send search request so we can go back to search result after message is sent - if (this.env.search_request) - url._search = this.env.search_request; + url._to = props; } // modify url if we're in addressbook else if (this.task == 'addressbook') { @@ -1008,8 +1010,12 @@ break; } } - else if (props) + else if (props && typeof props == 'string') { url._to = props; + } + else if (props && typeof props == 'object') { + $.extend(url, props); + } this.open_compose_step(url); break; @@ -1080,9 +1086,9 @@ case 'reply-list': case 'reply': if (uid = this.get_single_uid()) { - url = {_reply_uid: uid, _mbox: this.env.mailbox}; + url = {_reply_uid: uid, _mbox: this.env.mailbox, _search: this.env.search_request}; + // do reply-list, when list is detected and popup menu wasn't used if (command == 'reply-all') - // do reply-list, when list is detected and popup menu wasn't used url._all = (!props && this.env.reply_all_mode == 1 && this.commands['reply-list'] ? 'list' : 'all'); else if (command == 'reply-list') url._all = 'list'; @@ -1327,8 +1333,10 @@ var url = this.get_task_url(task); if (task == 'mail') url += '&_mbox=INBOX'; - else if (task == 'logout' && !this.env.server_error) + else if (task == 'logout' && !this.env.server_error) { + url += '&_token=' + this.env.request_token; this.clear_compose_data(); + } this.redirect(url); }; @@ -1338,7 +1346,10 @@ if (!url) url = this.env.comm_path; - return url.replace(/_task=[a-z0-9_-]+/i, '_task='+task); + if (url.match(/[?&]_task=[a-zA-Z0-9_-]+/)) + return url.replace(/_task=[a-zA-Z0-9_-]+/, '_task=' + task); + else + return url.replace(/\?.*$/, '') + '?_task=' + task; }; this.reload = function(delay) @@ -1797,7 +1808,7 @@ // attach events $.each(fn, function(i, f) { row[i].onclick = function(e) { f(e); return rcube_event.cancel(e); }; - if (bw.touch) { + if (bw.touch && row[i].addEventListener) { row[i].addEventListener('touchend', function(e) { if (e.changedTouches.length == 1) { f(e); @@ -2069,7 +2080,7 @@ if (preview && this.message_list && this.message_list.rows[id] && this.message_list.rows[id].unread && this.env.preview_pane_mark_read > 0) { this.preview_read_timer = setTimeout(function() { ref.set_unread_message(id, ref.env.mailbox); - ref.http_post('mark', {_uid: id, _flag: 'read', _quiet: 1}); + ref.http_post('mark', {_uid: id, _flag: 'read', _mbox: ref.env.mailbox, _quiet: 1}); }, this.env.preview_pane_mark_read * 1000); } } @@ -2287,7 +2298,7 @@ // expand all threads with unread children this.expand_unread = function() { - var r, tbody = this.gui_objects.messagelist.tBodies[0], + var r, tbody = this.message_list.tbody, new_row = tbody.firstChild; while (new_row) { @@ -3119,7 +3130,7 @@ if (!this.gui_objects.messageform) return false; - var input_from = $("[name='_from']"), + var i, pos, input_from = $("[name='_from']"), input_to = $("[name='_to']"), input_subject = $("input[name='_subject']"), input_message = $("[name='_message']").get(0), @@ -3148,23 +3159,28 @@ // init live search events this.init_address_input_events(input_to, ac_props); - for (var i in ac_fields) { + for (i in ac_fields) { this.init_address_input_events($("[name='_"+ac_fields[i]+"']"), ac_props); } if (!html_mode) { - this.set_caret_pos(input_message, this.env.top_posting ? 0 : $(input_message).val().length); + 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 (input_from.prop('type') == 'select-one') { this.change_identity(input_from[0]); } + + // scroll to the bottom of the textarea (#1490114) + if (pos) { + $(input_message).scrollTop(input_message.scrollHeight); + } } // check for locally stored compose data - if (window.localStorage) { - this.compose_restore_dialog(0, html_mode) - } + this.compose_restore_dialog(0, html_mode) if (input_to.val() == '') input_to.focus(); @@ -3425,6 +3441,8 @@ } else if (this.html2plain(tinyMCE.get(props.id).getContent(), props.id)) tinyMCE.execCommand('mceRemoveControl', false, props.id); + else + return false; return true; }; @@ -3648,14 +3666,13 @@ this.set_draft_id = function(id) { - var rc; - if (id && id != this.env.draft_id) { - if (rc = this.opener()) { - // refresh the drafts folder in opener window - if (rc.env.task == 'mail' && rc.env.action == '' && rc.env.mailbox == this.env.drafts_mailbox) - rc.command('checkmail'); - } + var filter = {task: 'mail', action: ''}, + rc = this.opener(false, filter) || this.opener(true, filter); + + // refresh the drafts folder in the opener window + if (rc && rc.env.mailbox == this.env.drafts_mailbox) + rc.command('checkmail'); this.env.draft_id = id; $("input[name='_draft_saveid']").val(id); @@ -3782,15 +3799,16 @@ } }); - if (window.localStorage && !empty) { + if (!empty) { var index = this.local_storage_get_item('compose.index', []), key = this.env.compose_id; - if ($.inArray(key, index) < 0) { - index.push(key); - } - this.local_storage_set_item('compose.' + key, formdata, true); - this.local_storage_set_item('compose.index', index); + if ($.inArray(key, index) < 0) { + index.push(key); + } + + this.local_storage_set_item('compose.' + key, formdata, true); + this.local_storage_set_item('compose.index', index); } }; @@ -3829,28 +3847,25 @@ // remove stored compose data from localStorage this.remove_compose_data = function(key) { - if (window.localStorage) { - var index = this.local_storage_get_item('compose.index', []); + var index = this.local_storage_get_item('compose.index', []); - if ($.inArray(key, index) >= 0) { - this.local_storage_remove_item('compose.' + key); - this.local_storage_set_item('compose.index', $.grep(index, function(val,i) { return val != key; })); - } + if ($.inArray(key, index) >= 0) { + this.local_storage_remove_item('compose.' + key); + this.local_storage_set_item('compose.index', $.grep(index, function(val,i) { return val != key; })); } }; // clear all stored compose data of this user this.clear_compose_data = function() { - if (window.localStorage) { - var index = this.local_storage_get_item('compose.index', []); + var i, index = this.local_storage_get_item('compose.index', []); - for (var i=0; i < index.length; i++) { - this.local_storage_remove_item('compose.' + index[i]); - } - this.local_storage_remove_item('compose.index'); + for (i=0; i < index.length; i++) { + this.local_storage_remove_item('compose.' + index[i]); } - } + + this.local_storage_remove_item('compose.index'); + }; this.change_identity = function(obj, show_sig) @@ -3861,6 +3876,16 @@ if (!show_sig) show_sig = this.env.show_sig; + var id = obj.options[obj.selectedIndex].value; + + // enable manual signature insert + if (this.env.signatures && this.env.signatures[id]) { + this.enable_command('insert-sig', true); + this.env.compose_commands.push('insert-sig'); + } + else + this.enable_command('insert-sig', false); + // first function execution if (!this.env.identities_initialized) { this.env.identities_initialized = true; @@ -3870,21 +3895,19 @@ return; } - var i, rx, cursor_pos, p = -1, - id = obj.options[obj.selectedIndex].value, + var cursor_pos, p = -1, input_message = $("[name='_message']"), message = input_message.val(), is_html = ($("input[name='_is_html']").val() == '1'), sig = this.env.identity, delim = this.env.recipients_separator, - rx_delim = RegExp.escape(delim), - headers = ['replyto', 'bcc']; + rx_delim = RegExp.escape(delim); // update reply-to/bcc fields with addresses defined in identities - for (i in headers) { - var key = headers[i], - old_val = sig && this.env.identities[sig] ? this.env.identities[sig][key] : '', - new_val = id && this.env.identities[id] ? this.env.identities[id][key] : '', + $.each(['replyto', 'bcc'], function() { + var rx, key = this, + old_val = sig && ref.env.identities[sig] ? ref.env.identities[sig][key] : '', + new_val = id && ref.env.identities[id] ? ref.env.identities[id][key] : '', input = $('[name="_'+key+'"]'), input_val = input.val(); // remove old address(es) @@ -3911,15 +3934,7 @@ if (old_val || new_val) input.val(input_val).change(); - } - - // enable manual signature insert - if (this.env.signatures && this.env.signatures[id]) { - this.enable_command('insert-sig', true); - this.env.compose_commands.push('insert-sig'); - } - else - this.enable_command('insert-sig', false); + }); if (!is_html) { // remove the 'old' signature @@ -4689,6 +4704,7 @@ this.list_contacts = function(src, group, page) { var win, folder, url = {}, + refresh = src === undefined && group === undefined && page === undefined, target = window; if (!src) @@ -4701,7 +4717,7 @@ page = this.env.current_page = 1; this.reset_qsearch(); } - else if (group != this.env.group) + else if (!refresh && group != this.env.group) page = this.env.current_page = 1; if (this.env.search_id) @@ -4837,6 +4853,9 @@ if (action && (cid || action=='add') && !this.drag_active) { if (this.env.group) url._gid = this.env.group; + + if (this.env.search_request) + url._search = this.env.search_request; url._action = action; url._source = this.env.source; @@ -7434,12 +7453,24 @@ }; // get window.opener.rcmail if available - this.opener = function() + this.opener = function(deep, filter) { + var i, win = window.opener; + // catch Error: Permission denied to access property rcmail try { - if (window.opener && !opener.closed && opener.rcmail) - return opener.rcmail; + if (win && !win.closed) { + // try parent of the opener window, e.g. preview frame + if (deep && (!win.rcmail || win.rcmail.env.framed) && win.parent && win.parent.rcmail) + win = win.parent; + + if (win.rcmail && filter) + for (i in filter) + if (win.rcmail.env[i] != filter[i]) + return; + + return win.rcmail; + } } catch (e) {} }; @@ -7657,7 +7688,7 @@ if (plugin && plugin.enabledPlugin) return 1; - if (window.ActiveXObject) { + if ('ActiveXObject' in window) { try { if (axObj = new ActiveXObject("AcroPDF.PDF")) return 1; @@ -7690,7 +7721,7 @@ if (plugin && plugin.enabledPlugin) return 1; - if (window.ActiveXObject) { + if ('ActiveXObject' in window) { try { if (axObj = new ActiveXObject("ShockwaveFlash.ShockwaveFlash")) return 1; @@ -7718,23 +7749,43 @@ // wrapper for localStorage.getItem(key) this.local_storage_get_item = function(key, deflt, encrypted) { + var item; // TODO: add encryption - var item = localStorage.getItem(this.get_local_storage_prefix() + key); + try { + item = localStorage.getItem(this.get_local_storage_prefix() + key); + } + catch (e) { } + return item !== null ? JSON.parse(item) : (deflt || null); }; // wrapper for localStorage.setItem(key, data) this.local_storage_set_item = function(key, data, encrypted) { - // TODO: add encryption - return localStorage.setItem(this.get_local_storage_prefix() + key, JSON.stringify(data)); + // try/catch to handle no localStorage support, but also error + // in Safari-in-private-browsing-mode where localStorage exists + // but can't be used (#1489996) + try { + // TODO: add encryption + localStorage.setItem(this.get_local_storage_prefix() + key, JSON.stringify(data)); + return true; + } + catch (e) { + return false; + } }; // wrapper for localStorage.removeItem(key) this.local_storage_remove_item = function(key) { - return localStorage.removeItem(this.get_local_storage_prefix() + key); + try { + localStorage.removeItem(this.get_local_storage_prefix() + key); + return true; + } + catch (e) { + return false; + } }; } // end object rcube_webmail -- Gitblit v1.9.1