Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

Commit bbb9ec5

Browse files
devversionjelbourn
authored andcommitted
fix(util): disableScrollAround should not remove disabled scroll mask (#9547)
* When the scroll mask is disabled per the new options which were recently added, the specified element will be used as scroll mask (under the hood) If restoring scroll, the scroll mask will be removed from the DOM (even the disabled one) - This is invalid. This causes an issue when restoring the scroll, while the element is still showing up (e.g dialog with z-index)
1 parent dfe1a00 commit bbb9ec5

File tree

2 files changed

+52
-19
lines changed

2 files changed

+52
-19
lines changed

src/core/util/util.js

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -198,44 +198,56 @@ function UtilFactory($document, $timeout, $compile, $rootScope, $$mdAnimate, $in
198198
* use the passed parent element.
199199
*/
200200
disableScrollAround: function(element, parent, options) {
201-
$mdUtil.disableScrollAround._count = $mdUtil.disableScrollAround._count || 0;
202-
++$mdUtil.disableScrollAround._count;
203-
if ($mdUtil.disableScrollAround._enableScrolling) return $mdUtil.disableScrollAround._enableScrolling;
204-
var body = $document[0].body,
205-
restoreBody = disableBodyScroll(),
206-
restoreElement = disableElementScroll(parent);
207-
208-
return $mdUtil.disableScrollAround._enableScrolling = function() {
209-
if (!--$mdUtil.disableScrollAround._count) {
201+
options = options || {};
202+
203+
$mdUtil.disableScrollAround._count = Math.max(0, $mdUtil.disableScrollAround._count || 0);
204+
$mdUtil.disableScrollAround._count++;
205+
206+
if ($mdUtil.disableScrollAround._restoreScroll) {
207+
return $mdUtil.disableScrollAround._restoreScroll;
208+
}
209+
210+
var body = $document[0].body;
211+
var restoreBody = disableBodyScroll();
212+
var restoreElement = disableElementScroll(parent);
213+
214+
return $mdUtil.disableScrollAround._restoreScroll = function() {
215+
if (--$mdUtil.disableScrollAround._count <= 0) {
210216
restoreBody();
211217
restoreElement();
212-
delete $mdUtil.disableScrollAround._enableScrolling;
218+
delete $mdUtil.disableScrollAround._restoreScroll;
213219
}
214220
};
215221

216-
// Creates a virtual scrolling mask to absorb touchmove, keyboard, scrollbar clicking, and wheel events
222+
/**
223+
* Creates a virtual scrolling mask to prevent touchmove, keyboard, scrollbar clicking,
224+
* and wheel events
225+
*/
217226
function disableElementScroll(element) {
218227
element = angular.element(element || body);
228+
219229
var scrollMask;
220-
if (options && options.disableScrollMask) {
230+
231+
if (options.disableScrollMask) {
221232
scrollMask = element;
222233
} else {
223-
element = element[0];
224234
scrollMask = angular.element(
225235
'<div class="md-scroll-mask">' +
226236
' <div class="md-scroll-mask-bar"></div>' +
227237
'</div>');
228-
element.appendChild(scrollMask[0]);
238+
element.append(scrollMask);
229239
}
230240

231241
scrollMask.on('wheel', preventDefault);
232242
scrollMask.on('touchmove', preventDefault);
233243

234-
return function restoreScroll() {
244+
return function restoreElementScroll() {
235245
scrollMask.off('wheel');
236246
scrollMask.off('touchmove');
237-
scrollMask[0].parentNode.removeChild(scrollMask[0]);
238-
delete $mdUtil.disableScrollAround._enableScrolling;
247+
248+
if (!options.disableScrollMask) {
249+
scrollMask[0].parentNode.removeChild(scrollMask[0]);
250+
}
239251
};
240252

241253
function preventDefault(e) {
@@ -279,10 +291,12 @@ function UtilFactory($document, $timeout, $compile, $rootScope, $$mdAnimate, $in
279291
}
280292

281293
},
294+
282295
enableScrolling: function() {
283-
var method = this.disableScrollAround._enableScrolling;
284-
method && method();
296+
var restoreFn = this.disableScrollAround._restoreScroll;
297+
restoreFn && restoreFn();
285298
},
299+
286300
floatingScrollbars: function() {
287301
if (this.floatingScrollbars.cached === undefined) {
288302
var tempNode = angular.element('<div><div></div></div>').css({

src/core/util/util.spec.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ describe('util', function() {
210210
});
211211

212212
describe('disableScrollAround', function() {
213+
213214
it('should prevent scrolling of the passed element', inject(function($mdUtil) {
214215
var element = angular.element('<div style="height: 2000px">');
215216
document.body.appendChild(element[0]);
@@ -226,6 +227,24 @@ describe('util', function() {
226227

227228
element.remove();
228229
}));
230+
231+
it('should not remove the element when being use as scorll mask', inject(function($mdUtil) {
232+
var element = angular.element('<div>');
233+
234+
document.body.appendChild(element[0]);
235+
236+
var enableScrolling = $mdUtil.disableScrollAround(element, null, {
237+
disableScrollMask: true
238+
});
239+
240+
// Restore the scrolling.
241+
enableScrolling();
242+
243+
expect(element[0].parentNode).toBeTruthy();
244+
245+
element.remove();
246+
}));
247+
229248
});
230249

231250
describe('getViewportTop', function() {

0 commit comments

Comments
 (0)