/******************************************************************************************************************** Fusion Menu Javascript. Originally based on script provided by Invision Power Services Inc, used with permission Fusion Menu Modifications (c) 2010 Fusion Digital Entertainment Limited ********************************************************************************************************************/ var fd = { menus: {} }; fd.menu = Class.create({ initialize: function (elem, target) { if (!$(elem) || !$(target)) { return; } this.elem = $(elem); this.target = $(target); $(this.target).hide(); $(elem).observe('mouseover', this.event_mouseover.bindAsEventListener(this)); $(elem).observe('mouseout', this.event_mouseout.bindAsEventListener(this)); }, doShow: function () { Debug.write("Showing " + $(this.elem).id); $(this.target).setStyle({ position: 'absolute' }); if (!$(this.elem).hasClassName('left')) { $(this.elem).addClassName('active'); } new Effect.Appear($(this.target), { duration: 0.1 }); }, doHide: function () { if ($(this.target).visible()) { Debug.write("Hiding " + $(this.elem).id); if (!$(this.elem).hasClassName('left')) { $(this.elem).removeClassName('active'); } new Effect.Fade($(this.target), { duration: 0.1 }); } }, event_mouseover: function (e) { window.clearTimeout(this._meventHide); this._meventShow = this.doShow.bind(this).delay(0.2); }, event_mouseout: function (e) { window.clearTimeout(this._meventShow); this._meventHide = this.doHide.bind(this).delay(0.2); } }); /************************************************/ /* IPB3 Javascript */ /* -------------------------------------------- */ /* ips.popup.js - Popup creator */ /* (c) IPS, Inc 2008 */ /* -------------------------------------------- */ /* Author: Rikki Tissier */ /************************************************/ /** * Full list of options: * * type: balloon, pane * modal: true/false * w: width * h: height * classname: classname to be applied to wrapper * initial: initial content * ajaxURL: If supplied, will ping URL for content and update popup * close: element that will close popup (wont work with balloon) * attach: { target, event, mouse, offset } * hideAtStart: Hide after creation (allows showing at a later time) * stem: true/false * delay: { show, hide } */ fd.popup = Class.create({ initialize: function( id, options, callbacks ) { /* Set up properties */ this.id = ''; this.wrapper = null; this.inner = null; this.stem = null; this.options = {}; this.timer = []; this.ready = false; this._startup = null; this.hideAfterSetup = false; this.eventPairs = { 'mouseover': 'mouseout', 'mousedown': 'mouseup' }; this._tmpEvent = null; /* Now run */ this.id = id; this.options = Object.extend({ type: 'pane', w: '500px', modal: false, modalOpacity: 0.4, hideAtStart: true, delay: { show: 0, hide: 0 }, defer: false, hideClose: false, closeContents: "x" }, arguments[1] || {}); this.callbacks = callbacks || {}; // Are we deferring the load? if( this.options.defer && $( this.options.attach.target ) ) { this._defer = this.init.bindAsEventListener( this ); $( this.options.attach.target ).observe( this.options.attach.event, this._defer ); if( this.eventPairs[ this.options.attach.event ] ) { this._startup = function(e){ this.hideAfterSetup = true; this.hide() }.bindAsEventListener( this ); $( this.options.attach.target ).observe( this.eventPairs[ this.options.attach.event ], this._startup ); } } else { this.init(); } }, init: function() { try { Event.stopObserving( $( this.options.attach.target ), this.options.attach.event, this._defer ); } catch(err) { } this.wrapper = new Element('div', { 'id': this.id + '_popup' } ).setStyle('z-index: 16000').hide().addClassName('popupWrapper'); this.inner = new Element('div', { 'id': this.id + '_inner' } ).addClassName('popupInner'); if( this.options.w ){ this.inner.setStyle( 'width: ' + this.options.w ); } if( this.options.h ){ this.inner.setStyle( 'max-height: ' + this.options.h ); } this.wrapper.insert( this.inner ); if( this.options.hideClose != true ) { this.closeLink = new Element('div', { 'id': this.id + '_close' } ).addClassName('popupClose').addClassName('clickable'); this.closeLink.update( this.options.closeContents ); this.closeLink.observe('click', this.hide.bindAsEventListener( this ) ); this.wrapper.insert( this.closeLink ); } $$('body')[0].insert( this.wrapper ); if( this.options.classname ){ this.wrapper.addClassName( this.options.classname ); } if( this.options.initial ){ this.update( this.options.initial ); } // If we are updating with ajax, handle the show there if( this.options.ajaxURL ){ this.updateAjax(); setTimeout( this.continueInit.bind(this), 80 ); } else { this.ready = true; this.continueInit(); } // Need to set a timeout for continue, // in case ajax is still running }, continueInit: function() { if( !this.ready ) { setTimeout( this.continueInit.bind(this), 80 ); return; } //Debug.write("Continuing..."); // What are we making? if( this.options.type == 'balloon' ){ this.setUpBalloon(); } else { this.setUpPane(); } // Set up close event try { if( this.options.close ){ closeElem = $( this.wrapper ).select( this.options.close )[0]; if( Object.isElement( closeElem ) ) { $( closeElem ).observe( 'click', this.hide.bindAsEventListener( this ) ); } } } catch( err ) { Debug.write( err ); } // Callback if( Object.isFunction( this.callbacks['afterInit'] ) ) { this.callbacks['afterInit']( this ); } if( !this.options.hideAtStart && !this.hideAfterSetup ) { this.show(); } if( this.hideAfterSetup && this._startup ) { Event.stopObserving( $( this.options.attach.target ), this.eventPairs[ this.options.attach.event ], this._startup ); } }, updateAjax: function() { new Ajax.Request( this.options.ajaxURL, { method: 'get', onSuccess: function(t) { if( t.responseText != 'error' ) { //Debug.write( t.responseText ); Debug.write( "AJAX done!" ); this.update( t.responseText ); this.ready = true; // Callback if( Object.isFunction( this.callbacks['afterAjax'] ) ) { this.callbacks['afterAjax']( this, t.responseText ); } } else { Debug.write( t.responseText ); return; } }.bind(this) }); }, show: function(e) { if( e ){ Event.stop(e); } if( this.timer['show'] ){ clearTimeout( this.timer['show'] ); } if( this.options.delay.show != 0 ){ this.timer['show'] = setTimeout( this._show.bind( this ), this.options.delay.show ); } else { this._show(); // Just show it } }, hide: function(e) { if( e ){ Event.stop(e); } if( this.document_event ){ Event.stopObserving( document, 'click', this.document_event ); } if( this.timer['hide'] ){ clearTimeout( this.timer['hide'] ); } if( this.options.delay.hide != 0 ){ this.timer['hide'] = setTimeout( this._hide.bind( this ), this.options.delay.hide ); } else { this._hide(); // Just hide it } }, _show: function() { if( this.options.modal == false ){ new Effect.Appear( $( this.wrapper ), { duration: 0.3, afterFinish: function(){ if( Object.isFunction( this.callbacks['afterShow'] ) ) { this.callbacks['afterShow']( this ); } }.bind(this) } ); this.document_event = this.handleDocumentClick.bindAsEventListener(this); Event.observe( document, 'click', this.document_event ); } else { new Effect.Appear( $('document_modal'), { duration: 0.3, to: this.options.modalOpacity, afterFinish: function(){ new Effect.Appear( $( this.wrapper ), { duration: 0.4, afterFinish: function(){ if( Object.isFunction( this.callbacks['afterShow'] ) ) { this.callbacks['afterShow']( this ); } }.bind(this) } ) }.bind(this) }); } }, _hide: function() { if( this._tmpEvent != null ) { Event.stopObserving( $( this.wrapper ), 'mouseout', this._tmpEvent ); this._tmpEvent = null; } if( this.options.modal == false ){ new Effect.Fade( $( this.wrapper ), { duration: 0.3, afterFinish: function(){ if( Object.isFunction( this.callbacks['afterHide'] ) ) { this.callbacks['afterHide']( this ); } }.bind(this) } ); } else { new Effect.Fade( $( this.wrapper ), { duration: 0.3, afterFinish: function(){ new Effect.Fade( $('document_modal'), { duration: 0.2, afterFinish: function(){ if( Object.isFunction( this.callbacks['afterHide'] ) ) { this.callbacks['afterHide']( this ); } }.bind(this) } ) }.bind(this) }); } }, handleDocumentClick: function(e) { if( !Event.element(e).descendantOf( this.wrapper ) ) { this._hide(e); } }, update: function( content ) { this.inner.update( content ); }, setUpBalloon: function() { // Are we attaching? if( this.options.attach ) { var attach = this.options.attach; if( attach.target && $( attach.target ) ) { if( this.options.stem == true ) { this.createStem(); } // Get position if( !attach.position ){ attach.position = 'auto'; } if( Object.isUndefined( attach.offset ) ){ attach.offset = { top: 0, left: 0 } } if( Object.isUndefined( attach.offset.top ) ){ attach.offset.top = 0 } if( Object.isUndefined( attach.offset.left ) ){ attach.offset.left = 0 } if( attach.position == 'auto' ) { Debug.write("Popup: auto-positioning"); var screendims = document.viewport.getDimensions(); var screenscroll = document.viewport.getScrollOffsets(); var toff = $( attach.target ).viewportOffset(); var wrapSize = $( this.wrapper ).getDimensions(); var delta = [0,0]; if (Element.getStyle( $( attach.target ), 'position') == 'absolute') { var parent = element.getOffsetParent(); delta = parent.viewportOffset(); } toff['left'] = toff[0] - delta[0]; toff['top'] = toff[1] - delta[1] + screenscroll.top; //Debug.write( toff['left'] + " " + toff['top'] ); // Need to figure out if it will be off-screen var start = 'top'; var end = 'left'; //Debug.write( "Target offset top: " + toff.top + ", wrapSize Height: " + wrapSize.height + ", screenscroll top: " + screenscroll.top); if( ( toff.top - wrapSize.height - attach.offset.top ) < ( 0 + screenscroll.top ) ){ var start = 'bottom'; } if( ( toff.left + wrapSize.width - attach.offset.left ) > ( screendims.width - screenscroll.left ) ){ var end = 'right'; } finalPos = this.position( start + end, { target: $( attach.target ), content: $( this.wrapper ), offset: attach.offset } ); if( this.options.stem == true ) { finalPos = this.positionStem( start + end, finalPos ); } } else { Debug.write("Popup: manual positioning"); finalPos = this.position( attach.position, { target: $( attach.target ), content: $( this.wrapper ), offset: attach.offset } ); if( this.options.stem == true ) { finalPos = this.positionStem( attach.position, finalPos ); } } // Add mouse events if( !Object.isUndefined( attach.event ) ){ $( attach.target ).observe( attach.event, this.show.bindAsEventListener( this ) ); if( attach.event != 'click' && !Object.isUndefined( this.eventPairs[ attach.event ] ) ){ $( attach.target ).observe( this.eventPairs[ attach.event ], this.hide.bindAsEventListener( this ) ); } $( this.wrapper ).observe( 'mouseover', this.wrapperEvent.bindAsEventListener( this ) ); } } } Debug.write("Popup: Left: " + finalPos.left + "; Top: " + finalPos.top); $( this.wrapper ).setStyle( 'top: ' + finalPos.top + 'px; left: ' + finalPos.left + 'px; position: absolute;' ); }, wrapperEvent: function(e) { if( this.timer['hide'] ) { // Cancel event now clearTimeout( this.timer['hide'] ); this.timer['hide'] = null; if( this.options.attach.event && this.options.attach.event == 'mouseover' ) { // Set new event to account for mouseout of the popup, // but only if we don't already have one - otherwise we get // expontentially more event calls. Bad. if( this._tmpEvent == null ){ this._tmpEvent = this.hide.bindAsEventListener( this ); $( this.wrapper ).observe('mouseout', this._tmpEvent ); } } } }, positionStem: function( pos, finalPos ) { var stemSize = { height: 16, width: 31 }; var wrapStyle = {}; var stemStyle = {}; switch( pos.toLowerCase() ) { case 'topleft': wrapStyle = { marginBottom: stemSize.height + 'px' }; stemStyle = { bottom: -(stemSize.height) + 'px', left: '5px' }; finalPos.left = finalPos.left - 15; break; case 'topright': wrapStyle = { marginBottom: stemSize.height + 'px' }; stemStyle = { bottom: -(stemSize.height) + 'px', right: '5px' }; finalPos.left = finalPos.left + 15; break; case 'bottomleft': wrapStyle = { marginTop: stemSize.height + 'px' }; stemStyle = { top: -(stemSize.height) + 'px', left: '5px' }; finalPos.left = finalPos.left - 15; break; case 'bottomright': wrapStyle = { marginTop: stemSize.height + 'px' }; stemStyle = { top: -(stemSize.height) + 'px', right: '5px' }; finalPos.left = finalPos.left + 15; break; } $( this.wrapper ).setStyle( wrapStyle ); $( this.stem ).setStyle( stemStyle ).setStyle('z-index: 6000').addClassName( pos.toLowerCase() ); return finalPos; }, position: function( pos, v ) { finalPos = {}; var toff = $( v.target ).viewportOffset(); var tsize = $( v.target ).getDimensions(); var wrapSize = $( v.content ).getDimensions(); var screenscroll = document.viewport.getScrollOffsets(); var offset = v.offset; var delta = [0,0]; if (Element.getStyle( $( v.target ), 'position') == 'absolute') { var parent = element.getOffsetParent(); delta = parent.viewportOffset(); } toff['left'] = toff[0] - delta[0]; toff['top'] = toff[1] - delta[1]; if( !Prototype.Browser.Opera ){ toff['top'] += screenscroll.top; } switch( pos.toLowerCase() ) { case 'topleft': finalPos.top = ( toff.top - wrapSize.height - tsize.height ) - offset.top; finalPos.left = toff.left + offset.left; break; case 'topright': finalPos.top = ( toff.top - wrapSize.height - tsize.height ) - offset.top; finalPos.left = ( toff.left - ( wrapSize.width - tsize.width ) ) - offset.left; break; case 'bottomleft': finalPos.top = ( toff.top + tsize.height ) + offset.top; finalPos.left = toff.left + offset.left; break; case 'bottomright': finalPos.top = ( toff.top + tsize.height ) + offset.top; finalPos.left = ( toff.left - ( wrapSize.width - tsize.width ) ) - offset.left; break; } return finalPos; }, createStem: function() { this.stem = new Element('div', { id: this.id + '_stem' } ).update(' ').addClassName('stem'); this.wrapper.insert( { top: this.stem } ); }, setUpPane: function() { // Does the document have a modal blackout? if( !$('document_modal') ){ this.createDocumentModal(); } this.positionPane(); }, positionPane: function() { // Position it in the middle var elem_s = $( this.wrapper ).getDimensions(); var window_s = document.viewport.getDimensions(); var window_offsets = document.viewport.getScrollOffsets(); var center = { left: ((window_s['width'] - elem_s['width']) / 2), top: (((window_s['height'] - elem_s['height']) / 2)/2) } if( center.top < 10 ){ center.top = 10; } $( this.wrapper ).setStyle('top: ' + center['top'] + 'px; left: ' + center['left'] + 'px; position: fixed;'); }, createDocumentModal: function() { var pageSize = $$('body')[0].getDimensions(); var viewSize = document.viewport.getDimensions(); var dims = []; //Debug.dir( pageSize ); //Debug.dir( viewSize ); if( viewSize['height'] < pageSize['height'] ){ dims['height'] = pageSize['height']; } else { dims['height'] = viewSize['height']; } if( viewSize['width'] < pageSize['width'] ){ dims['width'] = pageSize['width']; } else { dims['width'] = viewSize['width']; } var modal = new Element( 'div', { 'id': 'document_modal' } ).addClassName('modal').hide(); modal.setStyle('width: ' + dims['width'] + 'px; height: ' + dims['height'] + 'px; position: absolute; top: 0px; left: 0px; z-index: 15000;'); $$('body')[0].insert( modal ); }, getObj: function() { return $( this.wrapper ); } }); /**********************************************/ var Debug = { write: function( text ){ if( jsDebug && !Object.isUndefined(window.console) ){ console.log( text ); } }, dir: function( values ){ if( jsDebug && !Object.isUndefined(window.console) ){ console.dir( values ); } }, error: function( text ){ if( jsDebug && !Object.isUndefined(window.console) ){ console.error( text ); } }, warn: function( text ){ if( jsDebug && !Object.isUndefined(window.console) ){ console.warn( text ); } }, info: function( text ){ if( jsDebug && !Object.isUndefined(window.console) ){ console.info( text ); } } }