X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fstatic%2Fwclib.js;h=e6a57cfaa96951badb4efe67fe06f8b850d415a4;hb=8b15ba21b25ea45e21d5a4f10a8c5be108a54f77;hp=63fcd74525e6d2de46d7b58460263e4d5837ba75;hpb=2ee78ccecc589385a01ab403b1f64a27e0d2821d;p=citadel.git diff --git a/webcit/static/wclib.js b/webcit/static/wclib.js index 63fcd7452..e6a57cfaa 100644 --- a/webcit/static/wclib.js +++ b/webcit/static/wclib.js @@ -1,5 +1,5 @@ // -// $Id: wclib.js,v 625.2 2005/09/18 04:04:32 ajc Exp $ +// $Id$ // // JavaScript function library for WebCit. // @@ -7,6 +7,7 @@ var browserType; +var room_is_trash = 0; if (document.layers) {browserType = "nn4"} if (document.all) {browserType = "ie"} @@ -17,22 +18,37 @@ if (window.navigator.userAgent.toLowerCase().match("gecko")) { var ns6=document.getElementById&&!document.all; -// -// This code handles the popups for instant messages. -// +function CtdlRandomString() { + return((Math.random()+'').substr(3)); +} -function hide_page_popup() { - if (browserType == "gecko" ) - document.poppedLayer = eval('document.getElementById(\'page_popup\')'); - else if (browserType == "ie") - document.poppedLayer = eval('document.all[\'page_popup\']'); - else - document.poppedLayer = eval('document.layers[\'`page_popup\']'); - document.poppedLayer.style.visibility = "hidden"; +// We love string tokenizers. +function extract_token(source_string, token_num, delimiter) { + var i = 0; + var extracted_string = source_string; + + if (token_num > 0) { + for (i=0; i= 0) { + extracted_string = extracted_string.substr(j+1); + } + } + } + + j = extracted_string.indexOf(delimiter); + if (j >= 0) { + extracted_string = extracted_string.substr(0, j); + } + + return extracted_string; } + + +// This code handles the popups for important-messages. function hide_imsg_popup() { if (browserType == "gecko" ) document.poppedLayer = eval('document.getElementById(\'important_message\')'); @@ -44,6 +60,7 @@ function hide_imsg_popup() { document.poppedLayer.style.visibility = "hidden"; } + // This function activates the ajax-powered recipient autocompleters on the message entry screen. function activate_entmsg_autocompleters() { new Ajax.Autocompleter('cc_id', 'cc_name_choices', 'cc_autocomplete', {} ); @@ -52,10 +69,64 @@ function activate_entmsg_autocompleters() { } + +// Toggle the icon bar between menu/roomlist... +var which_div_expanded = null; +var num_drop_targets = 0; +var drop_targets_elements = new Array(); +var drop_targets_roomnames = new Array(); + +function switch_to_room_list() { + $('iconbar').innerHTML = $('iconbar').innerHTML.substr(0, $('iconbar').innerHTML.indexOf('switch')); + CtdlLoadScreen('iconbar'); + new Ajax.Updater('iconbar', 'iconbar_ajax_rooms', { method: 'get' } ); +} + +function expand_floor(floor_div) { + if (which_div_expanded != null) { + if ($(which_div_expanded) != null) { + $(which_div_expanded).style.display = 'none' ; + } + } + + // clicking on the already-expanded floor causes the whole list to collapse + if (which_div_expanded == floor_div) { + which_div_expanded = null; + + // notify the server that no floors are expanded + new Ajax.Request( + 'set_floordiv_expanded/-1', { + method: 'post' + } + ); + return true; + } + + // expand the requested floor + $(floor_div).style.display = 'block'; + which_div_expanded = floor_div; + + // notify the server of which floor is expanded + new Ajax.Request( + 'set_floordiv_expanded/'+floor_div, { + method: 'post' + } + ); +} + +function switch_to_menu_buttons() { + which_div_expanded = null; + num_drop_targets = 0; + CtdlLoadScreen('iconbar'); + new Ajax.Updater('iconbar', 'iconbar_ajax_menu', { method: 'get' } ); +} + + // Static variables for mailbox view... // var CtdlNumMsgsSelected = 0; -var CtdlMsgsSelected = new Array(65536); // arbitrary +var CtdlMsgsSelected = new Array(); +var CtdlLastMsgnumSelected = 0; // This gets called when you single click on a message in the mailbox view. // We know that the element id of the table row will be the letter 'm' plus the message number. @@ -65,9 +136,10 @@ function CtdlSingleClickMsg(evt, msgnum) { // Clear the preview pane until we load the new message $('preview_pane').innerHTML = ''; - // De-select any messages that were already selected, *unless* the Ctrl key - // is being pressed, in which case the user wants multi select. - if (!evt.ctrlKey) { + // De-select any messages that were already selected, *unless* the Ctrl or + // Shift key is being pressed, in which case the user wants multi select + // or group select. + if ( (!evt.ctrlKey) && (!evt.shiftKey) ) { if (CtdlNumMsgsSelected > 0) { for (i=0; i 0) { + for (i=0; i 0) { + new Ajax.Request( + 'ajax_servcmd', { + method: 'post', + parameters: 'g_cmd=DELE ' + CtdlMsgsSelected[i], + onComplete: CtdlClearDeletedMsg(CtdlMsgsSelected[i]) + } + ); + } + else { + new Ajax.Request( + 'ajax_servcmd', { + method: 'post', + parameters: 'g_cmd=MOVE ' + CtdlMsgsSelected[i] + '|_TRASH_|0', + onComplete: CtdlClearDeletedMsg(CtdlMsgsSelected[i]) + } + ); + } + } + CtdlNumMsgsSelected = 0; + + // Clear the preview pane too. + $('preview_pane').innerHTML = ''; +} + + +// Move selected messages. +function CtdlMoveSelectedMessages(evt, target_roomname) { + if (CtdlNumMsgsSelected < 1) { // Nothing to delete, so exit silently. return false; @@ -124,9 +289,9 @@ function CtdlDeleteSelectedMessages(evt) { for (i=0; i 0) { + alert('FIXME do ajax call to move position x=' + d.style.left + ' y=' + d.style.top); + } + + uid_of_note_being_dragged = ''; + return true; +} + +function NotesDragMouseMove(evt) { + x = (ns6 ? evt.clientX : event.clientX); + x_increment = x - saved_x; + y = (ns6 ? evt.clientY : event.clientY); + y_increment = y - saved_y; + + // Move the div + d = $('note-' + uid_of_note_being_dragged); + + divTop = parseInt(d.style.top); + divLeft = parseInt(d.style.left); + + d.style.top = (divTop + y_increment) + 'px'; + d.style.left = (divLeft + x_increment) + 'px'; + + saved_x = x; + saved_y = y; + note_was_dragged = 1; + return true; +} + + +function NotesDragMouseDown(evt, uid) { + saved_x = (ns6 ? evt.clientX : event.clientX); + saved_y = (ns6 ? evt.clientY : event.clientY); + document.onmouseup = NotesDragMouseUp; + document.onmousemove = NotesDragMouseMove; if (document.layers) { - document.captureEvents(Event.MOUSEUP); + document.captureEvents(Event.MOUSEUP | Event.MOUSEMOVE); } + uid_of_note_being_dragged = uid; + d = $('note-' + uid_of_note_being_dragged); + saved_cursor_style = d.style.cursor; + d.style.cursor = 'move'; + return false; // disable the default action } + + + + + + + + + + + + + + +// These functions handle drag and drop message moving + +var mm_div = null; + +function CtdlMoveMsgMouseDown(evt, msgnum) { + + // do the highlight first + CtdlSingleClickMsg(evt, msgnum); + + // Now handle the possibility of dragging + saved_x = (ns6 ? evt.clientX : event.clientX); + saved_y = (ns6 ? evt.clientY : event.clientY); + document.onmouseup = CtdlMoveMsgMouseUp; + document.onmousemove = CtdlMoveMsgMouseMove; + if (document.layers) { + document.captureEvents(Event.MOUSEUP | Event.MOUSEMOVE); + } + + return false; +} + +function CtdlMoveMsgMouseMove(evt) { + x = (ns6 ? evt.clientX : event.clientX); + y = (ns6 ? evt.clientY : event.clientY); + + if ( (x == saved_x) && (y == saved_y) ) { + return true; + } + + if (CtdlNumMsgsSelected < 1) { + return true; + } + + if (!mm_div) { + + + drag_o_text = "
"; + for (i=0; i'; + } + drag_o_text = drag_o_text + "
"; + + mm_div = document.createElement("DIV"); + mm_div.style.position='absolute'; + mm_div.style.top = y + 'px'; + mm_div.style.left = x + 'px'; + mm_div.style.pixelHeight = '300'; + mm_div.style.pixelWidth = '300'; + mm_div.innerHTML = drag_o_text; + document.body.appendChild(mm_div); + } + else { + mm_div.style.top = y + 'px'; + mm_div.style.left = x + 'px'; + } + + return false; // prevent the default mouse action from happening? +} + +function CtdlMoveMsgMouseUp(evt) { + document.onmouseup = null; + document.onmousemove = null; + if (document.layers) { + document.releaseEvents(Event.MOUSEUP | Event.MOUSEMOVE); + } + + if (mm_div) { + document.body.removeChild(mm_div); + mm_div = null; + } + + if (num_drop_targets < 1) { // nowhere to drop + return true; + } + + // Did we release the mouse button while hovering over a drop target? + // NOTE: this only works cross-browser because the iconbar div is always + // positioned at 0,0. Browsers differ in whether the 'offset' + // functions return pos relative to the document or parent. + + for (i=0; i= l) && (x <= r) && (y >= t) && (y <= b) ) { + // Yes, we dropped it on a hotspot. + CtdlMoveSelectedMessages(evt, drop_targets_roomnames[i]); + return true; + } + } + + return true; +} + + +function ctdl_ts_getInnerText(el) { + if (typeof el == "string") return el; + if (typeof el == "undefined") { return el }; + if (el.innerText) return el.innerText; //Not needed but it is faster + var str = ""; + + var cs = el.childNodes; + var l = cs.length; + for (var i = 0; i < l; i++) { + switch (cs[i].nodeType) { + case 1: //ELEMENT_NODE + str += ts_getInnerText(cs[i]); + break; + case 3: //TEXT_NODE + str += cs[i].nodeValue; + break; + } + } + return str; +} + + + +// This function handles the creation of new notes in the "Notes" view. +// +function add_new_note() { + + new_eid = CtdlRandomString(); + + $('new_notes_here').innerHTML = $('new_notes_here').innerHTML + + '\"Note\"' + + '' + + '' + Date() + '
' + ; + + new Ajax.InPlaceEditor('note' + new_eid, + 'updatenote?eid=' + new_eid , {rows:5,cols:72}); +} + +function CtdlShowRaw(msgnum) { +var customnav = document.createElement("span"); +var mode_citadel = document.createElement("a"); +mode_citadel.appendChild(document.createTextNode("Citadel Source")); +var mode_rfc822 = document.createElement("a"); +mode_rfc822.appendChild(document.createTextNode(" RFC822 Source")); +mode_citadel.setAttribute("href","#"); +mode_rfc822.setAttribute("href","#"); +mode_rfc822.setAttribute("onclick","rawSwitch822('" + msgnum + "');"); +mode_citadel.setAttribute("onclick","rawSwitchCitadel('" + msgnum + "');"); +customnav.appendChild(mode_citadel); +customnav.appendChild(mode_rfc822); +customnav.setAttribute("class","floatcustomnav"); +floatwindow("headerscreen","pre",customnav); +rawSwitch822(msgnum); +} + +function rawSwitch822(msgnum) { +CtdlLoadScreen("headerscreen"); +new Ajax.Updater("headerscreen", +'ajax_servcmd_esc', + { method: 'post',parameters: 'g_cmd=MSG2 ' +msgnum } ); + +} + +function rawSwitchCitadel(msgnum) { +CtdlLoadScreen("headerscreen"); +new Ajax.Updater("headerscreen", +'ajax_servcmd_esc', + { method: 'post',parameters: 'g_cmd=MSG0 ' +msgnum } ); + +} + +function floatwindow(newdivid,contentelementtype,customnav) { +var windiv = document.createElement("div"); +windiv.setAttribute("class","floatwindow"); +var winid = newdivid+"_window"; +windiv.setAttribute("id",winid); +var nav = document.createElement("div"); +if (customnav != null) { +nav.appendChild(customnav); +} +var minimizeA = document.createElement("a"); +var minimizeButton = document.createTextNode("Close"); +minimizeA.appendChild(minimizeButton); +minimizeA.setAttribute("onclick","killFloatWindow(this);"); +minimizeA.setAttribute("href","#"); +nav.appendChild(minimizeA); +nav.setAttribute("class","floatnav"); +windiv.appendChild(nav); +var contentarea = document.createElement("pre"); +contentarea.setAttribute("class","floatcontent"); +contentarea.setAttribute("id",newdivid); +windiv.appendChild(contentarea); +document.body.appendChild(windiv); +} +function killFloatWindow(caller) { +var span = caller.parentNode; +var fwindow = span.parentNode; +fwindow.parentNode.removeChild(fwindow); +} +// Place a gradient loadscreen on an element, e.g to use before Ajax.updater +function CtdlLoadScreen(elementid) { +var elem = document.getElementById(elementid); +elem.innerHTML = "

  Loading....

