2 * jQuery plugin to update the tooltip to show the correct access key
4 * @class jQuery.plugin.accessKeyLabel
8 // Cached access key modifiers for used browser
9 var cachedAccessKeyModifiers
,
11 // Whether 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 * Find the modifier keys that need to be pressed together with the accesskey to trigger the input.
21 * The result is dependant on the ua paramater or the current platform.
22 * For browsers that support accessKeyLabel, #getAccessKeyLabel never calls here.
23 * Valid key values that are returned can be: ctrl, alt, option, shift, esc
26 * @param {Object} [ua] An object with a 'userAgent' and 'platform' property.
27 * @return {Array} Array with 0 or more of the string values: ctrl, option, alt, shift, esc
29 function getAccessKeyModifiers( ua
) {
30 // use cached prefix if possible
31 if ( !ua
&& cachedAccessKeyModifiers
) {
32 return cachedAccessKeyModifiers
;
35 var profile
= $.client
.profile( ua
),
36 accessKeyModifiers
= [ 'alt' ];
38 // Classic Opera on any platform
39 if ( profile
.name
=== 'opera' && profile
.versionNumber
< 15 ) {
40 accessKeyModifiers
= [ 'shift', 'esc' ];
42 // Chrome and modern Opera on any platform
43 } else if ( profile
.name
=== 'chrome' || profile
.name
=== 'opera' ) {
44 accessKeyModifiers
= (
45 profile
.platform
=== 'mac'
47 ? [ 'ctrl', 'option' ]
48 // Chrome on Windows or Linux
49 // (both alt- and alt-shift work, but alt with E, D, F etc does not
50 // work since they are browser shortcuts)
54 // Non-Windows Safari with webkit_version > 526
55 } else if ( profile
.platform
!== 'win'
56 && profile
.name
=== 'safari'
57 && profile
.layoutVersion
> 526
59 accessKeyModifiers
= [ 'ctrl', 'alt' ];
61 // Safari/Konqueror on any platform, or any browser on Mac
62 // (but not Safari on Windows)
63 } else if ( !( profile
.platform
=== 'win' && profile
.name
=== 'safari' )
64 && ( profile
.name
=== 'safari'
65 || profile
.platform
=== 'mac'
66 || profile
.name
=== 'konqueror' )
68 accessKeyModifiers
= [ 'ctrl' ];
70 // Firefox/Iceweasel 2.x and later
71 } else if ( ( profile
.name
=== 'firefox' || profile
.name
=== 'iceweasel' )
72 && profile
.versionBase
> '1'
74 accessKeyModifiers
= [ 'alt', 'shift' ];
79 cachedAccessKeyModifiers
= accessKeyModifiers
;
81 return accessKeyModifiers
;
85 * Get the access key label for an element.
87 * Will use native accessKeyLabel if available (currently only in Firefox 8+),
88 * falls back to #getAccessKeyModifiers.
91 * @param {HTMLElement} element Element to get the label for
92 * @return {string} Access key label
94 function getAccessKeyLabel( element
) {
95 // abort early if no access key
96 if ( !element
.accessKey
) {
99 // use accessKeyLabel if possible
100 // http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#dom-accesskeylabel
101 if ( !useTestPrefix
&& element
.accessKeyLabel
) {
102 return element
.accessKeyLabel
;
104 return ( useTestPrefix
? 'test' : getAccessKeyModifiers().join( '-' ) ) + '-' + element
.accessKey
;
108 * Update the title for an element (on the element with the access key or it's label) to show
109 * the correct access key label.
112 * @param {HTMLElement} element Element with the accesskey
113 * @param {HTMLElement} titleElement Element with the title to update (may be the same as `element`)
115 function updateTooltipOnElement( element
, titleElement
) {
116 var array
= ( mw
.msg( 'word-separator' ) + mw
.msg( 'brackets' ) ).split( '$1' ),
117 regexp
= new RegExp( $.map( array
, mw
.RegExp
.escape
).join( '.*?' ) + '$' ),
118 oldTitle
= titleElement
.title
,
119 rawTitle
= oldTitle
.replace( regexp
, '' ),
121 accessKeyLabel
= getAccessKeyLabel( element
);
123 // don't add a title if the element didn't have one before
128 if ( accessKeyLabel
) {
129 // Should be build the same as in Linker::titleAttrib
130 newTitle
+= mw
.msg( 'word-separator' ) + mw
.msg( 'brackets', accessKeyLabel
);
132 if ( oldTitle
!== newTitle
) {
133 titleElement
.title
= newTitle
;
138 * Update the title for an element to show the correct access key label.
141 * @param {HTMLElement} element Element with the accesskey
143 function updateTooltip( element
) {
144 var id
, $element
, $label
, $labelParent
;
145 updateTooltipOnElement( element
, element
);
147 // update associated label if there is one
148 $element
= $( element
);
149 if ( $element
.is( labelable
) ) {
150 // Search it using 'for' attribute
151 id
= element
.id
.replace( /"/g, '\\"' );
153 $label = $( 'label
[for="' + id + '"]' );
154 if ( $label.length === 1 ) {
155 updateTooltipOnElement( element, $label[ 0 ] );
159 // Search it as parent, because the form control can also be inside the label element itself
160 $labelParent = $element.parents( 'label
' );
161 if ( $labelParent.length === 1 ) {
162 updateTooltipOnElement( element, $labelParent[ 0 ] );
168 * Update the titles for all elements in a jQuery selection.
173 $.fn.updateTooltipAccessKeys = function () {
174 return this.each( function () {
175 updateTooltip( this );
180 * getAccessKeyModifiers
182 * @method updateTooltipAccessKeys_getAccessKeyModifiers
183 * @inheritdoc #getAccessKeyModifiers
185 $.fn.updateTooltipAccessKeys.getAccessKeyModifiers = getAccessKeyModifiers;
190 * @method updateTooltipAccessKeys_getAccessKeyLabel
191 * @inheritdoc #getAccessKeyLabel
193 $.fn.updateTooltipAccessKeys.getAccessKeyLabel = getAccessKeyLabel;
198 * @method updateTooltipAccessKeys_getAccessKeyPrefix
199 * @deprecated 1.27 Use #getAccessKeyModifiers
201 $.fn.updateTooltipAccessKeys.getAccessKeyPrefix = function ( ua ) {
202 return getAccessKeyModifiers( ua ).join( '-' ) + '-';
206 * Switch test mode on and off.
208 * @method updateTooltipAccessKeys_setTestMode
209 * @param {boolean} mode New mode
211 $.fn.updateTooltipAccessKeys.setTestMode = function ( mode ) {
212 useTestPrefix = mode;
217 * @mixins jQuery.plugin.accessKeyLabel
220 }( jQuery, mediaWiki ) );