// The following code is used to support the small popups that give the full // description of an event when the user moves the mouse over it. // Thanks to Klaus Knopper (www.knoppix.com) for this script. // It has been modified to work with the existing WebCalendar // architecture on 02/25/2005. // // 03/05/2005 Prevent popup from going off screen by setting maximum width, // which is configurable. // // 11/10/2010 Allow popups to be placed relative to the popup element's // parent object. (for use in "includes" version of upcoming.php) // // 4/15/2011 Improved visual display of popups (incl. large popups), added // fixed position support. Fixed IE9 window size, made mouse moves more // selective, replaced recursive_resize, add'l support for quirks mode. // // 5/9/2011 Replaced getElementsBySelector with getElementsByClassName // for event handler setup. Removed mousemove function. Did some local // vs. global var. cleanup. New code to handle dynamically sorted tasks. // // Bubblehelp infoboxes, (c) 2002 Klaus Knopper // You can copy/modify and distribute this code under the conditions // of the GNU GENERAL PUBLIC LICENSE Version 2. var ns4, // Are we using Netscape4? followMe = 1, // allow popup to follow cursor...turn off for better performance idiv = null, // Pointer to infodiv container maxwidth = 300, // maximum width of popup window (default 300) px = 'px', // position suffix with "px" in some cases winW, winH, // Current help position and main window size oldwinW, // previous main window width (if window was resized) 11-10-10 WCscrollX, WCscrollY, // set as globals, got rid of scrollX/Y as these are non-IE windows globals 5-9-11 idivcoors = new Array(0,0), // idiv coordinates array - sum of element's and parent's x,y offsets 11-10-10 WCoffsetfound = false, // true if offset parent objects found 4-15-11 WCfirstLeft = 0, // first elements offsetLeft 11-10-10 WCfirstTop = 0, // first elements offsetTop 11-10-10 WCfirstpass = true, // first time through showPopup 4-15-11 MSIEbrowser = ( (window.navigator.appName == "Microsoft Internet Explorer") ? true : false ), //ie? 11-10-10 MSIEengine = 0, // ie engine (>5 is standards mode) 11-10-10 IEstandardsMode = false, // true if IE standards mode 11-10-10 IEquirksMode = false, // true if IE quirks mode 4-15-11 fixedposition = true, // default true. Set false for absolute pos., all browsers except IE7. 4-15-11 ie7fixed = true, // default true. Set false for IE7 absolute pos. 4-15-11 ie7adjustLeft = 0, // default = 0. Enter value in pixels to move popup to left for IE7 4-15-11. ie7adjustRight = 0, // default = 0. Enter value in pixels to move popup to right for IE7 4-15-11. taskInterval, // Interval object for setInterval to reset task event handlers after sort 5-9-11 intervalMax = 0, //counter of attempts to reset task event handlers after sort (max 100 times) 5-9-11 xoffset = 12, // popup distance from cursor x coor. (was 8, now displays under "view this event" popup 11-10-10) yoffset = 24; // popup distance from cursor y coor. (was 12, now displays under "view this event" popup 11-10-10) function nsfix () { setTimeout ( 'window.onresize = rebrowse', 2000 ); } function rebrowse () { window.location.reload (); } // 5-9-11 replaced Willison's getElementsBySelector with Nyman's getElementsByClassName. // Uses native getElementsByClassName and XPath support if available. Returns a real // array vs node list. Supports IE 5.5+ and all others. Current as of May, 08. /* Developed by Robert Nyman, http://www.robertnyman.com Code/licensing: http://code.google.com/p/getelementsbyclassname/ */ var getElementsByClassName = function (className, tag, elm){ if (document.getElementsByClassName) { getElementsByClassName = function (className, tag, elm) { elm = elm || document; var elements = elm.getElementsByClassName(className), nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null, returnElements = [], current; for(var i=0, il=elements.length; i 0 ); // 5-9-11 made local idiv = null; winW = 800; winH = 600; // Workaround for another Netscape bug: Fix browser confusion on resize. // Obviously Konqueror has a similar problem. :-( if ( ns4 || kon ) nsfix (); if ( ns4 ) px = ''; // 5-9-11 set non-task event handlers var entries = getElementsByClassName ( "entry", "a" ); entries = entries.concat ( getElementsByClassName ( "layerentry", "a" ) ); entries = entries.concat ( getElementsByClassName ( "unapprovedentry", "a" ) ); if (entries != null) setEvents (entries); var firstTime = true; setTaskEvents(firstTime); // 5-9-11 set task event handlers (first time) } function setTaskEvents(first) { if ( document.body.style.cursor != 'wait' || first ) { // ajax function sets cursor to "wait" while sorting tasks clearInterval ( taskInterval ); intervalMax = 0; var taskEvents = getElementsByClassName ( "task", "tr" ); // set new mouse event handlers if (taskEvents != null) { var sortTable = getElementsByClassName ( "sorter", "td" ); // up arrow sortTable = sortTable.concat ( getElementsByClassName ( "sorter sorterbottom", "td" ) ); // down arrow if ( sortTable != null ) { for ( var i = 0; i < sortTable.length; i++ ) { sortTable[i].onmouseup = function ( event ) { // can't use onclick, so we use mouseup // attempt to reset tasks every 200ms until successful, but quit after 100 trys (20 seconds) taskInterval = setInterval ( 'setTaskEvents()', 200 ); } } } setEvents (taskEvents); } } else { // cursor still in 'wait' state intervalMax += 1; if ( intervalMax > 100 ) { // if more than 100 attempts (200ms each, or 20 seconds) give up. clearInterval (taskInterval); intervalMax = 0; } } } function setEvents (eventsArray) { for ( var i = 0; i < eventsArray.length; i++ ) { eventsArray[i].onmouseover = function ( event ) { showPopUp ( event, 'eventinfo-' + this.id ); } eventsArray[i].onmouseout = function () { hidePopUp ( 'eventinfo-' + this.id ); } if ( followMe ) { eventsArray[i].onmousemove = function ( event ) { showtip ( event ); } } } } function hidePopUp ( name ) { if ( idiv ) //4-15-11 fix javascript error IE8 idiv.style.visibility = ( ns4 ? 'hide' : 'hidden' ); idiv = null; } function gettip ( name ) { return ( document.layers && document.layers[name] ? document.layers[name] : ( document.all && document.all[name] ? document.all[name] : ( document[name] ? document[name] : ( document.getElementById ( name ) ? document.getElementById ( name ) : 0 ) ) ) ); } function showPopUp ( evt, name ) { if ( idiv ) hidePopUp ( name ); // 4-15-11 fix typo. idiv = gettip ( name ); if ( idiv ) { WCscrollX = WCscrollY = 0; // 5-9-11 this was a windows global variable (scrollX/Y) WCscrollX = ( typeof window.pageXOffset == 'number' ? window.pageXOffset : ( document.documentElement && document.documentElement.scrollLeft ? document.documentElement.scrollLeft : ( document.body && document.body.scrollLeft ? document.body.scrollLeft : ( window.scrollX ? window.scrollX // 5-9-11 fixed : 0 ) ) ) ); WCscrollY = ( typeof window.pageYOffset == 'number' ? window.pageYOffset : ( document.documentElement && document.documentElement.scrollTop ? document.documentElement.scrollTop : ( document.body && document.body.scrollTop ? document.body.scrollTop : ( window.scrollY ? window.scrollY // 5-9-11 fixed : 0 ) ) ) ); // 11-10-10 rewrote winW and winH calculations. This new method gets correct // window width & height for all browsers, including IE. winW = ( window.innerWidth && !IEstandardsMode //4-15-11 corrected for IE9 ? window.innerWidth : ( document.documentElement && document.documentElement.clientWidth ? ( document.documentElement.clientWidth != 0 ? document.documentElement.clientWidth : document.body.clientWidth ) : document.body.clientWidth ) ) + WCscrollX; winH = ( window.innerHeight && !IEstandardsMode //4-15-11 corrected for IE9 ? window.innerHeight : ( document.documentElement && document.documentElement.clientHeight ? ( document.documentElement.clientHeight != 0 ? document.documentElement.clientHeight : document.body.clientHeight ) : document.body.clientHeight ) ) + WCscrollY; // 4-15-11 adjust winH/winW for hor./ver. scroll bars for non-ie browsers if ( !MSIEbrowser ) if ( window.innerHeight ) if ( document.documentElement && document.documentElement.clientHeight ) if ( document.documentElement.clientHeight > 0 ) if ( window.innerHeight != document.documentElement.clientHeight ) { winH = winH - 16; // probably a scroll bar unless quirks mode if (document.body && document.body.clientHeight ) if ( document.body.clientHeight > 0 ) if (document.body.clientHeight == window.innerHeight) winH = winH + 16; // likely quirks mode and no scroll bar } if ( !MSIEbrowser ) if ( window.innerWidth ) if ( document.documentElement && document.documentElement.clientWidth ) if ( document.documentElement.clientWidth > 0 ) if ( window.innerWidth != document.documentElement.clientWidth ) { winW = winW - 16; // probably scroll bar unless quirks mode if (document.body && document.body.clientWidth ) if ( document.body.clientWidth > 0 ) if (document.body.clientWidth == window.innerWidth) winW = winW + 16; // likely quirks mode and no scroll bar } // 11-10-10 - Determine x/y coordinates of parent object and get // new coors. if window changes (absolute only, non IE quirks). if ( !IEquirksMode && !fixedposition ) { if (WCfirstpass) { idivcoors = findWCPos ( idiv ); WCfirstpass = false; oldwinW = winW; } // check if window size changes if (oldwinW != winW) { idivcoors = findWCPos ( idiv ); } oldwinW = winW; } else { // 4-15-11 get popups offsetLeft/Top (for "fixed") if ( WCfirstpass && !IEquirksMode && fixedposition ) { WCfirstLeft = idiv.offsetLeft; WCfirstTop = idiv.offsetTop; WCfirstpass = false; } else { if ( WCfirstpass ) { // adjust maxwidth if IE quirks DIV too small maxwidth = newWCmax (idiv); WCfirstpass = false; } } } showtip ( evt ); } } function showtip ( e ) { var x = y = popupW = popupH = 0; // 5-9-11 changed to locals e = ( e ? e : window.event ); if ( idiv ) { if ( e ) { x = ( e.pageX ? e.pageX : ( e.clientX ? e.clientX + WCscrollX : 0 ) ); y = ( e.pageY ? e.pageY : ( e.clientY ? e.clientY + WCscrollY : 0 ) ); } else { x = y = 0; } // 11-10-10 for IE quirks mode use offsetX/Y if ( e.offsetY && IEquirksMode ) { y = e.offsetY; x = e.offsetX; } // Make sure we don't go off screen. // 4-15-11 remove recursive_resize, limit popup to maxwidth, else browser sizes it. if ( idiv.offsetWidth > maxwidth ) idiv.style.width = maxwidth + px; popupW = idiv.offsetWidth; popupH = idiv.offsetHeight; // 4-15-11: modified popup placement to make edge of page movement smoother & handle big popups. var top = left = 0; top = y + yoffset; left = x + xoffset; // 04-15-11 adjust the popup position for IE quirks mode if ( IEquirksMode ) { if ( x + xoffset + popupW >= maxwidth ) { left = maxwidth - popupW ; } else { left = x + xoffset ; } } // 4-15-11 adjust popup position for all other browsers and mode types else { if (y + yoffset + popupH >= winH ) { // bottom or further? if (x + popupW + xoffset >= winW ) { // at right edge? if (popupH + yoffset < y - WCscrollY ) { // room above? top = y - popupH - yoffset; left = winW - popupW; } else { // at right edge, no room above if ( popupH >= winH - WCscrollY ) { // popup full window top = WCscrollY; left = x - popupW - xoffset; } else { // at right, popup not full window top = winH - popupH ; left = x - popupW - xoffset; } } } else { // not at right edge, but at bottom if ( popupH >= winH - WCscrollY ) { // popup full window top = WCscrollY; left = x + xoffset; } else { top = winH - popupH ; left = x + xoffset; } } } else { // not at bottom if (x + popupW + xoffset >= winW ) { // at right edge? top = y + yoffset; left = winW - popupW; } else { // default position top = y + yoffset; left = x + xoffset; } } } // 04-15-11 adjust the popup position for iframes if ( popupW >= ( winW * .75 ) ) { // popupW 75% or more of window size? (likely iframe) if ( top <= WCscrollY ) { // top above window start? top = WCscrollY ; // show popups at top if ( top + popupH < y - yoffset ) { // will popup overlay mouse? if ( y - WCscrollY < ( winH - WCscrollY ) / 2 ) { // mouse above frame midpoint? top = y + yoffset; // place below mouse left = winW - popupW; // right justify } else { // mouse is below frame midpoint if ( top + popupH > y - yoffset ) { // will popup cover mouse? top = y + yoffset; // place below mouse left = winW - popupW; // right justify } else { left = winW - popupW; // leave it, right justify } } } else { top = y + yoffset; // place below mouse left = winW - popupW; // right justify } } else { if ( top + popupH + yoffset > y ) { // popup cover mouse? top = y + yoffset; // place below mouse left = winW - popupW; // right justify } else { left = winW - popupW; // right justify } } } if ( fixedposition ) { // 04-15-11 fixed position popup? top = top - WCscrollY - WCfirstTop ; // elim. scroll & popup's vert. offset left = left - WCscrollX ; // elim. scroll, horiz. offset should always be 0 idiv.style.position = "fixed"; } else { // absolute position popup if ( WCoffsetfound ) { top = top - idivcoors[1]; left = left - idivcoors[0]; } } idiv.style.top = top + px; idiv.style.left = left + px; idiv.style.visibility = ( ns4 ? 'show' : 'visible' ); } } // 11-10-10: calculate relative offsets, absolute position. hattip quirksmode.org (findPos js). function findWCPos( obj ) { var curleft = curtop = IE7error = 0; var firstloop = true; if (obj.offsetParent) { WCoffsetfound = true; do { if (WCfirstpass && firstloop) { // save initial offsetLeft/Top as these get modified curleft += obj.offsetLeft; curtop += obj.offsetTop; WCfirstLeft = curleft; WCfirstTop = curtop; firstloop = false; } else { if ( firstloop ) { curleft = WCfirstLeft; curtop = WCfirstTop; firstloop = false; } else { curleft += obj.offsetLeft; curtop += obj.offsetTop; } } // 4-15-11 attempt to adjust error IE7 offsetLeft by parent marginLeft. if ( MSIEengine == 7 && obj.offsetParent.currentStyle.marginLeft ) { var marginL = obj.offsetParent.currentStyle.marginLeft.replace("px", ""); if ( !isNaN(marginL) ) if ( marginL > 0 ) if ( obj.offsetLeft >= marginL ) if ( marginL >= obj.offsetParent.offsetLeft ) IE7error = IE7error + marginL; } obj = obj.offsetParent; } while (obj.offsetParent); } if ( MSIEengine == 7 ) // correct ie7's offsetLeft problem curleft = curleft + ie7adjustLeft - ie7adjustRight - IE7error; return [curleft, curtop]; } // 11-10-10: MS suggested function to check IE mode & engine. function checkWCMode() { engine = null; if ( MSIEbrowser ) { // This is an IE browser. What mode is the engine in? if ( document.documentMode ) { //IE8 or later engine = document.documentMode; } else { // IE 5-7 engine = 5; // Assume quirks mode unless proven otherwise if (document.compatMode) { if (document.compatMode == "CSS1Compat") { engine = 7; // standards mode } } } if ( engine > 5 ) { IEstandardsMode = true; } else { IEquirksMode = true; } } // the engine variable now contains document compatibility mode. return engine; } // 4-15-11: check if position: fixed supported. Hat tip Tadhg O'Higgins. function checkWCFixed() { var testDiv = document.createElement("div"); testDiv.id = "testingPositionFixed"; testDiv.style.position = "fixed"; testDiv.style.top = "0px"; testDiv.style.right = "0px"; document.body.appendChild(testDiv); var offset = 1; var supported = false; if (typeof testDiv.offsetTop == "number") { if (testDiv.offsetTop != null) { if (testDiv.offsetTop != "undefined") { offset = parseInt(testDiv.offsetTop); } } } if (offset === 0) { supported = true; } return supported; } // 4-15-11: for IE quirks, resize maxwidth if parent too small (prevents wrapping) function newWCmax(obj) { var padding = 0; var newmaxwidth = maxwidth; //parentNode.clientWidth excludes border and scrollbar if ( obj.parentNode.clientWidth ) { newmaxwidth = obj.parentNode.clientWidth; } // remove padding if (obj.parentNode.currentStyle.paddingLeft) { padding = obj.parentNode.currentStyle.paddingLeft.replace("px", ""); if ( !isNaN(padding) ) newmaxwidth = newmaxwidth - padding; } padding = 0; if (obj.parentNode.currentStyle.paddingRight) { padding = obj.parentNode.currentStyle.paddingRight.replace("px", ""); if ( !isNaN(padding) ) newmaxwidth = newmaxwidth - padding; } // only use new maximum if less than maxwidth, if greater set to maxwidth if ( newmaxwidth > maxwidth ) newmaxwidth = maxwidth; return newmaxwidth; } // Initialize after loading the page. if ( typeof addLoadHandler == 'undefined' ) { function addLoadHandler ( handler ) { if ( window.addEventListener ) { window.addEventListener ( 'load',handler,false); } else if ( window.attachEvent ) { window.attachEvent ( 'onload',handler ); } else if ( window.onload ) { var oldHandler = window.onload; window.onload = function piggyback () { oldHandler (); handler (); }; } else { window.onload = handler; } } } addLoadHandler ( infoinit );