"; +} + + +// Show info for a user, basically replaces showuser() +// matt@comalies is to blame for this poorly coded masterpiece. +function CtdlShowUserInfoPopup(Element) { + try { + // hopefully no one needs to use the class attribute... could be better done + // with xmlns though.. + var user = Element.getAttribute("class"); + var updname = "biospace_"+user; + if (document.getElementById(updname) == null) { + // insert a space for the bio + var pNode = Element.parentNode; + var newdiv = document.createElement("div"); + newdiv.id = updname; + newdiv.innerHTML = "Getting user info...."; + pNode.appendChild(newdiv); + CtdlLoadScreen(updname); + new Ajax.Updater(updname, 'showuser_ajax?who='+user, { method: 'get' } ); + } + } + catch(err) { + return true; + } + return false; +} + + + +// Pop open the address book (target_input is the INPUT field to populate) + +function PopOpenAddressBook(target_input) { + $('address_book_popup').style.display = 'block'; + p = 'target_input=' + target_input + '&r=' + CtdlRandomString(); + new Ajax.Updater( + 'address_book_popup_middle_div', + 'display_address_book_middle_div', + { + method: 'get', + parameters: p, + evalScripts: true + } + ); +} + +function PopulateAddressBookInnerDiv(which_addr_book, target_input) { + $('address_book_inner_div').innerHTML = "

  Loading....

