diff --git a/src/definitions/modules/flyout.js b/src/definitions/modules/flyout.js index 5ed35b1e25..59405b8ced 100644 --- a/src/definitions/modules/flyout.js +++ b/src/definitions/modules/flyout.js @@ -86,6 +86,7 @@ initialBodyMargin = '', tempBodyMargin = '', hadScrollbar = false, + windowRefocused = false, elementNamespace, id, @@ -264,9 +265,13 @@ module.setup.heights(); }, focus: function () { - if (module.is.visible() && settings.autofocus && settings.dimPage) { + windowRefocused = true; + }, + click: function (event) { + if (windowRefocused && document.activeElement !== event.target && module.is.visible() && settings.autofocus && settings.dimPage && $(document.activeElement).closest(selector.flyout).length === 0) { requestAnimationFrame(module.set.autofocus); } + windowRefocused = false; }, clickaway: function (event) { if (settings.closable) { @@ -373,6 +378,9 @@ $window .on('focus' + elementNamespace, module.event.focus) ; + $context + .on('click' + elementNamespace, module.event.click) + ; }, clickaway: function () { module.verbose('Adding clickaway events to context', $context); @@ -502,11 +510,12 @@ return nodes; }, - shouldRefreshInputs = false + shouldRefreshInputs = false, + ignoreAutofocus = true ; mutations.every(function (mutation) { if (mutation.type === 'attributes') { - if (observeAttributes && (mutation.attributeName === 'disabled' || $(mutation.target).find(':input').addBack(':input').length > 0)) { + if (observeAttributes && (mutation.attributeName === 'disabled' || $(mutation.target).find(':input').addBack(':input').filter(':visible').length > 0)) { shouldRefreshInputs = true; } } else { @@ -516,6 +525,7 @@ $removedInputs = $(collectNodes(mutation.removedNodes)).filter('a[href], [tabindex], :input'); if ($addedInputs.length > 0 || $removedInputs.length > 0) { shouldRefreshInputs = true; + ignoreAutofocus = false; } } @@ -523,7 +533,7 @@ }); if (shouldRefreshInputs) { - module.refreshInputs(); + module.refreshInputs(ignoreAutofocus); } }); observer.observe(element, { @@ -548,7 +558,7 @@ $flyouts = $context.children(selector.flyout); }, - refreshInputs: function () { + refreshInputs: function (ignoreAutofocus) { if ($inputs) { $inputs .off('keydown' + elementNamespace) @@ -560,8 +570,8 @@ $inputs = $module.find('a[href], [tabindex], :input:enabled').filter(':visible').filter(function () { return $(this).closest('.disabled').length === 0; }); - if ($inputs.length === 0) { - $inputs = $module; + if ($inputs.filter(':input').length === 0) { + $inputs = $module.add($inputs); $module.attr('tabindex', -1); } else { $module.removeAttr('tabindex'); @@ -572,7 +582,7 @@ $inputs.last() .on('keydown' + elementNamespace, module.event.inputKeyDown.last) ; - if (settings.autofocus && $inputs.filter(':focus').length === 0) { + if (!ignoreAutofocus && settings.autofocus && $inputs.filter(':focus').length === 0) { module.set.autofocus(); } }, @@ -850,20 +860,14 @@ var $autofocus = $inputs.filter('[autofocus]'), $rawInputs = $inputs.filter(':input'), - $input = $autofocus.length > 0 - ? $autofocus.first() + $input = ($autofocus.length > 0 + ? $autofocus : ($rawInputs.length > 0 ? $rawInputs - : $inputs.filter(':not(i.close)') - ).first() + : $module) + ).first() ; - // check if only the close icon is remaining - if ($input.length === 0 && $inputs.length > 0) { - $input = $inputs.first(); - } - if ($input.length > 0) { - $input.trigger('focus'); - } + $input.trigger('focus'); }, dimmerStyles: function () { if (settings.blurring) { diff --git a/src/definitions/modules/modal.js b/src/definitions/modules/modal.js index 6ea9b68c4d..5541527028 100755 --- a/src/definitions/modules/modal.js +++ b/src/definitions/modules/modal.js @@ -88,6 +88,7 @@ tempBodyMargin = '', keepScrollingClass = false, hadScrollbar = false, + windowRefocused = false, elementEventNamespace, id, @@ -251,6 +252,7 @@ .off(eventNamespace) ; $window.off(elementEventNamespace); + $context.off(elementEventNamespace); $dimmer.off(elementEventNamespace); $closeIcon.off(elementEventNamespace); if ($inputs) { @@ -272,11 +274,12 @@ return nodes; }, shouldRefresh = false, - shouldRefreshInputs = false + shouldRefreshInputs = false, + ignoreAutofocus = true ; mutations.every(function (mutation) { if (mutation.type === 'attributes') { - if (observeAttributes && (mutation.attributeName === 'disabled' || $(mutation.target).find(':input').addBack(':input').length > 0)) { + if (observeAttributes && (mutation.attributeName === 'disabled' || $(mutation.target).find(':input').addBack(':input').filter(':visible').length > 0)) { shouldRefreshInputs = true; } } else { @@ -287,6 +290,7 @@ $removedInputs = $(collectNodes(mutation.removedNodes)).filter('a[href], [tabindex], :input'); if ($addedInputs.length > 0 || $removedInputs.length > 0) { shouldRefreshInputs = true; + ignoreAutofocus = false; } } @@ -298,7 +302,7 @@ module.refresh(); } if (shouldRefreshInputs) { - module.refreshInputs(); + module.refreshInputs(ignoreAutofocus); } }); observer.observe(element, { @@ -326,7 +330,7 @@ $allModals = $otherModals.add($module); }, - refreshInputs: function () { + refreshInputs: function (ignoreAutofocus) { if ($inputs) { $inputs .off('keydown' + elementEventNamespace) @@ -335,8 +339,8 @@ $inputs = $module.find('a[href], [tabindex], :input:enabled').filter(':visible').filter(function () { return $(this).closest('.disabled').length === 0; }); - if ($inputs.length === 0) { - $inputs = $module; + if ($inputs.filter(':input').length === 0) { + $inputs = $module.add($inputs); $module.attr('tabindex', -1); } else { $module.removeAttr('tabindex'); @@ -347,7 +351,7 @@ $inputs.last() .on('keydown' + elementEventNamespace, module.event.inputKeyDown.last) ; - if (settings.autofocus && $inputs.filter(':focus').length === 0) { + if (!ignoreAutofocus && settings.autofocus && $inputs.filter(':focus').length === 0) { module.set.autofocus(); } }, @@ -385,6 +389,9 @@ .on('resize' + elementEventNamespace, module.event.resize) .on('focus' + elementEventNamespace, module.event.focus) ; + $context + .on('click' + elementEventNamespace, module.event.click) + ; }, scrollLock: function () { // touch events default to passive, due to changes in chrome to optimize mobile perf @@ -542,9 +549,13 @@ } }, focus: function () { - if ($dimmable.dimmer('is active') && module.is.active() && settings.autofocus) { + windowRefocused = true; + }, + click: function (event) { + if (windowRefocused && document.activeElement !== event.target && $dimmable.dimmer('is active') && module.is.active() && settings.autofocus && $(document.activeElement).closest(selector.modal).length === 0) { requestAnimationFrame(module.set.autofocus); } + windowRefocused = false; }, }, @@ -1054,20 +1065,14 @@ var $autofocus = $inputs.filter('[autofocus]'), $rawInputs = $inputs.filter(':input'), - $input = $autofocus.length > 0 - ? $autofocus.first() + $input = ($autofocus.length > 0 + ? $autofocus : ($rawInputs.length > 0 ? $rawInputs - : $inputs.filter(':not(i.close)') - ).first() + : $module) + ).first() ; - // check if only the close icon is remaining - if ($input.length === 0 && $inputs.length > 0) { - $input = $inputs.first(); - } - if ($input.length > 0) { - $input.trigger('focus'); - } + $input.trigger('focus'); }, bodyMargin: function () { var position = module.can.leftBodyScrollbar() ? 'left' : 'right';