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

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

ui.dialog patch for ticket #4575

  • 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               
     
    209219                }
    210220                (self.overlay && self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = ++$.ui.dialog.maxZ));
    211221
    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);
     222                // 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.
     223                // and the mouse event could be interaction with a scroll bar.
     224                //  http://dev.jqueryui.com/ticket/3193
     225                //  http://dev.jqueryui.com/ticket/4575
     226                if (isMouseEvent) {
     227               
     228                        var orderedDialogs = []
     229                        for (var dialogID in uiDialogPool)
     230                                if (uiDialogPool[dialogID] != self)
     231                                        orderedDialogs.push(uiDialogPool[dialogID]);
     232                        orderedDialogs.sort(function(d1, d2) { return d2.uiDialog.css('z-index') -
     233                                                                      d1.uiDialog.css('z-index'); });
     234               
     235                        var topZ = self.uiDialog.css('z-index');
     236                       
     237                        // Move the dialogs back starting from the backmost dialog to prevent flickering.
     238                        for (var i = orderedDialogs.length; i > 0; i--) {
     239                                orderedDialogs[i-1]._setZIndex(topZ - i);
     240                        }
     241                } else {
     242                        self._setZIndex(++$.ui.dialog.maxZ);
     243                }
     244               
     245                self._trigger('focus', event); 
    218246
    219247                return self;
    220248        },
     
    519547
    520548                (this.uiDialog.is(':ui-resizable') &&
    521549                        this.uiDialog.resizable('option', 'minHeight', this._minHeight()));
     550        },
     551       
     552        _fixZIndex: function() {
     553                var orderedArray = [];
     554                for (var dialogID in uiDialogPool)
     555                        orderedArray.push(uiDialogPool[dialogID]);
     556
     557                orderedArray.sort(function(d1, d2) { return d2.uiDialog.css('z-index') - d1.uiDialog.css('z-index') });
     558
     559                for (var i = 0; i < orderedArray.length; i++) {
     560                        orderedArray[i]._setZIndex($.ui.dialog.maxZ - i);
     561                }
     562        },
     563       
     564        _setZIndex: function(index) {
     565                var self = this;
     566               
     567                // Store the scroll positions before modifying the z-index.
     568                //  http://dev.jqueryui.com/ticket/3193
     569                //  http://dev.jqueryui.com/ticket/4575
     570                var saveScroll = []
     571                self.uiDialog.find("*").each(function() {
     572                        var currentElement = $(this)
     573                        var scrollTop = currentElement.attr('scrollTop');
     574                        var scrollLeft = currentElement.attr('scrollLeft');
     575                        if (scrollTop || scrollLeft) {
     576                                saveScroll.push({
     577                                        element: currentElement,
     578                                        attr: { scrollTop: currentElement.attr('scrollTop'),
     579                                                scrollLeft: currentElement.attr('scrollLeft') }
     580                                });
     581                        }
     582                });
     583
     584                self.uiDialog.css('z-index', index);
     585
     586                for (var i = 0; i < saveScroll.length; i++) {
     587                        var savedScroll = saveScroll[i];
     588                        savedScroll.element.attr(savedScroll.attr);
     589                }
    522590        }
    523591});
    524592