1/******************************************************************/ 2/* MOOdalBox 1.2.1 */ 3/* A modal box (inline popup), used to display remote content */ 4/* loaded using AJAX, written for the mootools framework */ 5/* by Razvan Brates, razvan [at] e-magine.ro */ 6/******************************************************************/ 7/* http://www.e-magine.ro/moodalbox */ 8/******************************************************************/ 9/* */ 10/* MIT style license: */ 11/* http://en.wikipedia.org/wiki/MIT_License */ 12/* */ 13/* mootools found at: */ 14/* http://mootools.net/ */ 15/* */ 16/* Original code based on "Slimbox", by Christophe Beyls: */ 17/* http://www.digitalia.be/software/slimbox */ 18/******************************************************************/ 19 20// Constants defined here can be changed for easy config / translation 21// (defined as vars, because of MSIE's lack of support for const) 22 23var _ERROR_MESSAGE = "Oops.. there was a problem with your request.<br /><br />" + 24 "Please try again.<br /><br />" + 25 "<em>Click anywhere to close.</em>"; // the error message displayed when the request has a problem 26var _RESIZE_DURATION = 400; // Duration of height and width resizing (ms) 27var _INITIAL_WIDTH = 250; // Initial width of the box (px) 28var _INITIAL_HEIGHT = 250; // Initial height of the box (px) 29var _CONTENTS_WIDTH = 930; // Actual width of the box (px) 30var _CONTENTS_HEIGHT = 470; // Actual height of the box (px) 31var _DEF_CONTENTS_WIDTH = 500; // Default width of the box (px) - used for resetting when a different setting was used 32var _DEF_CONTENTS_HEIGHT = 400; // Default height of the box (px) - used for resetting when a different setting was used 33var _ANIMATE_CAPTION = true; // Enable/Disable caption animation 34var _EVAL_SCRIPTS = false; // Option to evaluate scripts in the response text 35var _EVAL_RESPONSE = false; // Option to evaluate the whole response text 36 37// The MOOdalBox object in its beauty 38var MOOdalBox = { 39 40 // init the MOOdalBox 41 init: function (options) { 42 43 // init default options 44 this.options = Object.extend({ 45 resizeDuration: _RESIZE_DURATION, 46 initialWidth: _INITIAL_WIDTH, 47 initialHeight: _INITIAL_HEIGHT, 48 contentsWidth: _CONTENTS_WIDTH, 49 contentsHeight: _CONTENTS_HEIGHT, 50 defContentsWidth: _DEF_CONTENTS_WIDTH, 51 defContentsHeight: _DEF_CONTENTS_HEIGHT, 52 animateCaption: _ANIMATE_CAPTION, 53 evalScripts: _EVAL_SCRIPTS, 54 evalResponse: _EVAL_RESPONSE 55 }, options || {}); 56 57 // scan anchors for those opening a MOOdalBox 58 this.anchors = []; 59 $A($$('a')).each(function(el){ 60 // we use a regexp to check for links that 61 // have a rel attribute starting with "moodalbox" 62 if(el.rel && el.href && el.rel.test('^moodalbox', 'i')) { 63 el.onclick = this.click.pass(el, this); 64 this.anchors.push(el); 65 } 66 }, this); 67 68 // add event listeners 69 this.eventKeyDown = this.keyboardListener.bindWithEvent(this); 70 this.eventPosition = this.position.bind(this); 71 72 // init the HTML elements 73 // the overlay (clickable to close) 74 this.overlay = new Element('div').setProperty('id', 'mb_overlay').injectInside(document.body); 75 // the center element 76 this.center = new Element('div').setProperty('id', 'mb_center').setStyles({width: this.options.initialWidth+'px', height: this.options.initialHeight+'px', marginLeft: '-'+(this.options.initialWidth/2)+'px', display: 'none'}).injectInside(document.body); 77 // the actual page contents 78 this.contents = new Element('div').setProperty('id', 'mb_contents').injectInside(this.center); 79 80 // the bottom part (caption / close) 81 this.bottom = new Element('div').setProperty('id', 'mb_bottom').setStyle('display', 'none').injectInside(document.body);
82 this.closelink = new Element('a').setProperties({id: 'mb_close_link', href: '#'}).injectInside(this.bottom); 83 this.caption = new Element('div').setProperty('id', 'mb_caption').injectInside(this.bottom); 84 new Element('div').setStyle('clear', 'both').injectInside(this.bottom); 85 86 this.error = new Element('div').setProperty('id', 'mb_error').setHTML(_ERROR_MESSAGE); 87 88 // attach the close event to the close button / the overlay 89 this.closelink.onclick = this.overlay.onclick = this.close.bind(this); 90 91 // init the effects 92 var nextEffect = this.nextEffect.bind(this); 93 this.fx = { 94 overlay: this.overlay.effect('opacity', { duration: 500 }).hide(), 95 resize: this.center.effects({ duration: this.options.resizeDuration, onComplete: nextEffect }), 96 contents: this.contents.effect('opacity', { duration: 500, onComplete: nextEffect }), 97 bottom: this.bottom.effects({ duration: 400, onComplete: nextEffect }) 98 }; 99 100 this.ajaxRequest = Class.empty; 101 102 }, 103 104 click: function(link) { 105 return this.open (link.href, link.title, link.rel); 106 }, 107 108 open: function(sLinkHref, sLinkTitle, sLinkRel) { 109 this.href = sLinkHref; 110 this.title = sLinkTitle; 111 this.rel = sLinkRel; 112 this.position(); 113 this.setup(true); 114 this.top = Window.getScrollTop() + (Window.getHeight() / 15); 115 this.center.setStyles({top: this.top+'px', display: ''}); 116 this.fx.overlay.custom(0.8); 117 return this.loadContents(sLinkHref); 118 }, 119 120 position: function() { 121 this.overlay.setStyles({top: Window.getScrollTop()+'px', height: Window.getHeight()+'px'}); 122 }, 123 124 setup: function(open) { 125 var elements = $A($$('object')); 126 elements.extend($$(window.ActiveXObject ? 'select' : 'embed')); 127 elements.each(function(el){ el.style.visibility = open ? 'hidden' : ''; }); 128 var fn = open ? 'addEvent' : 'removeEvent'; 129 window[fn]('scroll', this.eventPosition)[fn]('resize', this.eventPosition); 130 document[fn]('keydown', this.eventKeyDown); 131 this.step = 0; 132 }, 133 134 loadContents: function() { 135 if(this.step) return false; 136 this.step = 1; 137 138 // check to see if there are specified dimensions 139 // if not, fall back to default values 140 var aDim = this.rel.match(/[0-9]+/g); 141 this.options.contentsWidth = (aDim && (aDim[0] > 0)) ? aDim[0] : this.options.defContentsWidth; 142 this.options.contentsHeight = (aDim && (aDim[1] > 0)) ? aDim[1] : this.options.defContentsHeight; 143 144 this.bottom.setStyles({opacity: '0', height: '0px', display: 'none'}); 145 this.center.className = 'mb_loading'; 146 147 this.fx.contents.hide(); 148 149 // AJAX call here 150 var nextEffect = this.nextEffect.bind(this); 151 var ajaxFailure = this.ajaxFailure.bind(this); 152 var ajaxOptions = { 153 method: 'get', 154 update: this.contents, 155 evalScripts: this.options.evalScripts, 156 evalResponse: this.options.evalResponse, 157 onComplete: nextEffect, 158 onFailure: ajaxFailure 159 }; 160 this.ajaxRequest = new Ajax(this.href, ajaxOptions).request(); 161 162 return false; 163 }, 164 165 ajaxFailure: function (){ 166 this.contents.setHTML(''); 167 this.error.clone().injectInside(this.contents); 168 this.nextEffect(); 169 this.center.setStyle('cursor', 'pointer'); 170 this.bottom.setStyle('cursor', 'pointer'); 171 this.center.onclick = this.bottom.onclick = this.close.bind(this); 172 }, 173 174 nextEffect: function() { 175 switch(this.step++) { 176 case 1: 177 // remove previous styling from the elements 178 // (e.g. styling applied in case of an error) 179 this.center.className = ''; 180 this.center.setStyle('cursor', 'default'); 181 this.bottom.setStyle('cursor', 'default'); 182 this.center.onclick = this.bottom.onclick = ''; 183 this.caption.setHTML(this.title); 184 185 this.contents.setStyles ({width: this.options.contentsWidth + "px", height: this.options.contentsHeight + "px"}); 186 187 if(this.center.clientHeight != this.contents.offsetHeight) { 188 this.fx.resize.custom({height: [this.center.clientHeight, this.contents.offsetHeight]}); 189 break; 190 } 191 this.step++; 192 193 case 2: 194 if(this.center.clientWidth != this.contents.offsetWidth) { 195 this.fx.resize.custom({width: [this.center.clientWidth, this.contents.offsetWidth], marginLeft: [-this.center.clientWidth/2, -this.contents.offsetWidth/2]}); 196 break; 197 } 198 this.step++; 199 200 case 3: 201 this.bottom.setStyles({top: (this.top + this.center.clientHeight)+'px', width: this.contents.style.width, marginLeft: this.center.style.marginLeft, display: ''}); 202 this.fx.contents.custom(0,1); 203 break; 204 205 case 4: 206 if(this.options.animateCaption) { 207 this.fx.bottom.custom({opacity: [0, 1], height: [0, this.bottom.scrollHeight]}); 208 break; 209 } 210 this.bottom.setStyles({opacity: '1', height: this.bottom.scrollHeight+'px'}); 211 212 case 5: 213 this.step = 0; 214 } 215 }, 216 217
218 keyboardListener: function(event) { 219 // close the MOOdalBox when the user presses CTRL + W, CTRL + X, ESC 220 if ((event.control && event.key == 'w') || (event.control && event.key == 'x') || (event.key == 'esc')) { 221 this.close(); 222 event.stop(); 223 } 224 }, 225 226 close: function() { 227 if(this.step < 0) return; 228 this.step = -1; 229 for(var f in this.fx) this.fx[f].clearTimer(); 230 this.center.style.display = this.bottom.style.display = 'none'; 231 this.center.className = 'mb_loading'; 232 this.fx.overlay.chain(this.setup.pass(false, this)).custom(0); 233 return false; 234 } 235 236}; 237 238// startup 239Window.onDomReady(MOOdalBox.init.bind(MOOdalBox));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.