Skip to content

Commit 5b497e3

Browse files
authored
fix(modal,flyout): avoid multiple autofocus on show animation
jquery's focus trigger does not seem to work / detect a non-input element as visible all the time. Although the autofocus is called after the animation has ended a same modal opened a second time (but without input content) does not focus the modal div again, thus focus trap did not work. This is caused by the new mutationobserver logic fetching class attributes, so the focussing takes place several times, while not necessary when the moda/flyout is animated. This PR now only observes attributes when the modal/flyout has completed showing as the showing process itself changes class attributes.
1 parent 81e635b commit 5b497e3

File tree

2 files changed

+21
-5
lines changed

2 files changed

+21
-5
lines changed

src/definitions/modules/flyout.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
elementNamespace,
8181
id,
8282
observer,
83+
observeAttributes = false,
8384
currentScroll,
8485
transitionEvent,
8586

@@ -498,7 +499,7 @@
498499
;
499500
mutations.every(function (mutation) {
500501
if (mutation.type === 'attributes') {
501-
if (mutation.attributeName === 'disabled' || $(mutation.target).find(':input').addBack(':input')) {
502+
if (observeAttributes && (mutation.attributeName === 'disabled' || $(mutation.target).find(':input').addBack(':input').length > 0)) {
502503
shouldRefreshInputs = true;
503504
}
504505
} else {
@@ -549,13 +550,14 @@
549550
if (!settings.dimPage) {
550551
return;
551552
}
552-
$inputs = $module.find('[tabindex], :input:enabled').filter(':visible').filter(function () {
553+
$inputs = $module.find('a[href], [tabindex], :input:enabled').filter(':visible').filter(function () {
553554
return $(this).closest('.disabled').length === 0;
554555
});
555-
$module.removeAttr('tabindex');
556556
if ($inputs.length === 0) {
557557
$inputs = $module;
558558
$module.attr('tabindex', -1);
559+
} else {
560+
$module.removeAttr('tabindex');
559561
}
560562
$inputs.first()
561563
.on('keydown' + elementNamespace, module.event.inputKeyDown.first)
@@ -652,6 +654,7 @@
652654
}
653655
}
654656
module.set.dimmerStyles();
657+
module.set.observeAttributes(false);
655658
module.pushPage(function () {
656659
callback.call(element);
657660
settings.onVisible.call(element);
@@ -660,6 +663,7 @@
660663
}
661664
module.save.focus();
662665
module.refreshInputs();
666+
requestAnimationFrame(module.set.observeAttributes);
663667
});
664668
settings.onChange.call(element);
665669
} else {
@@ -680,6 +684,7 @@
680684
if (module.is.visible() || module.is.animating()) {
681685
module.debug('Hiding flyout', callback);
682686
module.refreshFlyouts();
687+
module.set.observeAttributes(false);
683688
module.pullPage(function () {
684689
callback.call(element);
685690
if (isFunction(settings.onHidden)) {
@@ -831,6 +836,9 @@
831836
},
832837

833838
set: {
839+
observeAttributes: function (state) {
840+
observeAttributes = state !== false;
841+
},
834842
autofocus: function () {
835843
var
836844
$autofocus = $inputs.filter('[autofocus]'),

src/definitions/modules/modal.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
elementEventNamespace,
8383
id,
8484
observer,
85+
observeAttributes = false,
8586
module
8687
;
8788
module = {
@@ -265,7 +266,7 @@
265266
;
266267
mutations.every(function (mutation) {
267268
if (mutation.type === 'attributes') {
268-
if (mutation.attributeName === 'disabled' || $(mutation.target).find(':input').addBack(':input')) {
269+
if (observeAttributes && (mutation.attributeName === 'disabled' || $(mutation.target).find(':input').addBack(':input').length > 0)) {
269270
shouldRefreshInputs = true;
270271
}
271272
} else {
@@ -324,10 +325,11 @@
324325
$inputs = $module.find('a[href], [tabindex], :input:enabled').filter(':visible').filter(function () {
325326
return $(this).closest('.disabled').length === 0;
326327
});
327-
$module.removeAttr('tabindex');
328328
if ($inputs.length === 0) {
329329
$inputs = $module;
330330
$module.attr('tabindex', -1);
331+
} else {
332+
$module.removeAttr('tabindex');
331333
}
332334
$inputs.first()
333335
.on('keydown' + elementEventNamespace, module.event.inputKeyDown.first)
@@ -606,6 +608,7 @@
606608
}
607609
if (settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
608610
module.debug('Showing modal with css animations');
611+
module.set.observeAttributes(false);
609612
$module
610613
.transition({
611614
debug: settings.debug,
@@ -623,6 +626,7 @@
623626
module.save.focus();
624627
module.set.active();
625628
module.refreshInputs();
629+
requestAnimationFrame(module.set.observeAttributes);
626630
callback();
627631
},
628632
})
@@ -654,6 +658,7 @@
654658
module.debug('Hiding modal');
655659
if (settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
656660
module.remove.active();
661+
module.set.observeAttributes(false);
657662
$module
658663
.transition({
659664
debug: settings.debug,
@@ -1034,6 +1039,9 @@
10341039
},
10351040

10361041
set: {
1042+
observeAttributes: function (state) {
1043+
observeAttributes = state !== false;
1044+
},
10371045
autofocus: function () {
10381046
var
10391047
$autofocus = $inputs.filter('[autofocus]'),

0 commit comments

Comments
 (0)