diff -r 5e8fd89c02ea -r a38876c0793c includes/clientside/static/messagebox.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/static/messagebox.js Tue Jun 24 23:37:23 2008 -0400 @@ -0,0 +1,586 @@ +// Message box and visual effect system + +/** + * The ultimate message box framework for Javascript + * Syntax is (almost) identical to the MessageBox command in NSIS + * @param int type - a bitfield consisting of the MB_* constants + * @param string title - the blue text at the top of the window + * @param string text - HTML for the body of the message box + * Properties: + * onclick - an array of functions to be called on button click events + * NOTE: key names are to be strings, and they must be the value of the input, CaSe-SeNsItIvE + * onbeforeclick - same as onclick but called before the messagebox div is destroyed + * Methods: + * destroy: kills the running message box + * Example: + * var my_message = new MessageBox(MB_OK|MB_ICONSTOP, 'Error logging in', 'The username and/or password is incorrect. Please check the username and retype your password'); + * my_message.onclick['OK'] = function() { + * document.getElementById('password').value = ''; + * }; + * Deps: + * Modern browser that supports DOM + * darken() and enlighten() (above) + * opacity() - required for darken() and enlighten() + * MB_* constants are defined in enano-lib-basic.js + */ + +var mb_current_obj; +var mb_previously_had_darkener = false; + +function MessageBox(type, title, message) +{ + if ( !aclDisableTransitionFX ) + { + load_component('flyin'); + } + + var y = getScrollOffset(); + + // Prevent multiple instances + if ( document.getElementById('messageBox') ) + return; + + if ( document.getElementById('specialLayer_darkener') ) + if ( document.getElementById('specialLayer_darkener').style.display == 'block' ) + mb_previously_had_darkener = true; + if ( !mb_previously_had_darkener ) + darken(true); + if ( aclDisableTransitionFX ) + { + document.getElementById('specialLayer_darkener').style.zIndex = '5'; + } + var master_div = document.createElement('div'); + master_div.style.zIndex = String(getHighestZ() + 5); + var mydiv = document.createElement('div'); + mydiv.style.height = '200px'; + w = getWidth(); + h = getHeight(); + if ( aclDisableTransitionFX ) + { + master_div.style.left = ((w / 2) - 200)+'px'; + master_div.style.top = ((h / 2) + y - 120)+'px'; + master_div.style.position = 'absolute'; + } + else + { + master_div.style.top = '-10000px'; + master_div.style.position = ( IE ) ? 'absolute' : 'fixed'; + } + z = ( aclDisableTransitionFX ) ? document.getElementById('specialLayer_darkener').style.zIndex : getHighestZ(); + mydiv.style.backgroundColor = '#FFFFFF'; + mydiv.style.padding = '10px'; + mydiv.style.marginBottom = '1px'; + mydiv.id = 'messageBox'; + mydiv.style.overflow = 'auto'; + + var buttondiv = document.createElement('div'); + + mydiv.style.width = '400px'; + buttondiv.style.width = '400px'; + + w = getWidth(); + h = getHeight(); + if ( aclDisableTransitionFX ) + { + //buttondiv.style.left = ((w / 2) - 200)+'px'; + //buttondiv.style.top = ((h / 2) + y + 101)+'px'; + } + //buttondiv.style.position = ( IE ) ? 'absolute' : 'fixed'; + z = ( aclDisableTransitionFX ) ? document.getElementById('specialLayer_darkener').style.zIndex : getHighestZ(); + buttondiv.style.backgroundColor = '#C0C0C0'; + buttondiv.style.padding = '10px'; + buttondiv.style.textAlign = 'right'; + buttondiv.style.verticalAlign = 'middle'; + buttondiv.id = 'messageBoxButtons'; + + this.clickHandler = function() { messagebox_click(this, mb_current_obj); }; + + if( ( type & MB_ICONINFORMATION || type & MB_ICONSTOP || type & MB_ICONQUESTION || type & MB_ICONEXCLAMATION ) && !(type & MB_ICONLOCK) ) + { + mydiv.style.paddingLeft = '50px'; + mydiv.style.width = '360px'; + mydiv.style.backgroundRepeat = 'no-repeat'; + mydiv.style.backgroundPosition = '8px 8px'; + } + else if ( type & MB_ICONLOCK ) + { + mydiv.style.paddingLeft = '50px'; + mydiv.style.width = '360px'; + mydiv.style.backgroundRepeat = 'no-repeat'; + } + + if(type & MB_ICONINFORMATION) + { + mydiv.style.backgroundImage = 'url(\''+scriptPath+'/images/info.png\')'; + } + + if(type & MB_ICONQUESTION) + { + mydiv.style.backgroundImage = 'url(\''+scriptPath+'/images/question.png\')'; + } + + if(type & MB_ICONSTOP) + { + mydiv.style.backgroundImage = 'url(\''+scriptPath+'/images/error.png\')'; + } + + if(type & MB_ICONEXCLAMATION) + { + mydiv.style.backgroundImage = 'url(\''+scriptPath+'/images/warning.png\')'; + } + + if(type & MB_ICONLOCK) + { + mydiv.style.backgroundImage = 'url(\''+scriptPath+'/images/lock.png\')'; + } + + if(type & MB_OK) + { + btn = document.createElement('input'); + btn.type = 'button'; + btn.value = $lang.get('etc_ok'); + btn._GenericName = 'OK'; + btn.onclick = this.clickHandler; + btn.style.margin = '0 3px'; + buttondiv.appendChild(btn); + } + + if(type & MB_OKCANCEL) + { + btn = document.createElement('input'); + btn.type = 'button'; + btn.value = $lang.get('etc_ok'); + btn._GenericName = 'OK'; + btn.onclick = this.clickHandler; + btn.style.margin = '0 3px'; + buttondiv.appendChild(btn); + + btn = document.createElement('input'); + btn.type = 'button'; + btn.value = $lang.get('etc_cancel'); + btn._GenericName = 'Cancel'; + btn.onclick = this.clickHandler; + btn.style.margin = '0 3px'; + buttondiv.appendChild(btn); + } + + if(type & MB_YESNO) + { + btn = document.createElement('input'); + btn.type = 'button'; + btn.value = $lang.get('etc_yes'); + btn._GenericName = 'Yes'; + btn.onclick = this.clickHandler; + btn.style.margin = '0 3px'; + buttondiv.appendChild(btn); + + btn = document.createElement('input'); + btn.type = 'button'; + btn.value = $lang.get('etc_no'); + btn._GenericName = 'No'; + btn.onclick = this.clickHandler; + btn.style.margin = '0 3px'; + buttondiv.appendChild(btn); + } + + if(type & MB_YESNOCANCEL) + { + btn = document.createElement('input'); + btn.type = 'button'; + btn.value = $lang.get('etc_yes'); + btn._GenericName = 'Yes'; + btn.onclick = this.clickHandler; + btn.style.margin = '0 3px'; + buttondiv.appendChild(btn); + + btn = document.createElement('input'); + btn.type = 'button'; + btn.value = $lang.get('etc_no'); + btn._GenericName = 'No'; + btn.onclick = this.clickHandler; + btn.style.margin = '0 3px'; + buttondiv.appendChild(btn); + + btn = document.createElement('input'); + btn.type = 'button'; + btn.value = $lang.get('etc_cancel'); + btn._GenericName = 'Cancel'; + btn.onclick = this.clickHandler; + btn.style.margin = '0 3px'; + buttondiv.appendChild(btn); + } + + heading = document.createElement('h2'); + heading.innerHTML = title; + heading.style.color = '#50A0D0'; + heading.style.fontFamily = 'trebuchet ms, verdana, arial, helvetica, sans-serif'; + heading.style.fontSize = '12pt'; + heading.style.fontWeight = 'lighter'; + heading.style.textTransform = 'lowercase'; + heading.style.marginTop = '0'; + mydiv.appendChild(heading); + + var text = document.createElement('div'); + text.innerHTML = String(message); + this.text_area = text; + mydiv.appendChild(text); + + this.updateContent = function(text) + { + this.text_area.innerHTML = text; + }; + + this.destroy = function() + { + var mbdiv = document.getElementById('messageBox'); + mbdiv.parentNode.removeChild(mbdiv.nextSibling); + mbdiv.parentNode.removeChild(mbdiv); + if ( !mb_previously_had_darkener ) + enlighten(true); + }; + + //domObjChangeOpac(0, mydiv); + //domObjChangeOpac(0, master_div); + + body = document.getElementsByTagName('body'); + body = body[0]; + master_div.appendChild(mydiv); + master_div.appendChild(buttondiv); + + body.appendChild(master_div); + + if ( !aclDisableTransitionFX ) + setTimeout('mb_runFlyIn();', 100); + + this.onclick = new Array(); + this.onbeforeclick = new Array(); + mb_current_obj = this; +} + +var messagebox = MessageBox; + +function mb_runFlyIn() +{ + var mydiv = document.getElementById('messageBox'); + var maindiv = mydiv.parentNode; + fly_in_top(maindiv, true, false); +} + +function messagebox_click(obj, mb) +{ + val = ( typeof ( obj._GenericName ) == 'string' ) ? obj._GenericName : obj.value; + if(typeof mb.onbeforeclick[val] == 'function') + { + var o = mb.onbeforeclick[val]; + var resp = o(); + if ( resp ) + return false; + o = false; + } + + var mydiv = document.getElementById('messageBox'); + var maindiv = mydiv.parentNode; + + if ( aclDisableTransitionFX ) + { + var mbdiv = document.getElementById('messageBox'); + mbdiv.parentNode.removeChild(mbdiv.nextSibling); + mbdiv.parentNode.removeChild(mbdiv); + if ( !mb_previously_had_darkener ) + enlighten(true); + } + else + { + var to = fly_out_top(maindiv, true, false); + setTimeout("var mbdiv = document.getElementById('messageBox'); mbdiv.parentNode.removeChild(mbdiv.nextSibling); mbdiv.parentNode.removeChild(mbdiv); if ( !mb_previously_had_darkener ) enlighten(true);", to); + } + if(typeof mb.onclick[val] == 'function') + { + o = mb.onclick[val]; + o(); + o = false; + } +} + +function testMessageBox() +{ + mb = new MessageBox(MB_OKCANCEL|MB_ICONINFORMATION, 'Javascripted dynamic message boxes', 'This is soooooo coool, now if only document.createElement() worked in IE!
this is some more text




