| | |
| | | if (this.pending_message) |
| | | this.display_message(this.pending_message[0], this.pending_message[1], this.pending_message[2]); |
| | | |
| | | // map implicit containers |
| | | if (this.gui_objects.folderlist) { |
| | | this.gui_containers.foldertray = $(this.gui_objects.folderlist); |
| | | |
| | | // init treelist widget |
| | | if (window.rcube_treelist_widget) { |
| | | this.treelist = new rcube_treelist_widget(this.gui_objects.folderlist, { |
| | | // init treelist widget |
| | | if (this.gui_objects.folderlist && window.rcube_treelist_widget) { |
| | | this.treelist = new rcube_treelist_widget(this.gui_objects.folderlist, { |
| | | id_prefix: 'rcmli', |
| | | id_encode: this.html_identifier_encode, |
| | | id_decode: this.html_identifier_decode, |
| | | check_droptarget: function(node) { return !node.virtual && ref.check_droptarget(node.id) } |
| | | }); |
| | | this.treelist |
| | | .addEventListener('collapse', function(node) { ref.folder_collapsed(node) }) |
| | | .addEventListener('expand', function(node) { ref.folder_collapsed(node) }) |
| | | .addEventListener('select', function(node) { ref.triggerEvent('selectfolder', { folder:node.id, prefix:'rcmli' }) }); |
| | | } |
| | | }); |
| | | |
| | | this.treelist |
| | | .addEventListener('collapse', function(node) { ref.folder_collapsed(node) }) |
| | | .addEventListener('expand', function(node) { ref.folder_collapsed(node) }) |
| | | .addEventListener('select', function(node) { ref.triggerEvent('selectfolder', { folder:node.id, prefix:'rcmli' }) }); |
| | | } |
| | | |
| | | // activate html5 file drop feature (if browser supports it and if configured) |
| | |
| | | break; |
| | | |
| | | case 'list': |
| | | // re-send search query for the selected folder |
| | | if (props && props != '' && this.env.search_request && this.gui_objects.qsearchbox.value) { |
| | | var oldmbox = this.env.search_scope == 'all' ? '*' : this.env.mailbox; |
| | | this.env.search_mods[props] = this.env.search_mods[oldmbox]; // copy search mods from active search |
| | | this.env.mailbox = props; |
| | | this.env.search_scope = 'sub'; |
| | | this.qsearch(this.gui_objects.qsearchbox.value); |
| | | this.select_folder(this.env.mailbox, '', true); |
| | | break; |
| | | if (props && props != '') { |
| | | this.reset_qsearch(); |
| | | } |
| | | |
| | | if (this.env.action == 'compose' && this.env.extwin) |
| | | if (this.env.action == 'compose' && this.env.extwin) { |
| | | window.close(); |
| | | } |
| | | else if (this.task == 'mail') { |
| | | this.list_mailbox(props); |
| | | this.set_button_titles(); |
| | |
| | | list = this.message_list, |
| | | rows = list.rows, |
| | | message = this.env.messages[uid], |
| | | msg_id = this.html_identifier(uid,true), |
| | | row_class = 'message' |
| | | + (!flags.seen ? ' unread' : '') |
| | | + (flags.deleted ? ' deleted' : '') |
| | | + (flags.flagged ? ' flagged' : '') |
| | | + (message.selected ? ' selected' : ''), |
| | | row = { cols:[], style:{}, id:'rcmrow'+this.html_identifier(uid,true), uid:uid }; |
| | | row = { cols:[], style:{}, id:'rcmrow'+msg_id, uid:uid }; |
| | | |
| | | // message status icons |
| | | css_class = 'msgicon'; |
| | |
| | | if (this.env.threading) { |
| | | if (message.depth) { |
| | | // This assumes that div width is hardcoded to 15px, |
| | | tree += '<span id="rcmtab' + row.id + '" class="branch" style="width:' + (message.depth * 15) + 'px;"> </span>'; |
| | | tree += '<span id="rcmtab' + msg_id + '" class="branch" style="width:' + (message.depth * 15) + 'px;"> </span>'; |
| | | |
| | | if ((rows[message.parent_uid] && rows[message.parent_uid].expanded === false) |
| | | || ((this.env.autoexpand_threads == 0 || this.env.autoexpand_threads == 2) && |
| | |
| | | rows = this.message_list ? this.message_list.rows : {}; |
| | | |
| | | if (typeof uids == 'string') |
| | | uids = String(uids).split(','); |
| | | uids = uids.split(','); |
| | | |
| | | for (i=0, len=uids.length; i<len; i++) { |
| | | uid = uids[i]; |
| | |
| | | $(tinyMCE.get(props.id).getBody()).css('font-family', rcmail.env.default_font); |
| | | }, 500); |
| | | } |
| | | else { |
| | | var thisMCE = tinyMCE.get(props.id), existingHtml; |
| | | |
| | | if (existingHtml = thisMCE.getContent()) { |
| | | if (!confirm(this.get_label('editorwarning'))) { |
| | | return false; |
| | | } |
| | | this.html2plain(existingHtml, props.id); |
| | | } |
| | | else if (this.html2plain(tinyMCE.get(props.id).getContent(), props.id)) |
| | | tinyMCE.execCommand('mceRemoveControl', false, props.id); |
| | | } |
| | | |
| | | return true; |
| | | }; |
| | |
| | | this.ksearch_input.value = pre + insert + end; |
| | | |
| | | // set caret to insert pos |
| | | cpos = p+insert.length; |
| | | if (this.ksearch_input.setSelectionRange) |
| | | this.ksearch_input.setSelectionRange(cpos, cpos); |
| | | this.set_caret_pos(this.ksearch_input, p + insert.length); |
| | | |
| | | if (trigger) { |
| | | this.triggerEvent('autocomplete_insert', { field:this.ksearch_input, insert:insert, data:this.env.contacts[id] }); |
| | |
| | | |
| | | this.html2plain = function(htmlText, id) |
| | | { |
| | | // warn the user (if converted content is not empty) |
| | | if (!htmlText || !(htmlText.replace(/<[^>]+>| |\s/g, '')).length) { |
| | | // without setTimeout() here, textarea is filled with initial (onload) content |
| | | setTimeout(function() { $('#'+id).val(''); }, 50); |
| | | return true; |
| | | } |
| | | |
| | | if (!confirm(this.get_label('editorwarning'))) |
| | | return false; |
| | | |
| | | var url = '?_task=utils&_action=html2text', |
| | | lock = this.set_busy(true, 'converting'); |
| | | |
| | |
| | | error: function(o, status, err) { ref.http_error(o, status, err, lock); }, |
| | | success: function(data) { ref.set_busy(false, null, lock); $('#'+id).val(data); ref.log(data); } |
| | | }); |
| | | |
| | | return true; |
| | | }; |
| | | |
| | | this.plain2html = function(plain, id) |
| | |
| | | // helper method to send an HTTP request with the given iterator value |
| | | this.multi_thread_send_request = function(prop, item) |
| | | { |
| | | var postdata, query; |
| | | var k, postdata, query; |
| | | |
| | | // replace %s in post data |
| | | if (prop.postdata) { |
| | | postdata = {}; |
| | | for (var k in prop.postdata) { |
| | | for (k in prop.postdata) { |
| | | postdata[k] = String(prop.postdata[k]).replace('%s', item); |
| | | } |
| | | postdata._reqid = prop.reqid; |
| | |
| | | } |
| | | else if (typeof prop.query == 'object' && prop.query) { |
| | | query = {}; |
| | | for (var k in prop.query) { |
| | | for (k in prop.query) { |
| | | query[k] = String(prop.query[k]).replace('%s', item); |
| | | } |
| | | query._reqid = prop.reqid; |
| | |
| | | { |
| | | var msg = this.env.messages ? this.env.messages[uid] : {}; |
| | | return msg.mbox || this.env.mailbox; |
| | | } |
| | | }; |
| | | |
| | | // gets cursor position |
| | | this.get_caret_pos = function(obj) |
| | |
| | | if (obj.selectionEnd !== undefined) |
| | | return obj.selectionEnd; |
| | | |
| | | if (document.selection && document.selection.createRange) { |
| | | var range = document.selection.createRange(); |
| | | if (range.parentElement() != obj) |
| | | return 0; |
| | | |
| | | var gm = range.duplicate(); |
| | | if (obj.tagName == 'TEXTAREA') |
| | | gm.moveToElementText(obj); |
| | | else |
| | | gm.expand('textedit'); |
| | | |
| | | gm.setEndPoint('EndToStart', range); |
| | | var p = gm.text.length; |
| | | |
| | | return p <= obj.value.length ? p : -1; |
| | | } |
| | | |
| | | return obj.value.length; |
| | | }; |
| | | |
| | | // moves cursor to specified position |
| | | this.set_caret_pos = function(obj, pos) |
| | | { |
| | | if (obj.setSelectionRange) |
| | | obj.setSelectionRange(pos, pos); |
| | | else if (obj.createTextRange) { |
| | | var range = obj.createTextRange(); |
| | | range.collapse(true); |
| | | range.moveEnd('character', pos); |
| | | range.moveStart('character', pos); |
| | | range.select(); |
| | | try { |
| | | if (obj.setSelectionRange) |
| | | obj.setSelectionRange(pos, pos); |
| | | } |
| | | catch(e) {}; // catch Firefox exception if obj is hidden |
| | | }; |
| | | |
| | | // get selected text from an input field |
| | | // http://stackoverflow.com/questions/7186586/how-to-get-the-selected-text-in-textarea-using-jquery-in-internet-explorer-7 |
| | | this.get_input_selection = function(obj) |
| | | { |
| | | var start = 0, end = 0, |
| | | normalizedValue, range, |
| | | textInputRange, len, endRange; |
| | | var start = 0, end = 0, normalizedValue = ''; |
| | | |
| | | if (typeof obj.selectionStart == "number" && typeof obj.selectionEnd == "number") { |
| | | normalizedValue = obj.value; |
| | | start = obj.selectionStart; |
| | | end = obj.selectionEnd; |
| | | } |
| | | else { |
| | | range = document.selection.createRange(); |
| | | |
| | | if (range && range.parentElement() == obj) { |
| | | len = obj.value.length; |
| | | normalizedValue = obj.value; //.replace(/\r\n/g, "\n"); |
| | | |
| | | // create a working TextRange that lives only in the input |
| | | textInputRange = obj.createTextRange(); |
| | | textInputRange.moveToBookmark(range.getBookmark()); |
| | | |
| | | // Check if the start and end of the selection are at the very end |
| | | // of the input, since moveStart/moveEnd doesn't return what we want |
| | | // in those cases |
| | | endRange = obj.createTextRange(); |
| | | endRange.collapse(false); |
| | | |
| | | if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) { |
| | | start = end = len; |
| | | } |
| | | else { |
| | | start = -textInputRange.moveStart("character", -len); |
| | | start += normalizedValue.slice(0, start).split("\n").length - 1; |
| | | |
| | | if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) { |
| | | end = len; |
| | | } |
| | | else { |
| | | end = -textInputRange.moveEnd("character", -len); |
| | | end += normalizedValue.slice(0, end).split("\n").length - 1; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | return { start:start, end:end, text:normalizedValue.substr(start, end-start) }; |
| | | return {start: start, end: end, text: normalizedValue.substr(start, end-start)}; |
| | | }; |
| | | |
| | | // disable/enable all fields of a form |
| | |
| | | // remember which elem was disabled before lock |
| | | if (lock && elm.disabled) |
| | | this.disabled_form_elements.push(elm); |
| | | // check this.disabled_form_elements before inArray() as a workaround for FF5 bug |
| | | // http://bugs.jquery.com/ticket/9873 |
| | | else if (lock || (this.disabled_form_elements && $.inArray(elm, this.disabled_form_elements)<0)) |
| | | else if (lock || $.inArray(elm, this.disabled_form_elements) < 0) |
| | | elm.disabled = lock; |
| | | } |
| | | }; |