2 * jQuery plugin to update the tooltip to show the correct access key
4 * @class jQuery.plugin.accessKeyLabel
8 // Cached access key prefix for used browser
9 var cachedAccessKeyPrefix
,
11 // Wether to use 'test-' instead of correct prefix (used for testing)
12 useTestPrefix
= false,
14 // tag names which can have a label tag
15 // https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_categories#Form-associated_content
16 labelable
= 'button, input, textarea, keygen, meter, output, progress, select';
19 * Get the prefix for the access key.
20 * Will only give correct prefix for browsers not implementing the accessKeyLabel property.
21 * These browsers currently are:
24 * Exposed for testing.
27 * @param {Object} ua An object with atleast a 'userAgent' and 'platform' key.
28 * Defaults to the global Navigator object.
29 * @return {string} Access key prefix
31 function getAccessKeyPrefix( ua
) {
32 // use cached prefix if possible
33 if ( !ua
&& cachedAccessKeyPrefix
) {
34 return cachedAccessKeyPrefix
;
37 var profile
= $.client
.profile( ua
),
38 accessKeyPrefix
= 'alt-';
40 // Opera on any platform
41 if ( profile
.name
=== 'opera' ) {
42 accessKeyPrefix
= 'shift-esc-';
44 // Chrome on any platform
45 } else if ( profile
.name
=== 'chrome' ) {
47 profile
.platform
=== 'mac'
50 // Chrome on Windows or Linux
51 // (both alt- and alt-shift work, but alt with E, D, F etc does not
52 // work since they are browser shortcuts)
56 // Non-Windows Safari with webkit_version > 526
57 } else if ( profile
.platform
!== 'win'
58 && profile
.name
=== 'safari'
59 && profile
.layoutVersion
> 526
61 accessKeyPrefix
= 'ctrl-alt-';
63 // Safari/Konqueror on any platform, or any browser on Mac
64 // (but not Safari on Windows)
65 } else if ( !( profile
.platform
=== 'win' && profile
.name
=== 'safari' )
66 && ( profile
.name
=== 'safari'
67 || profile
.platform
=== 'mac'
68 || profile
.name
=== 'konqueror' )
70 accessKeyPrefix
= 'ctrl-';
72 // Firefox/Iceweasel 2.x and later
73 } else if ( ( profile
.name
=== 'firefox' || profile
.name
=== 'iceweasel' )
74 && profile
.versionBase
> '1'
76 accessKeyPrefix
= 'alt-shift-';
81 cachedAccessKeyPrefix
= accessKeyPrefix
;
83 return accessKeyPrefix
;
87 * Get the access key label for an element.
90 * @param {HTMLElement} domElement DOM element to get the label for
91 * @return {string} Access key label
93 function getAccessKeyLabel( domElement
) {
94 // abort early if no access key
95 if ( !domElement
.accessKey
) {
98 // use accessKeyLabel if possible
99 // http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#dom-accesskeylabel
100 if ( !useTestPrefix
&& domElement
.accessKeyLabel
) {
101 return domElement
.accessKeyLabel
;
103 return ( useTestPrefix
? 'test-' : getAccessKeyPrefix() ) + domElement
.accessKey
;
107 * Update the title for an element (on the element with the access key or it's label) to show the correct access key label.
110 * @param {HTMLElement} domElement DOM element with the accesskey
111 * @param {HTMLElement} titleElement DOM element with the title to update
113 function updateTooltipOnElement( domElement
, titleElement
) {
114 var oldTitle
= titleElement
.title
,
115 rawTitle
= oldTitle
.replace( / \[.*?\]$/, '' ),
117 accessKeyLabel
= getAccessKeyLabel( domElement
);
119 // don't add a title if the element didn't have one before
124 if ( accessKeyLabel
) {
125 newTitle
+= ' [' + accessKeyLabel
+ ']';
127 if ( oldTitle
!== newTitle
) {
128 titleElement
.title
= newTitle
;
133 * Update the title for an element to show the correct access key label.
136 * @param {HTMLElement} domElement DOM element with the accesskey
138 function updateTooltip( domElement
) {
139 var id
, $domElement
, $label
, $labelParent
;
140 updateTooltipOnElement( domElement
, domElement
);
142 // update associated label if there is one
143 $domElement
= $( domElement
);
144 if ( $domElement
.is( labelable
) ) {
145 // Search it using 'for' attribute
146 id
= domElement
.id
.replace( /"/g, '\\"' );
148 $label = $( 'label
[for="' + id + '"]' );
149 if ( $label.length === 1 ) {
150 updateTooltipOnElement( domElement, $label[0] );
154 // Search it as parent, because the form control can also inside the label element itself
155 $labelParent = $domElement.parents( 'label
' );
156 if ( $labelParent.length === 1 ) {
157 updateTooltipOnElement( domElement, $labelParent[0] );
163 * Update the titles for all elements in a jQuery selection.
168 $.fn.updateTooltipAccessKeys = function () {
169 return this.each( function () {
170 updateTooltip( this );
175 * @method updateTooltipAccessKeys_getAccessKeyPrefix
176 * @inheritdoc #getAccessKeyPrefix
178 $.fn.updateTooltipAccessKeys.getAccessKeyPrefix = getAccessKeyPrefix;
181 * Switch test mode on and off.
183 * @method updateTooltipAccessKeys_setTestMode
184 * @param {boolean} mode New mode
186 $.fn.updateTooltipAccessKeys.setTestMode = function ( mode ) {
187 useTestPrefix = mode;
192 * @mixins jQuery.plugin.accessKeyLabel