|
1 /*! |
|
2 * jQuery UI Dialog 1.10.3 |
|
3 * http://jqueryui.com |
|
4 * |
|
5 * Copyright 2013 jQuery Foundation and other contributors |
|
6 * Released under the MIT license. |
|
7 * http://jquery.org/license |
|
8 * |
|
9 * http://api.jqueryui.com/dialog/ |
|
10 * |
|
11 * Depends: |
|
12 * jquery.ui.core.js |
|
13 * jquery.ui.widget.js |
|
14 * jquery.ui.button.js |
|
15 * jquery.ui.draggable.js |
|
16 * jquery.ui.mouse.js |
|
17 * jquery.ui.position.js |
|
18 * jquery.ui.resizable.js |
|
19 */ |
|
20 (function( $, undefined ) { |
|
21 |
|
22 var sizeRelatedOptions = { |
|
23 buttons: true, |
|
24 height: true, |
|
25 maxHeight: true, |
|
26 maxWidth: true, |
|
27 minHeight: true, |
|
28 minWidth: true, |
|
29 width: true |
|
30 }, |
|
31 resizableRelatedOptions = { |
|
32 maxHeight: true, |
|
33 maxWidth: true, |
|
34 minHeight: true, |
|
35 minWidth: true |
|
36 }; |
|
37 |
|
38 $.widget( "ui.dialog", { |
|
39 version: "1.10.3", |
|
40 options: { |
|
41 appendTo: "body", |
|
42 autoOpen: true, |
|
43 buttons: [], |
|
44 closeOnEscape: true, |
|
45 closeText: "close", |
|
46 dialogClass: "", |
|
47 draggable: true, |
|
48 hide: null, |
|
49 height: "auto", |
|
50 maxHeight: null, |
|
51 maxWidth: null, |
|
52 minHeight: 150, |
|
53 minWidth: 150, |
|
54 modal: false, |
|
55 position: { |
|
56 my: "center", |
|
57 at: "center", |
|
58 of: window, |
|
59 collision: "fit", |
|
60 // Ensure the titlebar is always visible |
|
61 using: function( pos ) { |
|
62 var topOffset = $( this ).css( pos ).offset().top; |
|
63 if ( topOffset < 0 ) { |
|
64 $( this ).css( "top", pos.top - topOffset ); |
|
65 } |
|
66 } |
|
67 }, |
|
68 resizable: true, |
|
69 show: null, |
|
70 title: null, |
|
71 width: 300, |
|
72 |
|
73 // callbacks |
|
74 beforeClose: null, |
|
75 close: null, |
|
76 drag: null, |
|
77 dragStart: null, |
|
78 dragStop: null, |
|
79 focus: null, |
|
80 open: null, |
|
81 resize: null, |
|
82 resizeStart: null, |
|
83 resizeStop: null |
|
84 }, |
|
85 |
|
86 _create: function() { |
|
87 this.originalCss = { |
|
88 display: this.element[0].style.display, |
|
89 width: this.element[0].style.width, |
|
90 minHeight: this.element[0].style.minHeight, |
|
91 maxHeight: this.element[0].style.maxHeight, |
|
92 height: this.element[0].style.height |
|
93 }; |
|
94 this.originalPosition = { |
|
95 parent: this.element.parent(), |
|
96 index: this.element.parent().children().index( this.element ) |
|
97 }; |
|
98 this.originalTitle = this.element.attr("title"); |
|
99 this.options.title = this.options.title || this.originalTitle; |
|
100 |
|
101 this._createWrapper(); |
|
102 |
|
103 this.element |
|
104 .show() |
|
105 .removeAttr("title") |
|
106 .addClass("ui-dialog-content ui-widget-content") |
|
107 .appendTo( this.uiDialog ); |
|
108 |
|
109 this._createTitlebar(); |
|
110 this._createButtonPane(); |
|
111 |
|
112 if ( this.options.draggable && $.fn.draggable ) { |
|
113 this._makeDraggable(); |
|
114 } |
|
115 if ( this.options.resizable && $.fn.resizable ) { |
|
116 this._makeResizable(); |
|
117 } |
|
118 |
|
119 this._isOpen = false; |
|
120 }, |
|
121 |
|
122 _init: function() { |
|
123 if ( this.options.autoOpen ) { |
|
124 this.open(); |
|
125 } |
|
126 }, |
|
127 |
|
128 _appendTo: function() { |
|
129 var element = this.options.appendTo; |
|
130 if ( element && (element.jquery || element.nodeType) ) { |
|
131 return $( element ); |
|
132 } |
|
133 return this.document.find( element || "body" ).eq( 0 ); |
|
134 }, |
|
135 |
|
136 _destroy: function() { |
|
137 var next, |
|
138 originalPosition = this.originalPosition; |
|
139 |
|
140 this._destroyOverlay(); |
|
141 |
|
142 this.element |
|
143 .removeUniqueId() |
|
144 .removeClass("ui-dialog-content ui-widget-content") |
|
145 .css( this.originalCss ) |
|
146 // Without detaching first, the following becomes really slow |
|
147 .detach(); |
|
148 |
|
149 this.uiDialog.stop( true, true ).remove(); |
|
150 |
|
151 if ( this.originalTitle ) { |
|
152 this.element.attr( "title", this.originalTitle ); |
|
153 } |
|
154 |
|
155 next = originalPosition.parent.children().eq( originalPosition.index ); |
|
156 // Don't try to place the dialog next to itself (#8613) |
|
157 if ( next.length && next[0] !== this.element[0] ) { |
|
158 next.before( this.element ); |
|
159 } else { |
|
160 originalPosition.parent.append( this.element ); |
|
161 } |
|
162 }, |
|
163 |
|
164 widget: function() { |
|
165 return this.uiDialog; |
|
166 }, |
|
167 |
|
168 disable: $.noop, |
|
169 enable: $.noop, |
|
170 |
|
171 close: function( event ) { |
|
172 var that = this; |
|
173 |
|
174 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { |
|
175 return; |
|
176 } |
|
177 |
|
178 this._isOpen = false; |
|
179 this._destroyOverlay(); |
|
180 |
|
181 if ( !this.opener.filter(":focusable").focus().length ) { |
|
182 // Hiding a focused element doesn't trigger blur in WebKit |
|
183 // so in case we have nothing to focus on, explicitly blur the active element |
|
184 // https://bugs.webkit.org/show_bug.cgi?id=47182 |
|
185 $( this.document[0].activeElement ).blur(); |
|
186 } |
|
187 |
|
188 this._hide( this.uiDialog, this.options.hide, function() { |
|
189 that._trigger( "close", event ); |
|
190 }); |
|
191 }, |
|
192 |
|
193 isOpen: function() { |
|
194 return this._isOpen; |
|
195 }, |
|
196 |
|
197 moveToTop: function() { |
|
198 this._moveToTop(); |
|
199 }, |
|
200 |
|
201 _moveToTop: function( event, silent ) { |
|
202 var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length; |
|
203 if ( moved && !silent ) { |
|
204 this._trigger( "focus", event ); |
|
205 } |
|
206 return moved; |
|
207 }, |
|
208 |
|
209 open: function() { |
|
210 var that = this; |
|
211 if ( this._isOpen ) { |
|
212 if ( this._moveToTop() ) { |
|
213 this._focusTabbable(); |
|
214 } |
|
215 return; |
|
216 } |
|
217 |
|
218 this._isOpen = true; |
|
219 this.opener = $( this.document[0].activeElement ); |
|
220 |
|
221 this._size(); |
|
222 this._position(); |
|
223 this._createOverlay(); |
|
224 this._moveToTop( null, true ); |
|
225 this._show( this.uiDialog, this.options.show, function() { |
|
226 that._focusTabbable(); |
|
227 that._trigger("focus"); |
|
228 }); |
|
229 |
|
230 this._trigger("open"); |
|
231 }, |
|
232 |
|
233 _focusTabbable: function() { |
|
234 // Set focus to the first match: |
|
235 // 1. First element inside the dialog matching [autofocus] |
|
236 // 2. Tabbable element inside the content element |
|
237 // 3. Tabbable element inside the buttonpane |
|
238 // 4. The close button |
|
239 // 5. The dialog itself |
|
240 var hasFocus = this.element.find("[autofocus]"); |
|
241 if ( !hasFocus.length ) { |
|
242 hasFocus = this.element.find(":tabbable"); |
|
243 } |
|
244 if ( !hasFocus.length ) { |
|
245 hasFocus = this.uiDialogButtonPane.find(":tabbable"); |
|
246 } |
|
247 if ( !hasFocus.length ) { |
|
248 hasFocus = this.uiDialogTitlebarClose.filter(":tabbable"); |
|
249 } |
|
250 if ( !hasFocus.length ) { |
|
251 hasFocus = this.uiDialog; |
|
252 } |
|
253 hasFocus.eq( 0 ).focus(); |
|
254 }, |
|
255 |
|
256 _keepFocus: function( event ) { |
|
257 function checkFocus() { |
|
258 var activeElement = this.document[0].activeElement, |
|
259 isActive = this.uiDialog[0] === activeElement || |
|
260 $.contains( this.uiDialog[0], activeElement ); |
|
261 if ( !isActive ) { |
|
262 this._focusTabbable(); |
|
263 } |
|
264 } |
|
265 event.preventDefault(); |
|
266 checkFocus.call( this ); |
|
267 // support: IE |
|
268 // IE <= 8 doesn't prevent moving focus even with event.preventDefault() |
|
269 // so we check again later |
|
270 this._delay( checkFocus ); |
|
271 }, |
|
272 |
|
273 _createWrapper: function() { |
|
274 this.uiDialog = $("<div>") |
|
275 .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + |
|
276 this.options.dialogClass ) |
|
277 .hide() |
|
278 .attr({ |
|
279 // Setting tabIndex makes the div focusable |
|
280 tabIndex: -1, |
|
281 role: "dialog" |
|
282 }) |
|
283 .appendTo( this._appendTo() ); |
|
284 |
|
285 this._on( this.uiDialog, { |
|
286 keydown: function( event ) { |
|
287 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && |
|
288 event.keyCode === $.ui.keyCode.ESCAPE ) { |
|
289 event.preventDefault(); |
|
290 this.close( event ); |
|
291 return; |
|
292 } |
|
293 |
|
294 // prevent tabbing out of dialogs |
|
295 if ( event.keyCode !== $.ui.keyCode.TAB ) { |
|
296 return; |
|
297 } |
|
298 var tabbables = this.uiDialog.find(":tabbable"), |
|
299 first = tabbables.filter(":first"), |
|
300 last = tabbables.filter(":last"); |
|
301 |
|
302 if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) { |
|
303 first.focus( 1 ); |
|
304 event.preventDefault(); |
|
305 } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) { |
|
306 last.focus( 1 ); |
|
307 event.preventDefault(); |
|
308 } |
|
309 }, |
|
310 mousedown: function( event ) { |
|
311 if ( this._moveToTop( event ) ) { |
|
312 this._focusTabbable(); |
|
313 } |
|
314 } |
|
315 }); |
|
316 |
|
317 // We assume that any existing aria-describedby attribute means |
|
318 // that the dialog content is marked up properly |
|
319 // otherwise we brute force the content as the description |
|
320 if ( !this.element.find("[aria-describedby]").length ) { |
|
321 this.uiDialog.attr({ |
|
322 "aria-describedby": this.element.uniqueId().attr("id") |
|
323 }); |
|
324 } |
|
325 }, |
|
326 |
|
327 _createTitlebar: function() { |
|
328 var uiDialogTitle; |
|
329 |
|
330 this.uiDialogTitlebar = $("<div>") |
|
331 .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix") |
|
332 .prependTo( this.uiDialog ); |
|
333 this._on( this.uiDialogTitlebar, { |
|
334 mousedown: function( event ) { |
|
335 // Don't prevent click on close button (#8838) |
|
336 // Focusing a dialog that is partially scrolled out of view |
|
337 // causes the browser to scroll it into view, preventing the click event |
|
338 if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) { |
|
339 // Dialog isn't getting focus when dragging (#8063) |
|
340 this.uiDialog.focus(); |
|
341 } |
|
342 } |
|
343 }); |
|
344 |
|
345 this.uiDialogTitlebarClose = $("<button></button>") |
|
346 .button({ |
|
347 label: this.options.closeText, |
|
348 icons: { |
|
349 primary: "ui-icon-closethick" |
|
350 }, |
|
351 text: false |
|
352 }) |
|
353 .addClass("ui-dialog-titlebar-close") |
|
354 .appendTo( this.uiDialogTitlebar ); |
|
355 this._on( this.uiDialogTitlebarClose, { |
|
356 click: function( event ) { |
|
357 event.preventDefault(); |
|
358 this.close( event ); |
|
359 } |
|
360 }); |
|
361 |
|
362 uiDialogTitle = $("<span>") |
|
363 .uniqueId() |
|
364 .addClass("ui-dialog-title") |
|
365 .prependTo( this.uiDialogTitlebar ); |
|
366 this._title( uiDialogTitle ); |
|
367 |
|
368 this.uiDialog.attr({ |
|
369 "aria-labelledby": uiDialogTitle.attr("id") |
|
370 }); |
|
371 }, |
|
372 |
|
373 _title: function( title ) { |
|
374 if ( !this.options.title ) { |
|
375 title.html(" "); |
|
376 } |
|
377 title.text( this.options.title ); |
|
378 }, |
|
379 |
|
380 _createButtonPane: function() { |
|
381 this.uiDialogButtonPane = $("<div>") |
|
382 .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"); |
|
383 |
|
384 this.uiButtonSet = $("<div>") |
|
385 .addClass("ui-dialog-buttonset") |
|
386 .appendTo( this.uiDialogButtonPane ); |
|
387 |
|
388 this._createButtons(); |
|
389 }, |
|
390 |
|
391 _createButtons: function() { |
|
392 var that = this, |
|
393 buttons = this.options.buttons; |
|
394 |
|
395 // if we already have a button pane, remove it |
|
396 this.uiDialogButtonPane.remove(); |
|
397 this.uiButtonSet.empty(); |
|
398 |
|
399 if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) { |
|
400 this.uiDialog.removeClass("ui-dialog-buttons"); |
|
401 return; |
|
402 } |
|
403 |
|
404 $.each( buttons, function( name, props ) { |
|
405 var click, buttonOptions; |
|
406 props = $.isFunction( props ) ? |
|
407 { click: props, text: name } : |
|
408 props; |
|
409 // Default to a non-submitting button |
|
410 props = $.extend( { type: "button" }, props ); |
|
411 // Change the context for the click callback to be the main element |
|
412 click = props.click; |
|
413 props.click = function() { |
|
414 click.apply( that.element[0], arguments ); |
|
415 }; |
|
416 buttonOptions = { |
|
417 icons: props.icons, |
|
418 text: props.showText |
|
419 }; |
|
420 delete props.icons; |
|
421 delete props.showText; |
|
422 $( "<button></button>", props ) |
|
423 .button( buttonOptions ) |
|
424 .appendTo( that.uiButtonSet ); |
|
425 }); |
|
426 this.uiDialog.addClass("ui-dialog-buttons"); |
|
427 this.uiDialogButtonPane.appendTo( this.uiDialog ); |
|
428 }, |
|
429 |
|
430 _makeDraggable: function() { |
|
431 var that = this, |
|
432 options = this.options; |
|
433 |
|
434 function filteredUi( ui ) { |
|
435 return { |
|
436 position: ui.position, |
|
437 offset: ui.offset |
|
438 }; |
|
439 } |
|
440 |
|
441 this.uiDialog.draggable({ |
|
442 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", |
|
443 handle: ".ui-dialog-titlebar", |
|
444 containment: "document", |
|
445 start: function( event, ui ) { |
|
446 $( this ).addClass("ui-dialog-dragging"); |
|
447 that._blockFrames(); |
|
448 that._trigger( "dragStart", event, filteredUi( ui ) ); |
|
449 }, |
|
450 drag: function( event, ui ) { |
|
451 that._trigger( "drag", event, filteredUi( ui ) ); |
|
452 }, |
|
453 stop: function( event, ui ) { |
|
454 options.position = [ |
|
455 ui.position.left - that.document.scrollLeft(), |
|
456 ui.position.top - that.document.scrollTop() |
|
457 ]; |
|
458 $( this ).removeClass("ui-dialog-dragging"); |
|
459 that._unblockFrames(); |
|
460 that._trigger( "dragStop", event, filteredUi( ui ) ); |
|
461 } |
|
462 }); |
|
463 }, |
|
464 |
|
465 _makeResizable: function() { |
|
466 var that = this, |
|
467 options = this.options, |
|
468 handles = options.resizable, |
|
469 // .ui-resizable has position: relative defined in the stylesheet |
|
470 // but dialogs have to use absolute or fixed positioning |
|
471 position = this.uiDialog.css("position"), |
|
472 resizeHandles = typeof handles === "string" ? |
|
473 handles : |
|
474 "n,e,s,w,se,sw,ne,nw"; |
|
475 |
|
476 function filteredUi( ui ) { |
|
477 return { |
|
478 originalPosition: ui.originalPosition, |
|
479 originalSize: ui.originalSize, |
|
480 position: ui.position, |
|
481 size: ui.size |
|
482 }; |
|
483 } |
|
484 |
|
485 this.uiDialog.resizable({ |
|
486 cancel: ".ui-dialog-content", |
|
487 containment: "document", |
|
488 alsoResize: this.element, |
|
489 maxWidth: options.maxWidth, |
|
490 maxHeight: options.maxHeight, |
|
491 minWidth: options.minWidth, |
|
492 minHeight: this._minHeight(), |
|
493 handles: resizeHandles, |
|
494 start: function( event, ui ) { |
|
495 $( this ).addClass("ui-dialog-resizing"); |
|
496 that._blockFrames(); |
|
497 that._trigger( "resizeStart", event, filteredUi( ui ) ); |
|
498 }, |
|
499 resize: function( event, ui ) { |
|
500 that._trigger( "resize", event, filteredUi( ui ) ); |
|
501 }, |
|
502 stop: function( event, ui ) { |
|
503 options.height = $( this ).height(); |
|
504 options.width = $( this ).width(); |
|
505 $( this ).removeClass("ui-dialog-resizing"); |
|
506 that._unblockFrames(); |
|
507 that._trigger( "resizeStop", event, filteredUi( ui ) ); |
|
508 } |
|
509 }) |
|
510 .css( "position", position ); |
|
511 }, |
|
512 |
|
513 _minHeight: function() { |
|
514 var options = this.options; |
|
515 |
|
516 return options.height === "auto" ? |
|
517 options.minHeight : |
|
518 Math.min( options.minHeight, options.height ); |
|
519 }, |
|
520 |
|
521 _position: function() { |
|
522 // Need to show the dialog to get the actual offset in the position plugin |
|
523 var isVisible = this.uiDialog.is(":visible"); |
|
524 if ( !isVisible ) { |
|
525 this.uiDialog.show(); |
|
526 } |
|
527 this.uiDialog.position( this.options.position ); |
|
528 if ( !isVisible ) { |
|
529 this.uiDialog.hide(); |
|
530 } |
|
531 }, |
|
532 |
|
533 _setOptions: function( options ) { |
|
534 var that = this, |
|
535 resize = false, |
|
536 resizableOptions = {}; |
|
537 |
|
538 $.each( options, function( key, value ) { |
|
539 that._setOption( key, value ); |
|
540 |
|
541 if ( key in sizeRelatedOptions ) { |
|
542 resize = true; |
|
543 } |
|
544 if ( key in resizableRelatedOptions ) { |
|
545 resizableOptions[ key ] = value; |
|
546 } |
|
547 }); |
|
548 |
|
549 if ( resize ) { |
|
550 this._size(); |
|
551 this._position(); |
|
552 } |
|
553 if ( this.uiDialog.is(":data(ui-resizable)") ) { |
|
554 this.uiDialog.resizable( "option", resizableOptions ); |
|
555 } |
|
556 }, |
|
557 |
|
558 _setOption: function( key, value ) { |
|
559 /*jshint maxcomplexity:15*/ |
|
560 var isDraggable, isResizable, |
|
561 uiDialog = this.uiDialog; |
|
562 |
|
563 if ( key === "dialogClass" ) { |
|
564 uiDialog |
|
565 .removeClass( this.options.dialogClass ) |
|
566 .addClass( value ); |
|
567 } |
|
568 |
|
569 if ( key === "disabled" ) { |
|
570 return; |
|
571 } |
|
572 |
|
573 this._super( key, value ); |
|
574 |
|
575 if ( key === "appendTo" ) { |
|
576 this.uiDialog.appendTo( this._appendTo() ); |
|
577 } |
|
578 |
|
579 if ( key === "buttons" ) { |
|
580 this._createButtons(); |
|
581 } |
|
582 |
|
583 if ( key === "closeText" ) { |
|
584 this.uiDialogTitlebarClose.button({ |
|
585 // Ensure that we always pass a string |
|
586 label: "" + value |
|
587 }); |
|
588 } |
|
589 |
|
590 if ( key === "draggable" ) { |
|
591 isDraggable = uiDialog.is(":data(ui-draggable)"); |
|
592 if ( isDraggable && !value ) { |
|
593 uiDialog.draggable("destroy"); |
|
594 } |
|
595 |
|
596 if ( !isDraggable && value ) { |
|
597 this._makeDraggable(); |
|
598 } |
|
599 } |
|
600 |
|
601 if ( key === "position" ) { |
|
602 this._position(); |
|
603 } |
|
604 |
|
605 if ( key === "resizable" ) { |
|
606 // currently resizable, becoming non-resizable |
|
607 isResizable = uiDialog.is(":data(ui-resizable)"); |
|
608 if ( isResizable && !value ) { |
|
609 uiDialog.resizable("destroy"); |
|
610 } |
|
611 |
|
612 // currently resizable, changing handles |
|
613 if ( isResizable && typeof value === "string" ) { |
|
614 uiDialog.resizable( "option", "handles", value ); |
|
615 } |
|
616 |
|
617 // currently non-resizable, becoming resizable |
|
618 if ( !isResizable && value !== false ) { |
|
619 this._makeResizable(); |
|
620 } |
|
621 } |
|
622 |
|
623 if ( key === "title" ) { |
|
624 this._title( this.uiDialogTitlebar.find(".ui-dialog-title") ); |
|
625 } |
|
626 }, |
|
627 |
|
628 _size: function() { |
|
629 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content |
|
630 // divs will both have width and height set, so we need to reset them |
|
631 var nonContentHeight, minContentHeight, maxContentHeight, |
|
632 options = this.options; |
|
633 |
|
634 // Reset content sizing |
|
635 this.element.show().css({ |
|
636 width: "auto", |
|
637 minHeight: 0, |
|
638 maxHeight: "none", |
|
639 height: 0 |
|
640 }); |
|
641 |
|
642 if ( options.minWidth > options.width ) { |
|
643 options.width = options.minWidth; |
|
644 } |
|
645 |
|
646 // reset wrapper sizing |
|
647 // determine the height of all the non-content elements |
|
648 nonContentHeight = this.uiDialog.css({ |
|
649 height: "auto", |
|
650 width: options.width |
|
651 }) |
|
652 .outerHeight(); |
|
653 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); |
|
654 maxContentHeight = typeof options.maxHeight === "number" ? |
|
655 Math.max( 0, options.maxHeight - nonContentHeight ) : |
|
656 "none"; |
|
657 |
|
658 if ( options.height === "auto" ) { |
|
659 this.element.css({ |
|
660 minHeight: minContentHeight, |
|
661 maxHeight: maxContentHeight, |
|
662 height: "auto" |
|
663 }); |
|
664 } else { |
|
665 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); |
|
666 } |
|
667 |
|
668 if (this.uiDialog.is(":data(ui-resizable)") ) { |
|
669 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); |
|
670 } |
|
671 }, |
|
672 |
|
673 _blockFrames: function() { |
|
674 this.iframeBlocks = this.document.find( "iframe" ).map(function() { |
|
675 var iframe = $( this ); |
|
676 |
|
677 return $( "<div>" ) |
|
678 .css({ |
|
679 position: "absolute", |
|
680 width: iframe.outerWidth(), |
|
681 height: iframe.outerHeight() |
|
682 }) |
|
683 .appendTo( iframe.parent() ) |
|
684 .offset( iframe.offset() )[0]; |
|
685 }); |
|
686 }, |
|
687 |
|
688 _unblockFrames: function() { |
|
689 if ( this.iframeBlocks ) { |
|
690 this.iframeBlocks.remove(); |
|
691 delete this.iframeBlocks; |
|
692 } |
|
693 }, |
|
694 |
|
695 _allowInteraction: function( event ) { |
|
696 if ( $( event.target ).closest(".ui-dialog").length ) { |
|
697 return true; |
|
698 } |
|
699 |
|
700 // TODO: Remove hack when datepicker implements |
|
701 // the .ui-front logic (#8989) |
|
702 return !!$( event.target ).closest(".ui-datepicker").length; |
|
703 }, |
|
704 |
|
705 _createOverlay: function() { |
|
706 if ( !this.options.modal ) { |
|
707 return; |
|
708 } |
|
709 |
|
710 var that = this, |
|
711 widgetFullName = this.widgetFullName; |
|
712 if ( !$.ui.dialog.overlayInstances ) { |
|
713 // Prevent use of anchors and inputs. |
|
714 // We use a delay in case the overlay is created from an |
|
715 // event that we're going to be cancelling. (#2804) |
|
716 this._delay(function() { |
|
717 // Handle .dialog().dialog("close") (#4065) |
|
718 if ( $.ui.dialog.overlayInstances ) { |
|
719 this.document.bind( "focusin.dialog", function( event ) { |
|
720 if ( !that._allowInteraction( event ) ) { |
|
721 event.preventDefault(); |
|
722 $(".ui-dialog:visible:last .ui-dialog-content") |
|
723 .data( widgetFullName )._focusTabbable(); |
|
724 } |
|
725 }); |
|
726 } |
|
727 }); |
|
728 } |
|
729 |
|
730 this.overlay = $("<div>") |
|
731 .addClass("ui-widget-overlay ui-front") |
|
732 .appendTo( this._appendTo() ); |
|
733 this._on( this.overlay, { |
|
734 mousedown: "_keepFocus" |
|
735 }); |
|
736 $.ui.dialog.overlayInstances++; |
|
737 }, |
|
738 |
|
739 _destroyOverlay: function() { |
|
740 if ( !this.options.modal ) { |
|
741 return; |
|
742 } |
|
743 |
|
744 if ( this.overlay ) { |
|
745 $.ui.dialog.overlayInstances--; |
|
746 |
|
747 if ( !$.ui.dialog.overlayInstances ) { |
|
748 this.document.unbind( "focusin.dialog" ); |
|
749 } |
|
750 this.overlay.remove(); |
|
751 this.overlay = null; |
|
752 } |
|
753 } |
|
754 }); |
|
755 |
|
756 $.ui.dialog.overlayInstances = 0; |
|
757 |
|
758 // DEPRECATED |
|
759 if ( $.uiBackCompat !== false ) { |
|
760 // position option with array notation |
|
761 // just override with old implementation |
|
762 $.widget( "ui.dialog", $.ui.dialog, { |
|
763 _position: function() { |
|
764 var position = this.options.position, |
|
765 myAt = [], |
|
766 offset = [ 0, 0 ], |
|
767 isVisible; |
|
768 |
|
769 if ( position ) { |
|
770 if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { |
|
771 myAt = position.split ? position.split(" ") : [ position[0], position[1] ]; |
|
772 if ( myAt.length === 1 ) { |
|
773 myAt[1] = myAt[0]; |
|
774 } |
|
775 |
|
776 $.each( [ "left", "top" ], function( i, offsetPosition ) { |
|
777 if ( +myAt[ i ] === myAt[ i ] ) { |
|
778 offset[ i ] = myAt[ i ]; |
|
779 myAt[ i ] = offsetPosition; |
|
780 } |
|
781 }); |
|
782 |
|
783 position = { |
|
784 my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " + |
|
785 myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]), |
|
786 at: myAt.join(" ") |
|
787 }; |
|
788 } |
|
789 |
|
790 position = $.extend( {}, $.ui.dialog.prototype.options.position, position ); |
|
791 } else { |
|
792 position = $.ui.dialog.prototype.options.position; |
|
793 } |
|
794 |
|
795 // need to show the dialog to get the actual offset in the position plugin |
|
796 isVisible = this.uiDialog.is(":visible"); |
|
797 if ( !isVisible ) { |
|
798 this.uiDialog.show(); |
|
799 } |
|
800 this.uiDialog.position( position ); |
|
801 if ( !isVisible ) { |
|
802 this.uiDialog.hide(); |
|
803 } |
|
804 } |
|
805 }); |
|
806 } |
|
807 |
|
808 }( jQuery ) ); |