Changeset 8fa9229 in github
- Timestamp:
- Apr 16, 2010 9:46:54 AM (3 years ago)
- Branches:
- master, HEAD, courier-fix, dev-browser-capabilities, pdo, release-0.6, release-0.7, release-0.8
- Children:
- c287f34
- Parents:
- 186537b
- Location:
- program/js
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
program/js/app.js
r186537b r8fa9229 21 21 function rcube_webmail() 22 22 { 23 this.env = new Object();24 this.labels = new Object();25 this.buttons = new Object();26 this.buttons_sel = new Object();27 this.gui_objects = new Object();28 this.gui_containers = new Object();29 this.commands = new Object();30 this.command_handlers = new Object();31 this.onloads = new Array();23 this.env = {}; 24 this.labels = {}; 25 this.buttons = {}; 26 this.buttons_sel = {}; 27 this.gui_objects = {}; 28 this.gui_containers = {}; 29 this.commands = {}; 30 this.command_handlers = {}; 31 this.onloads = []; 32 32 33 33 // create protected reference to myself 34 34 this.ref = 'rcmail'; 35 35 var ref = this; 36 36 37 37 // webmail client settings 38 38 this.dblclick_time = 500; 39 39 this.message_time = 3000; 40 40 41 41 this.identifier_expr = new RegExp('[^0-9a-z\-_]', 'gi'); 42 42 43 43 // mimetypes supported by the browser (default settings) 44 44 this.mimetypes = new Array('text/plain', 'text/html', 'text/xml', 45 'image/jpeg', 'image/gif', 'image/png', 46 'application/x-javascript', 'application/pdf', 47 'application/x-shockwave-flash'); 45 'image/jpeg', 'image/gif', 'image/png', 46 'application/x-javascript', 'application/pdf', 'application/x-shockwave-flash'); 48 47 49 48 // default environment vars … … 56 55 57 56 // set jQuery ajax options 58 jQuery.ajaxSetup({57 $.ajaxSetup({ 59 58 cache:false, 60 59 error:function(request, status, err){ ref.http_error(request, status, err); }, … … 64 63 // set environment variable(s) 65 64 this.set_env = function(p, value) 66 {65 { 67 66 if (p != null && typeof(p) == 'object' && !value) 68 67 for (var n in p) … … 70 69 else 71 70 this.env[p] = value; 72 };71 }; 73 72 74 73 // add a localized label to the client environment 75 74 this.add_label = function(key, value) 76 {75 { 77 76 this.labels[key] = value; 78 };77 }; 79 78 80 79 // add a button to the button list 81 80 this.register_button = function(command, id, type, act, sel, over) 82 {81 { 83 82 if (!this.buttons[command]) 84 this.buttons[command] = new Array();85 83 this.buttons[command] = []; 84 86 85 var button_prop = {id:id, type:type}; 87 86 if (act) button_prop.act = act; … … 90 89 91 90 this.buttons[command][this.buttons[command].length] = button_prop; 92 };91 }; 93 92 94 93 // register a specific gui object 95 94 this.gui_object = function(name, id) 96 {95 { 97 96 this.gui_objects[name] = id; 98 };99 97 }; 98 100 99 // register a container object 101 100 this.gui_container = function(name, id) … … 103 102 this.gui_containers[name] = id; 104 103 }; 105 104 106 105 // add a GUI element (html node) to a specified container 107 106 this.add_element = function(elm, container) … … 115 114 { 116 115 this.command_handlers[command] = callback; 117 116 118 117 if (enable) 119 118 this.enable_command(command, true); 120 119 }; 121 120 122 121 // execute the given script on load 123 122 this.add_onload = function(f) … … 128 127 // initialize webmail client 129 128 this.init = function() 130 {129 { 131 130 var p = this; 132 131 this.task = this.env.task; 133 132 134 133 // check browser 135 134 if (!bw.dom || !bw.xmlhttp_test()) { 136 135 this.goto_url('error', '_code=0x199'); 137 136 return; 138 }137 } 139 138 140 139 // find all registered gui containers … … 145 144 for (var n in this.gui_objects) 146 145 this.gui_objects[n] = rcube_find_object(this.gui_objects[n]); 147 146 148 147 // init registered buttons 149 148 this.init_buttons(); … … 155 154 // enable general commands 156 155 this.enable_command('logout', 'mail', 'addressbook', 'settings', true); 157 156 158 157 if (this.env.permaurl) 159 158 this.enable_command('permaurl', true); 160 159 161 switch (this.task) 162 { 160 switch (this.task) { 161 163 162 case 'mail': 164 163 // enable mail commands 165 164 this.enable_command('list', 'checkmail', 'compose', 'add-contact', 'search', 'reset-search', 'collapse-folder', true); 166 167 if (this.gui_objects.messagelist) 168 { 165 166 if (this.gui_objects.messagelist) { 167 169 168 this.message_list = new rcube_list_widget(this.gui_objects.messagelist, 170 169 {multiselect:true, multiexpand:true, draggable:true, keyboard:true, dblclick_time:this.dblclick_time}); … … 185 184 this.message_list.init(); 186 185 this.enable_command('toggle_status', 'toggle_flag', 'menu-open', 'menu-save', true); 187 186 188 187 // load messages 189 188 if (this.env.messagecount) 190 189 this.command('list'); 191 }190 } 192 191 193 192 if (this.gui_objects.qsearchbox) { 194 193 if (this.env.search_text != null) { 195 194 this.gui_objects.qsearchbox.value = this.env.search_text; 196 }195 } 197 196 $(this.gui_objects.qsearchbox).focusin(function() { rcmail.message_list.blur(); }); 198 }197 } 199 198 200 199 if (this.env.trash_mailbox && this.env.mailbox != this.env.trash_mailbox) … … 208 207 this.enable_command('nextmessage', true); 209 208 this.enable_command('lastmessage', true); 210 }209 } 211 210 if (this.env.prev_uid) { 212 211 this.enable_command('previousmessage', true); 213 212 this.enable_command('firstmessage', true); 214 }215 213 } 214 216 215 if (this.env.blockedobjects) { 217 216 if (this.gui_objects.remoteobjectsmsg) 218 217 this.gui_objects.remoteobjectsmsg.style.display = 'block'; 219 218 this.enable_command('load-images', 'always-load', true); 220 }219 } 221 220 222 221 // make preview/message frame visible … … 224 223 this.enable_command('compose', 'add-contact', false); 225 224 parent.rcmail.show_contentframe(true); 226 }227 225 } 226 } 228 227 else if (this.env.action == 'compose') { 229 228 this.enable_command('add-attachment', 'send-attachment', 'remove-attachment', 'send', true); … … 234 233 if ($("input[name='_is_html']").val() == '1') 235 234 this.display_spellcheck_controls(false); 236 }235 } 237 236 238 237 if (this.env.drafts_mailbox) 239 238 this.enable_command('savedraft', true); 240 239 241 240 document.onmouseup = function(e){ return p.doc_mouse_up(e); }; 242 241 243 242 // init message compose form 244 243 this.init_messageform(); 245 }244 } 246 245 // show printing dialog 247 246 else if (this.env.action == 'print') … … 251 250 this.enable_command('select-all', 'select-none', 'expunge', true); 252 251 this.enable_command('expand-all', 'expand-unread', 'collapse-all', this.env.threading); 253 }252 } 254 253 255 254 if (this.purge_mailbox_test()) … … 263 262 this.gui_objects.folderlist = this.gui_objects.mailboxlist; 264 263 this.http_request('getunread', ''); 265 }266 264 } 265 267 266 // ask user to send MDN 268 267 if (this.env.mdn_request && this.env.uid) { … … 272 271 else 273 272 this.http_post('mark', mdnurl+'&_flag=mdnsent'); 274 }273 } 275 274 276 275 break; … … 280 279 if (this.gui_objects.folderlist) 281 280 this.env.contactfolders = $.extend($.extend({}, this.env.address_sources), this.env.contactgroups); 282 283 if (this.gui_objects.contactslist) 284 { 281 282 if (this.gui_objects.contactslist) { 283 285 284 this.contact_list = new rcube_list_widget(this.gui_objects.contactslist, 286 285 {multiselect:true, draggable:this.gui_objects.folderlist?true:false, keyboard:true}); … … 300 299 if (this.gui_objects.qsearchbox) { 301 300 $(this.gui_objects.qsearchbox).focusin(function() { rcmail.contact_list.blur(); }); 302 }303 301 } 302 } 304 303 305 304 this.set_page_buttons(); 306 305 307 306 if (this.env.address_sources && this.env.address_sources[this.env.source] && !this.env.address_sources[this.env.source].readonly) { 308 307 this.enable_command('add', 'import', true); 309 308 this.enable_command('group-create', this.env.address_sources[this.env.source].groups); 310 309 } 311 310 312 311 if (this.env.cid) 313 312 this.enable_command('show', 'edit', true); … … 317 316 else 318 317 this.enable_command('search', 'reset-search', 'moveto', true); 319 318 320 319 if (this.contact_list && this.contact_list.rowcount > 0) 321 320 this.enable_command('export', true); … … 327 326 case 'settings': 328 327 this.enable_command('preferences', 'identities', 'save', 'folders', true); 329 328 330 329 if (this.env.action=='identities') { 331 330 this.enable_command('add', this.env.identities_level < 2); … … 363 362 var input_user = $('#rcmloginuser'); 364 363 input_user.bind('keyup', function(e){ return rcmail.login_user_keyup(e); }); 365 364 366 365 if (input_user.val() == '') 367 366 input_user.focus(); … … 374 373 this.enable_command('login', true); 375 374 break; 376 375 377 376 default: 378 377 break; … … 385 384 if (this.pending_message) 386 385 this.display_message(this.pending_message[0], this.pending_message[1]); 387 386 388 387 // map implicit containers 389 388 if (this.gui_objects.folderlist) … … 392 391 // trigger init event hook 393 392 this.triggerEvent('init', { task:this.task, action:this.env.action }); 394 393 395 394 // execute all foreign onload scripts 396 395 // @deprecated … … 413 412 // execute a specific command on the web client 414 413 this.command = function(command, props, obj) 415 {414 { 416 415 if (obj && obj.blur) 417 416 obj.blur(); … … 421 420 422 421 // command not supported or allowed 423 if (!this.commands[command]) 424 { 422 if (!this.commands[command]) { 425 423 // pass command to parent window 426 424 if (this.env.framed && parent.rcmail && parent.rcmail.command) … … 428 426 429 427 return false; 430 }431 432 // check input before leaving compose step433 if (this.task=='mail' && this.env.action=='compose' && (command=='list' || command=='mail' || command=='addressbook' || command=='settings'))434 {435 if (this.cmp_hash != this.compose_field_hash() && !confirm(this.get_label('notsentwarning')))428 } 429 430 // check input before leaving compose step 431 if (this.task=='mail' && this.env.action=='compose' 432 && (command == 'list' || command == 'mail' || command == 'addressbook' || command == 'settings')) { 433 if (this.cmp_hash != this.compose_field_hash() && !confirm(this.get_label('notsentwarning'))) 436 434 return false; 437 }435 } 438 436 439 437 // process external commands 440 if (typeof this.command_handlers[command] == 'function') 441 { 438 if (typeof this.command_handlers[command] == 'function') { 442 439 var ret = this.command_handlers[command](props, obj); 443 440 return ret !== null ? ret : (obj ? false : true); 444 441 } 445 else if (typeof this.command_handlers[command] == 'string') 446 { 442 else if (typeof this.command_handlers[command] == 'string') { 447 443 var ret = window[this.command_handlers[command]](props, obj); 448 444 return ret !== null ? ret : (obj ? false : true); 449 445 } 450 446 451 447 // trigger plugin hook 452 448 var event_ret = this.triggerEvent('before'+command, props); … … 460 456 461 457 // process internal command 462 switch (command) 463 { 458 switch (command) { 459 464 460 case 'login': 465 461 if (this.gui_objects.loginform) … … 610 606 case 'save-identity': 611 607 case 'save': 612 if (this.gui_objects.editform) 613 { 608 if (this.gui_objects.editform) { 614 609 var input_pagesize = $("input[name='_pagesize']"); 615 610 var input_name = $("input[name='_name']"); … … 617 612 618 613 // user prefs 619 if (input_pagesize.length && isNaN(parseInt(input_pagesize.val()))) 620 { 614 if (input_pagesize.length && isNaN(parseInt(input_pagesize.val()))) { 621 615 alert(this.get_label('nopagesizewarning')); 622 616 input_pagesize.focus(); 623 617 break; 624 }618 } 625 619 // contacts/identities 626 else 627 { 628 if (input_name.length && input_name.val() == '') 629 { 620 else { 621 if (input_name.length && input_name.val() == '') { 630 622 alert(this.get_label('nonamewarning')); 631 623 input_name.focus(); 632 624 break; 633 } 634 else if (input_email.length && !rcube_check_email(input_email.val())) 635 { 625 } 626 else if (input_email.length && !rcube_check_email(input_email.val())) { 636 627 alert(this.get_label('noemailwarning')); 637 628 input_email.focus(); 638 629 break; 639 }640 630 } 631 } 641 632 642 633 this.gui_objects.editform.submit(); 643 }634 } 644 635 break; 645 636 … … 674 665 this.mark_message(props); 675 666 break; 676 667 677 668 case 'toggle_status': 678 669 if (props && !props._row) 679 670 break; 680 681 var uid; 682 var flag = 'read'; 683 671 672 var uid, flag = 'read'; 673 684 674 if (props._row.uid) { 685 675 uid = props._row.uid; 686 676 687 677 // toggle read/unread 688 678 if (this.message_list.rows[uid].deleted) { … … 692 682 flag = 'unread'; 693 683 } 694 684 695 685 this.mark_message(flag, uid); 696 686 break; 697 687 698 688 case 'toggle_flag': 699 689 if (props && !props._row) 700 690 break; 701 691 702 var uid; 703 var flag = 'flagged'; 692 var uid, flag = 'flagged'; 704 693 705 694 if (props._row.uid) { … … 718 707 break; 719 708 } 720 709 721 710 case 'load-images': 722 711 if (this.env.uid) … … 726 715 case 'load-attachment': 727 716 var qstring = '_mbox='+urlencode(this.env.mailbox)+'&_uid='+this.env.uid+'&_part='+props.part; 728 717 729 718 // open attachment in frame if it's of a supported mimetype 730 if (this.env.uid && props.mimetype && jQuery.inArray(props.mimetype, this.mimetypes)>=0) {719 if (this.env.uid && props.mimetype && $.inArray(props.mimetype, this.mimetypes)>=0) { 731 720 if (props.mimetype == 'text/html') 732 721 qstring += '&_safe=1'; … … 740 729 this.goto_url('get', qstring+'&_download=1', false); 741 730 break; 742 731 743 732 case 'select-all': 744 733 this.select_all_mode = props ? false : true; … … 788 777 this.show_message(this.env.first_uid); 789 778 break; 790 779 791 780 case 'checkmail': 792 781 this.check_for_recent(true); 793 782 break; 794 783 795 784 case 'compose': 796 785 var url = this.env.comm_path+'&_action=compose'; 797 786 798 787 if (this.task=='mail') { 799 788 url += '&_mbox='+urlencode(this.env.mailbox); 800 789 801 790 if (this.env.mailbox==this.env.drafts_mailbox) { 802 791 var uid; … … 815 804 break; 816 805 } 817 806 818 807 // use contact_id passed as command parameter 819 var a_cids = new Array();808 var a_cids = []; 820 809 if (props) 821 810 a_cids[a_cids.length] = props; … … 826 815 a_cids[a_cids.length] = selection[n]; 827 816 } 828 817 829 818 if (a_cids.length) 830 819 this.http_request('mailto', '_cid='+urlencode(a_cids.join(','))+'&_source='+urlencode(this.env.source), true); … … 838 827 this.redirect(url); 839 828 break; 840 829 841 830 case 'spellcheck': 842 831 if (window.tinyMCE && tinyMCE.get(this.env.composebody)) { … … 884 873 form._draft.value = ''; 885 874 form.submit(); 886 875 887 876 // clear timeout (sending could take longer) 888 877 clearTimeout(this.request_timer); … … 891 880 case 'add-attachment': 892 881 this.show_attachment_form(true); 893 882 894 883 case 'send-attachment': 895 884 // Reset the auto-save timer … … 898 887 this.upload_file(props) 899 888 break; 900 889 901 890 case 'remove-attachment': 902 891 this.remove_attachment(props); … … 919 908 this.goto_url('compose', '_forward_uid='+uid+'&_mbox='+urlencode(this.env.mailbox), true); 920 909 break; 921 910 922 911 case 'print': 923 912 var uid; 924 if (uid = this.get_single_uid()) 925 { 913 if (uid = this.get_single_uid()) { 926 914 ref.printwin = window.open(this.env.comm_path+'&_action=print&_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)+(this.env.safemode ? '&_safe=1' : '')); 927 if (this.printwin) 928 { 915 if (this.printwin) { 929 916 window.setTimeout(function(){ ref.printwin.focus(); }, 20); 930 917 if (this.env.action != 'show') … … 936 923 case 'viewsource': 937 924 var uid; 938 if (uid = this.get_single_uid()) 939 { 925 if (uid = this.get_single_uid()) { 940 926 ref.sourcewin = window.open(this.env.comm_path+'&_action=viewsource&_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)); 941 927 if (this.sourcewin) … … 958 944 if (!props && this.gui_objects.qsearchbox) 959 945 props = this.gui_objects.qsearchbox.value; 960 if (props) 961 { 946 if (props) { 962 947 this.qsearch(props); 963 948 break; … … 968 953 var s = this.env.search_request; 969 954 this.reset_qsearch(); 970 955 971 956 if (s && this.env.mailbox) 972 957 this.list_mailbox(this.env.mailbox); … … 978 963 this.add_contact_group(props) 979 964 break; 980 965 981 966 case 'group-rename': 982 967 this.rename_contact_group(); 983 968 break; 984 969 985 970 case 'group-delete': 986 971 this.delete_contact_group(); … … 1001 986 this.goto_url('import', (this.env.source ? '_target='+urlencode(this.env.source)+'&' : '')); 1002 987 break; 1003 988 1004 989 case 'export': 1005 990 if (this.contact_list.rowcount > 0) { … … 1007 992 if (this.env.search_request) 1008 993 add_url += '_search='+this.env.search_request; 1009 994 1010 995 this.goto_url('export', add_url); 1011 996 } … … 1026 1011 this.goto_url('identities'); 1027 1012 break; 1028 1013 1029 1014 case 'delete-identity': 1030 1015 this.delete_identity(); 1031 1016 1032 1017 case 'folders': 1033 1018 this.goto_url('folders'); … … 1062 1047 break; 1063 1048 1064 }1065 1049 } 1050 1066 1051 this.triggerEvent('after'+command, props); 1067 1052 1068 1053 return obj ? false : true; 1069 };1054 }; 1070 1055 1071 1056 // set command enabled or disabled 1072 1057 this.enable_command = function() 1073 {1058 { 1074 1059 var args = arguments; 1075 if(!args.length) return -1; 1076 1077 var command; 1078 var enable = args[args.length-1]; 1079 1080 for(var n=0; n<args.length-1; n++) 1081 { 1060 if (!args.length) 1061 return -1; 1062 1063 var command, enable = args[args.length-1]; 1064 1065 for (var n=0; n<args.length-1; n++) { 1082 1066 command = args[n]; 1083 1067 this.commands[command] = enable; 1084 1068 this.set_button(command, (enable ? 'act' : 'pas')); 1085 }1086 return true;1087 };1069 } 1070 return true; 1071 }; 1088 1072 1089 1073 // lock/unlock interface 1090 1074 this.set_busy = function(a, message) 1091 { 1092 if (a && message) 1093 { 1075 { 1076 if (a && message) { 1094 1077 var msg = this.get_label(message); 1095 1078 if (msg==message) … … 1097 1080 1098 1081 this.display_message(msg, 'loading', true); 1099 }1082 } 1100 1083 else if (!a) 1101 1084 this.hide_message(); … … 1103 1086 this.busy = a; 1104 1087 //document.body.style.cursor = a ? 'wait' : 'default'; 1105 1088 1106 1089 if (this.gui_objects.editform) 1107 1090 this.lock_form(this.gui_objects.editform, a); 1108 1091 1109 1092 // clear pending timer 1110 1093 if (this.request_timer) … … 1114 1097 if (a && this.env.request_timeout) 1115 1098 this.request_timer = window.setTimeout(function(){ ref.request_timed_out(); }, this.env.request_timeout * 1000); 1116 };1099 }; 1117 1100 1118 1101 // return a localized string 1119 1102 this.get_label = function(name, domain) 1120 {1103 { 1121 1104 if (domain && this.labels[domain+'.'+name]) 1122 1105 return this.labels[domain+'.'+name]; … … 1125 1108 else 1126 1109 return name; 1127 };1128 1110 }; 1111 1129 1112 // alias for convenience reasons 1130 1113 this.gettext = this.get_label; … … 1132 1115 // switch to another application task 1133 1116 this.switch_task = function(task) 1134 {1117 { 1135 1118 if (this.task===task && task!='mail') 1136 1119 return; … … 1141 1124 1142 1125 this.redirect(url); 1143 };1126 }; 1144 1127 1145 1128 this.get_task_url = function(task, url) 1146 {1129 { 1147 1130 if (!url) 1148 1131 url = this.env.comm_path; 1149 1132 1150 1133 return url.replace(/_task=[a-z]+/, '_task='+task); 1151 };1152 1134 }; 1135 1153 1136 // called when a request timed out 1154 1137 this.request_timed_out = function() 1155 {1138 { 1156 1139 this.set_busy(false); 1157 1140 this.display_message('Request timed out!', 'error'); 1158 };1159 1141 }; 1142 1160 1143 this.reload = function(delay) 1161 1144 { … … 1175 1158 this.drag_menu = function(e, target) 1176 1159 { 1177 var modkey = rcube_event.get_modifier(e) ;1178 varmenu = $('#'+this.gui_objects.message_dragmenu);1160 var modkey = rcube_event.get_modifier(e), 1161 menu = $('#'+this.gui_objects.message_dragmenu); 1179 1162 1180 1163 if (menu && modkey == SHIFT_KEY && this.commands['copy']) { … … 1184 1167 return true; 1185 1168 } 1186 1169 1187 1170 return false; 1188 1171 }; … … 1205 1188 if (this.preview_timer) 1206 1189 clearTimeout(this.preview_timer); 1207 1190 1208 1191 if (this.preview_read_timer) 1209 1192 clearTimeout(this.preview_read_timer); … … 1220 1203 this.env.folderlist_coords = { x1:pos.left, y1:pos.top, x2:pos.left + list.width(), y2:pos.top + list.height() }; 1221 1204 1222 this.env.folder_coords = new Array();1205 this.env.folder_coords = []; 1223 1206 for (var k in model) { 1224 1207 if (li = this.get_folder_li(k)) { … … 1238 1221 this.drag_active = false; 1239 1222 this.env.last_folder_target = null; 1240 1223 1241 1224 if (this.folder_auto_timer) { 1242 1225 window.clearTimeout(this.folder_auto_timer); … … 1253 1236 } 1254 1237 }; 1255 1238 1256 1239 this.drag_move = function(e) 1257 1240 { … … 1261 1244 var moffset = this.initialListScrollTop-this.gui_objects.folderlist.parentNode.scrollTop; 1262 1245 var toffset = -moffset-boffset; 1263 1264 1246 var li, div, pos, mouse; 1247 1265 1248 mouse = rcube_event.get_mouse_pos(e); 1266 1249 pos = this.env.folderlist_coords; … … 1276 1259 return; 1277 1260 } 1278 1261 1279 1262 // over the folders 1280 1263 for (var k in this.env.folder_coords) { … … 1290 1273 if (this.folder_auto_timer) 1291 1274 window.clearTimeout(this.folder_auto_timer); 1292 1275 1293 1276 this.folder_auto_expand = k; 1294 1277 this.folder_auto_timer = window.setTimeout(function() { … … 1301 1284 this.folder_auto_expand = null; 1302 1285 } 1303 1286 1304 1287 $(li).addClass('droptarget'); 1305 1288 this.env.last_folder_target = k; … … 1316 1299 this.collapse_folder = function(id) 1317 1300 { 1318 var li = this.get_folder_li(id) ;1319 vardiv = $(li.getElementsByTagName('div')[0]);1320 1301 var li = this.get_folder_li(id), 1302 div = $(li.getElementsByTagName('div')[0]); 1303 1321 1304 if (!div || (!div.hasClass('collapsed') && !div.hasClass('expanded'))) 1322 1305 return; 1323 1306 1324 1307 var ul = $(li.getElementsByTagName('ul')[0]); 1308 1325 1309 if (div.hasClass('collapsed')) { 1326 1310 ul.show(); … … 1379 1363 if (this.drag_active && model && this.env.last_folder_target) { 1380 1364 var target = model[this.env.last_folder_target]; 1381 1365 1382 1366 $(this.get_folder_li(this.env.last_folder_target)).removeClass('droptarget'); 1383 1367 this.env.last_folder_target = null; … … 1490 1474 this.show_contentframe(false); 1491 1475 }; 1492 1476 1493 1477 this.msglist_expand = function(row) 1494 1478 { … … 1496 1480 this.env.messages[row.uid].expanded = row.expanded; 1497 1481 }; 1498 1482 1499 1483 this.check_droptarget = function(id) 1500 1484 { … … 1516 1500 this.init_message_row = function(row) 1517 1501 { 1518 var self = this; 1519 var uid = row.uid; 1520 1502 var self = this, uid = row.uid; 1503 1521 1504 if (uid && this.env.messages[uid]) 1522 1505 $.extend(row, this.env.messages[uid]); … … 1552 1535 else 1553 1536 var tbody = this.gui_objects.messagelist.tBodies[0]; 1554 1555 var rows = this.message_list.rows;1556 var rowcount = tbody.rows.length;1557 var even = rowcount%2;1558 1537 1559 1538 if (!this.env.messages[uid]) … … 1573 1552 }); 1574 1553 1575 var message = this.env.messages[uid]; 1576 1577 var css_class = 'message' 1554 var tree = expando = '', 1555 rows = this.message_list.rows, 1556 rowcount = tbody.rows.length, 1557 even = rowcount%2, 1558 message = this.env.messages[uid], 1559 css_class = 'message' 1578 1560 + (even ? ' even' : ' odd') 1579 1561 + (flags.unread ? ' unread' : '') … … 1581 1563 + (flags.flagged ? ' flagged' : '') 1582 1564 + (flags.unread_children && !flags.unread && !this.env.autoexpand_threads ? ' unroot' : '') 1583 + (this.message_list.in_selection(uid) ? ' selected' : ''); 1584 1585 // for performance use DOM instead of jQuery here 1586 var row = document.createElement('tr'); 1565 + (this.message_list.in_selection(uid) ? ' selected' : ''), 1566 // for performance use DOM instead of jQuery here 1567 row = document.createElement('tr'), 1568 col = document.createElement('td'); 1569 1587 1570 row.id = 'rcmrow'+uid; 1588 1571 row.className = css_class; 1589 1572 1573 // message status icon 1590 1574 var icon = this.env.messageicon; 1591 1575 if (!flags.unread && flags.unread_children > 0 && this.env.unreadchildrenicon) … … 1604 1588 icon = this.env.unreadicon; 1605 1589 1606 var tree = expando = ''; 1607 1590 // threads 1608 1591 if (this.env.threading) { 1609 1592 // This assumes that div width is hardcoded to 15px, … … 1632 1615 1633 1616 tree += icon ? '<img id="msgicn'+uid+'" src="'+icon+'" alt="" class="msgicon" />' : ''; 1634 1617 1635 1618 // first col is always there 1636 var col = document.createElement('td');1637 1619 col.className = 'threads'; 1638 1620 col.innerHTML = expando; 1639 1621 row.appendChild(col); 1640 1622 1641 1623 // build subject link 1642 1624 if (!bw.ie && cols.subject) { … … 1695 1677 if (sort_col) 1696 1678 $('#rcm'+sort_col).addClass('sorted'+sort_order); 1697 1679 1698 1680 this.env.sort_col = sort_col; 1699 1681 this.env.sort_order = sort_order; … … 1708 1690 this.set_list_sorting(sort_col, sort_order); 1709 1691 } 1710 1692 1711 1693 if (this.env.threading != threads) { 1712 1694 update = 1; … … 1797 1779 if (page > 0 && page <= this.env.pagecount) { 1798 1780 this.env.current_page = page; 1799 1781 1800 1782 if (this.task=='mail') 1801 1783 this.list_mailbox(this.env.mailbox, page); … … 1866 1848 return; 1867 1849 } 1868 1850 1869 1851 if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) { 1870 1852 target = window.frames[this.env.contentframe]; … … 1897 1879 var new_row = tbody.firstChild; 1898 1880 var r; 1899 1881 1900 1882 while (new_row) { 1901 1883 if (new_row.nodeType == 1 && (r = this.message_list.rows[new_row.uid]) … … 1936 1918 } 1937 1919 // this.message_list.expand(null); 1938 } 1920 }; 1939 1921 1940 1922 // update parent in a thread … … 1945 1927 1946 1928 var root = this.message_list.find_root(uid); 1947 1929 1948 1930 if (uid == root) 1949 1931 return; … … 1975 1957 var depth = rows[uid].depth; 1976 1958 var r, parent, count = 0; 1977 var roots = new Array();1959 var roots = []; 1978 1960 1979 1961 if (!row.depth) // root message: decrease roots count … … 2024 2006 row = row.nextSibling; 2025 2007 } 2026 2008 2027 2009 // update unread_children for roots 2028 2010 for (var i=0; i<roots.length; i++) … … 2038 2020 var row = tbody.firstChild; 2039 2021 var cnt = this.env.pagesize + 1; 2040 2022 2041 2023 while (row) { 2042 2024 if (row.nodeType == 1 && (r = rows[row.uid])) { … … 2076 2058 else if (this.env.messageicon) 2077 2059 icn_src = this.env.messageicon; 2078 2060 2079 2061 if (icn_src && rows[uid].icon) 2080 2062 rows[uid].icon.src = icn_src; 2081 2063 2082 2064 icn_src = ''; 2083 2065 2084 2066 if (rows[uid].flagged && this.env.flaggedicon) 2085 2067 icn_src = this.env.flaggedicon; … … 2117 2099 2118 2100 if (!rows[uid]) return false; 2119 2101 2120 2102 if (flag) 2121 2103 this.set_message_status(uid, flag, status); … … 2127 2109 else if (!rows[uid].unread && rowobj.hasClass('unread')) 2128 2110 rowobj.removeClass('unread'); 2129 2111 2130 2112 if (rows[uid].deleted && !rowobj.hasClass('deleted')) 2131 2113 rowobj.addClass('deleted'); … … 2164 2146 2165 2147 var add_url = '&_target_mbox='+urlencode(mbox)+'&_from='+(this.env.action ? this.env.action : ''); 2166 var a_uids = new Array();2148 var a_uids = []; 2167 2149 2168 2150 if (this.env.uid) … … 2186 2168 if (mbox && typeof mbox == 'object') 2187 2169 mbox = mbox.id; 2188 2170 2189 2171 // exit if current or no mailbox specified or if selection is empty 2190 2172 if (!mbox || mbox == this.env.mailbox || (!this.env.uid && (!this.message_list || !this.message_list.get_selection().length))) … … 2211 2193 this.delete_messages = function() 2212 2194 { 2213 var selection = this.message_list ? $.merge([], this.message_list.get_selection()) : new Array();2195 var selection = this.message_list ? $.merge([], this.message_list.get_selection()) : []; 2214 2196 2215 2197 // exit if no mailbox specified or if selection is empty 2216 2198 if (!this.env.uid && !selection.length) 2217 2199 return; 2218 2200 2219 2201 // also select childs of collapsed rows 2220 2202 for (var uid, i=0; i < selection.length; i++) { … … 2223 2205 this.message_list.select_childs(uid); 2224 2206 } 2225 2207 2226 2208 // if config is set to flag for deletion 2227 2209 if (this.env.flag_for_deletion) { … … 2252 2234 if (!this.env.uid && (!this.message_list || !this.message_list.get_selection().length)) 2253 2235 return; 2254 2236 2255 2237 this.show_contentframe(false); 2256 2238 this._with_selected_messages('delete', false, '&_from='+(this.env.action ? this.env.action : '')); … … 2261 2243 this._with_selected_messages = function(action, lock, add_url) 2262 2244 { 2263 var a_uids = new Array(), 2264 count = 0; 2245 var a_uids = [], count = 0; 2265 2246 2266 2247 if (this.env.uid) … … 2302 2283 this.mark_message = function(flag, uid) 2303 2284 { 2304 var a_uids = new Array(), 2305 r_uids = new Array(), 2306 selection = this.message_list ? this.message_list.get_selection() : new Array(); 2285 var a_uids = [], r_uids = [], 2286 selection = this.message_list ? this.message_list.get_selection() : []; 2307 2287 2308 2288 if (uid) … … 2374 2354 this.http_post('mark', '_uid='+this.uids_to_list(a_uids)+'&_flag='+flag); 2375 2355 }; 2376 2356 2377 2357 // mark all message rows as deleted/undeleted 2378 2358 this.toggle_delete_status = function(a_uids) 2379 2359 { 2380 var rows = this.message_list ? this.message_list.rows : new Array(); 2381 2382 if (a_uids.length==1) 2383 { 2360 var rows = this.message_list ? this.message_list.rows : []; 2361 2362 if (a_uids.length==1) { 2384 2363 if (!rows.length || (rows[a_uids[0]] && !rows[a_uids[0]].deleted)) 2385 2364 this.flag_as_deleted(a_uids); … … 2389 2368 return true; 2390 2369 } 2391 2370 2392 2371 var all_deleted = true; 2393 for (var uid, i=0; i<a_uids.length; i++) 2394 { 2372 for (var uid, i=0; i<a_uids.length; i++) { 2395 2373 uid = a_uids[i]; 2396 2374 if (rows[uid] && !rows[uid].deleted) { … … 2399 2377 } 2400 2378 } 2401 2379 2402 2380 if (all_deleted) 2403 2381 this.flag_as_undeleted(a_uids); 2404 2382 else 2405 2383 this.flag_as_deleted(a_uids); 2406 2384 2407 2385 return true; 2408 2386 }; … … 2420 2398 { 2421 2399 var add_url = '', 2422 r_uids = new Array(),2423 rows = this.message_list ? this.message_list.rows : new Array(),2400 r_uids = [], 2401 rows = this.message_list ? this.message_list.rows : [], 2424 2402 count = 0; 2425 2403 … … 2451 2429 2452 2430 add_url = '&_from='+(this.env.action ? this.env.action : ''); 2453 2431 2454 2432 // ?? 2455 2433 if (r_uids.length) … … 2463 2441 add_url += '&_next_uid='+this.env.next_uid; 2464 2442 } 2465 2443 2466 2444 this.http_post('mark', '_uid='+this.uids_to_list(a_uids)+'&_flag=delete'+add_url); 2467 2445 return true; … … 2473 2451 { 2474 2452 var icn_src, uid, 2475 rows = this.message_list ? this.message_list.rows : new Array(),2453 rows = this.message_list ? this.message_list.rows : [], 2476 2454 str = String(uids), 2477 2455 a_uids = str.split(','); … … 2481 2459 if (rows[uid]) 2482 2460 this.set_message(uid, 'unread', false); 2483 }2461 } 2484 2462 }; 2485 2463 … … 2490 2468 return this.select_all_mode ? '*' : uids.join(','); 2491 2469 }; 2492 2470 2493 2471 2494 2472 /*********************************************************/ … … 2497 2475 2498 2476 this.expunge_mailbox = function(mbox) 2499 {2477 { 2500 2478 var lock = false; 2501 2479 var add_url = ''; 2502 2480 2503 2481 // lock interface if it's the active mailbox 2504 if (mbox == this.env.mailbox) 2505 { 2482 if (mbox == this.env.mailbox) { 2506 2483 lock = true; 2507 2484 this.set_busy(true, 'loading'); 2508 2485 add_url = '&_reload=1'; 2509 }2486 } 2510 2487 2511 2488 // send request to server 2512 2489 var url = '_mbox='+urlencode(mbox); 2513 2490 this.http_post('expunge', url+add_url, lock); 2514 };2491 }; 2515 2492 2516 2493 this.purge_mailbox = function(mbox) 2517 {2494 { 2518 2495 var lock = false; 2519 2496 var add_url = ''; 2520 2497 2521 2498 if (!confirm(this.get_label('purgefolderconfirm'))) 2522 2499 return false; 2523 2500 2524 2501 // lock interface if it's the active mailbox 2525 if (mbox == this.env.mailbox) 2526 { 2502 if (mbox == this.env.mailbox) { 2527 2503 lock = true; 2528 2504 this.set_busy(true, 'loading'); 2529 2505 add_url = '&_reload=1'; 2530 }2506 } 2531 2507 2532 2508 // send request to server … … 2534 2510 this.http_post('purge', url+add_url, lock); 2535 2511 return true; 2536 };2512 }; 2537 2513 2538 2514 // test if purge command is allowed … … 2544 2520 }; 2545 2521 2546 2522 2547 2523 /*********************************************************/ 2548 2524 /********* login form methods *********/ … … 2560 2536 return rcube_event.cancel(e); 2561 2537 } 2562 2538 2563 2539 return true; 2564 2540 }; … … 2568 2544 /********* message compose methods *********/ 2569 2545 /*********************************************************/ 2570 2546 2571 2547 // init message compose form: set focus and eventhandlers 2572 2548 this.init_messageform = function() … … 2574 2550 if (!this.gui_objects.messageform) 2575 2551 return false; 2576 2552 2577 2553 //this.messageform = this.gui_objects.messageform; 2578 2554 var input_from = $("[name='_from']"); … … 2586 2562 this.init_address_input_events($("[name='_cc']")); 2587 2563 this.init_address_input_events($("[name='_bcc']")); 2588 2564 2589 2565 if (!html_mode) { 2590 2566 // add signature according to selected identity … … 2605 2581 // get summary of all field values 2606 2582 this.compose_field_hash(true); 2607 2583 2608 2584 // start the auto-save timer 2609 2585 this.auto_save_start(); … … 2650 2626 } 2651 2627 } 2652 2628 2653 2629 // display localized warning for missing subject 2654 2630 if (input_subject.val() == '') { … … 2734 2710 var value_subject = $("[name='_subject']").val(); 2735 2711 var str = ''; 2736 2712 2737 2713 if (value_to) 2738 2714 str += value_to+':'; … … 2743 2719 if (value_subject) 2744 2720 str += value_subject+':'; 2745 2721 2746 2722 var editor = tinyMCE.get(this.env.composebody); 2747 2723 if (editor) … … 2759 2735 return str; 2760 2736 }; 2761 2737 2762 2738 this.change_identity = function(obj, show_sig) 2763 2739 { … … 2777 2753 if (!this.env.identity) 2778 2754 this.env.identity = id 2779 2755 2780 2756 // enable manual signature insert 2781 2757 if (this.env.signatures && this.env.signatures[id]) … … 2904 2880 $(elm).toggle(); 2905 2881 } 2906 2882 2907 2883 // clear upload form 2908 2884 try { … … 2911 2887 } 2912 2888 catch(e){} // ignore errors 2913 2889 2914 2890 return true; 2915 2891 }; … … 2920 2896 if (!form) 2921 2897 return false; 2922 2898 2923 2899 // get file input fields 2924 2900 var send = false; … … 2928 2904 break; 2929 2905 } 2930 2906 2931 2907 // create hidden iframe and post upload form 2932 2908 if (send) { … … 2976 2952 form.setAttribute('enctype', 'multipart/form-data'); 2977 2953 form.submit(); 2978 2954 2979 2955 // hide upload form 2980 2956 this.show_attachment_form(false); … … 2987 2963 this.add2attachment_list(ts, { name:'', html:content, complete:false }); 2988 2964 } 2989 2965 2990 2966 // set reference to the form object 2991 2967 this.gui_objects.attachmentform = form; … … 2999 2975 if (!this.gui_objects.attachmentlist) 3000 2976 return false; 3001 2977 3002 2978 var li = $('<li>').attr('id', name).html(att.html); 3003 2979 var indicator; 3004 2980 3005 2981 // replace indicator's li 3006 2982 if (upload_id && (indicator = document.getElementById(upload_id))) { … … 3010 2986 li.appendTo(this.gui_objects.attachmentlist); 3011 2987 } 3012 2988 3013 2989 if (upload_id && this.env.attachments[upload_id]) 3014 2990 delete this.env.attachments[upload_id]; 3015 2991 3016 2992 this.env.attachments[name] = att; 3017 2993 3018 2994 return true; 3019 2995 }; … … 3023 2999 if (this.env.attachments[name]) 3024 3000 delete this.env.attachments[name]; 3025 3001 3026 3002 if (!this.gui_objects.attachmentlist) 3027 3003 return false; … … 3056 3032 if (value) 3057 3033 this.http_post('addcontact', '_address='+value); 3058 3034 3059 3035 return true; 3060 3036 }; … … 3070 3046 var mods = this.env.search_mods[this.env.mailbox] ? this.env.search_mods[this.env.mailbox] : this.env.search_mods['*']; 3071 3047 if (mods) { 3072 var head_arr = new Array();3048 var head_arr = []; 3073 3049 for (var n in mods) 3074 3050 head_arr.push(n); … … 3101 3077 if (this.gui_objects.qsearchbox) 3102 3078 this.gui_objects.qsearchbox.value = ''; 3103 3079 3104 3080 this.env.search_request = null; 3105 3081 return true; … … 3127 3103 var mod = rcube_event.get_modifier(e); 3128 3104 3129 switch (key) 3130 { 3105 switch (key) { 3131 3106 case 38: // key up 3132 3107 case 40: // key down 3133 3108 if (!this.ksearch_pane) 3134 3109 break; 3135 3110 3136 3111 var dir = key==38 ? 1 : 0; 3137 3112 3138 3113 highlight = document.getElementById('rcmksearchSelected'); 3139 3114 if (!highlight) 3140 3115 highlight = this.ksearch_pane.__ul.firstChild; 3141 3116 3142 3117 if (highlight) 3143 3118 this.ksearch_select(dir ? highlight.previousSibling : highlight.nextSibling); … … 3162 3137 this.ksearch_hide(); 3163 3138 break; 3164 3139 3165 3140 case 37: // left 3166 3141 case 39: // right 3167 3142 if (mod != SHIFT_KEY) 3168 return;3169 }3143 return; 3144 } 3170 3145 3171 3146 // start timer 3172 3147 this.ksearch_timer = window.setTimeout(function(){ ref.ksearch_get_results(); }, 200); 3173 3148 this.ksearch_input = obj; 3174 3149 3175 3150 return true; 3176 3151 }; 3177 3152 3178 3153 this.ksearch_select = function(node) 3179 3154 { … … 3193 3168 if (!this.env.contacts[id] || !this.ksearch_input) 3194 3169 return; 3195 3170 3196 3171 // get cursor pos 3197 3172 var inp_value = this.ksearch_input.value; … … 3203 3178 var end = this.ksearch_input.value.substring(p+this.ksearch_value.length, this.ksearch_input.value.length); 3204 3179 var insert = ''; 3205 3180 3206 3181 // insert all members of a group 3207 3182 if (typeof this.env.contacts[id] == 'object' && this.env.contacts[id].id) { … … 3221 3196 this.ksearch_input.setSelectionRange(cpos, cpos); 3222 3197 }; 3223 3198 3224 3199 this.replace_group_recipients = function(id, recipients) 3225 3200 { … … 3236 3211 if (inp_value === null) 3237 3212 return; 3238 3213 3239 3214 if (this.ksearch_pane && this.ksearch_pane.is(":visible")) 3240 3215 this.ksearch_pane.hide(); … … 3251 3226 if (q == this.ksearch_value) 3252 3227 return; 3253 3228 3254 3229 var old_value = this.ksearch_value; 3255 3230 this.ksearch_value = q; 3256 3231 3257 3232 // ...string is empty 3258 3233 if (!q.length) … … 3262 3237 if (old_value && old_value.length && this.env.contacts && !this.env.contacts.length && q.indexOf(old_value) == 0) 3263 3238 return; 3264 3239 3265 3240 this.display_message(this.get_label('searching'), 'loading', false); 3266 3241 this.http_post('autocomplete', '_search='+urlencode(q)); … … 3272 3247 if (this.ksearch_value && search != this.ksearch_value) 3273 3248 return; 3274 3249 3275 3250 this.hide_message(); 3276 3251 this.env.contacts = results ? results : []; … … 3283 3258 if (a_results.length && this.ksearch_input && this.ksearch_value) { 3284 3259 var p, ul, li, text, s_val = this.ksearch_value; 3285 3260 3286 3261 // create results pane if not present 3287 3262 if (!this.ksearch_pane) { … … 3318 3293 this.ksearch_hide(); 3319 3294 }; 3320 3295 3321 3296 this.ksearch_click = function(node) 3322 3297 { … … 3329 3304 3330 3305 this.ksearch_blur = function() 3331 {3306 { 3332 3307 if (this.ksearch_timer) 3333 3308 clearTimeout(this.ksearch_timer); … … 3335 3310 this.ksearch_value = ''; 3336 3311 this.ksearch_input = null; 3337 3338 3312 this.ksearch_hide(); 3339 };3313 }; 3340 3314 3341 3315 3342 3316 this.ksearch_hide = function() 3343 {3317 { 3344 3318 this.ksearch_selected = null; 3345 3319 3346 3320 if (this.ksearch_pane) 3347 3321 this.ksearch_pane.hide(); 3348 };3322 }; 3349 3323 3350 3324 … … 3354 3328 3355 3329 this.contactlist_keypress = function(list) 3356 {3357 if (list.key_pressed == list.DELETE_KEY)3358 this.command('delete');3359 };3330 { 3331 if (list.key_pressed == list.DELETE_KEY) 3332 this.command('delete'); 3333 }; 3360 3334 3361 3335 this.contactlist_select = function(list) 3362 {3363 if (this.preview_timer)3364 clearTimeout(this.preview_timer);3365 3366 var id, frame, ref = this;3367 if (id = list.get_single_selection())3368 this.preview_timer = window.setTimeout(function(){ ref.load_contact(id, 'show'); }, 200);3369 else if (this.env.contentframe)3370 this.show_contentframe(false);3371 3372 this.enable_command('compose', list.selection.length > 0);3373 this.enable_command('edit', (id && this.env.address_sources && !this.env.address_sources[this.env.source].readonly) ? true : false);3374 this.enable_command('delete', list.selection.length && this.env.address_sources && !this.env.address_sources[this.env.source].readonly);3375 3376 return false;3377 };3336 { 3337 if (this.preview_timer) 3338 clearTimeout(this.preview_timer); 3339 3340 var id, frame, ref = this; 3341 if (id = list.get_single_selection()) 3342 this.preview_timer = window.setTimeout(function(){ ref.load_contact(id, 'show'); }, 200); 3343 else if (this.env.contentframe) 3344 this.show_contentframe(false); 3345 3346 this.enable_command('compose', list.selection.length > 0); 3347 this.enable_command('edit', (id && this.env.address_sources && !this.env.address_sources[this.env.source].readonly) ? true : false); 3348 this.enable_command('delete', list.selection.length && this.env.address_sources && !this.env.address_sources[this.env.source].readonly); 3349 3350 return false; 3351 }; 3378 3352 3379 3353 this.list_contacts = function(src, group, page) 3380 {3354 { 3381 3355 var add_url = ''; 3382 3356 var target = window; 3383 3357 3384 3358 // currently all groups belong to the local address book 3385 3359 if (group) … … 3387 3361 else if (!src) 3388 3362 src = this.env.source; 3389 3363 3390 3364 if (page && this.current_page == page && src == this.env.source && group == this.env.group) 3391 3365 return false; 3392 3393 if (src != this.env.source) 3394 { 3366 3367 if (src != this.env.source) { 3395 3368 page = 1; 3396 3369 this.env.current_page = page; 3397 3370 this.reset_qsearch(); 3398 }3371 } 3399 3372 else if (group != this.env.group) 3400 3373 page = this.env.current_page = 1; 3401 3374 3402 3375 this.select_folder((group ? 'G'+group : src), (this.env.group ? 'G'+this.env.group : this.env.source)); 3403 3376 3404 3377 this.env.source = src; 3405 3378 this.env.group = group; 3406 3379 3407 3380 // load contacts remotely 3408 if (this.gui_objects.contactslist) 3409 { 3381 if (this.gui_objects.contactslist) { 3410 3382 this.list_contacts_remote(src, group, page); 3411 3383 return; 3412 } 3413 3414 if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) 3415 { 3384 } 3385 3386 if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) { 3416 3387 target = window.frames[this.env.contentframe]; 3417 3388 add_url = '&_framed=1'; 3418 }3419 3389 } 3390 3420 3391 if (group) 3421 3392 add_url += '&_gid='+group; … … 3429 3400 this.set_busy(true, 'loading'); 3430 3401 target.location.href = this.env.comm_path + (src ? '&_source='+urlencode(src) : '') + add_url; 3431 };3402 }; 3432 3403 3433 3404 // send remote request to load contacts list 3434 3405 this.list_contacts_remote = function(src, group, page) 3435 {3406 { 3436 3407 // clear message list first 3437 3408 this.contact_list.clear(true); … … 3443 3414 this.env.source = src; 3444 3415 this.env.group = group; 3445 3416 3446 3417 if (group) 3447 3418 url += '&_gid='+group; 3448 3419 3449 3420 // also send search request to get the right messages 3450 3421 if (this.env.search_request) … … 3453 3424 this.set_busy(true, 'loading'); 3454 3425 this.http_request('list', url, true); 3455 };3426 }; 3456 3427 3457 3428 // load contact record 3458 3429 this.load_contact = function(cid, action, framed) 3459 {3430 { 3460 3431 var add_url = ''; 3461 3432 var target = window; 3462 if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) 3463 { 3433 if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) { 3464 3434 add_url = '&_framed=1'; 3465 3435 target = window.frames[this.env.contentframe]; 3466 3436 this.show_contentframe(true); 3467 }3437 } 3468 3438 else if (framed) 3469 3439 return false; 3470 3471 if (action && (cid || action=='add') && !this.drag_active) 3472 { 3440 3441 if (action && (cid || action=='add') && !this.drag_active) { 3473 3442 this.set_busy(true); 3474 3443 target.location.href = this.env.comm_path+'&_action='+action+'&_source='+urlencode(this.env.source)+'&_gid='+urlencode(this.env.group)+'&_cid='+urlencode(cid) + add_url; 3475 }3444 } 3476 3445 return true; 3477 };3446 }; 3478 3447 3479 3448 // copy a contact to the specified target (group or directory) 3480 3449 this.copy_contact = function(cid, to) 3481 {3450 { 3482 3451 if (!cid) 3483 3452 cid = this.contact_list.get_selection().join(','); … … 3487 3456 else if (to.id != this.env.source && cid && this.env.address_sources[to.id] && !this.env.address_sources[to.id].readonly) 3488 3457 this.http_post('copy', '_cid='+urlencode(cid)+'&_source='+urlencode(this.env.source)+'&_to='+urlencode(to.id)); 3489 };3458 }; 3490 3459 3491 3460 3492 3461 this.delete_contacts = function() 3493 {3462 { 3494 3463 // exit if no mailbox specified or if selection is empty 3495 3464 var selection = this.contact_list.get_selection(); 3496 3465 if (!(selection.length || this.env.cid) || (!this.env.group && !confirm(this.get_label('deletecontactconfirm')))) 3497 3466 return; 3498 3499 var a_cids = new Array(); 3500 var qs = ''; 3467 3468 var a_cids = [], qs = ''; 3501 3469 3502 3470 if (this.env.cid) 3503 3471 a_cids[a_cids.length] = this.env.cid; 3504 else 3505 { 3472 else { 3506 3473 var id; 3507 for (var n=0; n<selection.length; n++) 3508 { 3474 for (var n=0; n<selection.length; n++) { 3509 3475 id = selection[n]; 3510 3476 a_cids[a_cids.length] = id; 3511 3477 this.contact_list.remove_row(id, (n == selection.length-1)); 3512 }3478 } 3513 3479 3514 3480 // hide content frame if we delete the currently displayed contact 3515 3481 if (selection.length == 1) 3516 3482 this.show_contentframe(false); 3517 }3483 } 3518 3484 3519 3485 // also send search request to get the right records from the next page … … 3526 3492 else 3527 3493 this.http_post('delete', '_cid='+urlencode(a_cids.join(','))+'&_source='+urlencode(this.env.source)+'&_from='+(this.env.action ? this.env.action : '')+qs); 3528 3494 3529 3495 return true; 3530 };3496 }; 3531 3497 3532 3498 // update a contact record in the list … … 3556 3522 // add row to contacts list 3557 3523 this.add_contact_row = function(cid, cols, select) 3558 {3524 { 3559 3525 if (!this.gui_objects.contactslist || !this.gui_objects.contactslist.tBodies[0]) 3560 3526 return false; 3561 3562 var tbody = this.gui_objects.contactslist.tBodies[0] ;3563 var rowcount = tbody.rows.length;3564 var even = rowcount%2;3565 3566 var row = document.createElement('tr'); 3527 3528 var tbody = this.gui_objects.contactslist.tBodies[0], 3529 rowcount = tbody.rows.length, 3530 even = rowcount%2, 3531 row = document.createElement('tr'); 3532 3567 3533 row.id = 'rcmrow'+cid; 3568 3534 row.className = 'contact '+(even ? 'even' : 'odd'); 3569 3535 3570 3536 if (this.contact_list.in_selection(cid)) 3571 3537 row.className += ' selected'; … … 3578 3544 row.appendChild(col); 3579 3545 } 3580 3546 3581 3547 this.contact_list.insert_row(row); 3582 3548 3583 3549 this.enable_command('export', (this.contact_list.rowcount > 0)); 3584 };3585 3586 3550 }; 3551 3552 3587 3553 this.add_contact_group = function() 3588 3554 { 3589 3555 if (!this.gui_objects.folderlist || !this.env.address_sources[this.env.source].groups) 3590 3556 return; 3591 3557 3592 3558 if (!this.name_input) { 3593 3559 this.name_input = document.createElement('input'); 3594 3560 this.name_input.type = 'text'; 3595 3561 this.name_input.onkeypress = function(e){ return rcmail.add_input_keypress(e); }; 3596 3562 3597 3563 this.gui_objects.folderlist.parentNode.appendChild(this.name_input); 3598 3564 } 3599 3565 3600 3566 this.name_input.select(); 3601 3567 }; 3602 3568 3603 3569 this.rename_contact_group = function() 3604 3570 { 3605 3571 if (!this.env.group || !this.gui_objects.folderlist) 3606 3572 return; 3607 3573 3608 3574 if (!this.name_input) { 3609 3575 this.enable_command('list', 'listgroup', false); … … 3623 3589 this.name_input.select(); 3624 3590 }; 3625 3591 3626 3592 this.delete_contact_group = function() 3627 3593 { … … 3629 3595 this.http_post('group-delete', '_source='+urlencode(this.env.source)+'&_gid='+urlencode(this.env.group), true); 3630 3596 }; 3631 3597 3632 3598 // callback from server upon group-delete command 3633 3599 this.remove_group_item = function(id) … … 3636 3602 if ((li = this.get_folder_li(key))) { 3637 3603 this.triggerEvent('removegroup', { id:id, li:li }); 3638 3604 3639 3605 li.parentNode.removeChild(li); 3640 3606 delete this.env.contactfolders[key]; 3641 3607 delete this.env.contactgroups[key]; 3642 3608 } 3643 3609 3644 3610 this.list_contacts(null, 0); 3645 3611 }; 3646 3612 3647 3613 // handler for keyboard events on the input field 3648 3614 this.add_input_keypress = function(e) … … 3653 3619 if (key == 13) { 3654 3620 var newname = this.name_input.value; 3655 3621 3656 3622 if (newname) { 3657 3623 this.set_busy(true, 'loading'); … … 3666 3632 else if (key == 27) 3667 3633 this.reset_add_input(); 3668 3634 3669 3635 return true; 3670 3636 }; 3671 3637 3672 3638 this.reset_add_input = function() 3673 3639 { … … 3678 3644 this.env.group_renaming = false; 3679 3645 } 3680 3646 3681 3647 this.name_input.parentNode.removeChild(this.name_input); 3682 3648 this.name_input = null; … … 3685 3651 this.enable_command('list', 'listgroup', true); 3686 3652 }; 3687 3653 3688 3654 // callback for creating a new contact group 3689 3655 this.insert_contact_group = function(prop) 3690 3656 { 3691 3657 this.reset_add_input(); 3692 3658 3693 3659 prop.type = 'group'; 3694 3660 var key = 'G'+prop.id; … … 3700 3666 var li = $('<li>').attr('id', 'rcmli'+key).addClass('contactgroup').append(link); 3701 3667 $(this.gui_objects.folderlist).append(li); 3702 3668 3703 3669 this.triggerEvent('insertgroup', { id:prop.id, name:prop.name, li:li[0] }); 3704 3670 }; 3705 3671 3706 3672 // callback for renaming a contact group 3707 3673 this.update_contact_group = function(id, name) 3708 3674 { 3709 3675 this.reset_add_input(); 3710 3711 var key = 'G'+id ;3712 var link, li = this.get_folder_li(key); 3676 3677 var key = 'G'+id, link, li = this.get_folder_li(key); 3678 3713 3679 if (li && (link = li.firstChild) && link.tagName.toLowerCase() == 'a') 3714 3680 link.innerHTML = name; 3715 3681 3716 3682 this.env.contactfolders[key].name = this.env.contactgroups[key].name = name; 3717 3683 this.triggerEvent('updategroup', { id:id, name:name, li:li[0] }); … … 3724 3690 3725 3691 this.init_subscription_list = function() 3726 {3692 { 3727 3693 var p = this; 3728 3694 this.subscription_list = new rcube_list_widget(this.gui_objects.subscriptionlist, {multiselect:false, draggable:true, keyboard:false, toggleselect:true}); … … 3730 3696 this.subscription_list.addEventListener('dragstart', function(o){ p.drag_active = true; }); 3731 3697 this.subscription_list.addEventListener('dragend', function(o){ p.subscription_move_folder(o); }); 3732 this.subscription_list.row_init = function (row) 3733 { 3698 this.subscription_list.row_init = function (row) { 3734 3699 var anchors = row.obj.getElementsByTagName('a'); 3735 3700 if (anchors[0]) … … 3739 3704 row.obj.onmouseover = function() { p.focus_subscription(row.id); }; 3740 3705 row.obj.onmouseout = function() { p.unfocus_subscription(row.id); }; 3741 }3706 }; 3742 3707 this.subscription_list.init(); 3743 }3708 }; 3744 3709 3745 3710 // preferences section select and load options frame 3746 3711 this.section_select = function(list) 3747 {3712 { 3748 3713 var id = list.get_single_selection(); 3749 3714 3750 3715 if (id) { 3751 var add_url = ''; 3752 var target = window; 3716 var add_url = '', target = window; 3753 3717 this.set_busy(true); 3754 3718 … … 3756 3720 add_url = '&_framed=1'; 3757 3721 target = window.frames[this.env.contentframe]; 3758 }3722 } 3759 3723 target.location.href = this.env.comm_path+'&_action=edit-prefs&_section='+id+add_url; 3760 }3724 } 3761 3725 3762 3726 return true; 3763 };3727 }; 3764 3728 3765 3729 this.identity_select = function(list) 3766 {3730 { 3767 3731 var id; 3768 3732 if (id = list.get_single_selection()) 3769 3733 this.load_identity(id, 'edit-identity'); 3770 };3734 }; 3771 3735 3772 3736 // load identity record 3773 3737 this.load_identity = function(id, action) 3774 {3738 { 3775 3739 if (action=='edit-identity' && (!id || id==this.env.iid)) 3776 3740 return false; 3777 3741 3778 var add_url = ''; 3779 var target = window; 3780 if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) 3781 { 3742 var add_url = '', target = window; 3743 3744 if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) { 3782 3745 add_url = '&_framed=1'; 3783 3746 target = window.frames[this.env.contentframe]; 3784 3747 document.getElementById(this.env.contentframe).style.visibility = 'inherit'; 3785 } 3786 3787 if (action && (id || action=='add-identity')) 3788 { 3748 } 3749 3750 if (action && (id || action=='add-identity')) { 3789 3751 this.set_busy(true); 3790 3752 target.location.href = this.env.comm_path+'&_action='+action+'&_iid='+id+add_url; 3791 } 3753 } 3754 3792 3755 return true; 3793 };3756 }; 3794 3757 3795 3758 this.delete_identity = function(id) 3796 {3759 { 3797 3760 // exit if no mailbox specified or if selection is empty 3798 3761 var selection = this.identity_list.get_selection(); 3799 3762 if (!(selection.length || this.env.iid)) 3800 3763 return; 3801 3764 3802 3765 if (!id) 3803 3766 id = this.env.iid ? this.env.iid : selection[0]; … … 3805 3768 // append token to request 3806 3769 this.goto_url('delete-identity', '_iid='+id+'&_token='+this.env.request_token, true); 3807 3770 3808 3771 return true; 3809 };3772 }; 3810 3773 3811 3774 this.focus_subscription = function(id) 3812 {3813 var row, folder ;3814 varreg = RegExp('['+RegExp.escape(this.env.delimiter)+']?[^'+RegExp.escape(this.env.delimiter)+']+$');3775 { 3776 var row, folder, 3777 reg = RegExp('['+RegExp.escape(this.env.delimiter)+']?[^'+RegExp.escape(this.env.delimiter)+']+$'); 3815 3778 3816 3779 if (this.drag_active && this.env.folder && (row = document.getElementById(id))) 3817 3780 if (this.env.subscriptionrows[id] && 3818 (folder = this.env.subscriptionrows[id][0])) 3819 { 3781 (folder = this.env.subscriptionrows[id][0])) { 3820 3782 if (this.check_droptarget(folder) && 3821 3783 !this.env.subscriptionrows[this.get_folder_row_id(this.env.folder)][2] && 3822 3784 (folder != this.env.folder.replace(reg, '')) && 3823 (!folder.match(new RegExp('^'+RegExp.escape(this.env.folder+this.env.delimiter))))) 3824 { 3785 (!folder.match(new RegExp('^'+RegExp.escape(this.env.folder+this.env.delimiter))))) { 3825 3786 this.set_env('dstfolder', folder); 3826 3787 $(row).addClass('droptarget'); 3827 } 3828 } 3829 else if (this.env.folder.match(new RegExp(RegExp.escape(this.env.delimiter)))) 3830 { 3788 } 3789 } 3790 else if (this.env.folder.match(new RegExp(RegExp.escape(this.env.delimiter)))) { 3831 3791 this.set_env('dstfolder', this.env.delimiter); 3832 3792 $(this.subscription_list.frame).addClass('droptarget'); 3833 }3834 }3793 } 3794 }; 3835 3795 3836 3796 this.unfocus_subscription = function(id) 3837 { 3838 var row = $('#'+id); 3839 this.set_env('dstfolder', null); 3840 if (this.env.subscriptionrows[id] && row[0]) 3841 row.removeClass('droptarget'); 3842 else 3843 $(this.subscription_list.frame).removeClass('droptarget'); 3844 } 3797 { 3798 var row = $('#'+id); 3799 3800 this.set_env('dstfolder', null); 3801 if (this.env.subscriptionrows[id] && row[0]) 3802 row.removeClass('droptarget'); 3803 else 3804 $(this.subscription_list.frame).removeClass('droptarget'); 3805 }; 3845 3806 3846 3807 this.subscription_select = function(list) 3847 {3808 { 3848 3809 var id, folder; 3849 3810 if ((id = list.get_single_selection()) && … … 3853 3814 else 3854 3815 this.set_env('folder', null); 3855 3816 3856 3817 if (this.gui_objects.createfolderhint) 3857 3818 $(this.gui_objects.createfolderhint).html(this.env.folder ? this.get_label('addsubfolderhint') : ''); 3858 };3819 }; 3859 3820 3860 3821 this.subscription_move_folder = function(list) 3861 {3822 { 3862 3823 var reg = RegExp('['+RegExp.escape(this.env.delimiter)+']?[^'+RegExp.escape(this.env.delimiter)+']+$'); 3863 3824 if (this.env.folder && this.env.dstfolder && (this.env.dstfolder != this.env.folder) && 3864 (this.env.dstfolder != this.env.folder.replace(reg, ''))) 3865 { 3825 (this.env.dstfolder != this.env.folder.replace(reg, ''))) { 3866 3826 var reg = new RegExp('[^'+RegExp.escape(this.env.delimiter)+']*['+RegExp.escape(this.env.delimiter)+']', 'g'); 3867 3827 var basename = this.env.folder.replace(reg, ''); … … 3870 3830 this.set_busy(true, 'foldermoving'); 3871 3831 this.http_post('rename-folder', '_folder_oldname='+urlencode(this.env.folder)+'&_folder_newname='+urlencode(newname), true); 3872 }3832 } 3873 3833 this.drag_active = false; 3874 3834 this.unfocus_subscription(this.get_folder_row_id(this.env.dstfolder)); 3875 };3835 }; 3876 3836 3877 3837 // tell server to create and subscribe a new mailbox 3878 3838 this.create_folder = function(name) 3879 {3839 { 3880 3840 if (this.edit_folder) 3881 3841 this.reset_folder_rename(); 3882 3842 3883 3843 var form; 3884 if ((form = this.gui_objects.editform) && form.elements['_folder_name']) 3885 { 3844 if ((form = this.gui_objects.editform) && form.elements['_folder_name']) { 3886 3845 name = form.elements['_folder_name'].value; 3887 3846 3888 if (name.indexOf(this.env.delimiter)>=0) 3889 { 3847 if (name.indexOf(this.env.delimiter)>=0) { 3890 3848 alert(this.get_label('forbiddencharacter')+' ('+this.env.delimiter+')'); 3891 3849 return false; 3892 }3850 } 3893 3851 3894 3852 if (this.env.folder && name != '') … … 3897 3855 this.set_busy(true, 'foldercreating'); 3898 3856 this.http_post('create-folder', '_name='+urlencode(name), true); 3899 }3857 } 3900 3858 else if (form.elements['_folder_name']) 3901 3859 form.elements['_folder_name'].focus(); 3902 };3860 }; 3903 3861 3904 3862 // start renaming the mailbox name. 3905 3863 // this will replace the name string with an input field 3906 3864 this.rename_folder = function(id) 3907 {3865 { 3908 3866 var temp, row, form; 3909 3867 3910 3868 // reset current renaming 3911 if (temp = this.edit_folder) 3912 { 3869 if (temp = this.edit_folder) { 3913 3870 this.reset_folder_rename(); 3914 3871 if (temp == id) 3915 3872 return; 3916 } 3917 3918 if (id && this.env.subscriptionrows[id] && (row = document.getElementById(id))) 3919 { 3873 } 3874 3875 if (id && this.env.subscriptionrows[id] && (row = document.getElementById(id))) { 3920 3876 var reg = new RegExp('.*['+RegExp.escape(this.env.delimiter)+']'); 3921 3877 this.name_input = document.createElement('input'); … … 3926 3882 this.name_input.__parent = this.env.subscriptionrows[id][0].replace(reg, ''); 3927 3883 this.name_input.onkeypress = function(e){ rcmail.name_input_keypress(e); }; 3928 3884 3929 3885 row.cells[0].replaceChild(this.name_input, row.cells[0].firstChild); 3930 3886 this.edit_folder = id; 3931 3887 this.name_input.select(); 3932 3888 3933 3889 if (form = this.gui_objects.editform) 3934 3890 form.onsubmit = function(){ return false; }; 3935 }3936 };3891 } 3892 }; 3937 3893 3938 3894 // remove the input field and write the current mailbox name to the table cell 3939 3895 this.reset_folder_rename = function() 3940 {3896 { 3941 3897 var cell = this.name_input ? this.name_input.parentNode : null; 3942 3898 3943 3899 if (cell && this.edit_folder && this.env.subscriptionrows[this.edit_folder]) 3944 3900 $(cell).html(this.env.subscriptionrows[this.edit_folder][1]); 3945 3901 3946 3902 this.edit_folder = null; 3947 };3903 }; 3948 3904 3949 3905 // handler for keyboard events on the input field 3950 3906 this.name_input_keypress = function(e) 3951 {3907 { 3952 3908 var key = rcube_event.get_keycode(e); 3953 3909 3954 3910 // enter 3955 if (key==13) 3956 { 3911 if (key==13) { 3957 3912 var newname = this.name_input ? this.name_input.value : null; 3958 if (this.edit_folder && newname) 3959 { 3960 if (newname.indexOf(this.env.delimiter)>=0) 3961 { 3913 if (this.edit_folder && newname) { 3914 if (newname.indexOf(this.env.delimiter)>=0) { 3962 3915 alert(this.get_label('forbiddencharacter')+' ('+this.env.delimiter+')'); 3963 3916 return false; 3964 }3917 } 3965 3918 3966 3919 if (this.name_input.__parent) … … 3969 3922 this.set_busy(true, 'folderrenaming'); 3970 3923 this.http_post('rename-folder', '_folder_oldname='+urlencode(this.env.subscriptionrows[this.edit_folder][0])+'&_folder_newname='+urlencode(newname), true); 3971 }3972 }3924 } 3925 } 3973 3926 // escape 3974 3927 else if (key==27) 3975 3928 this.reset_folder_rename(); 3976 };3929 }; 3977 3930 3978 3931 // delete a specific mailbox with all its messages 3979 3932 this.delete_folder = function(id) 3980 {3933 { 3981 3934 var folder = this.env.subscriptionrows[id][0]; 3982 3935 … … 3984 3937 this.reset_folder_rename(); 3985 3938 3986 if (folder && confirm(this.get_label('deletefolderconfirm'))) 3987 { 3939 if (folder && confirm(this.get_label('deletefolderconfirm'))) { 3988 3940 this.set_busy(true, 'folderdeleting'); 3989 3941 this.http_post('delete-folder', '_mboxes='+urlencode(folder), true); … … 3991 3943 3992 3944 $(this.gui_objects.createfolderhint).html(''); 3993 }3994 };3945 } 3946 }; 3995 3947 3996 3948 // add a new folder to the subscription list by cloning a folder row 3997 3949 this.add_folder_row = function(name, display_name, replace, before) 3998 {3950 { 3999 3951 if (!this.gui_objects.subscriptionlist) 4000 3952 return false; … … 4002 3954 // find not protected folder 4003 3955 var refid; 4004 for (var rid in this.env.subscriptionrows) 3956 for (var rid in this.env.subscriptionrows) { 4005 3957 if (this.env.subscriptionrows[rid]!=null && !this.env.subscriptionrows[rid][2]) { 4006 3958 refid = rid; 4007 3959 break; 4008 3960 } 4009 4010 var refrow, form; 4011 var tbody = this.gui_objects.subscriptionlist.tBodies[0];4012 var id = 'rcmrow'+(tbody.childNodes.length+1);4013 var selection = this.subscription_list.get_single_selection();4014 4015 if (replace && replace.id) 4016 {3961 } 3962 3963 var refrow, form, 3964 tbody = this.gui_objects.subscriptionlist.tBodies[0], 3965 id = 'rcmrow'+(tbody.childNodes.length+1), 3966 selection = this.subscription_list.get_single_selection(); 3967 3968 if (replace && replace.id) { 4017 3969 id = replace.id; 4018 3970 refid = replace.id; 4019 3971 } 4020 3972 4021 if (!id || !refid || !(refrow = document.getElementById(refid))) 4022 { 3973 if (!id || !refid || !(refrow = document.getElementById(refid))) { 4023 3974 // Refresh page if we don't have a table row to clone 4024 3975 this.goto_url('folders'); 4025 3976 return false; 4026 } 4027 else 4028 { 3977 } 3978 else { 4029 3979 // clone a table row if there are existing rows 4030 3980 var row = this.clone_table_row(refrow); … … 4035 3985 else 4036 3986 tbody.appendChild(row); 4037 3987 4038 3988 if (replace) 4039 3989 tbody.removeChild(replace); 4040 }3990 } 4041 3991 4042 3992 // add to folder/row-ID map … … 4045 3995 // set folder name 4046 3996 row.cells[0].innerHTML = display_name; 4047 3997 4048 3998 // set messages count to zero 4049 3999 if (!replace) 4050 4000 row.cells[1].innerHTML = '*'; 4051 4001 4052 if (!replace && row.cells[2] && row.cells[2].firstChild.tagName.toLowerCase()=='input') 4053 { 4002 if (!replace && row.cells[2] && row.cells[2].firstChild.tagName.toLowerCase()=='input') { 4054 4003 row.cells[2].firstChild.value = name; 4055 4004 row.cells[2].firstChild.checked = true; 4056 }4057 4005 } 4006 4058 4007 // add new folder to rename-folder list and clear input field 4059 if (!replace && (form = this.gui_objects.editform)) 4060 { 4008 if (!replace && (form = this.gui_objects.editform)) { 4061 4009 if (form.elements['_folder_oldname']) 4062 4010 form.elements['_folder_oldname'].options[form.elements['_folder_oldname'].options.length] = new Option(name,name); 4063 4011 if (form.elements['_folder_name']) 4064 4012 form.elements['_folder_name'].value = ''; 4065 }4013 } 4066 4014 4067 4015 this.init_subscription_list(); … … 4071 4019 if (document.getElementById(id).scrollIntoView) 4072 4020 document.getElementById(id).scrollIntoView(); 4073 };4021 }; 4074 4022 4075 4023 // replace an existing table row with a new folder line 4076 4024 this.replace_folder_row = function(oldfolder, newfolder, display_name, before) 4077 { 4078 var id = this.get_folder_row_id(oldfolder); 4079 var row = document.getElementById(id); 4080 4025 { 4026 var form, elm, 4027 id = this.get_folder_row_id(oldfolder), 4028 row = document.getElementById(id); 4029 4081 4030 // replace an existing table row (if found) 4082 4031 this.add_folder_row(newfolder, display_name, row, before); 4083 4032 4084 4033 // rename folder in rename-folder dropdown 4085 var form, elm; 4086 if ((form = this.gui_objects.editform) && (elm = form.elements['_folder_oldname'])) 4087 { 4088 for (var i=0;i<elm.options.length;i++) 4089 { 4090 if (elm.options[i].value == oldfolder) 4091 { 4034 if ((form = this.gui_objects.editform) && (elm = form.elements['_folder_oldname'])) { 4035 for (var i=0; i<elm.options.length; i++) { 4036 if (elm.options[i].value == oldfolder) { 4092 4037 elm.options[i].text = display_name; 4093 4038 elm.options[i].value = newfolder; 4094 4039 break; 4095 }4096 }4040 } 4041 } 4097 4042 4098 4043 form.elements['_folder_newname'].value = ''; 4099 }4100 };4044 } 4045 }; 4101 4046 4102 4047 // remove the table row of a specific mailbox from the table 4103 4048 // (the row will not be removed, just hidden) 4104 4049 this.remove_folder_row = function(folder) 4105 {4106 var row;4107 var id = this.get_folder_row_id(folder); 4050 { 4051 var form, elm, row, id = this.get_folder_row_id(folder); 4052 4108 4053 if (id && (row = document.getElementById(id))) 4109 4054 row.style.display = 'none'; 4110 4055 4111 4056 // remove folder from rename-folder list 4112 var form; 4113 if ((form = this.gui_objects.editform) && form.elements['_folder_oldname']) 4114 { 4115 for (var i=0;i<form.elements['_folder_oldname'].options.length;i++) 4116 { 4117 if (form.elements['_folder_oldname'].options[i].value == folder) 4118 { 4119 form.elements['_folder_oldname'].options[i] = null; 4057 if ((form = this.gui_objects.editform) && (elm = form.elements['_folder_oldname'])) { 4058 for (var i=0; i<elm.options.length; i++) { 4059 if (elm.options[i].value == folder) { 4060 elm.options[i] = null; 4120 4061 break; 4121 }4122 }4123 }4124 4062 } 4063 } 4064 } 4065 4125 4066 if (form && form.elements['_folder_newname']) 4126 4067 form.elements['_folder_newname'].value = ''; 4127 };4068 }; 4128 4069 4129 4070 this.subscribe_folder = function(folder) 4130 {4071 { 4131 4072 if (folder) 4132 4073 this.http_post('subscribe', '_mbox='+urlencode(folder)); 4133 };4074 }; 4134 4075 4135 4076 this.unsubscribe_folder = function(folder) 4136 {4077 { 4137 4078 if (folder) 4138 4079 this.http_post('unsubscribe', '_mbox='+urlencode(folder)); 4139 };4080 }; 4140 4081 4141 4082 this.enable_threading = function(folder) 4142 {4083 { 4143 4084 if (folder) 4144 4085 this.http_post('enable-threading', '_mbox='+urlencode(folder)); 4145 };4086 }; 4146 4087 4147 4088 this.disable_threading = function(folder) 4148 {4089 { 4149 4090 if (folder) 4150 4091 this.http_post('disable-threading', '_mbox='+urlencode(folder)); 4151 }; 4152 4092 }; 4153 4093 4154 4094 // helper method to find a specific mailbox row ID 4155 4095 this.get_folder_row_id = function(folder) 4156 {4096 { 4157 4097 for (var id in this.env.subscriptionrows) 4158 4098 if (this.env.subscriptionrows[id] && this.env.subscriptionrows[id][0] == folder) 4159 4099 break; 4160 4100 4161 4101 return id; 4162 };4102 }; 4163 4103 4164 4104 // duplicate a specific table row 4165 4105 this.clone_table_row = function(row) 4166 {4167 var cell, td ;4168 varnew_row = document.createElement('tr');4169 for(var n=0; n<row.cells.length; n++) 4170 {4106 { 4107 var cell, td, 4108 new_row = document.createElement('tr'); 4109 4110 for(var n=0; n<row.cells.length; n++) { 4171 4111 cell = row.cells[n]; 4172 4112 td = document.createElement('td'); … … 4176 4116 if (cell.align) 4177 4117 td.setAttribute('align', cell.align); 4178 4118 4179 4119 td.innerHTML = cell.innerHTML; 4180 4120 new_row.appendChild(td); 4181 }4182 4121 } 4122 4183 4123 return new_row; 4184 };4124 }; 4185 4125 4186 4126 … … 4197 4137 this.enable_command('firstpage', (this.env.current_page > 1)); 4198 4138 }; 4199 4139 4200 4140 // set event handlers on registered buttons 4201 4141 this.init_buttons = function() … … 4204 4144 if (typeof cmd != 'string') 4205 4145 continue; 4206 4146 4207 4147 for (var i=0; i< this.buttons[cmd].length; i++) { 4208 4148 var prop = this.buttons[cmd][i]; … … 4216 4156 preload = true; 4217 4157 } 4218 4158 4219 4159 elm._command = cmd; 4220 4160 elm._id = prop.id; … … 4237 4177 // set button to a specific state 4238 4178 this.set_button = function(command, state) 4239 { 4240 var a_buttons = this.buttons[command]; 4241 var button, obj; 4242 4243 if(!a_buttons || !a_buttons.length) 4179 { 4180 var button, obj, a_buttons = this.buttons[command]; 4181 4182 if (!a_buttons || !a_buttons.length) 4244 4183 return false; 4245 4184 4246 for(var n=0; n<a_buttons.length; n++) 4247 { 4185 for (var n=0; n<a_buttons.length; n++) { 4248 4186 button = a_buttons[n]; 4249 4187 obj = document.getElementById(button.id); … … 4260 4198 4261 4199 // set image according to button state 4262 if (obj && button.type=='image' && button[state]) 4263 { 4200 if (obj && button.type=='image' && button[state]) { 4264 4201 button.status = state; 4265 4202 obj.src = button[state]; 4266 }4203 } 4267 4204 // set class name according to button state 4268 else if (obj && typeof(button[state])!='undefined') 4269 { 4205 else if (obj && typeof(button[state])!='undefined') { 4270 4206 button.status = state; 4271 4207 obj.className = button[state]; 4272 }4208 } 4273 4209 // disable/enable input buttons 4274 if (obj && button.type=='input') 4275 { 4210 if (obj && button.type=='input') { 4276 4211 button.status = state; 4277 4212 obj.disabled = !state; 4278 }4279 }4280 };4213 } 4214 } 4215 }; 4281 4216 4282 4217 // display a specific alttext 4283 4218 this.set_alttext = function(command, label) 4284 { 4285 if (!this.buttons[command] || !this.buttons[command].length) 4286 return; 4287 4288 var button, obj, link; 4289 for (var n=0; n<this.buttons[command].length; n++) 4290 { 4291 button = this.buttons[command][n]; 4292 obj = document.getElementById(button.id); 4293 4294 if (button.type=='image' && obj) 4295 { 4296 obj.setAttribute('alt', this.get_label(label)); 4297 if ((link = obj.parentNode) && link.tagName.toLowerCase() == 'a') 4298 link.setAttribute('title', this.get_label(label)); 4299 } 4300 else if (obj) 4301 obj.setAttribute('title', this.get_label(label)); 4302 } 4303 }; 4219 { 4220 if (!this.buttons[command] || !this.buttons[command].length) 4221 return; 4222 4223 var button, obj, link; 4224 for (var n=0; n<this.buttons[command].length; n++) { 4225 button = this.buttons[command][n]; 4226 obj = document.getElementById(button.id); 4227 4228 if (button.type=='image' && obj) { 4229 obj.setAttribute('alt', this.get_label(label)); 4230 if ((link = obj.parentNode) && link.tagName.toLowerCase() == 'a') 4231 link.setAttribute('title', this.get_label(label)); 4232 } 4233 else if (obj) 4234 obj.setAttribute('title', this.get_label(label)); 4235 } 4236 }; 4304 4237 4305 4238 // mouse over button 4306 4239 this.button_over = function(command, id) 4307 4240 { 4308 var a_buttons = this.buttons[command]; 4309 var button, elm; 4310 4311 if(!a_buttons || !a_buttons.length) 4241 var button, elm, a_buttons = this.buttons[command]; 4242 4243 if (!a_buttons || !a_buttons.length) 4312 4244 return false; 4313 4245 4314 for(var n=0; n<a_buttons.length; n++) 4315 { 4246 for (var n=0; n<a_buttons.length; n++) { 4316 4247 button = a_buttons[n]; 4317 if(button.id==id && button.status=='act') 4318 { 4248 if (button.id == id && button.status == 'act') { 4319 4249 elm = document.getElementById(button.id); 4320 4250 if (elm && button.over) { … … 4331 4261 this.button_sel = function(command, id) 4332 4262 { 4333 var a_buttons = this.buttons[command]; 4334 var button, elm; 4335 4336 if(!a_buttons || !a_buttons.length) 4263 var button, elm, a_buttons = this.buttons[command]; 4264 4265 if (!a_buttons || !a_buttons.length) 4337 4266 return; 4338 4267 4339 for(var n=0; n<a_buttons.length; n++) 4340 { 4268 for (var n=0; n<a_buttons.length; n++) { 4341 4269 button = a_buttons[n]; 4342 if(button.id==id && button.status=='act') 4343 { 4270 if (button.id == id && button.status == 'act') { 4344 4271 elm = document.getElementById(button.id); 4345 4272 if (elm && button.sel) { … … 4357 4284 this.button_out = function(command, id) 4358 4285 { 4359 var a_buttons = this.buttons[command]; 4360 var button, elm; 4361 4362 if(!a_buttons || !a_buttons.length) 4286 var button, elm, a_buttons = this.buttons[command]; 4287 4288 if (!a_buttons || !a_buttons.length) 4363 4289 return; 4364 4290 4365 for(var n=0; n<a_buttons.length; n++) 4366 { 4291 for (var n=0; n<a_buttons.length; n++) { 4367 4292 button = a_buttons[n]; 4368 if(button.id==id && button.status=='act') 4369 { 4293 if (button.id == id && button.status == 'act') { 4370 4294 elm = document.getElementById(button.id); 4371 4295 if (elm && button.act) { … … 4384 4308 if (title && document.title) 4385 4309 document.title = title; 4386 } 4310 }; 4387 4311 4388 4312 // display a system message 4389 4313 this.display_message = function(msg, type, hold) 4390 {4391 if (!this.loaded) // save message in order to display after page loaded4392 {4314 { 4315 if (!this.loaded) { 4316 // save message in order to display after page loaded 4393 4317 this.pending_message = new Array(msg, type); 4394 4318 return true; 4395 }4319 } 4396 4320 4397 4321 // pass command to parent window … … 4404 4328 if (this.message_timer) 4405 4329 clearTimeout(this.message_timer); 4406 4330 4407 4331 var cont = msg; 4408 4332 if (type) … … 4410 4334 4411 4335 var obj = $(this.gui_objects.message).html(cont).show(); 4412 4336 4413 4337 if (type!='loading') 4414 4338 obj.bind('mousedown', function(){ ref.hide_message(); return true; }); 4415 4339 4416 4340 if (!hold) 4417 4341 this.message_timer = window.setTimeout(function(){ ref.hide_message(true); }, this.message_time); 4418 };4342 }; 4419 4343 4420 4344 // make a message row disapear 4421 4345 this.hide_message = function(fade) 4422 {4346 { 4423 4347 if (this.gui_objects.message) 4424 4348 $(this.gui_objects.message).unbind()[(fade?'fadeOut':'hide')](); 4425 };4349 }; 4426 4350 4427 4351 // mark a mailbox as selected and set environment variable 4428 4352 this.select_folder = function(name, old, prefix) 4429 4353 { 4430 if (this.gui_objects.folderlist) 4431 { 4354 if (this.gui_objects.folderlist) { 4432 4355 var current_li, target_li; 4433 4356 4434 4357 if ((current_li = this.get_folder_li(old, prefix))) { 4435 4358 $(current_li).removeClass('selected').removeClass('unfocused'); … … 4438 4361 $(target_li).removeClass('unfocused').addClass('selected'); 4439 4362 } 4440 4363 4441 4364 // trigger event hook 4442 4365 this.triggerEvent('selectfolder', { folder:name, old:old, prefix:prefix }); … … 4449 4372 if (!prefix) 4450 4373 prefix = 'rcmli'; 4451 if (this.gui_objects.folderlist) 4452 {4374 4375 if (this.gui_objects.folderlist) { 4453 4376 name = String(name).replace(this.identifier_expr, '_'); 4454 4377 return document.getElementById(prefix+name); … … 4463 4386 { 4464 4387 this.env.coltypes = coltypes; 4465 4388 4466 4389 // set correct list titles 4467 4390 var thead = this.gui_objects.messagelist ? this.gui_objects.messagelist.tHead : null; … … 4482 4405 4483 4406 var cell, col, n; 4484 for (n=0; thead && n<this.env.coltypes.length; n++) 4485 { 4407 for (n=0; thead && n<this.env.coltypes.length; n++) { 4486 4408 col = this.env.coltypes[n]; 4487 if ((cell = thead.rows[0].cells[n+1]) && (col=='from' || col=='to')) 4488 { 4409 if ((cell = thead.rows[0].cells[n+1]) && (col=='from' || col=='to')) { 4489 4410 // if we have links for sorting, it's a bit more complicated... 4490 if (cell.firstChild && cell.firstChild.tagName.toLowerCase()=='a') 4491 { 4411 if (cell.firstChild && cell.firstChild.tagName.toLowerCase()=='a') { 4492 4412 cell.firstChild.innerHTML = this.get_label(this.env.coltypes[n]); 4493 4413 cell.firstChild.onclick = function(){ return rcmail.command('sort', this.__col, this); }; 4494 4414 cell.firstChild.__col = col; 4495 }4415 } 4496 4416 else 4497 4417 cell.innerHTML = this.get_label(this.env.coltypes[n]); 4498 4418 4499 4419 cell.id = 'rcm'+col; 4500 }4501 }4420 } 4421 } 4502 4422 4503 4423 // remove excessive columns … … 4509 4429 4510 4430 var found; 4511 if((found = jQuery.inArray('subject', this.env.coltypes)) >= 0) {4431 if((found = $.inArray('subject', this.env.coltypes)) >= 0) { 4512 4432 this.set_env('subject_col', found); 4513 4433 if (this.message_list) 4514 4434 this.message_list.subject_col = found+1; 4515 }4516 if((found = jQuery.inArray('flag', this.env.coltypes)) >= 0)4435 } 4436 if((found = $.inArray('flag', this.env.coltypes)) >= 0) 4517 4437 this.set_env('flagged_col', found); 4518 4438 }; … … 4520 4440 // replace content of row count display 4521 4441 this.set_rowcount = function(text) 4522 {4442 { 4523 4443 $(this.gui_objects.countdisplay).html(text); 4524 4444 4525 4445 // update page navigation buttons 4526 4446 this.set_page_buttons(); 4527 };4447 }; 4528 4448 4529 4449 // replace content of mailboxname display 4530 4450 this.set_mailboxname = function(content) 4531 {4451 { 4532 4452 if (this.gui_objects.mailboxname && content) 4533 4453 this.gui_objects.mailboxname.innerHTML = content; 4534 };4454 }; 4535 4455 4536 4456 // replace content of quota display 4537 4457 this.set_quota = function(content) 4538 {4458 { 4539 4459 if (content && this.gui_objects.quotadisplay) { 4540 4460 if (typeof(content) == 'object') … … 4542 4462 else 4543 4463 $(this.gui_objects.quotadisplay).html(content); 4544 }4545 };4464 } 4465 }; 4546 4466 4547 4467 // update the mailboxlist 4548 4468 this.set_unread_count = function(mbox, count, set_title) 4549 {4469 { 4550 4470 if (!this.gui_objects.mailboxlist) 4551 4471 return false; … … 4553 4473 this.env.unread_counts[mbox] = count; 4554 4474 this.set_unread_count_display(mbox, set_title); 4555 }4475 }; 4556 4476 4557 4477 // update the mailbox count display 4558 4478 this.set_unread_count_display = function(mbox, set_title) 4559 {4479 { 4560 4480 var reg, text_obj, item, mycount, childcount, div; 4561 if (item = this.get_folder_li(mbox)) 4562 { 4481 if (item = this.get_folder_li(mbox)) { 4563 4482 mycount = this.env.unread_counts[mbox] ? this.env.unread_counts[mbox] : 0; 4564 4483 text_obj = item.getElementsByTagName('a')[0]; … … 4567 4486 childcount = 0; 4568 4487 if ((div = item.getElementsByTagName('div')[0]) && 4569 div.className.match(/collapsed/)) 4570 { 4488 div.className.match(/collapsed/)) { 4571 4489 // add children's counters 4572 4490 for (var k in this.env.unread_counts) 4573 4491 if (k.indexOf(mbox + this.env.delimiter) == 0) 4574 4492 childcount += this.env.unread_counts[k]; 4575 }4493 } 4576 4494 4577 4495 if (mycount && text_obj.innerHTML.match(reg)) … … 4592 4510 else 4593 4511 $(item).removeClass('unread'); 4594 }4512 } 4595 4513 4596 4514 // set unread count to window title 4597 4515 reg = /^\([0-9]+\)\s+/i; 4598 if (set_title && document.title) 4599 { 4516 if (set_title && document.title) { 4600 4517 var doc_title = String(document.title); 4601 4518 var new_title = ""; … … 4607 4524 else 4608 4525 new_title = doc_title.replace(reg, ''); 4609 4526 4610 4527 this.set_pagetitle(new_title); 4611 }4612 };4528 } 4529 }; 4613 4530 4614 4531 // notifies that a new message(s) has hit the mailbox 4615 4532 this.new_message_focus = function() 4616 {4533 { 4617 4534 // focus main window 4618 4535 if (this.env.framed && window.parent) … … 4620 4537 else 4621 4538 window.focus(); 4622 }4539 }; 4623 4540 4624 4541 this.toggle_prefer_html = function(checkbox) 4625 {4542 { 4626 4543 var addrbook_show_images; 4627 4544 if (addrbook_show_images = document.getElementById('rcmfd_addrbook_show_images')) 4628 4545 addrbook_show_images.disabled = !checkbox.checked; 4629 }4546 }; 4630 4547 4631 4548 this.toggle_preview_pane = function(checkbox) 4632 {4549 { 4633 4550 var preview_pane_mark_read; 4634 4551 if (preview_pane_mark_read = document.getElementById('rcmfd_preview_pane_mark_read')) 4635 4552 preview_pane_mark_read.disabled = !checkbox.checked; 4636 }4553 }; 4637 4554 4638 4555 // display fetched raw headers … … 4651 4568 // display all-headers row and fetch raw message headers 4652 4569 this.load_headers = function(elem) 4653 {4570 { 4654 4571 if (!this.gui_objects.all_headers_row || !this.gui_objects.all_headers_box || !this.env.uid) 4655 4572 return; 4656 4573 4657 4574 $(elem).removeClass('show-headers').addClass('hide-headers'); 4658 4575 $(this.gui_objects.all_headers_row).show(); 4659 elem.onclick = function() { rcmail.hide_headers(elem); } 4576 elem.onclick = function() { rcmail.hide_headers(elem); }; 4660 4577 4661 4578 // fetch headers only once 4662 if (!this.gui_objects.all_headers_box.innerHTML) 4663 { 4579 if (!this.gui_objects.all_headers_box.innerHTML) { 4664 4580 this.display_message(this.get_label('loading'), 'loading', true); 4665 4581 this.http_post('headers', '_uid='+this.env.uid); 4666 }4667 }4582 } 4583 }; 4668 4584 4669 4585 // hide all-headers row 4670 4586 this.hide_headers = function(elem) 4671 {4587 { 4672 4588 if (!this.gui_objects.all_headers_row || !this.gui_objects.all_headers_box) 4673 4589 return; … … 4675 4591 $(elem).removeClass('hide-headers').addClass('show-headers'); 4676 4592 $(this.gui_objects.all_headers_row).hide(); 4677 elem.onclick = function() { rcmail.load_headers(elem); } 4678 }4593 elem.onclick = function() { rcmail.load_headers(elem); }; 4594 }; 4679 4595 4680 4596 // percent (quota) indicator 4681 4597 this.percent_indicator = function(obj, data) 4682 {4598 { 4683 4599 if (!data || !obj) 4684 4600 return false; … … 4694 4610 this.env.indicator_width = width; 4695 4611 this.env.indicator_height = height; 4696 4612 4697 4613 // overlimit 4698 4614 if (quota_width > width) { 4699 4615 quota_width = width; 4700 4616 quota = 100; 4701 }4702 4617 } 4618 4703 4619 // main div 4704 4620 var main = $('<div>'); 4705 4621 main.css({position: 'absolute', top: pos.top, left: pos.left, 4706 width: width + 'px', height: height + 'px', zIndex: 100, lineHeight: height + 'px'})4707 .attr('title', data.title).addClass('quota_text').html(quota + '%');4622 width: width + 'px', height: height + 'px', zIndex: 100, lineHeight: height + 'px'}) 4623 .attr('title', data.title).addClass('quota_text').html(quota + '%'); 4708 4624 // used bar 4709 4625 var bar1 = $('<div>'); 4710 4626 bar1.css({position: 'absolute', top: pos.top + 1, left: pos.left + 1, 4711 width: quota_width + 'px', height: height + 'px', zIndex: 99});4627 width: quota_width + 'px', height: height + 'px', zIndex: 99}); 4712 4628 // background 4713 4629 var bar2 = $('<div>'); 4714 4630 bar2.css({position: 'absolute', top: pos.top + 1, left: pos.left + 1, 4715 width: width + 'px', height: height + 'px', zIndex: 98})4716 .addClass('quota_bg');4631 width: width + 'px', height: height + 'px', zIndex: 98}) 4632 .addClass('quota_bg'); 4717 4633 4718 4634 if (quota >= limit_high) { 4719 4635 main.addClass(' quota_text_high'); 4720 4636 bar1.addClass('quota_high'); 4721 }4637 } 4722 4638 else if(quota >= limit_mid) { 4723 4639 main.addClass(' quota_text_mid'); 4724 4640 bar1.addClass('quota_mid'); 4725 }4641 } 4726 4642 else { 4727 4643 main.addClass(' quota_text_normal'); 4728 4644 bar1.addClass('quota_low'); 4729 }4645 } 4730 4646 4731 4647 // replace quota image 4732 4648 obj.innerHTML = ''; 4733 4649 $(obj).append(bar1).append(bar2).append(main); 4734 }4650 }; 4735 4651 4736 4652 /********************************************************/ … … 4739 4655 4740 4656 this.html2plain = function(htmlText, id) 4741 {4657 { 4742 4658 var url = this.env.bin_path+'html2text.php'; 4743 4659 var rcmail = this; … … 4749 4665 error: function(o) { rcmail.http_error(o); }, 4750 4666 success: function(data) { rcmail.set_busy(false); $(document.getElementById(id)).val(data); console.log(data); } 4751 });4752 }4667 }); 4668 }; 4753 4669 4754 4670 this.plain2html = function(plainText, id) 4755 {4671 { 4756 4672 this.set_busy(true, 'converting'); 4757 4673 $(document.getElementById(id)).val('<pre>'+plainText+'</pre>'); 4758 4674 this.set_busy(false); 4759 }4675 }; 4760 4676 4761 4677 … … 4765 4681 4766 4682 this.redirect = function(url, lock) 4767 {4683 { 4768 4684 if (lock || lock === null) 4769 4685 this.set_busy(true); … … 4773 4689 else 4774 4690 location.href = url; 4775 };4691 }; 4776 4692 4777 4693 this.goto_url = function(action, query, lock) 4778 {4694 { 4779 4695 var querystring = query ? '&'+query : ''; 4780 4696 this.redirect(this.env.comm_path+'&_action='+action+querystring, lock); 4781 };4697 }; 4782 4698 4783 4699 // send a http request to the server … … 4786 4702 querystring += (querystring ? '&' : '') + '_remote=1'; 4787 4703 var url = this.env.comm_path + '&_action=' + action + '&' + querystring 4788 4704 4789 4705 // send request 4790 4706 console.log('HTTP GET: ' + url); 4791 jQuery.get(url, { _unlock:(lock?1:0) }, function(data){ ref.http_response(data); }, 'json');4707 $.get(url, { _unlock:(lock?1:0) }, function(data){ ref.http_response(data); }, 'json'); 4792 4708 }; 4793 4709 … … 4796 4712 { 4797 4713 var url = this.env.comm_path+'&_action=' + action; 4798 4714 4799 4715 if (postdata && typeof(postdata) == 'object') { 4800 4716 postdata._remote = 1; … … 4806 4722 // send request 4807 4723 console.log('HTTP POST: ' + url); 4808 jQuery.post(url, postdata, function(data){ ref.http_response(data); }, 'json');4724 $.post(url, postdata, function(data){ ref.http_response(data); }, 'json'); 4809 4725 }; 4810 4726 … … 4813 4729 { 4814 4730 var console_msg = ''; 4815 4731 4816 4732 if (response.unlock) 4817 4733 this.set_busy(false); … … 4833 4749 eval(response.exec); 4834 4750 } 4835 4751 4836 4752 // execute callback functions of plugins 4837 4753 if (response.callbacks && response.callbacks.length) { … … 4849 4765 this.enable_command('export', (this.contact_list && this.contact_list.rowcount > 0)); 4850 4766 } 4851 4767 4852 4768 case 'moveto': 4853 4769 if (this.env.action == 'show') { … … 4857 4773 this.message_list.init(); 4858 4774 break; 4859 4775 4860 4776 case 'purge': 4861 4777 case 'expunge': … … 4883 4799 this.enable_command('show', 'expunge', 'select-all', 'select-none', 'sort', (this.env.messagecount > 0)); 4884 4800 this.enable_command('purge', this.purge_mailbox_test()); 4885 4801 4886 4802 this.enable_command('expand-all', 'expand-unread', 'collapse-all', this.env.threading && this.env.messagecount); 4887 4803 … … 4891 4807 else if (this.task == 'addressbook') { 4892 4808 this.enable_command('export', (this.contact_list && this.contact_list.rowcount > 0)); 4893 4809 4894 4810 if (response.action == 'list') { 4895 4811 this.enable_command('group-create', this.env.address_sources[this.env.source].groups); … … 4904 4820 // handle HTTP request errors 4905 4821 this.http_error = function(request, status, err) 4906 {4822 { 4907 4823 var errmsg = request.statusText; 4908 4824 4909 4825 this.set_busy(false); 4910 4826 request.abort(); 4911 4827 4912 4828 if (errmsg) 4913 4829 this.display_message(this.get_label('servererror') + ' (' + errmsg + ')', 'error'); 4914 };4830 }; 4915 4831 4916 4832 // use an image to send a keep-alive siganl to the server 4917 4833 this.send_keep_alive = function() 4918 {4834 { 4919 4835 var d = new Date(); 4920 4836 this.http_request('keep-alive', '_t='+d.getTime()); 4921 };4837 }; 4922 4838 4923 4839 // start interval for keep-alive/recent_check signal 4924 4840 this.start_keepalive = function() 4925 {4841 { 4926 4842 if (this.env.keep_alive && !this.env.framed && this.task=='mail' && this.gui_objects.mailboxlist) 4927 4843 this._int = setInterval(function(){ ref.check_for_recent(false); }, this.env.keep_alive * 1000); 4928 4844 else if (this.env.keep_alive && !this.env.framed && this.task!='login') 4929 4845 this._int = setInterval(function(){ ref.send_keep_alive(); }, this.env.keep_alive * 1000); 4930 }4846 }; 4931 4847 4932 4848 // send periodic request to check for recent messages 4933 4849 this.check_for_recent = function(refresh) 4934 {4850 { 4935 4851 if (this.busy) 4936 4852 return; … … 4951 4867 4952 4868 this.http_request('check-recent', addurl, true); 4953 };4869 }; 4954 4870 4955 4871 … … 4957 4873 /********* helper methods *********/ 4958 4874 /********************************************************/ 4959 4875 4960 4876 // check if we're in show mode or if we have a unique selection 4961 4877 // and return the message uid 4962 4878 this.get_single_uid = function() 4963 {4879 { 4964 4880 return this.env.uid ? this.env.uid : (this.message_list ? this.message_list.get_single_selection() : null); 4965 };4881 }; 4966 4882 4967 4883 // same as above but for contacts 4968 4884 this.get_single_cid = function() 4969 {4885 { 4970 4886 return this.env.cid ? this.env.cid : (this.contact_list ? this.contact_list.get_single_selection() : null); 4971 };4972 4973 4887 }; 4888 4889 // gets cursor position 4974 4890 this.get_caret_pos = function(obj) 4975 {4891 { 4976 4892 if (typeof(obj.selectionEnd)!='undefined') 4977 4893 return obj.selectionEnd; 4978 else if (document.selection && document.selection.createRange) 4979 { 4894 else if (document.selection && document.selection.createRange) { 4980 4895 var range = document.selection.createRange(); 4981 4896 if (range.parentElement()!=obj) … … 4983 4898 4984 4899 var gm = range.duplicate(); 4985 if (obj.tagName =='TEXTAREA')4900 if (obj.tagName == 'TEXTAREA') 4986 4901 gm.moveToElementText(obj); 4987 4902 else 4988 4903 gm.expand('textedit'); 4989 4904 4990 4905 gm.setEndPoint('EndToStart', range); 4991 4906 var p = gm.text.length; 4992 4907 4993 4908 return p<=obj.value.length ? p : -1; 4994 }4909 } 4995 4910 else 4996 4911 return obj.value.length; 4997 }; 4998 4912 }; 4913 4914 // moves cursor to specified position 4999 4915 this.set_caret_pos = function(obj, pos) 5000 {4916 { 5001 4917 if (obj.setSelectionRange) 5002 4918 obj.setSelectionRange(pos, pos); 5003 else if (obj.createTextRange) 5004 { 4919 else if (obj.createTextRange) { 5005 4920 var range = obj.createTextRange(); 5006 4921 range.collapse(true); … … 5008 4923 range.moveStart('character', pos); 5009 4924 range.select(); 5010 }5011 }4925 } 4926 }; 5012 4927 5013 4928 // set all fields of a form disabled 5014 4929 this.lock_form = function(form, lock) 5015 {4930 { 5016 4931 if (!form || !form.elements) 5017 4932 return; 5018 4933 5019 4934 var type; 5020 for (var n=0; n<form.elements.length; n++) 5021 { 4935 for (var n=0; n<form.elements.length; n++) { 5022 4936 type = form.elements[n]; 5023 4937 if (type=='hidden') 5024 4938 continue; 5025 4939 5026 4940 form.elements[n].disabled = lock; 5027 }5028 };5029 4941 } 4942 }; 4943 5030 4944 } // end object rcube_webmail 5031 4945 -
program/js/common.js
r186537b r8fa9229 25 25 */ 26 26 function roundcube_browser() 27 {27 { 28 28 this.ver = parseFloat(navigator.appVersion); 29 29 this.appver = navigator.appVersion; … … 73 73 this.vendver = (/khtml\/([0-9\.]+)/i.test(this.agent)) ? parseFloat(RegExp.$1) : 0; 74 74 75 76 75 // get real language out of safari's user agent 77 76 if(this.safari && (/;\s+([a-z]{2})-[a-z]{2}\)/i.test(this.agent))) … … 86 85 87 86 // test for XMLHTTP support 88 this.xmlhttp_test = function() 89 { 87 this.xmlhttp_test = function() { 90 88 var activeX_test = new Function("try{var o=new ActiveXObject('Microsoft.XMLHTTP');return true;}catch(err){return false;}"); 91 89 this.xmlhttp = (window.XMLHttpRequest || (window.ActiveXObject && activeX_test())) ? true : false; 92 90 return this.xmlhttp; 93 }94 } 91 } 92 }; 95 93 96 94 … … 133 131 e = e || window.event; 134 132 135 if (bw.mac && e) 136 { 133 if (bw.mac && e) { 137 134 opcode += (e.metaKey && CONTROL_KEY) + (e.shiftKey && SHIFT_KEY); 138 135 return opcode; 139 } 140 if (e) 141 { 136 } 137 if (e) { 142 138 opcode += (e.ctrlKey && CONTROL_KEY) + (e.shiftKey && SHIFT_KEY); 143 139 return opcode; 144 }140 } 145 141 }, 146 142 … … 154 150 var mY = (e.pageY) ? e.pageY : e.clientY; 155 151 156 if (document.body && document.all) 157 { 152 if (document.body && document.all) { 158 153 mX += document.body.scrollLeft; 159 154 mY += document.body.scrollTop; … … 187 182 if (p.element.addEventListener) 188 183 p.element.addEventListener(p.event, p.object._rc_events[key], false); 189 else if (p.element.attachEvent) 190 { 184 else if (p.element.attachEvent) { 191 185 // IE allows multiple events with the same function to be applied to the same object 192 186 // forcibly detach the event, then attach 193 187 p.element.detachEvent('on'+p.event, p.object._rc_events[key]); 194 188 p.element.attachEvent('on'+p.event, p.object._rc_events[key]); 195 }189 } 196 190 else 197 191 p.element['on'+p.event] = p.object._rc_events[key]; … … 242 236 { 243 237 this._events = {}; 244 } 238 }; 245 239 246 240 rcube_event_engine.prototype = { … … 314 308 } 315 309 316 } // end rcube_event_engine.prototype310 }; // end rcube_event_engine.prototype 317 311 318 312 … … 329 323 // create a new layer in the current document 330 324 this.create = function(arg) 331 {325 { 332 326 var l = (arg.x) ? arg.x : 0; 333 327 var t = (arg.y) ? arg.y : 0; … … 341 335 obj = document.createElement('DIV'); 342 336 343 with(obj) 344 { 337 with(obj) { 345 338 id = this.name; 346 with(style) 347 { 348 position = 'absolute'; 339 with(style) { 340 position = 'absolute'; 349 341 visibility = (vis) ? (vis==2) ? 'inherit' : 'visible' : 'hidden'; 350 342 left = l+'px'; 351 343 top = t+'px'; 352 344 if (w) 353 width = w.toString().match(/\%$/) ? w : w+'px';345 width = w.toString().match(/\%$/) ? w : w+'px'; 354 346 if (h) 355 height = h.toString().match(/\%$/) ? h : h+'px';347 height = h.toString().match(/\%$/) ? h : h+'px'; 356 348 if(z) zIndex = z; 357 }358 }349 } 350 } 359 351 360 352 if (parent) … … 364 356 365 357 this.elm = obj; 366 }; 367 358 }; 368 359 369 360 // create new layer 370 if(attributes!=null) 371 { 361 if(attributes != null) { 372 362 this.create(attributes); 373 363 this.name = this.elm.id; 374 }364 } 375 365 else // just refer to the object 376 366 this.elm = document.getElementById(id); 377 378 367 379 368 if(!this.elm) … … 394 383 // ********* layer object methods ********* 395 384 396 397 385 // move the layer to a specific position 398 386 this.move = function(x, y) 399 {387 { 400 388 this.x = x; 401 389 this.y = y; 402 390 this.css.left = Math.round(this.x)+'px'; 403 391 this.css.top = Math.round(this.y)+'px'; 404 }392 }; 405 393 406 394 // change the layers width and height 407 395 this.resize = function(w,h) 408 {396 { 409 397 this.css.width = w+'px'; 410 398 this.css.height = h+'px'; 411 399 this.width = w; 412 400 this.height = h; 413 } 414 401 }; 415 402 416 403 // show or hide the layer 417 404 this.show = function(a) 418 { 419 if(a==1) 420 { 405 { 406 if(a == 1) { 421 407 this.css.visibility = 'visible'; 422 408 this.visible = true; 423 } 424 else if(a==2) 425 { 409 } 410 else if(a == 2) { 426 411 this.css.visibility = 'inherit'; 427 412 this.visible = true; 428 } 429 else 430 { 413 } 414 else { 431 415 this.css.visibility = 'hidden'; 432 416 this.visible = false; 433 }434 417 } 435 418 }; 436 419 437 420 // write new content into a Layer 438 421 this.write = function(cont) 439 {422 { 440 423 this.elm.innerHTML = cont; 441 }442 443 } 424 }; 425 426 }; 444 427 445 428 … … 448 431 // http://code.iamcal.com/php/rfc822/ 449 432 function rcube_check_email(input, inline) 450 { 451 if (input && window.RegExp) 452 { 433 { 434 if (input && window.RegExp) { 453 435 var qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]'; 454 436 var dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]'; … … 465 447 var reg1 = inline ? new RegExp('(^|<|'+delim+')'+addr_spec+'($|>|'+delim+')', 'i') : new RegExp('^'+addr_spec+'$', 'i'); 466 448 return reg1.test(input) ? true : false; 467 }449 } 468 450 return false; 469 } 470 451 }; 452 471 453 472 454 // recursively copy an object … … 483 465 484 466 return out; 485 } 467 }; 486 468 487 469 // make a string URL safe … … 489 471 { 490 472 return window.encodeURIComponent ? encodeURIComponent(str) : escape(str); 491 } 473 }; 492 474 493 475 … … 524 506 525 507 return obj; 526 } 508 }; 527 509 528 510 // determine whether the mouse is over the given object or not … … 534 516 return ((mouse.x >= pos.left) && (mouse.x < (pos.left + obj.offsetWidth)) && 535 517 (mouse.y >= pos.top) && (mouse.y < (pos.top + obj.offsetHeight))); 536 } 518 }; 537 519 538 520 539 521 // cookie functions by GoogieSpell 540 522 function setCookie(name, value, expires, path, domain, secure) 541 {523 { 542 524 var curCookie = name + "=" + escape(value) + 543 525 (expires ? "; expires=" + expires.toGMTString() : "") + … … 546 528 (secure ? "; secure" : ""); 547 529 document.cookie = curCookie; 548 } 549 550 roundcube_browser.prototype.set_cookie = setCookie; 530 }; 551 531 552 532 function getCookie(name) 553 {533 { 554 534 var dc = document.cookie; 555 535 var prefix = name + "="; 556 536 var begin = dc.indexOf("; " + prefix); 557 if (begin == -1) 558 { 537 if (begin == -1) { 559 538 begin = dc.indexOf(prefix); 560 539 if (begin != 0) return null; 561 }540 } 562 541 else 563 542 begin += 2; … … 566 545 end = dc.length; 567 546 return unescape(dc.substring(begin + prefix.length, end)); 568 } 569 547 }; 548 549 roundcube_browser.prototype.set_cookie = setCookie; 570 550 roundcube_browser.prototype.get_cookie = getCookie; 571 551 … … 598 578 box.innerText = box.value = ''; 599 579 }; 600 } 580 }; 601 581 602 582 var bw = new roundcube_browser(); … … 608 588 // http://dev.rubyonrails.org/changeset/7271 609 589 RegExp.escape = function(str) 610 {590 { 611 591 return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); 612 } 592 }; 613 593 614 594 615 595 // Make getElementById() case-sensitive on IE 616 596 if (bw.ie) 617 {597 { 618 598 document._getElementById = document.getElementById; 619 599 document.getElementById = function(id) 620 {600 { 621 601 var i = 0; 622 602 var o = document._getElementById(id); … … 627 607 628 608 return o; 629 }630 } 609 } 610 }; -
program/js/list.js
rda8f11c r8fa9229 23 23 */ 24 24 function rcube_list_widget(list, p) 25 {25 { 26 26 // static contants 27 27 this.ENTER_KEY = 13; 28 28 this.DELETE_KEY = 46; 29 29 this.BACKSPACE_KEY = 8; 30 30 31 31 this.list = list ? list : null; 32 32 this.frame = null; … … 34 34 this.selection = []; 35 35 this.rowcount = 0; 36 36 37 37 this.subject_col = -1; 38 38 this.shiftkey = false; … … 43 43 this.keyboard = false; 44 44 this.toggleselect = false; 45 45 46 46 this.dont_select = false; 47 47 this.drag_active = false; … … 53 53 this.dblclick_time = 600; 54 54 this.row_init = function(){}; 55 55 56 56 // overwrite default paramaters 57 if (p && typeof(p) =='object')57 if (p && typeof(p) == 'object') 58 58 for (var n in p) 59 59 this[n] = p[n]; 60 } 60 }; 61 61 62 62 … … 69 69 init: function() 70 70 { 71 if (this.list && this.list.tBodies[0]) 72 { 73 this.rows = new Array(); 71 if (this.list && this.list.tBodies[0]) { 72 this.rows = []; 74 73 this.rowcount = 0; 75 74 76 75 var row; 77 for(var r=0; r<this.list.tBodies[0].childNodes.length; r++) 78 { 76 for(var r=0; r<this.list.tBodies[0].childNodes.length; r++) { 79 77 row = this.list.tBodies[0].childNodes[r]; 80 while (row && row.nodeType != 1) 81 { 78 while (row && row.nodeType != 1) { 82 79 row = row.nextSibling; 83 80 r++; … … 105 102 { 106 103 // make references in internal array and set event handlers 107 if (row && String(row.id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i)) 108 { 104 if (row && String(row.id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i)) { 109 105 var p = this; 110 106 var uid = RegExp.$1; … … 132 128 this.list.insertBefore(tbody, this.list.tBodies[0]); 133 129 this.list.removeChild(this.list.tBodies[1]); 134 this.rows = new Array();130 this.rows = []; 135 131 this.rowcount = 0; 136 137 if (sel) this.clear_selection(); 132 133 if (sel) 134 this.clear_selection(); 138 135 }, 139 136 … … 182 179 { 183 180 this.focused = true; 184 for (var n=0; n<this.selection.length; n++) 185 { 181 for (var n=0; n<this.selection.length; n++) { 186 182 id = this.selection[n]; 187 183 if (this.rows[id] && this.rows[id].obj) { … … 202 198 var id; 203 199 this.focused = false; 204 for (var n=0; n<this.selection.length; n++) 205 { 200 for (var n=0; n<this.selection.length; n++) { 206 201 id = this.selection[n]; 207 202 if (this.rows[id] && this.rows[id].obj) { … … 222 217 if (this.dont_select || (evtarget && (tagname == 'input' || tagname == 'img'))) 223 218 return true; 224 219 225 220 // accept right-clicks 226 221 if (rcube_event.get_button(e) == 2) 227 222 return true; 228 223 229 224 this.in_selection_before = this.in_selection(id) ? id : false; 230 225 231 226 // selects currently unselected row 232 if (!this.in_selection_before) 233 { 227 if (!this.in_selection_before) { 234 228 var mod_key = rcube_event.get_modifier(e); 235 229 this.select_row(id, mod_key, false); 236 230 } 237 231 238 if (this.draggable && this.selection.length) 239 { 232 if (this.draggable && this.selection.length) { 240 233 this.drag_start = true; 241 234 this.drag_mouse_start = rcube_event.get_mouse_pos(e); … … 273 266 274 267 // don't do anything (another action processed before) 275 if (this.dont_select) 276 { 268 if (this.dont_select) { 277 269 this.dont_select = false; 278 270 return false; 279 271 } 280 272 281 273 var dblclicked = now - this.rows[id].clicked < this.dblclick_time; 282 274 … … 426 418 this.update_expando(row.uid); 427 419 this.triggerEvent('expandcollapse', { uid:row.uid, expanded:row.expanded }); 428 420 429 421 // don't collapse sub-root tree in multiexpand mode 430 422 if (depth && this.multiexpand) … … 536 528 get_first_row: function() 537 529 { 538 if (this.rowcount) 539 { 530 if (this.rowcount) { 540 531 var rows = this.list.tBodies[0].rows; 541 532 542 533 for(var i=0; i<rows.length-1; i++) 543 534 if(rows[i].id && String(rows[i].id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i) && this.rows[RegExp.$1] != null) 535 544 536 return RegExp.$1; 545 }537 } 546 538 547 539 return null; … … 550 542 get_last_row: function() 551 543 { 552 if (this.rowcount) 553 { 544 if (this.rowcount) { 554 545 var rows = this.list.tBodies[0].rows; 555 546 556 547 for(var i=rows.length-1; i>=0; i--) 557 548 if(rows[i].id && String(rows[i].id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i) && this.rows[RegExp.$1] != null) 549 558 550 return RegExp.$1; 559 }551 } 560 552 561 553 return null; … … 571 563 if (!this.multiselect) 572 564 mod_key = 0; 573 565 574 566 if (!this.shift_start) 575 567 this.shift_start = id 576 568 577 if (!mod_key) 578 { 569 if (!mod_key) { 579 570 this.shift_start = id; 580 571 this.highlight_row(id, false); 581 572 this.multi_selecting = false; 582 573 } 583 else 584 { 585 switch (mod_key) 586 { 574 else { 575 switch (mod_key) { 587 576 case SHIFT_KEY: 588 577 this.shift_select(id, false); … … 613 602 614 603 // unselect if toggleselect is active and the same row was clicked again 615 if (this.toggleselect && this.last_selected == id) 616 { 604 if (this.toggleselect && this.last_selected == id) { 617 605 this.clear_selection(); 618 606 id = null; … … 691 679 if (!this.rows[uid] || !this.rows[uid].has_children) 692 680 return; 693 681 694 682 var depth = this.rows[uid].depth; 695 683 var row = this.rows[uid].obj.nextSibling; … … 723 711 724 712 // iterate through the entire message list 725 for (var n in this.rows) 726 { 727 if ((this.rows[n].obj.rowIndex >= i) && (this.rows[n].obj.rowIndex <= j)) 728 { 713 for (var n in this.rows) { 714 if ((this.rows[n].obj.rowIndex >= i) && (this.rows[n].obj.rowIndex <= j)) { 729 715 if (!this.in_selection(n)) { 730 716 this.highlight_row(n, true); 731 717 } 732 718 } 733 else 734 { 719 else { 735 720 if (this.in_selection(n) && !control) { 736 721 this.highlight_row(n, true); … … 764 749 // reset but remember selection first 765 750 var select_before = this.selection.join(','); 766 this.selection = new Array(); 767 768 for (var n in this.rows) 769 { 770 if (!filter || (this.rows[n] && this.rows[n][filter] == true)) 771 { 751 this.selection = []; 752 753 for (var n in this.rows) { 754 if (!filter || (this.rows[n] && this.rows[n][filter] == true)) { 772 755 this.last_selected = n; 773 756 this.highlight_row(n, true); 774 757 } 775 else if (this.rows[n]) 776 { 758 else if (this.rows[n]) { 777 759 $(this.rows[n].obj).removeClass('selected').removeClass('unfocused'); 778 760 } … … 799 781 // remember old selection 800 782 var select_before = this.selection.join(','); 801 783 802 784 for (var n in this.rows) 803 785 this.highlight_row(n, true); … … 821 803 822 804 // one row 823 if (id) 824 { 805 if (id) { 825 806 for (var n=0; n<this.selection.length; n++) 826 807 if (this.selection[n] == id) { … … 828 809 break; 829 810 } 830 }811 } 831 812 // all rows 832 else 833 { 813 else { 834 814 for (var n=0; n<this.selection.length; n++) 835 815 if (this.rows[this.selection[n]]) { 836 816 $(this.rows[this.selection[n]].obj).removeClass('selected').removeClass('unfocused'); 837 }838 839 this.selection = new Array();840 }817 } 818 819 this.selection = []; 820 } 841 821 842 822 if (num_select && !this.selection.length) … … 871 851 highlight_row: function(id, multiple) 872 852 { 873 if (this.rows[id] && !multiple) 874 { 875 if (this.selection.length > 1 || !this.in_selection(id)) 876 { 853 if (this.rows[id] && !multiple) { 854 if (this.selection.length > 1 || !this.in_selection(id)) { 877 855 this.clear_selection(); 878 856 this.selection[0] = id; … … 880 858 } 881 859 } 882 else if (this.rows[id]) 883 { 884 if (!this.in_selection(id)) // select row 885 { 860 else if (this.rows[id]) { 861 if (!this.in_selection(id)) { // select row 886 862 this.selection[this.selection.length] = id; 887 863 $(this.rows[id].obj).addClass('selected'); 888 864 } 889 else // unselect row 890 { 891 var p = jQuery.inArray(id, this.selection); 865 else { // unselect row 866 var p = $.inArray(id, this.selection); 892 867 var a_pre = this.selection.slice(0, p); 893 868 var a_post = this.selection.slice(p+1, this.selection.length); … … 910 885 var mod_key = rcube_event.get_modifier(e); 911 886 912 switch (keyCode) 913 { 887 switch (keyCode) { 914 888 case 40: 915 889 case 38: … … 939 913 this.key_pressed = keyCode; 940 914 this.triggerEvent('keypress'); 941 915 942 916 if (this.key_pressed == this.BACKSPACE_KEY) 943 917 return rcube_event.cancel(e); 944 918 } 945 919 946 920 return true; 947 921 }, … … 952 926 key_down: function(e) 953 927 { 954 switch (rcube_event.get_keycode(e)) 955 { 928 switch (rcube_event.get_keycode(e)) { 956 929 case 27: 957 930 if (this.drag_active) 958 931 return this.drag_mouse_up(e); 959 932 960 933 case 40: 961 934 case 38: … … 968 941 if (!rcube_event.get_modifier(e) && this.focused) 969 942 return rcube_event.cancel(e); 970 943 971 944 default: 972 945 } 973 946 974 947 return true; 975 948 }, … … 989 962 new_row = this.get_prev_row(); 990 963 991 if (new_row) 992 { 964 if (new_row) { 993 965 this.select_row(new_row.uid, mod_key, true); 994 966 this.scrollto(new_row.uid); … … 1035 1007 { 1036 1008 var row = this.rows[id].obj; 1037 if (row && this.frame) 1038 { 1009 if (row && this.frame) { 1039 1010 var scroll_to = Number(row.offsetTop); 1040 1011 … … 1059 1030 drag_mouse_move: function(e) 1060 1031 { 1061 if (this.drag_start) 1062 { 1032 if (this.drag_start) { 1063 1033 // check mouse movement, of less than 3 pixels, don't start dragging 1064 1034 var m = rcube_event.get_mouse_pos(e); … … 1066 1036 if (!this.drag_mouse_start || (Math.abs(m.x - this.drag_mouse_start.x) < 3 && Math.abs(m.y - this.drag_mouse_start.y) < 3)) 1067 1037 return false; 1068 1038 1069 1039 if (!this.draglayer) 1070 1040 this.draglayer = $('<div>').attr('id', 'rcmdraglayer').css({ position:'absolute', display:'none', 'z-index':2000 }).appendTo(document.body); 1071 1041 1072 1042 // also select childs of (collapsed) threads for dragging 1073 1043 var selection = $.merge([], this.selection); … … 1082 1052 var names = ''; 1083 1053 var c, i, subject, obj; 1084 for(var n=0; n<this.selection.length; n++) 1085 { 1086 if (n>12) // only show 12 lines 1087 { 1054 for(var n=0; n<this.selection.length; n++) { 1055 // only show 12 lines 1056 if (n>12) { 1088 1057 names += '...'; 1089 1058 break; 1090 1059 } 1091 1060 1092 if (obj = this.rows[this.selection[n]].obj) 1093 { 1061 if (obj = this.rows[this.selection[n]].obj) { 1094 1062 subject = ''; 1095 1063 1096 for (c=0, i=0; i<obj.childNodes.length; i++) 1097 { 1098 if (obj.childNodes[i].nodeName == 'TD') 1099 { 1064 for (c=0, i=0; i<obj.childNodes.length; i++) { 1065 if (obj.childNodes[i].nodeName == 'TD') { 1100 1066 if (n == 0) 1101 this.drag_start_pos = $(obj.childNodes[i]).offset(); 1102 1103 if (this.subject_col < 0 || (this.subject_col >= 0 && this.subject_col == c)) 1104 { 1105 var node, tmp_node, nodes = obj.childNodes[i].childNodes; 1106 // find text node 1107 for (m=0; m<nodes.length; m++) { 1108 if ((tmp_node = obj.childNodes[i].childNodes[m]) && (tmp_node.nodeType==3 || tmp_node.nodeName=='A')) 1109 node = tmp_node; 1110 } 1111 1112 if (!node) 1113 break; 1067 this.drag_start_pos = $(obj.childNodes[i]).offset(); 1068 1069 if (this.subject_col < 0 || (this.subject_col >= 0 && this.subject_col == c)) { 1070 var node, tmp_node, nodes = obj.childNodes[i].childNodes; 1071 // find text node 1072 for (m=0; m<nodes.length; m++) { 1073 if ((tmp_node = obj.childNodes[i].childNodes[m]) && (tmp_node.nodeType==3 || tmp_node.nodeName=='A')) 1074 node = tmp_node; 1075 } 1076 1077 if (!node) 1078 break; 1114 1079 1115 1080 subject = node.nodeType==3 ? node.data : node.innerHTML; 1116 // remove leading spaces1117 subject = subject.replace(/^\s+/i, '');1081 // remove leading spaces 1082 subject = subject.replace(/^\s+/i, ''); 1118 1083 // truncate line to 50 characters 1119 names += (subject.length > 50 ? subject.substring(0, 50)+'...' : subject) + '<br />';1084 names += (subject.length > 50 ? subject.substring(0, 50)+'...' : subject) + '<br />'; 1120 1085 break; 1121 1086 } … … 1133 1098 } 1134 1099 1135 if (this.drag_active && this.draglayer) 1136 { 1100 if (this.drag_active && this.draglayer) { 1137 1101 var pos = rcube_event.get_mouse_pos(e); 1138 1102 this.draglayer.css({ left:(pos.x+20)+'px', top:(pos.y-5 + (bw.ie ? document.documentElement.scrollTop : 0))+'px' });
Note: See TracChangeset
for help on using the changeset viewer.
