Ticket #4575: ui.dialog-opera-scroll-and-overlay.patch

File ui.dialog-opera-scroll-and-overlay.patch, 4.9 KB (added by Mikko Rantanen, 10 years ago)

ui.dialog patch for ticket #4575 with overlay handling

  • ui.dialog.js

     
    3030                'ui-dialog ' +
    3131                'ui-widget ' +
    3232                'ui-widget-content ' +
    33                 'ui-corner-all ';
     33                'ui-corner-all ',
     34       
     35    uiDialogPool = {};
    3436
    3537$.widget("ui.dialog", {
    3638
     
    6365                                        'aria-labelledby': titleId
    6466                                })
    6567                                .mousedown(function(event) {
    66                                         self.moveToTop(false, event);
     68                                        self.moveToTop(false, event, true);
     69                                })
     70                                .mouseup(function(event) {
     71                                        self._fixZIndex(event);
    6772                                }),
    6873
    6974                        uiDialogContent = self.element
     
    126131                                .html(title)
    127132                                .prependTo(uiDialogTitlebar);
    128133
     134                // Title ID is unique to a dialog so we'll use that one to identify the dialogs.
     135                uiDialogPool[titleId] = self;
     136
    129137                uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection();
    130138
    131139                (options.draggable && $.fn.draggable && self._makeDraggable());
     
    150158                        .hide().appendTo('body');
    151159                self.uiDialog.remove();
    152160
     161                uiDialogPool[self] = null;
     162
    153163                (self.originalTitle && self.element.attr('title', self.originalTitle));
    154164
    155165                return self;
     
    195205
    196206        // the force parameter allows us to move modal dialogs to their correct
    197207        // position on open
    198         moveToTop: function(force, event) {
     208        moveToTop: function(force, event, isMouseEvent) {
    199209                var self = this,
    200210                        options = self.options;
    201211               
     
    207217                if (options.zIndex > $.ui.dialog.maxZ) {
    208218                        $.ui.dialog.maxZ = options.zIndex;
    209219                }
    210                 (self.overlay && self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = ++$.ui.dialog.maxZ));
    211220
    212                 //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed.
    213                 //  http://ui.jquery.com/bugs/ticket/3193
    214                 var saveScroll = { scrollTop: self.element.attr('scrollTop'), scrollLeft: self.element.attr('scrollLeft') };
    215                 self.uiDialog.css('z-index', ++$.ui.dialog.maxZ);
    216                 self.element.attr(saveScroll);
    217                 self._trigger('focus', event);
     221                // If this is a result of a mouse event drop other dialogs below the current one since Opera 9.5+ resets scroll positions when parent z-Index is changed.
     222                // and the mouse event could be interaction with a scroll bar.
     223                //  http://dev.jqueryui.com/ticket/3193
     224                //  http://dev.jqueryui.com/ticket/4575
     225                if (isMouseEvent) {
    218226
     227                        var orderedLayers = []
     228                        var layerCount = 0;
     229                        for (var dialogID in uiDialogPool)
     230                                if (uiDialogPool[dialogID] != self) {
     231                                        orderedLayers.push(uiDialogPool[dialogID]);
     232                                        layerCount++;
     233                                        if (uiDialogPool[dialogID].overlay)
     234                                                layerCount++;
     235                                }
     236                        orderedLayers.sort(function(d1, d2) { return d2.uiDialog.css('z-index') -
     237                                                                      d1.uiDialog.css('z-index'); });
     238
     239                        // Leave room for the possible overlay
     240                        if (self.overlay) layerCount++;
     241                       
     242                        var topZ = self.uiDialog.css('z-index');
     243                       
     244                        // Move the dialogs back starting from the backmost dialog to prevent flickering.
     245                        for (var i = orderedLayers.length; i > 0; i--) {
     246                                var currentDialog = orderedLayers[i-1];
     247                                (currentDialog.overlay && currentDialog.overlay.$el.css('z-index', topZ - (layerCount--)));
     248                                currentDialog._setZIndex(topZ - (layerCount--));
     249                        }
     250                       
     251                } else {
     252                        (self.overlay && self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = ++$.ui.dialog.maxZ));
     253                        self._setZIndex(++$.ui.dialog.maxZ);
     254                }
     255               
     256                self._trigger('focus', event); 
     257
    219258                return self;
    220259        },
    221260
     
    519558
    520559                (this.uiDialog.is(':ui-resizable') &&
    521560                        this.uiDialog.resizable('option', 'minHeight', this._minHeight()));
     561        },
     562
     563        _fixZIndex: function() {
     564                var orderedArray = [];
     565                for (var dialogID in uiDialogPool)
     566                        orderedArray.push(uiDialogPool[dialogID]);
     567
     568                orderedArray.sort(function(d1, d2) { return d2.uiDialog.css('z-index') - d1.uiDialog.css('z-index') });
     569
     570                var zIndex = $.ui.dialog.maxZ;
     571               
     572                for (var i = 0; i < orderedArray.length; i++) {
     573                        var currentDialog = orderedArray[i];
     574                        currentDialog._setZIndex(zIndex--);
     575                        (currentDialog.overlay && currentDialog.overlay.$el.css('z-index', zIndex--));
     576                }
     577        },
     578
     579        _setZIndex: function(index) {
     580                var self = this;
     581               
     582                // Store the scroll positions before modifying the z-index.
     583                //  http://dev.jqueryui.com/ticket/3193
     584                //  http://dev.jqueryui.com/ticket/4575
     585                var saveScroll = []
     586                self.uiDialog.find("*").each(function() {
     587                        var currentElement = $(this)
     588                        var scrollTop = currentElement.attr('scrollTop');
     589                        var scrollLeft = currentElement.attr('scrollLeft');
     590                        if (scrollTop || scrollLeft) {
     591                                saveScroll.push({
     592                                        element: currentElement,
     593                                        attr: { scrollTop: currentElement.attr('scrollTop'),
     594                                                scrollLeft: currentElement.attr('scrollLeft') }
     595                                });
     596                        }
     597                });
     598
     599                self.uiDialog.css('z-index', index);
     600
     601                for (var i = 0; i < saveScroll.length; i++) {
     602                        var savedScroll = saveScroll[i];
     603                        savedScroll.element.attr(savedScroll.attr);
     604                }
    522605        }
    523606});
    524607