From 23c00eee86f1a1af9fa74bc9daf30c8d33ba33f0 Mon Sep 17 00:00:00 2001 From: Thomas Bruederli <thomas@roundcube.net> Date: Mon, 16 Jun 2014 08:46:31 -0400 Subject: [PATCH] Fix tab navigation with TinyMCE editor (#1489946) --- program/js/app.js | 126 ++++++++++++++++++++++++------------------ 1 files changed, 72 insertions(+), 54 deletions(-) diff --git a/program/js/app.js b/program/js/app.js index d12dd81..82b69c4 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -46,12 +46,12 @@ this.messages = {}; this.group2expand = {}; this.http_request_jobs = {}; - this.menu_stack = new Array(); + this.menu_stack = []; // webmail client settings this.dblclick_time = 500; this.message_time = 5000; - this.identifier_expr = new RegExp('[^0-9a-z\-_]', 'gi'); + this.identifier_expr = /[^0-9a-z_-]/gi; // environment defaults this.env = { @@ -314,9 +314,9 @@ }); // avoid textarea loosing focus when hitting the save-response button/link - for (var i=0; this.buttons['save-response'] && i < this.buttons['save-response'].length; i++) { - $('#'+this.buttons['save-response'][i].id).mousedown(function(e){ return rcube_event.cancel(e); }) - } + $.each(this.buttons['save-response'] || [], function (i, v) { + $('#' + v.id).mousedown(function(e){ return rcube_event.cancel(e); }) + }); } // init message compose form @@ -403,9 +403,6 @@ .addEventListener('dragend', function(e) { ref.drag_end(e); }) .init(); - if (this.env.cid) - this.contact_list.highlight_row(this.env.cid); - this.gui_objects.contactslist.parentNode.onmousedown = function(e){ return ref.click_on_list(e); }; $(this.gui_objects.qsearchbox).focusin(function() { ref.contact_list.blur(); }); @@ -471,9 +468,6 @@ }) .init() .focus(); - - if (this.env.iid) - this.identity_list.highlight_row(this.env.iid); } else if (this.gui_objects.sectionslist) { this.sections_list = new rcube_list_widget(this.gui_objects.sectionslist, {multiselect:false, draggable:false, keyboard:true}); @@ -1344,7 +1338,7 @@ this.command_enabled = function(cmd) { return this.commands[cmd]; - } + }; // lock/unlock interface this.set_busy = function(a, message, id) @@ -1386,10 +1380,11 @@ // switch to another application task this.switch_task = function(task) { - if (this.task===task && task!='mail') + if (this.task === task && task != 'mail') return; var url = this.get_task_url(task); + if (task == 'mail') url += '&_mbox=INBOX'; else if (task == 'logout') @@ -1444,10 +1439,10 @@ this.save_pref = function(prop) { - var request = {'_name': prop.name, '_value': prop.value}; + var request = {_name: prop.name, _value: prop.value}; if (prop.session) - request['_session'] = prop.session; + request._session = prop.session; if (prop.env) this.env[prop.env] = prop.value; @@ -1587,7 +1582,7 @@ // select the folder if one of its childs is currently selected // don't select if it's virtual (#1488346) - if (this.env.mailbox && this.env.mailbox.startsWith(name + this.env.delimiter) && !node.virtual) + if (!node.virtual && this.env.mailbox && this.env.mailbox.startsWith(name + this.env.delimiter)) this.command('list', name); } else { @@ -1629,7 +1624,7 @@ } // reset popup menus; delayed to have updated menu_stack data - window.setTimeout(function(e){ + setTimeout(function(e){ var obj, skip, config, id, i, parents = $(target).parents(); for (i = ref.menu_stack.length - 1; i >= 0; i--) { id = ref.menu_stack[i]; @@ -1669,6 +1664,9 @@ var target = e.target || {}, keyCode = rcube_event.get_keycode(e); + // save global reference for keyboard detection on click events in IE + rcube_event._last_keyboard_event = e; + if (e.keyCode != 27 && (!this.menu_keyboard_active || target.nodeName == 'TEXTAREA' || target.nodeName == 'SELECT')) { return true; } @@ -1678,8 +1676,8 @@ case 40: case 63232: // "up", in safari keypress case 63233: // "down", in safari keypress - focus_menu_item(mod = keyCode == 38 || keyCode == 63232 ? -1 : 1); - break; + focus_menu_item(keyCode == 38 || keyCode == 63232 ? -1 : 1); + return rcube_event.cancel(e); case 9: // tab if (this.focused_menu) { @@ -2428,6 +2426,9 @@ url._framed = 1; } + if (this.env.uid) + url._uid = this.env.uid; + // load message list to target frame/window if (mbox) { this.set_busy(true, 'loading'); @@ -2474,7 +2475,7 @@ selection.push(selected[i]); this.message_list.selection = selection; - } + }; // expand all threads with unread children this.expand_unread = function() @@ -2487,8 +2488,10 @@ this.message_list.expand_all(r); this.set_unread_children(r.uid); } + new_row = new_row.nextSibling; } + return false; }; @@ -2705,8 +2708,8 @@ } // update unread_children for roots - for (var i=0; i<roots.length; i++) - this.set_unread_children(roots[i].uid); + for (r=0; r<roots.length; r++) + this.set_unread_children(roots[r].uid); return count; }; @@ -3595,6 +3598,11 @@ $(e.target).filter('select').val(props.html ? 'plain' : 'html'); } + if (result) { + // update internal format flag + $("input[name='_is_html']").val(props.html ? 1 : 0); + } + return result; }; @@ -3701,8 +3709,9 @@ { var active = this.editor.spellcheck_state(); - if (this.buttons.spellcheck) - $('#'+this.buttons.spellcheck[0].id)[active ? 'addClass' : 'removeClass']('selected'); + $.each(this.buttons.spellcheck || [], function(i, v) { + $('#' + v.id)[active ? 'addClass' : 'removeClass']('selected'); + }); return active; }; @@ -3900,7 +3909,7 @@ } this.local_storage_remove_item('compose.index'); } - } + }; this.change_identity = function(obj, show_sig) @@ -4114,7 +4123,7 @@ this.upload_progress_update = function(param) { - var elem = $('#'+param.name + '> span'); + var elem = $('#'+param.name + ' > span'); if (!elem.length || !param.text) return; @@ -4271,21 +4280,22 @@ this.display_message(msg, type); if (this.env.extwin) { - var rc = this.opener(); this.lock_form(this.gui_objects.messageform); + + var rc = this.opener(); if (rc) { rc.display_message(msg, type); // refresh the folder where sent message was saved or replied message comes from if (folders && rc.env.task == 'mail' && rc.env.action == '' && $.inArray(rc.env.mailbox, folders) >= 0) { - // @TODO: try with 'checkmail' here when #1485186 is fixed. See also #1489249. - rc.command('list'); + rc.command('checkmail'); } } - setTimeout(function(){ window.close() }, 1000); + + setTimeout(function() { window.close(); }, 1000); } else { // before redirect we need to wait some time for Chrome (#1486177) - setTimeout(function(){ ref.list_mailbox(); }, 500); + setTimeout(function() { ref.list_mailbox(); }, 500); } }; @@ -4508,7 +4518,7 @@ // register (delegate) event handlers ul.on('mouseover', 'li', function(e){ ref.ksearch_select(e.target); }) - .on('onmouseup', 'li', function(e){ ref.ksearch_click(e.target); }) + .on('mouseup', 'li', function(e){ ref.ksearch_click(e.target); }) } ul = this.ksearch_pane.__ul; @@ -4963,7 +4973,7 @@ { var selection = this.contact_list ? this.contact_list.get_selection() : []; - // exit if no mailbox specified or if selection is empty + // exit if no contact specified or if selection is empty if (!selection.length && !this.env.cid) return; @@ -7250,11 +7260,24 @@ 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); + } + delete this.env.list_uid; + } + this.enable_command('set-listmode', this.env.threads && !is_multifolder); - if (this.message_list.rowcount > 0) - this.message_list.focus(); - this.msglist_select(this.message_list); - this.triggerEvent('listupdate', { folder:this.env.mailbox, rowcount:this.message_list.rowcount }); + if (list.rowcount > 0) + list.focus(); + this.msglist_select(list); + this.triggerEvent('listupdate', { folder:this.env.mailbox, rowcount:list.rowcount }); + } } else if (this.task == 'addressbook') { @@ -7475,8 +7498,10 @@ // post the given form to a hidden iframe this.async_upload_form = function(form, action, onload) { - var frame, ts = new Date().getTime(), - frame_name = 'rcmupload'+ts; + // create hidden iframe + var ts = new Date().getTime(), + frame_name = 'rcmupload' + ts, + frame = this.async_upload_form_frame(frame_name); // upload progress support if (this.env.upload_progress_name) { @@ -7491,21 +7516,7 @@ field.val(ts); } - // have to do it this way for IE - // otherwise the form will be posted to a new window - if (document.all) { - document.body.insertAdjacentHTML('BeforeEnd', '<iframe name="'+frame_name+'"' - + ' src="program/resources/blank.gif" style="width:0;height:0;visibility:hidden;"></iframe>'); - frame = $('iframe[name="'+frame_name+'"]'); - } - // for standards-compliant browsers - else { - frame = $('<iframe>').attr('name', frame_name) - .css({border: 'none', width: 0, height: 0, visibility: 'hidden'}) - .appendTo(document.body); - } - - // handle upload errors, parsing iframe content in onload + // handle upload errors by parsing iframe content in onload frame.bind('load', {ts:ts}, onload); $(form).attr({ @@ -7518,6 +7529,13 @@ return frame_name; }; + // create iframe element for files upload + this.async_upload_form_frame = function(name) + { + return $('<iframe>').attr({name: name, style: 'border: none; width: 0; height: 0; visibility: hidden'}) + .appendTo(document.body); + }; + // html5 file-drop API this.document_drag_hover = function(e, over) { -- Gitblit v1.9.1