Fossil SCM
fossil.tabs.TabManager now experimentally (and optionally, defaulting to on) assigns 'accesskey' values to each tab button equal to their 1-based index in the tab list.
Commit
4cf3586431a9edccae06eede2d66419b89fc6db669375304bdeda3f9a7588268
Parent
d9543f4c2ca2f6a…
1 file changed
+33
-5
+33
-5
| --- src/fossil.tabs.js | ||
| +++ src/fossil.tabs.js | ||
| @@ -3,17 +3,34 @@ | ||
| 3 | 3 | const E = (s)=>document.querySelector(s), |
| 4 | 4 | EA = (s)=>document.querySelectorAll(s), |
| 5 | 5 | D = F.dom; |
| 6 | 6 | |
| 7 | 7 | /** |
| 8 | - Creates a TabManager. If passed an argument, it is | |
| 9 | - passed to init(). | |
| 8 | + Creates a TabManager. If passed a truthy first argument, it is | |
| 9 | + passed to init(). If passed a truthy second argument, it must be | |
| 10 | + an Object holding configuration options: | |
| 11 | + | |
| 12 | + { | |
| 13 | + tabAccessKeys: boolean (=true) | |
| 14 | + If true, tab buttons are assigned "accesskey" values | |
| 15 | + equal to their 1-based tab number. | |
| 16 | + } | |
| 10 | 17 | */ |
| 11 | - const TabManager = function(domElem){ | |
| 18 | + const TabManager = function(domElem, options){ | |
| 12 | 19 | this.e = {}; |
| 20 | + this.options = F.mergeLastWins(TabManager.defaultOptions , options); | |
| 13 | 21 | if(domElem) this.init(domElem); |
| 14 | 22 | }; |
| 23 | + | |
| 24 | + /** | |
| 25 | + Default values for the options object passed to the TabManager | |
| 26 | + constructor. Changing these affects the defaults of all | |
| 27 | + TabManager instances instantiated after that point. | |
| 28 | + */ | |
| 29 | + TabManager.defaultOptions = { | |
| 30 | + tabAccessKeys: true | |
| 31 | + }; | |
| 15 | 32 | |
| 16 | 33 | /** |
| 17 | 34 | Internal helper to normalize a method argument to a tab |
| 18 | 35 | element. arg may be a tab DOM element or an index into |
| 19 | 36 | tabMgr.e.tabs.childNodes. Returns the corresponding tab element. |
| @@ -28,11 +45,10 @@ | ||
| 28 | 45 | arg = arg.firstElementChild; |
| 29 | 46 | } |
| 30 | 47 | } |
| 31 | 48 | return arg; |
| 32 | 49 | }; |
| 33 | - | |
| 34 | 50 | |
| 35 | 51 | /** |
| 36 | 52 | Sets sets the visibility of tab element e to on or off. e MUST be |
| 37 | 53 | a TabManager tab element which has been wrapped in a |
| 38 | 54 | FIELDSET.tab-wrapper parent element. We disable the hidden |
| @@ -131,10 +147,18 @@ | ||
| 131 | 147 | }, |
| 132 | 148 | /** |
| 133 | 149 | Adds the given DOM element or unique selector as the next |
| 134 | 150 | tab in the tab container, adding a button to switch to |
| 135 | 151 | the tab. Returns this object. |
| 152 | + | |
| 153 | + If this object's options include a truthy tabAccessKeys then | |
| 154 | + each tab button gets assigned an accesskey attribute equal to | |
| 155 | + its 1-based index in the tab list. e.g. key 1 is the first tab | |
| 156 | + and key 5 is the 5th. Whether/how that accesskey is accessed is | |
| 157 | + dependent on the browser and its OS: | |
| 158 | + | |
| 159 | + https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/accesskey | |
| 136 | 160 | */ |
| 137 | 161 | addTab: function f(tab){ |
| 138 | 162 | if(!f.click){ |
| 139 | 163 | f.click = function(e){ |
| 140 | 164 | e.target.$manager.switchToTab(e.target.$tab); |
| @@ -143,15 +167,19 @@ | ||
| 143 | 167 | tab = tabArg(tab); |
| 144 | 168 | tab.remove(); |
| 145 | 169 | const eFs = D.addClass(D.fieldset(), 'tab-wrapper'); |
| 146 | 170 | D.append(eFs, D.addClass(tab,'tab-panel')); |
| 147 | 171 | D.append(this.e.tabs, eFs); |
| 148 | - const lbl = tab.dataset.tabLabel || 'Tab #'+(this.e.tabs.childNodes.length-1); | |
| 172 | + const tabCount = this.e.tabBar.childNodes.length+1; | |
| 173 | + const lbl = tab.dataset.tabLabel || 'Tab #'+tabCount; | |
| 149 | 174 | const btn = D.addClass(D.append(D.span(), lbl), 'tab-button'); |
| 150 | 175 | D.append(this.e.tabBar,btn); |
| 151 | 176 | btn.$manager = this; |
| 152 | 177 | btn.$tab = tab; |
| 178 | + if(this.options.tabAccessKeys){ | |
| 179 | + D.attr(btn, 'accesskey', tabCount); | |
| 180 | + } | |
| 153 | 181 | btn.addEventListener('click', f.click, false); |
| 154 | 182 | return this; |
| 155 | 183 | }, |
| 156 | 184 | |
| 157 | 185 | /** |
| 158 | 186 |
| --- src/fossil.tabs.js | |
| +++ src/fossil.tabs.js | |
| @@ -3,17 +3,34 @@ | |
| 3 | const E = (s)=>document.querySelector(s), |
| 4 | EA = (s)=>document.querySelectorAll(s), |
| 5 | D = F.dom; |
| 6 | |
| 7 | /** |
| 8 | Creates a TabManager. If passed an argument, it is |
| 9 | passed to init(). |
| 10 | */ |
| 11 | const TabManager = function(domElem){ |
| 12 | this.e = {}; |
| 13 | if(domElem) this.init(domElem); |
| 14 | }; |
| 15 | |
| 16 | /** |
| 17 | Internal helper to normalize a method argument to a tab |
| 18 | element. arg may be a tab DOM element or an index into |
| 19 | tabMgr.e.tabs.childNodes. Returns the corresponding tab element. |
| @@ -28,11 +45,10 @@ | |
| 28 | arg = arg.firstElementChild; |
| 29 | } |
| 30 | } |
| 31 | return arg; |
| 32 | }; |
| 33 | |
| 34 | |
| 35 | /** |
| 36 | Sets sets the visibility of tab element e to on or off. e MUST be |
| 37 | a TabManager tab element which has been wrapped in a |
| 38 | FIELDSET.tab-wrapper parent element. We disable the hidden |
| @@ -131,10 +147,18 @@ | |
| 131 | }, |
| 132 | /** |
| 133 | Adds the given DOM element or unique selector as the next |
| 134 | tab in the tab container, adding a button to switch to |
| 135 | the tab. Returns this object. |
| 136 | */ |
| 137 | addTab: function f(tab){ |
| 138 | if(!f.click){ |
| 139 | f.click = function(e){ |
| 140 | e.target.$manager.switchToTab(e.target.$tab); |
| @@ -143,15 +167,19 @@ | |
| 143 | tab = tabArg(tab); |
| 144 | tab.remove(); |
| 145 | const eFs = D.addClass(D.fieldset(), 'tab-wrapper'); |
| 146 | D.append(eFs, D.addClass(tab,'tab-panel')); |
| 147 | D.append(this.e.tabs, eFs); |
| 148 | const lbl = tab.dataset.tabLabel || 'Tab #'+(this.e.tabs.childNodes.length-1); |
| 149 | const btn = D.addClass(D.append(D.span(), lbl), 'tab-button'); |
| 150 | D.append(this.e.tabBar,btn); |
| 151 | btn.$manager = this; |
| 152 | btn.$tab = tab; |
| 153 | btn.addEventListener('click', f.click, false); |
| 154 | return this; |
| 155 | }, |
| 156 | |
| 157 | /** |
| 158 |
| --- src/fossil.tabs.js | |
| +++ src/fossil.tabs.js | |
| @@ -3,17 +3,34 @@ | |
| 3 | const E = (s)=>document.querySelector(s), |
| 4 | EA = (s)=>document.querySelectorAll(s), |
| 5 | D = F.dom; |
| 6 | |
| 7 | /** |
| 8 | Creates a TabManager. If passed a truthy first argument, it is |
| 9 | passed to init(). If passed a truthy second argument, it must be |
| 10 | an Object holding configuration options: |
| 11 | |
| 12 | { |
| 13 | tabAccessKeys: boolean (=true) |
| 14 | If true, tab buttons are assigned "accesskey" values |
| 15 | equal to their 1-based tab number. |
| 16 | } |
| 17 | */ |
| 18 | const TabManager = function(domElem, options){ |
| 19 | this.e = {}; |
| 20 | this.options = F.mergeLastWins(TabManager.defaultOptions , options); |
| 21 | if(domElem) this.init(domElem); |
| 22 | }; |
| 23 | |
| 24 | /** |
| 25 | Default values for the options object passed to the TabManager |
| 26 | constructor. Changing these affects the defaults of all |
| 27 | TabManager instances instantiated after that point. |
| 28 | */ |
| 29 | TabManager.defaultOptions = { |
| 30 | tabAccessKeys: true |
| 31 | }; |
| 32 | |
| 33 | /** |
| 34 | Internal helper to normalize a method argument to a tab |
| 35 | element. arg may be a tab DOM element or an index into |
| 36 | tabMgr.e.tabs.childNodes. Returns the corresponding tab element. |
| @@ -28,11 +45,10 @@ | |
| 45 | arg = arg.firstElementChild; |
| 46 | } |
| 47 | } |
| 48 | return arg; |
| 49 | }; |
| 50 | |
| 51 | /** |
| 52 | Sets sets the visibility of tab element e to on or off. e MUST be |
| 53 | a TabManager tab element which has been wrapped in a |
| 54 | FIELDSET.tab-wrapper parent element. We disable the hidden |
| @@ -131,10 +147,18 @@ | |
| 147 | }, |
| 148 | /** |
| 149 | Adds the given DOM element or unique selector as the next |
| 150 | tab in the tab container, adding a button to switch to |
| 151 | the tab. Returns this object. |
| 152 | |
| 153 | If this object's options include a truthy tabAccessKeys then |
| 154 | each tab button gets assigned an accesskey attribute equal to |
| 155 | its 1-based index in the tab list. e.g. key 1 is the first tab |
| 156 | and key 5 is the 5th. Whether/how that accesskey is accessed is |
| 157 | dependent on the browser and its OS: |
| 158 | |
| 159 | https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/accesskey |
| 160 | */ |
| 161 | addTab: function f(tab){ |
| 162 | if(!f.click){ |
| 163 | f.click = function(e){ |
| 164 | e.target.$manager.switchToTab(e.target.$tab); |
| @@ -143,15 +167,19 @@ | |
| 167 | tab = tabArg(tab); |
| 168 | tab.remove(); |
| 169 | const eFs = D.addClass(D.fieldset(), 'tab-wrapper'); |
| 170 | D.append(eFs, D.addClass(tab,'tab-panel')); |
| 171 | D.append(this.e.tabs, eFs); |
| 172 | const tabCount = this.e.tabBar.childNodes.length+1; |
| 173 | const lbl = tab.dataset.tabLabel || 'Tab #'+tabCount; |
| 174 | const btn = D.addClass(D.append(D.span(), lbl), 'tab-button'); |
| 175 | D.append(this.e.tabBar,btn); |
| 176 | btn.$manager = this; |
| 177 | btn.$tab = tab; |
| 178 | if(this.options.tabAccessKeys){ |
| 179 | D.attr(btn, 'accesskey', tabCount); |
| 180 | } |
| 181 | btn.addEventListener('click', f.click, false); |
| 182 | return this; |
| 183 | }, |
| 184 | |
| 185 | /** |
| 186 |