Mercurial > hg > MPIWGThesaurus
comparison jquery-ui/development-bundle/ui/jquery.ui.dialog.js @ 0:b2e4605f20b2
beta version
author | dwinter |
---|---|
date | Thu, 30 Jun 2011 09:07:49 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:b2e4605f20b2 |
---|---|
1 /* | |
2 * jQuery UI Dialog 1.8.11 | |
3 * | |
4 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) | |
5 * Dual licensed under the MIT or GPL Version 2 licenses. | |
6 * http://jquery.org/license | |
7 * | |
8 * http://docs.jquery.com/UI/Dialog | |
9 * | |
10 * Depends: | |
11 * jquery.ui.core.js | |
12 * jquery.ui.widget.js | |
13 * jquery.ui.button.js | |
14 * jquery.ui.draggable.js | |
15 * jquery.ui.mouse.js | |
16 * jquery.ui.position.js | |
17 * jquery.ui.resizable.js | |
18 */ | |
19 (function( $, undefined ) { | |
20 | |
21 var uiDialogClasses = | |
22 'ui-dialog ' + | |
23 'ui-widget ' + | |
24 'ui-widget-content ' + | |
25 'ui-corner-all ', | |
26 sizeRelatedOptions = { | |
27 buttons: true, | |
28 height: true, | |
29 maxHeight: true, | |
30 maxWidth: true, | |
31 minHeight: true, | |
32 minWidth: true, | |
33 width: true | |
34 }, | |
35 resizableRelatedOptions = { | |
36 maxHeight: true, | |
37 maxWidth: true, | |
38 minHeight: true, | |
39 minWidth: true | |
40 }; | |
41 | |
42 $.widget("ui.dialog", { | |
43 options: { | |
44 autoOpen: true, | |
45 buttons: {}, | |
46 closeOnEscape: true, | |
47 closeText: 'close', | |
48 dialogClass: '', | |
49 draggable: true, | |
50 hide: null, | |
51 height: 'auto', | |
52 maxHeight: false, | |
53 maxWidth: false, | |
54 minHeight: 150, | |
55 minWidth: 150, | |
56 modal: false, | |
57 position: { | |
58 my: 'center', | |
59 at: 'center', | |
60 collision: 'fit', | |
61 // ensure that the titlebar is never outside the document | |
62 using: function(pos) { | |
63 var topOffset = $(this).css(pos).offset().top; | |
64 if (topOffset < 0) { | |
65 $(this).css('top', pos.top - topOffset); | |
66 } | |
67 } | |
68 }, | |
69 resizable: true, | |
70 show: null, | |
71 stack: true, | |
72 title: '', | |
73 width: 300, | |
74 zIndex: 1000 | |
75 }, | |
76 | |
77 _create: function() { | |
78 this.originalTitle = this.element.attr('title'); | |
79 // #5742 - .attr() might return a DOMElement | |
80 if ( typeof this.originalTitle !== "string" ) { | |
81 this.originalTitle = ""; | |
82 } | |
83 | |
84 this.options.title = this.options.title || this.originalTitle; | |
85 var self = this, | |
86 options = self.options, | |
87 | |
88 title = options.title || ' ', | |
89 titleId = $.ui.dialog.getTitleId(self.element), | |
90 | |
91 uiDialog = (self.uiDialog = $('<div></div>')) | |
92 .appendTo(document.body) | |
93 .hide() | |
94 .addClass(uiDialogClasses + options.dialogClass) | |
95 .css({ | |
96 zIndex: options.zIndex | |
97 }) | |
98 // setting tabIndex makes the div focusable | |
99 // setting outline to 0 prevents a border on focus in Mozilla | |
100 .attr('tabIndex', -1).css('outline', 0).keydown(function(event) { | |
101 if (options.closeOnEscape && event.keyCode && | |
102 event.keyCode === $.ui.keyCode.ESCAPE) { | |
103 | |
104 self.close(event); | |
105 event.preventDefault(); | |
106 } | |
107 }) | |
108 .attr({ | |
109 role: 'dialog', | |
110 'aria-labelledby': titleId | |
111 }) | |
112 .mousedown(function(event) { | |
113 self.moveToTop(false, event); | |
114 }), | |
115 | |
116 uiDialogContent = self.element | |
117 .show() | |
118 .removeAttr('title') | |
119 .addClass( | |
120 'ui-dialog-content ' + | |
121 'ui-widget-content') | |
122 .appendTo(uiDialog), | |
123 | |
124 uiDialogTitlebar = (self.uiDialogTitlebar = $('<div></div>')) | |
125 .addClass( | |
126 'ui-dialog-titlebar ' + | |
127 'ui-widget-header ' + | |
128 'ui-corner-all ' + | |
129 'ui-helper-clearfix' | |
130 ) | |
131 .prependTo(uiDialog), | |
132 | |
133 uiDialogTitlebarClose = $('<a href="#"></a>') | |
134 .addClass( | |
135 'ui-dialog-titlebar-close ' + | |
136 'ui-corner-all' | |
137 ) | |
138 .attr('role', 'button') | |
139 .hover( | |
140 function() { | |
141 uiDialogTitlebarClose.addClass('ui-state-hover'); | |
142 }, | |
143 function() { | |
144 uiDialogTitlebarClose.removeClass('ui-state-hover'); | |
145 } | |
146 ) | |
147 .focus(function() { | |
148 uiDialogTitlebarClose.addClass('ui-state-focus'); | |
149 }) | |
150 .blur(function() { | |
151 uiDialogTitlebarClose.removeClass('ui-state-focus'); | |
152 }) | |
153 .click(function(event) { | |
154 self.close(event); | |
155 return false; | |
156 }) | |
157 .appendTo(uiDialogTitlebar), | |
158 | |
159 uiDialogTitlebarCloseText = (self.uiDialogTitlebarCloseText = $('<span></span>')) | |
160 .addClass( | |
161 'ui-icon ' + | |
162 'ui-icon-closethick' | |
163 ) | |
164 .text(options.closeText) | |
165 .appendTo(uiDialogTitlebarClose), | |
166 | |
167 uiDialogTitle = $('<span></span>') | |
168 .addClass('ui-dialog-title') | |
169 .attr('id', titleId) | |
170 .html(title) | |
171 .prependTo(uiDialogTitlebar); | |
172 | |
173 //handling of deprecated beforeclose (vs beforeClose) option | |
174 //Ticket #4669 http://dev.jqueryui.com/ticket/4669 | |
175 //TODO: remove in 1.9pre | |
176 if ($.isFunction(options.beforeclose) && !$.isFunction(options.beforeClose)) { | |
177 options.beforeClose = options.beforeclose; | |
178 } | |
179 | |
180 uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection(); | |
181 | |
182 if (options.draggable && $.fn.draggable) { | |
183 self._makeDraggable(); | |
184 } | |
185 if (options.resizable && $.fn.resizable) { | |
186 self._makeResizable(); | |
187 } | |
188 | |
189 self._createButtons(options.buttons); | |
190 self._isOpen = false; | |
191 | |
192 if ($.fn.bgiframe) { | |
193 uiDialog.bgiframe(); | |
194 } | |
195 }, | |
196 | |
197 _init: function() { | |
198 if ( this.options.autoOpen ) { | |
199 this.open(); | |
200 } | |
201 }, | |
202 | |
203 destroy: function() { | |
204 var self = this; | |
205 | |
206 if (self.overlay) { | |
207 self.overlay.destroy(); | |
208 } | |
209 self.uiDialog.hide(); | |
210 self.element | |
211 .unbind('.dialog') | |
212 .removeData('dialog') | |
213 .removeClass('ui-dialog-content ui-widget-content') | |
214 .hide().appendTo('body'); | |
215 self.uiDialog.remove(); | |
216 | |
217 if (self.originalTitle) { | |
218 self.element.attr('title', self.originalTitle); | |
219 } | |
220 | |
221 return self; | |
222 }, | |
223 | |
224 widget: function() { | |
225 return this.uiDialog; | |
226 }, | |
227 | |
228 close: function(event) { | |
229 var self = this, | |
230 maxZ, thisZ; | |
231 | |
232 if (false === self._trigger('beforeClose', event)) { | |
233 return; | |
234 } | |
235 | |
236 if (self.overlay) { | |
237 self.overlay.destroy(); | |
238 } | |
239 self.uiDialog.unbind('keypress.ui-dialog'); | |
240 | |
241 self._isOpen = false; | |
242 | |
243 if (self.options.hide) { | |
244 self.uiDialog.hide(self.options.hide, function() { | |
245 self._trigger('close', event); | |
246 }); | |
247 } else { | |
248 self.uiDialog.hide(); | |
249 self._trigger('close', event); | |
250 } | |
251 | |
252 $.ui.dialog.overlay.resize(); | |
253 | |
254 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) | |
255 if (self.options.modal) { | |
256 maxZ = 0; | |
257 $('.ui-dialog').each(function() { | |
258 if (this !== self.uiDialog[0]) { | |
259 thisZ = $(this).css('z-index'); | |
260 if(!isNaN(thisZ)) { | |
261 maxZ = Math.max(maxZ, thisZ); | |
262 } | |
263 } | |
264 }); | |
265 $.ui.dialog.maxZ = maxZ; | |
266 } | |
267 | |
268 return self; | |
269 }, | |
270 | |
271 isOpen: function() { | |
272 return this._isOpen; | |
273 }, | |
274 | |
275 // the force parameter allows us to move modal dialogs to their correct | |
276 // position on open | |
277 moveToTop: function(force, event) { | |
278 var self = this, | |
279 options = self.options, | |
280 saveScroll; | |
281 | |
282 if ((options.modal && !force) || | |
283 (!options.stack && !options.modal)) { | |
284 return self._trigger('focus', event); | |
285 } | |
286 | |
287 if (options.zIndex > $.ui.dialog.maxZ) { | |
288 $.ui.dialog.maxZ = options.zIndex; | |
289 } | |
290 if (self.overlay) { | |
291 $.ui.dialog.maxZ += 1; | |
292 self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ); | |
293 } | |
294 | |
295 //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed. | |
296 // http://ui.jquery.com/bugs/ticket/3193 | |
297 saveScroll = { scrollTop: self.element.attr('scrollTop'), scrollLeft: self.element.attr('scrollLeft') }; | |
298 $.ui.dialog.maxZ += 1; | |
299 self.uiDialog.css('z-index', $.ui.dialog.maxZ); | |
300 self.element.attr(saveScroll); | |
301 self._trigger('focus', event); | |
302 | |
303 return self; | |
304 }, | |
305 | |
306 open: function() { | |
307 if (this._isOpen) { return; } | |
308 | |
309 var self = this, | |
310 options = self.options, | |
311 uiDialog = self.uiDialog; | |
312 | |
313 self.overlay = options.modal ? new $.ui.dialog.overlay(self) : null; | |
314 self._size(); | |
315 self._position(options.position); | |
316 uiDialog.show(options.show); | |
317 self.moveToTop(true); | |
318 | |
319 // prevent tabbing out of modal dialogs | |
320 if (options.modal) { | |
321 uiDialog.bind('keypress.ui-dialog', function(event) { | |
322 if (event.keyCode !== $.ui.keyCode.TAB) { | |
323 return; | |
324 } | |
325 | |
326 var tabbables = $(':tabbable', this), | |
327 first = tabbables.filter(':first'), | |
328 last = tabbables.filter(':last'); | |
329 | |
330 if (event.target === last[0] && !event.shiftKey) { | |
331 first.focus(1); | |
332 return false; | |
333 } else if (event.target === first[0] && event.shiftKey) { | |
334 last.focus(1); | |
335 return false; | |
336 } | |
337 }); | |
338 } | |
339 | |
340 // set focus to the first tabbable element in the content area or the first button | |
341 // if there are no tabbable elements, set focus on the dialog itself | |
342 $(self.element.find(':tabbable').get().concat( | |
343 uiDialog.find('.ui-dialog-buttonpane :tabbable').get().concat( | |
344 uiDialog.get()))).eq(0).focus(); | |
345 | |
346 self._isOpen = true; | |
347 self._trigger('open'); | |
348 | |
349 return self; | |
350 }, | |
351 | |
352 _createButtons: function(buttons) { | |
353 var self = this, | |
354 hasButtons = false, | |
355 uiDialogButtonPane = $('<div></div>') | |
356 .addClass( | |
357 'ui-dialog-buttonpane ' + | |
358 'ui-widget-content ' + | |
359 'ui-helper-clearfix' | |
360 ), | |
361 uiButtonSet = $( "<div></div>" ) | |
362 .addClass( "ui-dialog-buttonset" ) | |
363 .appendTo( uiDialogButtonPane ); | |
364 | |
365 // if we already have a button pane, remove it | |
366 self.uiDialog.find('.ui-dialog-buttonpane').remove(); | |
367 | |
368 if (typeof buttons === 'object' && buttons !== null) { | |
369 $.each(buttons, function() { | |
370 return !(hasButtons = true); | |
371 }); | |
372 } | |
373 if (hasButtons) { | |
374 $.each(buttons, function(name, props) { | |
375 props = $.isFunction( props ) ? | |
376 { click: props, text: name } : | |
377 props; | |
378 var button = $('<button type="button"></button>') | |
379 .attr( props, true ) | |
380 .unbind('click') | |
381 .click(function() { | |
382 props.click.apply(self.element[0], arguments); | |
383 }) | |
384 .appendTo(uiButtonSet); | |
385 if ($.fn.button) { | |
386 button.button(); | |
387 } | |
388 }); | |
389 uiDialogButtonPane.appendTo(self.uiDialog); | |
390 } | |
391 }, | |
392 | |
393 _makeDraggable: function() { | |
394 var self = this, | |
395 options = self.options, | |
396 doc = $(document), | |
397 heightBeforeDrag; | |
398 | |
399 function filteredUi(ui) { | |
400 return { | |
401 position: ui.position, | |
402 offset: ui.offset | |
403 }; | |
404 } | |
405 | |
406 self.uiDialog.draggable({ | |
407 cancel: '.ui-dialog-content, .ui-dialog-titlebar-close', | |
408 handle: '.ui-dialog-titlebar', | |
409 containment: 'document', | |
410 start: function(event, ui) { | |
411 heightBeforeDrag = options.height === "auto" ? "auto" : $(this).height(); | |
412 $(this).height($(this).height()).addClass("ui-dialog-dragging"); | |
413 self._trigger('dragStart', event, filteredUi(ui)); | |
414 }, | |
415 drag: function(event, ui) { | |
416 self._trigger('drag', event, filteredUi(ui)); | |
417 }, | |
418 stop: function(event, ui) { | |
419 options.position = [ui.position.left - doc.scrollLeft(), | |
420 ui.position.top - doc.scrollTop()]; | |
421 $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag); | |
422 self._trigger('dragStop', event, filteredUi(ui)); | |
423 $.ui.dialog.overlay.resize(); | |
424 } | |
425 }); | |
426 }, | |
427 | |
428 _makeResizable: function(handles) { | |
429 handles = (handles === undefined ? this.options.resizable : handles); | |
430 var self = this, | |
431 options = self.options, | |
432 // .ui-resizable has position: relative defined in the stylesheet | |
433 // but dialogs have to use absolute or fixed positioning | |
434 position = self.uiDialog.css('position'), | |
435 resizeHandles = (typeof handles === 'string' ? | |
436 handles : | |
437 'n,e,s,w,se,sw,ne,nw' | |
438 ); | |
439 | |
440 function filteredUi(ui) { | |
441 return { | |
442 originalPosition: ui.originalPosition, | |
443 originalSize: ui.originalSize, | |
444 position: ui.position, | |
445 size: ui.size | |
446 }; | |
447 } | |
448 | |
449 self.uiDialog.resizable({ | |
450 cancel: '.ui-dialog-content', | |
451 containment: 'document', | |
452 alsoResize: self.element, | |
453 maxWidth: options.maxWidth, | |
454 maxHeight: options.maxHeight, | |
455 minWidth: options.minWidth, | |
456 minHeight: self._minHeight(), | |
457 handles: resizeHandles, | |
458 start: function(event, ui) { | |
459 $(this).addClass("ui-dialog-resizing"); | |
460 self._trigger('resizeStart', event, filteredUi(ui)); | |
461 }, | |
462 resize: function(event, ui) { | |
463 self._trigger('resize', event, filteredUi(ui)); | |
464 }, | |
465 stop: function(event, ui) { | |
466 $(this).removeClass("ui-dialog-resizing"); | |
467 options.height = $(this).height(); | |
468 options.width = $(this).width(); | |
469 self._trigger('resizeStop', event, filteredUi(ui)); | |
470 $.ui.dialog.overlay.resize(); | |
471 } | |
472 }) | |
473 .css('position', position) | |
474 .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se'); | |
475 }, | |
476 | |
477 _minHeight: function() { | |
478 var options = this.options; | |
479 | |
480 if (options.height === 'auto') { | |
481 return options.minHeight; | |
482 } else { | |
483 return Math.min(options.minHeight, options.height); | |
484 } | |
485 }, | |
486 | |
487 _position: function(position) { | |
488 var myAt = [], | |
489 offset = [0, 0], | |
490 isVisible; | |
491 | |
492 if (position) { | |
493 // deep extending converts arrays to objects in jQuery <= 1.3.2 :-( | |
494 // if (typeof position == 'string' || $.isArray(position)) { | |
495 // myAt = $.isArray(position) ? position : position.split(' '); | |
496 | |
497 if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) { | |
498 myAt = position.split ? position.split(' ') : [position[0], position[1]]; | |
499 if (myAt.length === 1) { | |
500 myAt[1] = myAt[0]; | |
501 } | |
502 | |
503 $.each(['left', 'top'], function(i, offsetPosition) { | |
504 if (+myAt[i] === myAt[i]) { | |
505 offset[i] = myAt[i]; | |
506 myAt[i] = offsetPosition; | |
507 } | |
508 }); | |
509 | |
510 position = { | |
511 my: myAt.join(" "), | |
512 at: myAt.join(" "), | |
513 offset: offset.join(" ") | |
514 }; | |
515 } | |
516 | |
517 position = $.extend({}, $.ui.dialog.prototype.options.position, position); | |
518 } else { | |
519 position = $.ui.dialog.prototype.options.position; | |
520 } | |
521 | |
522 // need to show the dialog to get the actual offset in the position plugin | |
523 isVisible = this.uiDialog.is(':visible'); | |
524 if (!isVisible) { | |
525 this.uiDialog.show(); | |
526 } | |
527 this.uiDialog | |
528 // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781 | |
529 .css({ top: 0, left: 0 }) | |
530 .position($.extend({ of: window }, position)); | |
531 if (!isVisible) { | |
532 this.uiDialog.hide(); | |
533 } | |
534 }, | |
535 | |
536 _setOptions: function( options ) { | |
537 var self = this, | |
538 resizableOptions = {}, | |
539 resize = false; | |
540 | |
541 $.each( options, function( key, value ) { | |
542 self._setOption( key, value ); | |
543 | |
544 if ( key in sizeRelatedOptions ) { | |
545 resize = true; | |
546 } | |
547 if ( key in resizableRelatedOptions ) { | |
548 resizableOptions[ key ] = value; | |
549 } | |
550 }); | |
551 | |
552 if ( resize ) { | |
553 this._size(); | |
554 } | |
555 if ( this.uiDialog.is( ":data(resizable)" ) ) { | |
556 this.uiDialog.resizable( "option", resizableOptions ); | |
557 } | |
558 }, | |
559 | |
560 _setOption: function(key, value){ | |
561 var self = this, | |
562 uiDialog = self.uiDialog; | |
563 | |
564 switch (key) { | |
565 //handling of deprecated beforeclose (vs beforeClose) option | |
566 //Ticket #4669 http://dev.jqueryui.com/ticket/4669 | |
567 //TODO: remove in 1.9pre | |
568 case "beforeclose": | |
569 key = "beforeClose"; | |
570 break; | |
571 case "buttons": | |
572 self._createButtons(value); | |
573 break; | |
574 case "closeText": | |
575 // ensure that we always pass a string | |
576 self.uiDialogTitlebarCloseText.text("" + value); | |
577 break; | |
578 case "dialogClass": | |
579 uiDialog | |
580 .removeClass(self.options.dialogClass) | |
581 .addClass(uiDialogClasses + value); | |
582 break; | |
583 case "disabled": | |
584 if (value) { | |
585 uiDialog.addClass('ui-dialog-disabled'); | |
586 } else { | |
587 uiDialog.removeClass('ui-dialog-disabled'); | |
588 } | |
589 break; | |
590 case "draggable": | |
591 var isDraggable = uiDialog.is( ":data(draggable)" ); | |
592 if ( isDraggable && !value ) { | |
593 uiDialog.draggable( "destroy" ); | |
594 } | |
595 | |
596 if ( !isDraggable && value ) { | |
597 self._makeDraggable(); | |
598 } | |
599 break; | |
600 case "position": | |
601 self._position(value); | |
602 break; | |
603 case "resizable": | |
604 // currently resizable, becoming non-resizable | |
605 var isResizable = uiDialog.is( ":data(resizable)" ); | |
606 if (isResizable && !value) { | |
607 uiDialog.resizable('destroy'); | |
608 } | |
609 | |
610 // currently resizable, changing handles | |
611 if (isResizable && typeof value === 'string') { | |
612 uiDialog.resizable('option', 'handles', value); | |
613 } | |
614 | |
615 // currently non-resizable, becoming resizable | |
616 if (!isResizable && value !== false) { | |
617 self._makeResizable(value); | |
618 } | |
619 break; | |
620 case "title": | |
621 // convert whatever was passed in o a string, for html() to not throw up | |
622 $(".ui-dialog-title", self.uiDialogTitlebar).html("" + (value || ' ')); | |
623 break; | |
624 } | |
625 | |
626 $.Widget.prototype._setOption.apply(self, arguments); | |
627 }, | |
628 | |
629 _size: function() { | |
630 /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content | |
631 * divs will both have width and height set, so we need to reset them | |
632 */ | |
633 var options = this.options, | |
634 nonContentHeight, | |
635 minContentHeight, | |
636 isVisible = this.uiDialog.is( ":visible" ); | |
637 | |
638 // reset content sizing | |
639 this.element.show().css({ | |
640 width: 'auto', | |
641 minHeight: 0, | |
642 height: 0 | |
643 }); | |
644 | |
645 if (options.minWidth > options.width) { | |
646 options.width = options.minWidth; | |
647 } | |
648 | |
649 // reset wrapper sizing | |
650 // determine the height of all the non-content elements | |
651 nonContentHeight = this.uiDialog.css({ | |
652 height: 'auto', | |
653 width: options.width | |
654 }) | |
655 .height(); | |
656 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); | |
657 | |
658 if ( options.height === "auto" ) { | |
659 // only needed for IE6 support | |
660 if ( $.support.minHeight ) { | |
661 this.element.css({ | |
662 minHeight: minContentHeight, | |
663 height: "auto" | |
664 }); | |
665 } else { | |
666 this.uiDialog.show(); | |
667 var autoHeight = this.element.css( "height", "auto" ).height(); | |
668 if ( !isVisible ) { | |
669 this.uiDialog.hide(); | |
670 } | |
671 this.element.height( Math.max( autoHeight, minContentHeight ) ); | |
672 } | |
673 } else { | |
674 this.element.height( Math.max( options.height - nonContentHeight, 0 ) ); | |
675 } | |
676 | |
677 if (this.uiDialog.is(':data(resizable)')) { | |
678 this.uiDialog.resizable('option', 'minHeight', this._minHeight()); | |
679 } | |
680 } | |
681 }); | |
682 | |
683 $.extend($.ui.dialog, { | |
684 version: "1.8.11", | |
685 | |
686 uuid: 0, | |
687 maxZ: 0, | |
688 | |
689 getTitleId: function($el) { | |
690 var id = $el.attr('id'); | |
691 if (!id) { | |
692 this.uuid += 1; | |
693 id = this.uuid; | |
694 } | |
695 return 'ui-dialog-title-' + id; | |
696 }, | |
697 | |
698 overlay: function(dialog) { | |
699 this.$el = $.ui.dialog.overlay.create(dialog); | |
700 } | |
701 }); | |
702 | |
703 $.extend($.ui.dialog.overlay, { | |
704 instances: [], | |
705 // reuse old instances due to IE memory leak with alpha transparency (see #5185) | |
706 oldInstances: [], | |
707 maxZ: 0, | |
708 events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','), | |
709 function(event) { return event + '.dialog-overlay'; }).join(' '), | |
710 create: function(dialog) { | |
711 if (this.instances.length === 0) { | |
712 // prevent use of anchors and inputs | |
713 // we use a setTimeout in case the overlay is created from an | |
714 // event that we're going to be cancelling (see #2804) | |
715 setTimeout(function() { | |
716 // handle $(el).dialog().dialog('close') (see #4065) | |
717 if ($.ui.dialog.overlay.instances.length) { | |
718 $(document).bind($.ui.dialog.overlay.events, function(event) { | |
719 // stop events if the z-index of the target is < the z-index of the overlay | |
720 // we cannot return true when we don't want to cancel the event (#3523) | |
721 if ($(event.target).zIndex() < $.ui.dialog.overlay.maxZ) { | |
722 return false; | |
723 } | |
724 }); | |
725 } | |
726 }, 1); | |
727 | |
728 // allow closing by pressing the escape key | |
729 $(document).bind('keydown.dialog-overlay', function(event) { | |
730 if (dialog.options.closeOnEscape && event.keyCode && | |
731 event.keyCode === $.ui.keyCode.ESCAPE) { | |
732 | |
733 dialog.close(event); | |
734 event.preventDefault(); | |
735 } | |
736 }); | |
737 | |
738 // handle window resize | |
739 $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize); | |
740 } | |
741 | |
742 var $el = (this.oldInstances.pop() || $('<div></div>').addClass('ui-widget-overlay')) | |
743 .appendTo(document.body) | |
744 .css({ | |
745 width: this.width(), | |
746 height: this.height() | |
747 }); | |
748 | |
749 if ($.fn.bgiframe) { | |
750 $el.bgiframe(); | |
751 } | |
752 | |
753 this.instances.push($el); | |
754 return $el; | |
755 }, | |
756 | |
757 destroy: function($el) { | |
758 var indexOf = $.inArray($el, this.instances); | |
759 if (indexOf != -1){ | |
760 this.oldInstances.push(this.instances.splice(indexOf, 1)[0]); | |
761 } | |
762 | |
763 if (this.instances.length === 0) { | |
764 $([document, window]).unbind('.dialog-overlay'); | |
765 } | |
766 | |
767 $el.remove(); | |
768 | |
769 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) | |
770 var maxZ = 0; | |
771 $.each(this.instances, function() { | |
772 maxZ = Math.max(maxZ, this.css('z-index')); | |
773 }); | |
774 this.maxZ = maxZ; | |
775 }, | |
776 | |
777 height: function() { | |
778 var scrollHeight, | |
779 offsetHeight; | |
780 // handle IE 6 | |
781 if ($.browser.msie && $.browser.version < 7) { | |
782 scrollHeight = Math.max( | |
783 document.documentElement.scrollHeight, | |
784 document.body.scrollHeight | |
785 ); | |
786 offsetHeight = Math.max( | |
787 document.documentElement.offsetHeight, | |
788 document.body.offsetHeight | |
789 ); | |
790 | |
791 if (scrollHeight < offsetHeight) { | |
792 return $(window).height() + 'px'; | |
793 } else { | |
794 return scrollHeight + 'px'; | |
795 } | |
796 // handle "good" browsers | |
797 } else { | |
798 return $(document).height() + 'px'; | |
799 } | |
800 }, | |
801 | |
802 width: function() { | |
803 var scrollWidth, | |
804 offsetWidth; | |
805 // handle IE 6 | |
806 if ($.browser.msie && $.browser.version < 7) { | |
807 scrollWidth = Math.max( | |
808 document.documentElement.scrollWidth, | |
809 document.body.scrollWidth | |
810 ); | |
811 offsetWidth = Math.max( | |
812 document.documentElement.offsetWidth, | |
813 document.body.offsetWidth | |
814 ); | |
815 | |
816 if (scrollWidth < offsetWidth) { | |
817 return $(window).width() + 'px'; | |
818 } else { | |
819 return scrollWidth + 'px'; | |
820 } | |
821 // handle "good" browsers | |
822 } else { | |
823 return $(document).width() + 'px'; | |
824 } | |
825 }, | |
826 | |
827 resize: function() { | |
828 /* If the dialog is draggable and the user drags it past the | |
829 * right edge of the window, the document becomes wider so we | |
830 * need to stretch the overlay. If the user then drags the | |
831 * dialog back to the left, the document will become narrower, | |
832 * so we need to shrink the overlay to the appropriate size. | |
833 * This is handled by shrinking the overlay before setting it | |
834 * to the full document size. | |
835 */ | |
836 var $overlays = $([]); | |
837 $.each($.ui.dialog.overlay.instances, function() { | |
838 $overlays = $overlays.add(this); | |
839 }); | |
840 | |
841 $overlays.css({ | |
842 width: 0, | |
843 height: 0 | |
844 }).css({ | |
845 width: $.ui.dialog.overlay.width(), | |
846 height: $.ui.dialog.overlay.height() | |
847 }); | |
848 } | |
849 }); | |
850 | |
851 $.extend($.ui.dialog.overlay.prototype, { | |
852 destroy: function() { | |
853 $.ui.dialog.overlay.destroy(this.$el); | |
854 } | |
855 }); | |
856 | |
857 }(jQuery)); |