changeset 325858970d4f in sao:default
details: https://hg.tryton.org/sao?cmd=changeset&node=325858970d4f
description:
        Add accesskey to widgets and buttons

        issue10307
        review330781002
diffstat:

 CHANGELOG        |   1 +
 src/common.js    |  13 +++++++++++++
 src/sao.js       |   6 ++++++
 src/sao.less     |  40 ++++++++++++++++++++++++++++++++++++++++
 src/view/form.js |  11 ++++++++++-
 5 files changed, 70 insertions(+), 1 deletions(-)

diffs (142 lines):

diff -r 16479a3d9f7e -r 325858970d4f CHANGELOG
--- a/CHANGELOG Mon Jun 07 22:21:49 2021 +0100
+++ b/CHANGELOG Fri Jun 11 00:22:22 2021 +0200
@@ -1,3 +1,4 @@
+* Add accesskey to widgets and buttons
 * Support Binary field in CSV import/export
 
 Version 6.0.0 - 2021-05-03
diff -r 16479a3d9f7e -r 325858970d4f src/common.js
--- a/src/common.js     Mon Jun 07 22:21:49 2021 +0100
+++ b/src/common.js     Fri Jun 11 00:22:22 2021 +0200
@@ -849,6 +849,9 @@
                         'class': 'badge'
                     }));
                 }
+                this.el.attr(
+                    'accesskey',
+                    Sao.common.accesskey(attributes.string || ''));
             }
             this.icon = this.el.children('img');
             if (!this.icon.length) {
@@ -3859,6 +3862,16 @@
         return string.slice(0, length - ellipsis.length) + ellipsis;
     };
 
+    Sao.common.accesskey = function(string) {
+        for (var i=0; i < string.length; i++) {
+            var c = string.charAt(i).toLowerCase();
+            // Skip sao and browser shortcuts
+            if (!~['d', 'e', 'f', 'i', 'n', 't', 'w'].indexOf(c)) {
+                return c;
+            }
+        }
+    };
+
     Sao.common.debounce = function(func, wait) {
         return function() {
             var args = [].slice(arguments);
diff -r 16479a3d9f7e -r 325858970d4f src/sao.js
--- a/src/sao.js        Mon Jun 07 22:21:49 2021 +0100
+++ b/src/sao.js        Fri Jun 11 00:22:22 2021 +0200
@@ -1076,6 +1076,12 @@
                 callback: function() {
                     shortcuts_dialog();
                 },
+            }, {
+                shortcut: 'ctrl+f1',
+                label: Sao.i18n.gettext('Show/Hide access keys'),
+                callback: function() {
+                    jQuery('html').toggleClass('accesskey');
+                },
             },
         ];
     }
diff -r 16479a3d9f7e -r 325858970d4f src/sao.less
--- a/src/sao.less      Mon Jun 07 22:21:49 2021 +0100
+++ b/src/sao.less      Fri Jun 11 00:22:22 2021 +0200
@@ -188,6 +188,46 @@
 .table-row-variant(warning; @state-warning-bg);
 .table-row-variant(danger; @state-danger-bg);
 
+html.accesskey {
+
+    *[accesskey]+span[data-accesskey]:after,
+    *[accesskey]:after {
+        background-color: @brand-info;
+        color: #fff;
+        font-size: x-small;
+        padding: 0 2px;
+        position: absolute;
+        text-transform: uppercase;
+        margin: 0 -1em;
+        z-index: 5;
+    }
+
+    input[accesskey][type="checkbox"]:after {
+        background-color: initial;
+    }
+
+    *[accesskey]+span[data-accesskey] {
+        float: right;
+        position: relative;
+
+        &:after {
+            content: attr(data-accesskey);
+        }
+    }
+
+    *[accesskey]:after {
+        content: attr(accesskey);
+    }
+
+    input[accesskey][type="checkbox"],
+    input[accesskey][type="checkbox"],
+    select[accesskey] {
+        &+span[data-accesskey] {
+            bottom: 1em;
+        }
+    }
+}
+
 .tab-form, .tab-board {
     nav.toolbar {
         position: -webkit-sticky;
diff -r 16479a3d9f7e -r 325858970d4f src/view/form.js
--- a/src/view/form.js  Mon Jun 07 22:21:49 2021 +0100
+++ b/src/view/form.js  Fri Jun 11 00:22:22 2021 +0200
@@ -84,9 +84,17 @@
 
             if (this._mnemonics[name] && widget.labelled) {
                 var label = this._mnemonics[name];
+                var accesskey = Sao.common.accesskey(label.label_el.text());
                 label.label_el.uniqueId();
                 widget.labelled.uniqueId();
                 widget.labelled.attr('aria-labelledby', label.el.attr('id'));
+                widget.labelled.attr('accesskey', accesskey);
+                if (~['INPUT', 'SELECT'].indexOf(
+                    widget.labelled.get(0).tagName)) {
+                    jQuery('<span/>', {
+                        'data-accesskey': accesskey,
+                    }).insertAfter(widget.labelled);
+                }
                 label.label_el.attr('for', widget.labelled.attr('id'));
             }
         },
@@ -1025,6 +1033,7 @@
         },
         set_label: function(name, domains, counter) {
             this.label.text(name);
+            this.el.attr('accesskey', Sao.common.accesskey(name));
             if (domains.length) {
                 domains.map(function(d, i) {
                     var name = d[0];
@@ -4245,7 +4254,7 @@
         init: function(view, attributes) {
             Sao.View.Form.URL._super.init.call(this, view, attributes);
             this.input.attr('type', 'url');
-            this.button = jQuery('<a/>', {
+            this.button = this.labelled = jQuery('<a/>', {
                 'class': 'btn btn-default',
                 'target': '_blank',
                 'rel': 'noreferrer noopener',

Reply via email to