"; + p = 'which_addr_book=' + which_addr_book + + '&target_input=' + target_input + + '&r=' + CtdlRandomString(); + new Ajax.Updater( + 'address_book_inner_div', + 'display_address_book_inner_div', + { + method: 'get', + parameters: p + } + ); +} + +// What happens when a contact is selected from the address book popup +// (populate the specified target) + +function AddContactsToTarget(target, whichaddr) { + while (whichaddr.selectedIndex != -1) { + if (target.value.length > 0) { + target.value = target.value + ', '; + } + target.value = target.value + whichaddr.value; + whichaddr.options[whichaddr.selectedIndex].selected = false; + } +} + +// Respond to a meeting invitation +function RespondToInvitation(question_divname, title_divname, msgnum, cal_partnum, sc) { + p = 'msgnum=' + msgnum + '&cal_partnum=' + cal_partnum + '&sc=' + sc ; + new Ajax.Updater(title_divname, 'respond_to_request', { method: 'post', parameters: p } ); + Effect.Fade(question_divname, { duration: 0.5 }); +} + +// Handle a received RSVP +function HandleRSVP(question_divname, title_divname, msgnum, cal_partnum, sc) { + p = 'msgnum=' + msgnum + '&cal_partnum=' + cal_partnum + '&sc=' + sc ; + new Ajax.Updater(title_divname, 'handle_rsvp', { method: 'post', parameters: p } ); + Effect.Fade(question_divname, { duration: 0.5 }); +} +