| | |
| | | if (over) button_prop.over = over; |
| | | |
| | | this.buttons[command].push(button_prop); |
| | | |
| | | |
| | | if (this.loaded) |
| | | init_button(command, button_prop); |
| | | }; |
| | |
| | | } |
| | | |
| | | // enable general commands |
| | | this.enable_command('logout', 'mail', 'addressbook', 'settings', 'save-pref', 'undo', true); |
| | | this.enable_command('logout', 'mail', 'addressbook', 'settings', 'save-pref', 'compose', 'undo', true); |
| | | |
| | | if (this.env.permaurl) |
| | | this.enable_command('permaurl', true); |
| | |
| | | |
| | | case 'mail': |
| | | // enable mail commands |
| | | this.enable_command('list', 'checkmail', 'compose', 'add-contact', 'search', 'reset-search', 'collapse-folder', true); |
| | | this.enable_command('list', 'checkmail', 'add-contact', 'search', 'reset-search', 'collapse-folder', true); |
| | | |
| | | if (this.gui_objects.messagelist) { |
| | | |
| | |
| | | break; |
| | | |
| | | case 'compose': |
| | | var url = this.env.comm_path+'&_action=compose'; |
| | | var url = this.url('mail/compose'); |
| | | |
| | | if (this.task == 'mail') { |
| | | url += '&_mbox='+urlencode(this.env.mailbox); |
| | |
| | | |
| | | break; |
| | | } |
| | | else if (props) |
| | | url += '&_to='+urlencode(props); |
| | | |
| | | this.redirect(url); |
| | | break; |
| | |
| | | |
| | | this.msglist_keypress = function(list) |
| | | { |
| | | if (list.modkey == CONTROL_KEY) |
| | | return; |
| | | |
| | | if (list.key_pressed == list.ENTER_KEY) |
| | | this.command('show'); |
| | | else if (list.key_pressed == list.DELETE_KEY) |
| | | this.command('delete'); |
| | | else if (list.key_pressed == list.BACKSPACE_KEY) |
| | | else if (list.key_pressed == list.DELETE_KEY || list.key_pressed == list.BACKSPACE_KEY) |
| | | this.command('delete'); |
| | | else if (list.key_pressed == 33) |
| | | this.command('previouspage'); |
| | |
| | | if (!this.gui_objects.messagelist || !this.message_list) |
| | | return false; |
| | | |
| | | // Prevent from adding messages from different folder (#1487752) |
| | | if (flags.mbox != this.env.mailbox && !flags.skip_mbox_check) |
| | | return false; |
| | | |
| | | if (!this.env.messages[uid]) |
| | | this.env.messages[uid] = {}; |
| | | |
| | | // merge flags over local message object |
| | | $.extend(this.env.messages[uid], { |
| | | deleted: flags.deleted?1:0, |
| | | replied: flags.replied?1:0, |
| | | unread: flags.unread?1:0, |
| | | replied: flags.answered?1:0, |
| | | unread: !flags.seen?1:0, |
| | | forwarded: flags.forwarded?1:0, |
| | | flagged: flags.flagged?1:0, |
| | | has_children: flags.has_children?1:0, |
| | |
| | | message = this.env.messages[uid], |
| | | css_class = 'message' |
| | | + (even ? ' even' : ' odd') |
| | | + (flags.unread ? ' unread' : '') |
| | | + (!flags.seen ? ' unread' : '') |
| | | + (flags.deleted ? ' deleted' : '') |
| | | + (flags.flagged ? ' flagged' : '') |
| | | + (flags.unread_children && !flags.unread && !this.env.autoexpand_threads ? ' unroot' : '') |
| | | + (flags.unread_children && flags.seen && !this.env.autoexpand_threads ? ' unroot' : '') |
| | | + (message.selected ? ' selected' : ''), |
| | | // for performance use DOM instead of jQuery here |
| | | row = document.createElement('tr'), |
| | |
| | | css_class += ' status'; |
| | | if (flags.deleted) |
| | | css_class += ' deleted'; |
| | | else if (flags.unread) |
| | | else if (!flags.seen) |
| | | css_class += ' unread'; |
| | | else if (flags.unread_children > 0) |
| | | css_class += ' unreadchildren'; |
| | | } |
| | | if (flags.replied) |
| | | if (flags.answered) |
| | | css_class += ' replied'; |
| | | if (flags.forwarded) |
| | | css_class += ' forwarded'; |
| | |
| | | else if (c == 'status') { |
| | | if (flags.deleted) |
| | | css_class = 'deleted'; |
| | | else if (flags.unread) |
| | | else if (!flags.seen) |
| | | css_class = 'unread'; |
| | | else if (flags.unread_children > 0) |
| | | css_class = 'unreadchildren'; |
| | |
| | | } |
| | | else if (c == 'threads') |
| | | html = expando; |
| | | else if (c == 'subject') |
| | | else if (c == 'subject') { |
| | | if (bw.ie) |
| | | col.onmouseover = function() { rcube_webmail.long_subject_title_ie(this, message.depth+1); }; |
| | | html = tree + cols[c]; |
| | | } |
| | | else if (c == 'priority') { |
| | | if (flags.prio > 0 && flags.prio < 6) |
| | | html = '<span class="prio'+flags.prio+'"> </span>'; |
| | |
| | | new_row = tbody.firstChild; |
| | | |
| | | while (new_row) { |
| | | if (new_row.nodeType == 1 && (r = this.message_list.rows[new_row.uid]) |
| | | && r.unread_children) { |
| | | if (new_row.nodeType == 1 && (r = this.message_list.rows[new_row.uid]) && r.unread_children) { |
| | | this.message_list.expand_all(r); |
| | | this.set_unread_children(r.uid); |
| | | } |
| | |
| | | }; |
| | | |
| | | // Initializes threads indicators/expanders after list update |
| | | this.init_threads = function(roots) |
| | | this.init_threads = function(roots, mbox) |
| | | { |
| | | // #1487752 |
| | | if (mbox && mbox != this.env.mailbox) |
| | | return false; |
| | | |
| | | for (var n=0, len=roots.length; n<len; n++) |
| | | this.add_tree_icons(roots[n]); |
| | | this.expand_threads(); |
| | |
| | | // if there is a trash mailbox defined and we're not currently in it |
| | | else { |
| | | // if shift was pressed delete it immediately |
| | | if (list && list.shiftkey) { |
| | | if (list && list.modkey == SHIFT_KEY) { |
| | | if (confirm(this.get_label('deletemessagesconfirm'))) |
| | | this.permanently_remove_messages(); |
| | | } |
| | |
| | | sig = this.env.signatures[sig].is_html ? this.env.signatures[sig].plain_text : this.env.signatures[sig].text; |
| | | sig = sig.replace(/\r\n/g, '\n'); |
| | | |
| | | if (!sig.match(/^--[ -]\n/)) |
| | | if (!sig.match(/^--[ -]\n/m)) |
| | | sig = sig_separator + '\n' + sig; |
| | | |
| | | p = this.env.sig_above ? message.indexOf(sig) : message.lastIndexOf(sig); |
| | |
| | | sig = this.env.signatures[id]['is_html'] ? this.env.signatures[id]['plain_text'] : this.env.signatures[id]['text']; |
| | | sig = sig.replace(/\r\n/g, '\n'); |
| | | |
| | | if (!sig.match(/^--[ -]\n/)) |
| | | if (!sig.match(/^--[ -]\n/m)) |
| | | sig = sig_separator + '\n' + sig; |
| | | |
| | | if (this.env.sig_above) { |
| | |
| | | if (this.env.signatures[id]) { |
| | | if (this.env.signatures[id].is_html) { |
| | | sig = this.env.signatures[id].text; |
| | | if (!this.env.signatures[id].plain_text.match(/^--[ -]\r?\n/)) |
| | | if (!this.env.signatures[id].plain_text.match(/^--[ -]\r?\n/m)) |
| | | sig = sig_separator + '<br />' + sig; |
| | | } |
| | | else { |
| | | sig = this.env.signatures[id].text; |
| | | if (!sig.match(/^--[ -]\r?\n/)) |
| | | if (!sig.match(/^--[ -]\r?\n/m)) |
| | | sig = sig_separator + '\n' + sig; |
| | | sig = '<pre>' + sig + '</pre>'; |
| | | } |
| | |
| | | |
| | | return rcube_event.cancel(e); |
| | | |
| | | case 9: // tab |
| | | if (mod == SHIFT_KEY) |
| | | break; |
| | | case 9: // tab |
| | | if (mod == SHIFT_KEY || !this.ksearch_visible()) { |
| | | this.ksearch_hide(); |
| | | return; |
| | | } |
| | | |
| | | case 13: // enter |
| | | if (this.ksearch_selected === null || !this.ksearch_value) |
| | | break; |
| | | if (!this.ksearch_visible()) |
| | | return false; |
| | | |
| | | // insert selected address and hide ksearch pane |
| | | this.insert_recipient(this.ksearch_selected); |
| | |
| | | return true; |
| | | }; |
| | | |
| | | this.ksearch_visible = function() |
| | | { |
| | | return (this.ksearch_selected !== null && this.ksearch_selected !== undefined && this.ksearch_value); |
| | | }; |
| | | |
| | | this.ksearch_select = function(node) |
| | | { |
| | | var current = $('#rcmksearchSelected'); |
| | |
| | | |
| | | this.insert_recipient = function(id) |
| | | { |
| | | if (!this.env.contacts[id] || !this.ksearch_input) |
| | | if (id === null || !this.env.contacts[id] || !this.ksearch_input) |
| | | return; |
| | | |
| | | // get cursor pos |
| | |
| | | if (q == this.ksearch_value) |
| | | return; |
| | | |
| | | this.ksearch_destroy(); |
| | | |
| | | if (q.length && q.length < min) { |
| | | if (!this.env.acinfo) { |
| | | this.env.acinfo = this.display_message( |
| | | if (!this.ksearch_info) { |
| | | this.ksearch_info = this.display_message( |
| | | this.get_label('autocompletechars').replace('$min', min)); |
| | | } |
| | | return; |
| | | } |
| | | else if (this.env.acinfo) { |
| | | this.hide_message(this.env.acinfo); |
| | | } |
| | | |
| | | var old_value = this.ksearch_value; |
| | | this.ksearch_value = q; |
| | | |
| | | this.ksearch_destroy(); |
| | | |
| | | // ...string is empty |
| | | if (!q.length) |
| | |
| | | return; |
| | | |
| | | // display search results |
| | | var p, ul, li, text, init, s_val = this.ksearch_value, |
| | | var ul, li, text, init, |
| | | value = this.ksearch_value, |
| | | data = this.ksearch_data, |
| | | maxlen = this.env.autocomplete_max ? this.env.autocomplete_max : 15; |
| | | |
| | | // create results pane if not present |
| | |
| | | for (i=0; i < results.length && maxlen > 0; i++) { |
| | | text = typeof results[i] === 'object' ? results[i].name : results[i]; |
| | | li = document.createElement('LI'); |
| | | li.innerHTML = text.replace(new RegExp('('+RegExp.escape(s_val)+')', 'ig'), '##$1%%').replace(/</g, '<').replace(/>/g, '>').replace(/##([^%]+)%%/g, '<b>$1</b>'); |
| | | li.innerHTML = text.replace(new RegExp('('+RegExp.escape(value)+')', 'ig'), '##$1%%').replace(/</g, '<').replace(/>/g, '>').replace(/##([^%]+)%%/g, '<b>$1</b>'); |
| | | li.onmouseover = function(){ ref.ksearch_select(this); }; |
| | | li.onmouseup = function(){ ref.ksearch_click(this) }; |
| | | li._rcm_id = this.env.contacts.length + i; |
| | |
| | | this.env.contacts = this.env.contacts.concat(results); |
| | | |
| | | // run next parallel search |
| | | if (maxlen > 0 && this.ksearch_data.id == reqid && this.ksearch_data.sources.length) { |
| | | var lock, xhr, props = this.ksearch_data, source = props.sources.shift(); |
| | | if (source) { |
| | | lock = this.display_message(this.get_label('searching'), 'loading'); |
| | | xhr = this.http_post(props.action, '_search='+urlencode(s_val)+'&_id='+reqid |
| | | +'&_source='+urlencode(source), lock); |
| | | if (data.id == reqid) { |
| | | if (maxlen > 0 && data.sources.length) { |
| | | var lock, xhr, source = data.sources.shift(); |
| | | if (source) { |
| | | lock = this.display_message(this.get_label('searching'), 'loading'); |
| | | xhr = this.http_post(data.action, '_search='+urlencode(value)+'&_id='+reqid |
| | | +'&_source='+urlencode(source), lock); |
| | | |
| | | this.ksearch_data.locks.push(lock); |
| | | this.ksearch_data.requests.push(xhr); |
| | | this.ksearch_data.locks.push(lock); |
| | | this.ksearch_data.requests.push(xhr); |
| | | } |
| | | } |
| | | else if (!maxlen) { |
| | | if (!this.ksearch_msg) |
| | | this.ksearch_msg = this.display_message(this.get_label('autocompletemore')); |
| | | // abort pending searches |
| | | this.ksearch_abort(); |
| | | } |
| | | } |
| | | }; |
| | |
| | | this.ksearch_destroy(); |
| | | }; |
| | | |
| | | // Aborts pending autocomplete requests |
| | | // Clears autocomplete data/requests |
| | | this.ksearch_destroy = function() |
| | | { |
| | | this.ksearch_abort(); |
| | | |
| | | if (this.ksearch_info) |
| | | this.hide_message(this.ksearch_info); |
| | | |
| | | if (this.ksearch_msg) |
| | | this.hide_message(this.ksearch_msg); |
| | | |
| | | this.ksearch_data = null; |
| | | this.ksearch_info = null; |
| | | this.ksearch_msg = null; |
| | | } |
| | | |
| | | // Aborts pending autocomplete requests |
| | | this.ksearch_abort = function() |
| | | { |
| | | var i, len, ac = this.ksearch_data; |
| | | |
| | |
| | | |
| | | for (i=0, len=ac.locks.length; i<len; i++) |
| | | this.abort_request({request: ac.requests[i], lock: ac.locks[i]}); |
| | | }; |
| | | |
| | | this.ksearch_data = null; |
| | | } |
| | | |
| | | /*********************************************************/ |
| | | /********* address book methods *********/ |
| | |
| | | { |
| | | // exit if no mailbox specified or if selection is empty |
| | | var selection = this.contact_list.get_selection(); |
| | | if (!(selection.length || this.env.cid) || !confirm(this.get_label('deletecontactconfirm'))) |
| | | var undelete = this.env.address_sources[this.env.source].undelete; |
| | | if (!(selection.length || this.env.cid) || (!undelete && !confirm(this.get_label('deletecontactconfirm')))) |
| | | return; |
| | | |
| | | var id, n, a_cids = [], qs = ''; |
| | |
| | | }; |
| | | |
| | | // replace content of row count display |
| | | this.set_rowcount = function(text) |
| | | this.set_rowcount = function(text, mbox) |
| | | { |
| | | // #1487752 |
| | | if (mbox && mbox != this.env.mailbox) |
| | | return false; |
| | | |
| | | $(this.gui_objects.countdisplay).html(text); |
| | | |
| | | // update page navigation buttons |
| | |
| | | var base = this.env.comm_path; |
| | | |
| | | // overwrite task name |
| | | if (query._action.match(/([a-z]+)\/([a-z-_.]+)/)) { |
| | | if (query._action.match(/([a-z]+)\/([a-z0-9-_.]+)/)) { |
| | | query._action = RegExp.$2; |
| | | base = base.replace(/\_task=[a-z]+/, '_task='+RegExp.$1); |
| | | } |
| | |
| | | } |
| | | }; |
| | | |
| | | rcube_webmail.long_subject_title_ie = function(elem, indent) |
| | | { |
| | | if (!elem.title) { |
| | | var $elem = $(elem), |
| | | txt = $.trim($elem.text()), |
| | | tmp = $('<span>').text(txt) |
| | | .css({'position': 'absolute', 'float': 'left', 'visibility': 'hidden', |
| | | 'font-size': $elem.css('font-size'), 'font-weight': $elem.css('font-weight')}) |
| | | .appendTo($('body')), |
| | | w = tmp.width(); |
| | | |
| | | tmp.remove(); |
| | | if (w + indent * 15 > $elem.width()) |
| | | elem.title = txt; |
| | | } |
| | | }; |
| | | |
| | | // copy event engine prototype |
| | | rcube_webmail.prototype.addEventListener = rcube_event_engine.prototype.addEventListener; |
| | | rcube_webmail.prototype.removeEventListener = rcube_event_engine.prototype.removeEventListener; |