1/* 2 * jQuery Impromptu 3 * By: Trent Richardson [http://trentrichardson.com] 4 * Version 4.2 5 * Last Modified: 01/25/2013 6 * 7 * Copyright 2013 Trent Richardson 8 * You may use this project under MIT or GPL licenses. 9 * http://trentrichardson.com/Impromptu/GPL-LICENSE.txt 10 * http://trentrichardson.com/Impromptu/MIT-LICENSE.txt 11 * 12 */ 13 14(function($) { 15 $.prompt = function(message, options) { 16 $.prompt.options = $.extend({},$.prompt.defaults,options); 17 $.prompt.currentPrefix = $.prompt.options.prefix; 18 $.prompt.currentStateName = ""; 19 20 var $body = $(document.body); 21 var $window = $(window); 22 23 $.prompt.options.classes = $.trim($.prompt.options.classes); 24 if($.prompt.options.classes != '') 25 $.prompt.options.classes = ' '+ $.prompt.options.classes; 26 27 //build the box and fade 28 var msgbox = '<div class="'+ $.prompt.options.prefix +'box'+ $.prompt.options.classes +'">'; 29 if($.prompt.options.useiframe && ($('object, applet').length > 0)) { 30 msgbox += '<iframe src="javascript:false;" style="display:block;position:absolute;z-index:-1;" class="'+ $.prompt.options.prefix +'fade"></iframe>'; 31 } else { 32 msgbox +='<div class="'+ $.prompt.options.prefix +'fade"></div>'; 33 } 34 msgbox += '<div class="'+ $.prompt.options.prefix +'"><div class="'+ $.prompt.options.prefix +'container"><div class="'; 35 msgbox += $.prompt.options.prefix +'close">X</div><div class="'+ $.prompt.options.prefix +'states"></div>'; 36 msgbox += '</div></div></div>'; 37 38 $.prompt.jqib = $(msgbox).appendTo($body); 39 $.prompt.jqi = $.prompt.jqib.children('.'+ $.prompt.options.prefix); 40 $.prompt.jqif = $.prompt.jqib.children('.'+ $.prompt.options.prefix +'fade'); 41 42 //if a string was passed, convert to a single state 43 if(message.constructor == String){ 44 message = { 45 state0: { 46 title: $.prompt.options.title, 47 html: message, 48 buttons: $.prompt.options.buttons, 49 position: $.prompt.options.position, 50 focus: $.prompt.options.focus, 51 submit: $.prompt.options.submit 52 } 53 }; 54 } 55 56 //build the states 57 var states = ""; 58 59 $.each(message,function(statename,stateobj){ 60 stateobj = $.extend({},$.prompt.defaults.state,stateobj); 61 message[statename] = stateobj; 62 63 var arrow = "", 64 title = ""; 65 if(stateobj.position.arrow !== null) 66 arrow = '<div class="'+ $.prompt.options.prefix + 'arrow '+ $.prompt.options.prefix + 'arrow'+ stateobj.position.arrow +'"></div>'; 67 if(stateobj.title && stateobj.title !== '') 68 title = '<div class="'+ $.prompt.options.prefix + 'title">'+ stateobj.title +'</div>'; 69 states += '<div id="'+ $.prompt.options.prefix +'state_'+ statename +'" class="'+ $.prompt.options.prefix + 'state" style="display:none;">'+ arrow + title +'<div class="'+ $.prompt.options.prefix +'message">' + stateobj.html +'</div><div class="'+ $.prompt.options.prefix +'buttons">'; 70 71 $.each(stateobj.buttons, function(k, v){ 72 if(typeof v == 'object'){ 73 states += '<div class="button-wrap val-'+v.value+'"><button '; 74 75 if(typeof v.classes !== "undefined"){ 76 states += 'class="' + ($.isArray(v.classes)? v.classes.join(' ') : v.classes) + '" '; 77 } 78 79 states += ' name="' + $.prompt.options.prefix + '_' + statename + '_button' + v.title.replace(/[^a-z0-9]+/gi,'') + '" id="' + $.prompt.options.prefix + '_' + statename + '_button' + v.title.replace(/[^a-z0-9]+/gi,'') + '" value="' + v.value + '">' + v.title + '</button></div>'; 80 81 } else { 82 states += '<div class="button-wrap val-'+v+'">
82<button name="' + $.prompt.options.prefix + '_' + statename + '_button' + k + '" id="' + $.prompt.options.prefix + '_' + statename + '_button' + k + '" value="' + v + '">' + k + '</button></div>'; 83 84 } 85 }); 86 states += '</div></div>'; 87 }); 88 89 //insert the states... 90 $.prompt.states = message; 91 $.prompt.jqi.find('.'+ $.prompt.options.prefix +'states').html(states).children('.'+ $.prompt.options.prefix +'state:first').css('display','block'); 92 $.prompt.jqi.find('.'+ $.prompt.options.prefix +'buttons:empty').css('display','none'); 93 94 //Events 95 $.each(message,function(statename,stateobj){ 96 var $state = $.prompt.jqi.find('#'+ $.prompt.options.prefix +'state_'+ statename); 97 98 if($.prompt.currentStateName === "") 99 $.prompt.currentStateName = statename; 100 101 $state.bind('promptsubmit', stateobj.submit); 102 103 $state.children('.'+ $.prompt.options.prefix +'buttons').find('button').click(function(){ 104 var $t = $(this), 105 msg = $state.children('.'+ $.prompt.options.prefix +'message'), 106 clicked = stateobj.buttons[$t.text()] || stateobj.buttons[$t.html()]; 107 if(clicked == undefined){ 108 for(var i in stateobj.buttons) 109 if(stateobj.buttons[i].title == $t.text() || stateobj.buttons[i].title == $t.html()) 110 clicked = stateobj.buttons[i].value; 111 } 112 113 if(typeof clicked == 'object') 114 clicked = clicked.value; 115 var forminputs = {}; 116 117 //collect all form element values from all states 118 $.each($.prompt.jqi.find('.'+ $.prompt.options.prefix +'states :input').serializeArray(),function(i,obj){ 119 if (forminputs[obj.name] === undefined) { 120 forminputs[obj.name] = obj.value; 121 } else if (typeof forminputs[obj.name] == Array || typeof forminputs[obj.name] == 'object') { 122 forminputs[obj.name].push(obj.value); 123 } else { 124 forminputs[obj.name] = [forminputs[obj.name],obj.value]; 125 } 126 }); 127 128 // trigger an event 129 var promptsubmite = new $.Event('promptsubmit'); 130 promptsubmite.stateName = statename; 131 promptsubmite.state = $state; 132 $state.trigger(promptsubmite, [clicked, msg, forminputs]); 133 134 if(!promptsubmite.isDefaultPrevented()){ 135 $.prompt.close(true, clicked,msg,forminputs); 136 } 137 }); 138 $state.find('.'+ $.prompt.options.prefix +'buttons button:eq('+ stateobj.focus +')').addClass($.prompt.options.prefix +'defaultbutton'); 139 140 }); 141 142 var fadeClicked = function(){ 143 if($.prompt.options.persistent){ 144 var offset = ($.prompt.options.top.toString().indexOf('%') >= 0? ($window.height()*(parseInt($.prompt.options.top,10)/100)) : parseInt($.prompt.options.top,10)), 145 top = parseInt($.prompt.jqi.css('top').replace('px',''),10) - offset; 146 147 //$window.scrollTop(top); 148 $('html,body').animate({ scrollTop: top }, 'fast', function(){ 149 var i = 0; 150 $.prompt.jqib.addClass($.prompt.options.prefix +'warning'); 151 var intervalid = setInterval(function(){ 152 $.prompt.jqib.toggleClass($.prompt.options.prefix +'warning'); 153 if(i++ > 1){ 154 clearInterval(intervalid); 155 $.prompt.jqib.removeClass($.prompt.options.prefix +'warning'); 156 } 157 }, 100); 158 }); 159 } 160 else { 161 $.prompt.close(true); 162 } 163 }; 164 165 var keyPressEventHandler = function(e){ 166 var key = (window.event) ? event.keyCode : e.keyCode; // MSIE or Firefox? 167 168 //escape key closes 169 if(key==27) { 170 fadeClicked(); 171 } 172 173 //constrain tabs 174 if (key == 9){ 175 var $inputels = $(':input:enabled:visible',$.prompt.jqib); 176 var fwd = !e.shiftKey && e.target == $inputels[$inputels.length-1]; 177 var back = e.shiftKey && e.target == $inputels[0]; 178 if (fwd || back) { 179 setTimeout(function(){ 180 if (!$inputels) 181 return; 182 var el = $inputels[back===true ? $inputels.length-1 : 0]; 183 184 if (el) 185 el.focus(); 186 },10); 187 return false; 188 } 189 } 190 }; 191 192 $.prompt.position(); 193 $.prompt.style(); 194 195 $.prompt.jqif.click(fadeClicked); 196 $window.resize({animate:false}, $.prompt.position); 197 $.prompt.jqi.find('.'+ $.prompt.options.prefix +'close').click($.prompt.close); 198 $.prompt.jqib.bind("keydown keypress",keyPressEventHandler) 199 .bind('promptloaded', $.prompt.options.loaded) 200 .bind('promptclose', $.prompt.options.close) 201 .bind('promptstatechanging', $.prompt.options.statechanging) 202 .bind('promptstatechanged', $.prompt.options.statechanged); 203 204 //Show it 205 $.prompt.jqif.fadeIn($.prompt.options.overlayspeed); 206 $.prompt.jqi[$.prompt.options.show]($.prompt.options.promptspeed, function(){ 207 $.prompt.jqib.trigger('promptloaded'); 208 }); 209 $.prompt.jqi.find('.'+ $.prompt.options.prefix +'states .'+ $.prompt.options.prefix +'state:first .'+ $.prompt.options.prefix +'defaultbutton').focus(); 210 211 if($.prompt.options.timeout > 0) 212 setTimeout($.prompt.close,$.prompt.options.timeout); 213 214 return $.prompt.jqib; 215 }; 216 217 $.prompt.defaults = { 218 prefix:'jqi', 219 classes: '', 220 title: '', 221 buttons: { 222 Ok: true 223 }, 224 loaded: function(e){}, 225 submit: function(e,v,m,f){}, 226 close: function(e,v,m,f){}, 227 statechanging: function(e, from, to){}, 228 statechanged: function(e, to){}, 229 opacity: 0.6, 230 zIndex: 999, 231 overlayspeed: 'slow', 232 promptspeed: 'fast', 233 show: 'fadeIn', 234 focus: 0, 235 useiframe: false, 236 top: '15%', 237 position: { 238 container: null, 239 x: null, 240 y: null, 241 arrow: null, 242 width: null 243 }, 244 persistent: true, 245 timeout: 0, 246 state: { 247 title: '', 248 html: '', 249 buttons: { 250 Ok: true 251 }, 252 focus: 0, 253 position: { 254 container: null, 255 x: null, 256 y: null, 257 arrow: null, 258 width: null 259 }, 260 submit: function(e,v,m,f){ 261 return true; 262 } 263 } 264 }; 265 266 $.prompt.currentPrefix = $.prompt.defaults.prefix; 267 268 $.prompt.currentStateName = ""; 269 270 $.prompt.setDefaults = function(o) { 271 $.prompt.defaults = $.extend({}, $.prompt.defaults, o); 272 }; 273 274 $.prompt.setStateDefaults = function(o) { 275 $.prompt.defaults.state = $.extend({}, $.prompt.defaults.state, o); 276 }; 277 278 $.prompt.position = function(e){
279 var restoreFx = $.fx.off, 280 $window = $(window), 281 bodyHeight = $(document.body).outerHeight(true), 282 windowHeight = $(window).height(), 283 documentHeight = $(document).height(), 284 height = bodyHeight > windowHeight ? bodyHeight : windowHeight, 285 top = parseInt($window.scrollTop(),10) + ($.prompt.options.top.toString().indexOf('%') >= 0? 286 (windowHeight*(parseInt($.prompt.options.top,10)/100)) : parseInt($.prompt.options.top,10)), 287 pos = $.prompt.states[$.prompt.currentStateName].position; 288 289 // This fixes the whitespace at the bottom of the fade, but it is 290 // inconsistant and can cause an unneeded scrollbar, making the page jump 291 //height = height > documentHeight? height : documentHeight; 292 293 // when resizing the window turn off animation 294 if(e !== undefined && e.data.animate === false) 295 $.fx.off = true; 296 297 $.prompt.jqib.css({ 298 position: "absolute", 299 height: height, 300 width: "100%", 301 top: 0, 302 left: 0, 303 right: 0, 304 bottom: 0 305 }); 306 $.prompt.jqif.css({ 307 position: "absolute", 308 height: height, 309 width: "100%", 310 top: 0, 311 left: 0, 312 right: 0, 313 bottom: 0 314 }); 315 316 // tour positioning 317 if(pos && pos.container){ 318 var offset = $(pos.container).offset(); 319 320 if($.isPlainObject(offset) && offset.top !== undefined){ 321 $.prompt.jqi.css({ 322 position: "absolute" 323 }); 324 $.prompt.jqi.animate({ 325 top: offset.top + pos.y, 326 left: offset.left + pos.x, 327 marginLeft: 0, 328 width: (pos.width !== undefined)? pos.width : null 329 }); 330 top = (offset.top + pos.y) - ($.prompt.options.top.toString().indexOf('%') >= 0? (windowHeight*(parseInt($.prompt.options.top,10)/100)) : parseInt($.prompt.options.top,10)); 331 $('html,body').animate({ scrollTop: top }, 'slow', 'swing', function(){}); 332 } 333 } 334 // custom state width animation 335 else if(pos && pos.width){ 336 $.prompt.jqi.css({ 337 position: "absolute", 338 left: '50%' 339 }); 340 $.prompt.jqi.animate({ 341 top: pos.y || top, 342 left: pos.x || '50%', 343 marginLeft: ((pos.width/2)*-1), 344 width: pos.width 345 }); 346 } 347 // standard prompt positioning 348 else{ 349 $.prompt.jqi.css({ 350 position: "absolute", 351 top: top, 352 left: '50%',//$window.width()/2, 353 marginLeft: (($.prompt.jqi.outerWidth()/2)*-1) 354 }); 355 } 356 357 // restore fx settings 358 if(e !== undefined && e.data.animate === false) 359 $.fx.off = restoreFx; 360 }; 361 362 $.prompt.style = function(){ 363 $.prompt.jqif.css({ 364 zIndex: $.prompt.options.zIndex, 365 display: "none", 366 opacity: $.prompt.options.opacity 367 }); 368 $.prompt.jqi.css({ 369 zIndex: $.prompt.options.zIndex+1, 370 display: "none" 371 }); 372 $.prompt.jqib.css({ 373 zIndex: $.prompt.options.zIndex 374 }); 375 }; 376 377 $.prompt.getStateContent = function(state) { 378 return $('#'+ $.prompt.currentPrefix +'state_'+ state); 379 }; 380 381 $.prompt.getCurrentState = function() { 382 return $('.'+ $.prompt.currentPrefix +'state:visible'); 383 }; 384 385 $.prompt.getCurrentStateName = function() { 386 var stateid = $.prompt.getCurrentState().attr('id'); 387 388 return stateid.replace($.prompt.currentPrefix +'state_',''); 389 }; 390 391 $.prompt.goToState = function(state, callback) { 392 var promptstatechanginge = new $.Event('promptstatechanging'); 393 $.prompt.jqib.trigger(promptstatechanginge, [$.prompt.currentStateName, state]); 394 395 if(!promptstatechanginge.isDefaultPrevented()){ 396 $.prompt.currentStateName = state; 397 398 $('.'+ $.prompt.currentPrefix +'state').slideUp('slow') 399 .find('.'+ $.prompt.currentPrefix +'arrow').fadeOut(); 400 401 $('#'+ $.prompt.currentPrefix +'state_'+ state).slideDown('slow',function(){ 402 var $t = $(this); 403 $t.find('.'+ $.prompt.currentPrefix +'defaultbutton').focus(); 404 $t.find('.'+ $.prompt.currentPrefix +'arrow').fadeIn('slow'); 405 406 if (typeof callback == 'function'){ 407 $.prompt.jqib.bind('promptstatechanged.tmp', callback); 408 } 409 $.prompt.jqib.trigger('promptstatechanged', [state]); 410 if (typeof callback == 'function'){ 411 $.prompt.jqib.unbind('promptstatechanged.tmp'); 412 } 413 }); 414 415 $.prompt.position(); 416 417 } 418 }; 419 420 $.prompt.nextState = function(callback) { 421 var $next = $('#'+ $.prompt.currentPrefix +'state_'+ $.prompt.currentStateName).next(); 422 $.prompt.goToState( $next.attr('id').replace($.prompt.currentPrefix +'state_',''), callback ); 423 }; 424 425 $.prompt.prevState = function(callback) { 426 var $prev = $('#'+ $.prompt.currentPrefix +'state_'+ $.prompt.currentStateName).prev(); 427 $.prompt.goToState( $prev.attr('id').replace($.prompt.currentPrefix +'state_',''), callback ); 428 }; 429 430 $.prompt.close = function(callCallback, clicked, msg, formvals){ 431 $.prompt.jqib.fadeOut('fast',function(){ 432 433 if(callCallback) { 434 $.prompt.jqib.trigger('promptclose', [clicked,msg,formvals]); 435 } 436 $.prompt.jqib.remove(); 437 438 $('window').unbind('resize',$.prompt.position); 439 440 }); 441 }; 442 443 $.fn.extend({ 444 prompt: function(options){ 445 if(options == undefined) 446 options = {}; 447 if(options.withDataAndEvents == undefined) 448 options.withDataAndEvents = false; 449 450 $.prompt($(this).clone(options.withDataAndEvents).html(),options); 451 } 452 }); 453 454})(jQuery);
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.