this is some more text




this is some more text




this is some more text




this is some more text




this is some more text




this is some more text




this is some more text'); + mb.onclick['OK'] = function() + { + alert('You clicked OK!'); + } + mb.onbeforeclick['Cancel'] = function() + { + alert('You clicked Cancel!'); + } +} + +/** + * The miniPrompt function, for creating small prompts and dialogs. The window will be flown in and the window darkened with opac=0.4. + * @param function Will be passed an HTMLElement that is the body of the prompt window; the function can do with this as it pleases + */ + +function miniPrompt(call_on_create) +{ + if ( !aclDisableTransitionFX ) + { + load_component('flyin'); + } + if ( document.getElementById('specialLayer_darkener') ) + { + if ( document.getElementById('specialLayer_darkener').style.display != 'none' ) + { + var opac = parseFloat(document.getElementById('specialLayer_darkener').style.opacity); + opac = opac * 100; + darken(aclDisableTransitionFX, opac); + } + else + { + darken(aclDisableTransitionFX, 40); + } + } + else + { + darken(aclDisableTransitionFX, 40); + } + + var wrapper = document.createElement('div'); + wrapper.className = 'miniprompt'; + var top = document.createElement('div'); + top.className = 'mp-top'; + var body = document.createElement('div'); + body.className = 'mp-body'; + var bottom = document.createElement('div'); + bottom.className = 'mp-bottom'; + if ( typeof(call_on_create) == 'function' ) + { + call_on_create(body); + } + wrapper.appendChild(top); + wrapper.appendChild(body); + wrapper.appendChild(bottom); + var left = ( getWidth() / 2 ) - ( 388 / 2 ); + wrapper.style.left = left + 'px'; + var top = getScrollOffset() - 27; + wrapper.style.top = top + 'px'; + domObjChangeOpac(0, wrapper); + var realbody = document.getElementsByTagName('body')[0]; + realbody.appendChild(wrapper); + + if ( aclDisableTransitionFX ) + { + domObjChangeOpac(100, wrapper); + } + else + { + fly_in_top(wrapper, true, true); + + setTimeout(function() + { + domObjChangeOpac(100, wrapper); + }, 40); + } +} + +/** + * For a given element, loops through the element and all of its ancestors looking for a miniPrompt div, and returns it. Returns false on failure. + * @param object:HTMLElement Child node to scan + * @return object + */ + +function miniPromptGetParent(obj) +{ + while ( true ) + { + // prevent infinite loops + if ( !obj || obj.tagName == 'BODY' ) + return false; + + if ( $dynano(obj).hasClass('miniprompt') ) + { + return obj; + } + obj = obj.parentNode; + } + return false; +} + +/** + * Destroys the first miniPrompt div encountered by recursively checking all parent nodes. + * Usage: click + * @param object:HTMLElement a child of the div.miniprompt + * @param bool If true, does not call enlighten(). + */ + +function miniPromptDestroy(obj, nofade) +{ + obj = miniPromptGetParent(obj); + if ( !obj ) + return false; + + // found it + var parent = obj.parentNode; + if ( !nofade ) + enlighten(aclDisableTransitionFX); + if ( aclDisableTransitionFX ) + { + parent.removeChild(obj); + } + else + { + var timeout = fly_out_top(obj, true, true); + setTimeout(function() + { + parent.removeChild(obj); + }, timeout); + } +} + +/** + * Simple test case + */ + +function miniPromptTest() +{ + miniPrompt(function(div) { div.innerHTML = 'hello world! destroy me'; }); +} + +/** + * Message box system for miniPrompts. Less customization but easier to scale than the regular messageBox framework. + * @example + + miniPromptMessage({ + title: 'Delete page', + message: 'Do you really want to delete this page? This is reversible unless you clear the page logs.', + buttons: [ + { + text: 'Delete', + color: 'red', + style: { + fontWeight: 'bold' + }, + onclick: function() { + ajaxDeletePage(); + miniPromptDestroy(this); + } + }, + { + text: 'cancel', + onclick: function() { + miniPromptDestroy(this); + } + } + ] + }); + + */ + +function miniPromptMessage(parms) +{ + if ( !parms.title || !parms.message || !parms.buttons ) + return false; + + return miniPrompt(function(parent) + { + try + { + var h3 = document.createElement('h3'); + h3.appendChild(document.createTextNode(parms.title)); + var body = document.createElement('p'); + var message = parms.message.split(unescape('%0A')); + for ( var i = 0; i < message.length; i++ ) + { + body.appendChild(document.createTextNode(message[i])); + if ( i + 1 < message.length ) + body.appendChild(document.createElement('br')); + } + + parent.style.textAlign = 'center'; + + parent.appendChild(h3); + parent.appendChild(body); + parent.appendChild(document.createElement('br')); + + // construct buttons + for ( var i = 0; i < parms.buttons.length; i++ ) + { + var button = parms.buttons[i]; + button.input = document.createElement('a'); + button.input.href = '#'; + button.input.clickAction = button.onclick; + button.input.className = 'abutton'; + if ( button.color ) + { + button.input.className += ' abutton_' + button.color; + } + button.input.appendChild(document.createTextNode(button.text)); + if ( button.style ) + { + for ( var j in button.style ) + { + button.input.style[j] = button.style[j]; + } + } + button.input.onclick = function(e) + { + try + { + this.clickAction(e); + } + catch(e) + { + console.error(e); + } + return false; + } + parent.appendChild(button.input); + } + if ( parms.buttons[0] ) + { + setTimeout(function() + { + parms.buttons[0].input.focus(); + }, 300); + } + } + catch ( e ) + { + console.error(e); + } + }); +} + +function testMPMessageBox() +{ + miniPromptMessage({ + title: 'The Game of LIFE question #73', + message: 'You just got your girlfriend pregnant. Please select an option:', + buttons: [ + { + text: 'Abort', + color: 'red', + style: { + fontWeight: 'bold' + }, + onclick: function() { + miniPromptDestroy(this); + } + }, + { + text: 'Retry', + color: 'blue', + onclick: function() { + miniPromptDestroy(this); + } + }, + { + text: 'Ignore', + color: 'green', + onclick: function() { + miniPromptDestroy(this); + } + } + ] + }); +} +