diff options
Diffstat (limited to 'www/wiki/resources/src/jquery/jquery.accessKeyLabel.js')
-rw-r--r-- | www/wiki/resources/src/jquery/jquery.accessKeyLabel.js | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/www/wiki/resources/src/jquery/jquery.accessKeyLabel.js b/www/wiki/resources/src/jquery/jquery.accessKeyLabel.js new file mode 100644 index 00000000..91b70359 --- /dev/null +++ b/www/wiki/resources/src/jquery/jquery.accessKeyLabel.js @@ -0,0 +1,238 @@ +/** + * jQuery plugin to update the tooltip to show the correct access key + * + * @class jQuery.plugin.accessKeyLabel + */ +( function ( $, mw ) { + + // Cached access key modifiers for used browser + var cachedAccessKeyModifiers, + + // Whether to use 'test-' instead of correct prefix (used for testing) + useTestPrefix = false, + + // tag names which can have a label tag + // https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_categories#Form-associated_content + labelable = 'button, input, textarea, keygen, meter, output, progress, select'; + + /** + * Find the modifier keys that need to be pressed together with the accesskey to trigger the input. + * + * The result is dependant on the ua paramater or the current platform. + * For browsers that support accessKeyLabel, #getAccessKeyLabel never calls here. + * Valid key values that are returned can be: ctrl, alt, option, shift, esc + * + * @private + * @param {Object} [ua] An object with a 'userAgent' and 'platform' property. + * @return {Array} Array with 1 or more of the string values, in this order: ctrl, option, alt, shift, esc + */ + function getAccessKeyModifiers( ua ) { + var profile, accessKeyModifiers; + + // use cached prefix if possible + if ( !ua && cachedAccessKeyModifiers ) { + return cachedAccessKeyModifiers; + } + + profile = $.client.profile( ua ); + + switch ( profile.name ) { + case 'chrome': + case 'opera': + if ( profile.name === 'opera' && profile.versionNumber < 15 ) { + accessKeyModifiers = [ 'shift', 'esc' ]; + } else if ( profile.platform === 'mac' ) { + accessKeyModifiers = [ 'ctrl', 'option' ]; + } else { + // Chrome/Opera on Windows or Linux + // (both alt- and alt-shift work, but alt with E, D, F etc does not + // work since they are browser shortcuts) + accessKeyModifiers = [ 'alt', 'shift' ]; + } + break; + case 'firefox': + case 'iceweasel': + if ( profile.versionBase < 2 ) { + // Before v2, Firefox used alt, though it was rebindable in about:config + accessKeyModifiers = [ 'alt' ]; + } else { + if ( profile.platform === 'mac' ) { + if ( profile.versionNumber < 14 ) { + accessKeyModifiers = [ 'ctrl' ]; + } else { + accessKeyModifiers = [ 'ctrl', 'option' ]; + } + } else { + accessKeyModifiers = [ 'alt', 'shift' ]; + } + } + break; + case 'safari': + case 'konqueror': + if ( profile.platform === 'win' ) { + accessKeyModifiers = [ 'alt' ]; + } else { + if ( profile.layoutVersion > 526 ) { + // Non-Windows Safari with webkit_version > 526 + accessKeyModifiers = [ 'ctrl', profile.platform === 'mac' ? 'option' : 'alt' ]; + } else { + accessKeyModifiers = [ 'ctrl' ]; + } + } + break; + case 'msie': + case 'edge': + accessKeyModifiers = [ 'alt' ]; + break; + default: + accessKeyModifiers = profile.platform === 'mac' ? [ 'ctrl' ] : [ 'alt' ]; + break; + } + + // cache modifiers + if ( !ua ) { + cachedAccessKeyModifiers = accessKeyModifiers; + } + return accessKeyModifiers; + } + + /** + * Get the access key label for an element. + * + * Will use native accessKeyLabel if available (currently only in Firefox 8+), + * falls back to #getAccessKeyModifiers. + * + * @private + * @param {HTMLElement} element Element to get the label for + * @return {string} Access key label + */ + function getAccessKeyLabel( element ) { + // abort early if no access key + if ( !element.accessKey ) { + return ''; + } + // use accessKeyLabel if possible + // https://html.spec.whatwg.org/multipage/interaction.html#dom-accesskeylabel + if ( !useTestPrefix && element.accessKeyLabel ) { + return element.accessKeyLabel; + } + return ( useTestPrefix ? 'test' : getAccessKeyModifiers().join( '-' ) ) + '-' + element.accessKey; + } + + /** + * Update the title for an element (on the element with the access key or it's label) to show + * the correct access key label. + * + * @private + * @param {HTMLElement} element Element with the accesskey + * @param {HTMLElement} titleElement Element with the title to update (may be the same as `element`) + */ + function updateTooltipOnElement( element, titleElement ) { + var oldTitle, parts, regexp, newTitle, accessKeyLabel; + + oldTitle = titleElement.title; + if ( !oldTitle ) { + // don't add a title if the element didn't have one before + return; + } + + parts = ( mw.msg( 'word-separator' ) + mw.msg( 'brackets' ) ).split( '$1' ); + regexp = new RegExp( parts.map( mw.RegExp.escape ).join( '.*?' ) + '$' ); + newTitle = oldTitle.replace( regexp, '' ); + accessKeyLabel = getAccessKeyLabel( element ); + + if ( accessKeyLabel ) { + // Should be build the same as in Linker::titleAttrib + newTitle += mw.msg( 'word-separator' ) + mw.msg( 'brackets', accessKeyLabel ); + } + if ( oldTitle !== newTitle ) { + titleElement.title = newTitle; + } + } + + /** + * Update the title for an element to show the correct access key label. + * + * @private + * @param {HTMLElement} element Element with the accesskey + */ + function updateTooltip( element ) { + var id, $element, $label, $labelParent; + updateTooltipOnElement( element, element ); + + // update associated label if there is one + $element = $( element ); + if ( $element.is( labelable ) ) { + // Search it using 'for' attribute + id = element.id.replace( /"/g, '\\"' ); + if ( id ) { + $label = $( 'label[for="' + id + '"]' ); + if ( $label.length === 1 ) { + updateTooltipOnElement( element, $label[ 0 ] ); + } + } + + // Search it as parent, because the form control can also be inside the label element itself + $labelParent = $element.parents( 'label' ); + if ( $labelParent.length === 1 ) { + updateTooltipOnElement( element, $labelParent[ 0 ] ); + } + } + } + + /** + * Update the titles for all elements in a jQuery selection. + * + * @return {jQuery} + * @chainable + */ + $.fn.updateTooltipAccessKeys = function () { + return this.each( function () { + updateTooltip( this ); + } ); + }; + + /** + * getAccessKeyModifiers + * + * @method updateTooltipAccessKeys_getAccessKeyModifiers + * @inheritdoc #getAccessKeyModifiers + */ + $.fn.updateTooltipAccessKeys.getAccessKeyModifiers = getAccessKeyModifiers; + + /** + * getAccessKeyLabel + * + * @method updateTooltipAccessKeys_getAccessKeyLabel + * @inheritdoc #getAccessKeyLabel + */ + $.fn.updateTooltipAccessKeys.getAccessKeyLabel = getAccessKeyLabel; + + /** + * getAccessKeyPrefix + * + * @method updateTooltipAccessKeys_getAccessKeyPrefix + * @deprecated since 1.27 Use #getAccessKeyModifiers + * @param {Object} [ua] An object with a 'userAgent' and 'platform' property. + * @return {string} + */ + $.fn.updateTooltipAccessKeys.getAccessKeyPrefix = function ( ua ) { + return getAccessKeyModifiers( ua ).join( '-' ) + '-'; + }; + + /** + * Switch test mode on and off. + * + * @method updateTooltipAccessKeys_setTestMode + * @param {boolean} mode New mode + */ + $.fn.updateTooltipAccessKeys.setTestMode = function ( mode ) { + useTestPrefix = mode; + }; + + /** + * @class jQuery + * @mixins jQuery.plugin.accessKeyLabel + */ + +}( jQuery, mediaWiki ) ); |