Explorar o código

Ticket #5046 - Accessibility: Operable - Keyboard Accessible.

AntonLV hai 1 ano
pai
achega
eb8d2c6d4a

+ 1 - 7
inc/js/classes/BxDolMenuMoreAuto.js

@@ -102,13 +102,7 @@ BxDolMenuMoreAuto.prototype.more = function(oElement)
             el: oElement
         }, 
         moveToDocRoot: false,
-        cssClass: 'bx-popup-menu',
-        onShow: function(oPopup) {
-            oPopup.find('.bx-popup-content a:first').focus();
-        },
-        onHide: function(oPopup) {
-            $(oElement).focus();
-        }
+        cssClass: 'bx-popup-menu'
     });
 }
 

+ 30 - 15
inc/js/functions.js

@@ -427,13 +427,7 @@ function bx_menu_popup (o, e, options, vars) {
     var o = $.extend({}, $.fn.dolPopupDefaultOptions, {
         id: o, 
         url: bx_append_url_params('menu.php', $.extend({o:o}, vars)), 
-        cssClass: 'bx-popup-menu',
-        onShow: function(oPopup) {
-            oPopup.find('.bx-popup-content a:first').focus();
-        },
-        onHide: function(oPopup) {
-            $(e).focus();
-        }
+        cssClass: 'bx-popup-menu'
     }, options);
 
     $(e).dolPopupAjax(o);
@@ -457,7 +451,6 @@ function bx_menu_popup_inline (jSel, e, options) {
             pointer: bElement ? {el:$(e)} : false, 
             cssClass: 'bx-popup-menu',
             onShow: function(oPopup) {
-                oPopup.find('.bx-popup-content a:first').focus();
                 oPopup.find('a').each(function () {
                     $(this).off('click.bx-popup-menu');
                     $(this).on('click.bx-popup-menu', function() {
@@ -465,10 +458,6 @@ function bx_menu_popup_inline (jSel, e, options) {
                     });
                 });
             },
-            onHide: function(oPopup) {
-                if(bElement)
-                    $(e).focus();
-            }
         });
 
         $(jSel).dolPopup(o);
@@ -1536,9 +1525,9 @@ function bx_check_mq()
 
 function bx_get_focusable(oContext = 'document')
 {
-  return Array.from(oContext.querySelectorAll('button, [href], input:not([type="hidden"]), textarea, select, [tabindex]:not([tabindex="-1"])')).filter(function(oElement) { 
-      return !oElement.closest('[hidden]'); 
-  });
+    return Array.from(oContext.querySelectorAll('button, [href], input:not([type="hidden"]), textarea, select, [tabindex]:not([tabindex="-1"])')).filter(function(oElement) { 
+        return !$(oElement).closest(':hidden').length; 
+    });
 }
 
 /**
@@ -1733,4 +1722,30 @@ function bx_agents_action(oElement, sTool, sAction, aParams)
     );
 }
 
+function bx_clicked_stack_register()
+{
+    const iStackMaxLenth = 3;
+
+    $('a,button').on('click', function() {
+        if(typeof window.glClickedStack === 'undefined')
+            window.glClickedStack = [];    
+
+        window.glClickedStack.push(this);
+
+        if(window.glClickedStack.length > iStackMaxLenth)
+            window.glClickedStack = window.glClickedStack.slice(-iStackMaxLenth);
+    });
+}
+
+function bx_clicked_stack_get()
+{
+    const iLenth = window.glClickedStack.length;
+    return iLenth > 0 ? window.glClickedStack[iLenth - 1] : false;
+}
+
+function bx_clicked_stack_pop()
+{
+    return window.glClickedStack.length > 0 ? window.glClickedStack.pop() : false;
+}
+
 /** @} */

+ 41 - 7
inc/js/jquery.dolPopup.js

@@ -231,19 +231,49 @@
                 }
 
                 // show popup
-
                 $el.css({display: 'block', visibility: 'visible'});
                 if (o.fog) {
-                	var oOnHide = function() {
-                		$(window).triggerHandler('resize.popupFog');
-                	};
-                	
+                    var oOnHide = function() {
+                        $(window).triggerHandler('resize.popupFog');
+                    };
+
                     if (o.speed > 0)
                         $('#bx-popup-fog').fadeIn(o.speed, oOnHide);
                     else
                         $('#bx-popup-fog').show(oOnHide);
                 }
 
+                /*
+                 * Trap focus inside popup.
+                 */
+                $el.find('.bx-popup-focus-trap').bind('focus', function() {
+                    var aFocusable = bx_get_focusable($el.get(0));
+                    if(aFocusable && aFocusable.length > 0)
+                        $(aFocusable[0]).focus();
+                });
+
+                /*
+                 * Add onHide to return focus back.
+                 */
+                const oSource = o.pointer ? $(o.pointer.el).get(0) : bx_clicked_stack_get();
+                if(oSource) {
+                    var onHide = null;
+                    if(typeof(o.onHide) == 'function')
+                        onHide = o.onHide;
+                    else if(typeof(o.onHide) == 'string')
+                        onHide = function(oPopup) {
+                            eval(o.onHide);
+                        };
+
+                    o.onHide = function() {
+                        if(typeof(onHide) == 'function')
+                            onHide($el);
+
+                        bx_clicked_stack_pop();
+                        $(oSource).focus();
+                    };
+                }
+
                 setTimeout(function () {
                     // Don't should popup with pointer if there is no parent. Checking after showing.
                     if(typeof o.pointer.el == 'string')
@@ -254,12 +284,16 @@
                         return;
                     }
 
+                    var aFocusable = bx_get_focusable($el.get(0));
+                    console.log(aFocusable);
+                    if(aFocusable && aFocusable.length > 0) {
+                        $(aFocusable[0]).focus();
+                    }
+
                     if(typeof(o.onShow) == 'function')
                         o.onShow($el);
                     else if(typeof(o.onShow) == 'string')
                     	eval(o.onShow);
-                    else
-                        $el.find('input[type=text]:first').focus(); //NOTE. Put cursor to the first input element, ONLY IF there is no any custom behaviour for onShow event.
 
                 }, o.speed);
 

+ 1 - 0
modules/boonex/artificer/data/template/system/popup_box.html

@@ -12,6 +12,7 @@
                 </div>
             </div>
             <div class="bx-popup-content px-4 pb-4">__content__</div>
+            <div class="bx-popup-focus-trap w-0 h-0 outline-none" tabindex="0"></div>
         </div>
     </div>
 </div>

+ 1 - 0
template/_header_js.html

@@ -5,6 +5,7 @@
     $(document).ready(function () {
         bx_time('__lang_country__');
         bx_redirect_for_external_links($('.bx-def-vanilla-html'));
+        bx_clicked_stack_register();
     });
 
     __service_worker__

+ 1 - 0
template/popup_box.html

@@ -11,6 +11,7 @@
                 </a>
             </div>
             <div class="bx-popup-content bx-def-padding">__content__</div>
+            <div class="bx-popup-focus-trap w-0 h-0 outline-none" tabindex="0"></div>
         </div>
     </div>
 </div>

+ 1 - 0
template/popup_trans.html

@@ -9,6 +9,7 @@
                 </a>
             </div>
             <div class="bx-popup-content overflow-hidden">__content__</div>
+            <div class="bx-popup-focus-trap w-0 h-0 outline-none" tabindex="0"></div>
             <!-- Footer is needed for Safari in iOS -->
             <!-- <div class="bx-popup-footer-wrapper bx-def-media-desktop-hide bx-def-media-tablet-hide p-3 md:p-4 lg:p-6">&nbsp;</div> -->
         </div>