Skip to content

Commit ac16a50

Browse files
authored
fix(modal): support context properly
A possible use of modal inside a different context container than body was not properly implemented. Fetch/Hide/Restore of scrollbar did not work Positioning of the modal inside a scrolling container also broke Accidently usage of window or document as context setting broke the code What i also fixed many preset/cached variables were not reused, which slightly costs performance used the slightly quicker array Access instead of jquerys .get() method Removed unnecessary !important settings (those were infact needed in case the context container has scrolled when the modal is opened (when testing this, you should have to change .ui.dimmer {top:0!important} to .ui.dimmer {top:0} in the jsfiddle via console)
1 parent 6dec24a commit ac16a50

File tree

3 files changed

+54
-30
lines changed

3 files changed

+54
-30
lines changed

src/definitions/modules/dimmer.less

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828
.ui.dimmer {
2929
display: none;
3030
position: @dimmerPosition;
31-
top: 0 !important;
32-
left: 0 !important;
31+
top: 0;
32+
left: 0;
3333

3434
width: 100%;
3535
height: 100%;
@@ -303,11 +303,11 @@ body.dimmable > .dimmer {
303303
height: auto;
304304
}
305305
.ui[class*="bottom dimmer"] {
306-
top: auto !important;
306+
top: auto;
307307
bottom: 0;
308308
}
309309
.ui[class*="center dimmer"] {
310-
top:50% !important;
310+
top:50%;
311311
transform: translateY(-50%);
312312
-webkit-transform: translateY(calc(-50% - .5px));
313313
}

src/definitions/modules/modal.js

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ $.modal = $.fn.modal = function(parameters) {
6565
moduleNamespace = 'module-' + namespace,
6666

6767
$module = $(this),
68-
$context = [window,document].indexOf(settings.context) < 0 ? $(document).find(settings.context) : $(settings.context),
68+
$context = [window,document].indexOf(settings.context) < 0 ? $document.find(settings.context) : $body,
69+
isBody = $context[0] === $body[0],
6970
$closeIcon = $module.find(selector.closeIcon),
7071
$inputs,
7172

@@ -86,6 +87,8 @@ $.modal = $.fn.modal = function(parameters) {
8687
initialMouseDownInScrollbar,
8788
initialBodyMargin = '',
8889
tempBodyMargin = '',
90+
keepScrollingClass = false,
91+
hadScrollbar = false,
8992

9093
elementEventNamespace,
9194
id,
@@ -203,6 +206,7 @@ $.modal = $.fn.modal = function(parameters) {
203206
}
204207
module.debug('Creating dimmer');
205208
$dimmable = $context.dimmer(dimmerSettings);
209+
keepScrollingClass = module.is.scrolling();
206210
if(settings.detachable) {
207211
module.verbose('Modal is detachable, moving content into dimmer');
208212
$dimmable.dimmer('add content', $module);
@@ -328,13 +332,13 @@ $.modal = $.fn.modal = function(parameters) {
328332
},
329333
scrollLock: function() {
330334
// touch events default to passive, due to changes in chrome to optimize mobile perf
331-
$dimmable.get(0).addEventListener('touchmove', module.event.preventScroll, { passive: false });
335+
$dimmable[0].addEventListener('touchmove', module.event.preventScroll, { passive: false });
332336
}
333337
},
334338

335339
unbind: {
336340
scrollLock: function() {
337-
$dimmable.get(0).removeEventListener('touchmove', module.event.preventScroll, { passive: false });
341+
$dimmable[0].removeEventListener('touchmove', module.event.preventScroll, { passive: false });
338342
}
339343
},
340344

@@ -416,7 +420,7 @@ $.modal = $.fn.modal = function(parameters) {
416420
if(initialMouseDownInModal) {
417421
module.verbose('Mouse down event registered inside the modal');
418422
}
419-
initialMouseDownInScrollbar = module.is.scrolling() && ((!isRtl && $(window).outerWidth() - settings.scrollbarWidth <= event.clientX) || (isRtl && settings.scrollbarWidth >= event.clientX));
423+
initialMouseDownInScrollbar = module.is.scrolling() && ((!isRtl && $window.outerWidth() - settings.scrollbarWidth <= event.clientX) || (isRtl && settings.scrollbarWidth >= event.clientX));
420424
if(initialMouseDownInScrollbar) {
421425
module.verbose('Mouse down event registered inside the scrollbar');
422426
}
@@ -520,9 +524,12 @@ $.modal = $.fn.modal = function(parameters) {
520524
module.verbose('Show callback returned false cancelling show');
521525
return;
522526
}
527+
hadScrollbar = module.has.scrollbar();
523528
module.showDimmer();
524529
module.cacheSizes();
525-
module.set.bodyMargin();
530+
if(hadScrollbar) {
531+
module.set.bodyMargin();
532+
}
526533
if(module.can.useFlex()) {
527534
module.remove.legacy();
528535
}
@@ -651,7 +658,12 @@ $.modal = $.fn.modal = function(parameters) {
651658

652659
showDimmer: function() {
653660
if($dimmable.dimmer('is animating') || !$dimmable.dimmer('is active') ) {
654-
module.save.bodyMargin();
661+
if(hadScrollbar) {
662+
if(!isBody) {
663+
$dimmer.css('top', $dimmable.scrollTop());
664+
}
665+
module.save.bodyMargin();
666+
}
655667
module.debug('Showing dimmer');
656668
$dimmable.dimmer('show');
657669
}
@@ -664,7 +676,9 @@ $.modal = $.fn.modal = function(parameters) {
664676
if( $dimmable.dimmer('is animating') || ($dimmable.dimmer('is active')) ) {
665677
module.unbind.scrollLock();
666678
$dimmable.dimmer('hide', function() {
667-
module.restore.bodyMargin();
679+
if(hadScrollbar) {
680+
module.restore.bodyMargin();
681+
}
668682
module.remove.clickaway();
669683
module.remove.screenHeight();
670684
});
@@ -744,9 +758,9 @@ $.modal = $.fn.modal = function(parameters) {
744758
}
745759
},
746760
bodyMargin: function() {
747-
initialBodyMargin = $body.css('margin-'+(module.can.leftBodyScrollbar() ? 'left':'right'));
761+
initialBodyMargin = $context.css((isBody ? 'margin-':'padding-')+(module.can.leftBodyScrollbar() ? 'left':'right'));
748762
var bodyMarginRightPixel = parseInt(initialBodyMargin.replace(/[^\d.]/g, '')),
749-
bodyScrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
763+
bodyScrollbarWidth = isBody ? window.innerWidth - document.documentElement.clientWidth : $context[0].offsetWidth - $context[0].clientWidth;
750764
tempBodyMargin = bodyMarginRightPixel + bodyScrollbarWidth;
751765
}
752766
},
@@ -759,8 +773,8 @@ $.modal = $.fn.modal = function(parameters) {
759773
},
760774
bodyMargin: function() {
761775
var position = module.can.leftBodyScrollbar() ? 'left':'right';
762-
$body.css('margin-'+position, initialBodyMargin);
763-
$body.find(selector.bodyFixed.replace('right',position)).each(function(){
776+
$context.css((isBody ? 'margin-':'padding-')+position, initialBodyMargin);
777+
$context.find(selector.bodyFixed.replace('right',position)).each(function(){
764778
var el = $(this),
765779
attribute = el.css('position') === 'fixed' ? 'padding-'+position : position
766780
;
@@ -794,16 +808,17 @@ $.modal = $.fn.modal = function(parameters) {
794808
$dimmable.removeClass(className.blurring);
795809
},
796810
bodyStyle: function() {
797-
if($body.attr('style') === '') {
811+
if($context.attr('style') === '') {
798812
module.verbose('Removing style attribute');
799-
$body.removeAttr('style');
813+
$context.removeAttr('style');
800814
}
801815
},
802816
screenHeight: function() {
803817
module.debug('Removing page height');
804-
$body
818+
$context
805819
.css('height', '')
806820
;
821+
module.remove.bodyStyle()
807822
},
808823
keyboardShortcuts: function() {
809824
module.verbose('Removing keyboard shortcuts');
@@ -812,7 +827,9 @@ $.modal = $.fn.modal = function(parameters) {
812827
;
813828
},
814829
scrolling: function() {
815-
$dimmable.removeClass(className.scrolling);
830+
if(!keepScrollingClass) {
831+
$dimmable.removeClass(className.scrolling);
832+
}
816833
$module.removeClass(className.scrolling);
817834
}
818835
},
@@ -826,12 +843,12 @@ $.modal = $.fn.modal = function(parameters) {
826843
;
827844
if(module.cache.pageHeight === undefined || modalHeight !== 0) {
828845
$.extend(module.cache, {
829-
pageHeight : $(document).outerHeight(),
846+
pageHeight : $document.outerHeight(),
830847
width : modalWidth,
831848
height : modalHeight + settings.offset,
832849
scrollHeight : scrollHeight + settings.offset,
833-
contextHeight : (settings.context == 'body')
834-
? $(window).height()
850+
contextHeight : isBody
851+
? $window.height()
835852
: $dimmable.height(),
836853
});
837854
module.cache.topOffset = -(module.cache.height / 2);
@@ -905,6 +922,9 @@ $.modal = $.fn.modal = function(parameters) {
905922
has: {
906923
configActions: function () {
907924
return Array.isArray(settings.actions) && settings.actions.length > 0;
925+
},
926+
scrollbar: function() {
927+
return isBody || $context.css('overflow-y') !== 'hidden';
908928
}
909929
},
910930
is: {
@@ -936,7 +956,7 @@ $.modal = $.fn.modal = function(parameters) {
936956
},
937957
rtl: function() {
938958
if(module.cache.isRTL === undefined) {
939-
module.cache.isRTL = $body.attr('dir') === 'rtl' || $body.css('direction') === 'rtl';
959+
module.cache.isRTL = $module.attr('dir') === 'rtl' || $module.css('direction') === 'rtl' || $body.attr('dir') === 'rtl' || $body.css('direction') === 'rtl' || $context.attr('dir') === 'rtl' || $context.css('direction') === 'rtl';
940960
}
941961
return module.cache.isRTL;
942962
},
@@ -978,9 +998,9 @@ $.modal = $.fn.modal = function(parameters) {
978998
bodyMargin: function() {
979999
var position = module.can.leftBodyScrollbar() ? 'left':'right';
9801000
if(settings.detachable || module.can.fit()) {
981-
$body.css('margin-'+position, tempBodyMargin + 'px');
1001+
$context.css((isBody ? 'margin-':'padding-')+position, tempBodyMargin + 'px');
9821002
}
983-
$body.find(selector.bodyFixed.replace('right',position)).each(function(){
1003+
$context.find(selector.bodyFixed.replace('right',position)).each(function(){
9841004
var el = $(this),
9851005
attribute = el.css('position') === 'fixed' ? 'padding-'+position : position
9861006
;
@@ -1046,10 +1066,10 @@ $.modal = $.fn.modal = function(parameters) {
10461066
$module
10471067
.css({
10481068
top: (!$module.hasClass('aligned') && canFit)
1049-
? $(document).scrollTop() + (module.cache.contextHeight - module.cache.height) / 2
1069+
? $document.scrollTop() + (module.cache.contextHeight - module.cache.height) / 2
10501070
: !canFit || $module.hasClass('top')
1051-
? $(document).scrollTop() + settings.padding
1052-
: $(document).scrollTop() + (module.cache.contextHeight - module.cache.height - settings.padding),
1071+
? $document.scrollTop() + settings.padding
1072+
: $document.scrollTop() + (module.cache.contextHeight - module.cache.height - settings.padding),
10531073
marginLeft: -(module.cache.width / 2)
10541074
})
10551075
;
@@ -1067,11 +1087,11 @@ $.modal = $.fn.modal = function(parameters) {
10671087
},
10681088
screenHeight: function() {
10691089
if( module.can.fit() ) {
1070-
$body.css('height', '');
1090+
$context.css('height', '');
10711091
}
10721092
else if(!$module.hasClass('bottom')) {
10731093
module.debug('Modal is taller than page content, resizing page height');
1074-
$body
1094+
$context
10751095
.css('height', module.cache.height + (settings.padding * 2) )
10761096
;
10771097
}

src/definitions/modules/modal.less

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,10 @@
447447
justify-content: flex-start;
448448
position: fixed;
449449
}
450+
.scrolling.dimmable:not(body) > .dimmer {
451+
justify-content: center;
452+
position: absolute;
453+
}
450454
.scrolling.dimmable.dimmed > .dimmer {
451455
overflow: auto;
452456
-webkit-overflow-scrolling: touch;

0 commit comments

Comments
 (0)