From: umherirrender Date: Tue, 22 Apr 2014 12:16:45 +0000 (+0200) Subject: Add jquery.accessKeyLabel javascript module X-Git-Tag: 1.31.0-rc.0~16005^2 X-Git-Url: https://git.cyclocoop.org/admin/?a=commitdiff_plain;h=6a81b0e53836cf72d54fc3ceb4059f8ecb9aa51e;p=lhc%2Fweb%2Fwiklou.git Add jquery.accessKeyLabel javascript module Extracted the accessKey logic from mediawiki.util and moved it to it's own module. mediawiki.util now depends on the new module, moved the jquery.client dependency from mediawiki.util to the new module. Now the accesskey is also set, when no placeholder like '[x]' is set on the title (bug 48505). Also the label for a input or textarea (and some other elements) gets updated (bug 63849). Also implements support for the browsers accessKeyLabel function (bug 37239), which will give a localised accessKey string, if supported (at the moment FireFox 8+ only) Bug: 37239 Bug: 48505 Bug: 63849 Change-Id: I211593629ca23540dcd5a93b11834155f4f04883 --- diff --git a/maintenance/jsduck/config.json b/maintenance/jsduck/config.json index 493815eba7..c47377266d 100644 --- a/maintenance/jsduck/config.json +++ b/maintenance/jsduck/config.json @@ -15,6 +15,7 @@ "../../resources/src/mediawiki.page/mediawiki.page.watch.ajax.js", "../../resources/src/mediawiki.api", "../../resources/src/mediawiki.language", + "../../resources/src/jquery/jquery.accessKeyLabel.js", "../../resources/src/jquery/jquery.arrowSteps.js", "../../resources/src/jquery/jquery.autoEllipsis.js", "../../resources/src/jquery/jquery.badge.js", diff --git a/resources/Resources.php b/resources/Resources.php index a3c427e0d5..3433a234ef 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -185,6 +185,12 @@ return array( /* jQuery Plugins */ + 'jquery.accessKeyLabel' => array( + 'scripts' => 'resources/src/jquery/jquery.accessKeyLabel.js', + 'dependencies' => array( + 'jquery.client', + ), + ), 'jquery.appear' => array( 'scripts' => 'resources/lib/jquery/jquery.appear.js', ), @@ -897,7 +903,7 @@ return array( 'mediawiki.util' => array( 'scripts' => 'resources/src/mediawiki/mediawiki.util.js', 'dependencies' => array( - 'jquery.client', + 'jquery.accessKeyLabel', 'jquery.mwExtension', 'mediawiki.notify', ), diff --git a/resources/src/jquery/jquery.accessKeyLabel.js b/resources/src/jquery/jquery.accessKeyLabel.js new file mode 100644 index 0000000000..40a0f653c0 --- /dev/null +++ b/resources/src/jquery/jquery.accessKeyLabel.js @@ -0,0 +1,195 @@ +/** + * jQuery plugin to update the tooltip to show the correct access key + * + * @class jQuery.plugin.accessKeyLabel + */ +( function ( $ ) { + +// Cached access key prefix for used browser +var cachedAccessKeyPrefix, + + // Wether 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'; + +/** + * Get the prefix for the access key. + * Will only give correct prefix for browsers not implementing the accessKeyLabel property. + * These browsers currently are: + * Firefox 8+ + * + * Exposed for testing. + * + * @private + * @param {Object} ua An object with atleast a 'userAgent' and 'platform' key. + * Defaults to the global Navigator object. + * @return {string} Access key prefix + */ +function getAccessKeyPrefix( ua ) { + // use cached prefix if possible + if ( !ua && cachedAccessKeyPrefix ) { + return cachedAccessKeyPrefix; + } + + var profile = $.client.profile( ua ), + accessKeyPrefix = 'alt-'; + + // Opera on any platform + if ( profile.name === 'opera' ) { + accessKeyPrefix = 'shift-esc-'; + + // Chrome on any platform + } else if ( profile.name === 'chrome' ) { + accessKeyPrefix = ( + profile.platform === 'mac' + // Chrome on Mac + ? 'ctrl-option-' + // Chrome 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) + : 'alt-shift-' + ); + + // Non-Windows Safari with webkit_version > 526 + } else if ( profile.platform !== 'win' + && profile.name === 'safari' + && profile.layoutVersion > 526 + ) { + accessKeyPrefix = 'ctrl-alt-'; + + // Safari/Konqueror on any platform, or any browser on Mac + // (but not Safari on Windows) + } else if ( !( profile.platform === 'win' && profile.name === 'safari' ) + && ( profile.name === 'safari' + || profile.platform === 'mac' + || profile.name === 'konqueror' ) + ) { + accessKeyPrefix = 'ctrl-'; + + // Firefox/Iceweasel 2.x and later + } else if ( ( profile.name === 'firefox' || profile.name === 'iceweasel' ) + && profile.versionBase > '1' + ) { + accessKeyPrefix = 'alt-shift-'; + } + + // cache prefix + if ( !ua ) { + cachedAccessKeyPrefix = accessKeyPrefix; + } + return accessKeyPrefix; +} + +/** + * Get the access key label for an element. + * + * @private + * @param {HTMLElement} domElement DOM element to get the label for + * @return {string} Access key label + */ +function getAccessKeyLabel( domElement ) { + // abort early if no access key + if ( !domElement.accessKey ) { + return ''; + } + // use accessKeyLabel if possible + // http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#dom-accesskeylabel + if ( !useTestPrefix && domElement.accessKeyLabel ) { + return domElement.accessKeyLabel; + } + return ( useTestPrefix ? 'test-' : getAccessKeyPrefix() ) + domElement.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} domElement DOM element with the accesskey + * @param {HTMLElement} titleElement DOM element with the title to update + */ +function updateTooltipOnElement( domElement, titleElement ) { + var oldTitle = titleElement.title, + rawTitle = oldTitle.replace( / \[.*?\]$/, '' ), + newTitle = rawTitle, + accessKeyLabel = getAccessKeyLabel( domElement ); + + // don't add a title if the element didn't have one before + if ( !oldTitle ) { + return; + } + + if ( accessKeyLabel ) { + newTitle += ' [' + accessKeyLabel + ']'; + } + if ( oldTitle !== newTitle ) { + titleElement.title = newTitle; + } +} + +/** + * Update the title for an element to show the correct access key label. + * + * @private + * @param {HTMLElement} domElement DOM element with the accesskey + */ +function updateTooltip( domElement ) { + var id, $domElement, $label, $labelParent; + updateTooltipOnElement( domElement, domElement ); + + // update associated label if there is one + $domElement = $( domElement ); + if ( $domElement.is( labelable ) ) { + // Search it using 'for' attribute + id = domElement.id.replace( /"/g, '\\"' ); + if ( id ) { + $label = $( 'label[for="' + id + '"]' ); + if ( $label.length === 1 ) { + updateTooltipOnElement( domElement, $label[0] ); + } + } + + // Search it as parent, because the form control can also inside the label element itself + $labelParent = $domElement.parents( 'label' ); + if ( $labelParent.length === 1 ) { + updateTooltipOnElement( domElement, $labelParent[0] ); + } + } +} + +/** + * Update the titles for all elements in a jQuery selection. + * + * @return {jQuery} + * @chainable + */ +$.fn.updateTooltipAccessKeys = function () { + return this.each( function () { + updateTooltip( this ); + } ); +}; + +/** + * @method updateTooltipAccessKeys_getAccessKeyPrefix + * @inheritdoc #getAccessKeyPrefix + */ +$.fn.updateTooltipAccessKeys.getAccessKeyPrefix = getAccessKeyPrefix; + +/** + * 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 ) ); diff --git a/resources/src/mediawiki/mediawiki.util.js b/resources/src/mediawiki/mediawiki.util.js index a5bc7d9b24..b68575dff2 100644 --- a/resources/src/mediawiki/mediawiki.util.js +++ b/resources/src/mediawiki/mediawiki.util.js @@ -170,80 +170,6 @@ return null; }, - /** - * @property {string} - * Access key prefix. - */ - tooltipAccessKeyPrefix: ( function () { - var profile = $.client.profile(); - - // Opera on any platform - if ( profile.name === 'opera' ) { - return 'shift-esc-'; - } - - // Chrome on any platform - if ( profile.name === 'chrome' ) { - if ( profile.platform === 'mac' ) { - // Chrome on Mac - return 'ctrl-option-'; - } - // Chrome 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) - return 'alt-shift-'; - } - - // Non-Windows Safari with webkit_version > 526 - if ( profile.platform !== 'win' - && profile.name === 'safari' - && profile.layoutVersion > 526 - ) { - return 'ctrl-alt-'; - } - - // Firefox 14+ on Mac - if ( profile.platform === 'mac' - && profile.name === 'firefox' - && profile.versionNumber >= 14 - ) { - return 'ctrl-option-'; - } - - // Safari/Konqueror on any platform, or any browser on Mac - // (but not Safari on Windows) - if ( !( profile.platform === 'win' && profile.name === 'safari' ) - && ( profile.name === 'safari' - || profile.platform === 'mac' - || profile.name === 'konqueror' ) - ) { - return 'ctrl-'; - } - - // Firefox/Iceweasel 2.x and later - if ( ( profile.name === 'firefox' || profile.name === 'iceweasel' ) - && profile.versionBase > '1' ) { - return 'alt-shift-'; - } - - return 'alt-'; - } )(), - - /** - * @property {RegExp} - * Regex to match accesskey tooltips. - * - * Should match: - * - * - "ctrl-option-" - * - "alt-shift-" - * - "ctrl-alt-" - * - "ctrl-" - * - * The accesskey is matched in group $6. - */ - tooltipAccessKeyRegexp: /\[(ctrl-)?(option-)?(alt-)?(shift-)?(esc-)?(.)\]$/, - /** * Add the appropriate prefix to the accesskey shown in the tooltip. * @@ -273,13 +199,7 @@ $nodes = $( $nodes ); } - $nodes.attr( 'title', function ( i, val ) { - if ( val && util.tooltipAccessKeyRegexp.test( val ) ) { - return val.replace( util.tooltipAccessKeyRegexp, - '[' + util.tooltipAccessKeyPrefix + '$6]' ); - } - return val; - } ); + $nodes.updateTooltipAccessKeys(); }, /* @@ -380,22 +300,14 @@ $item.attr( 'id', id ); } - if ( tooltip ) { - // Trim any existing accesskey hint and the trailing space - tooltip = $.trim( tooltip.replace( util.tooltipAccessKeyRegexp, '' ) ); - if ( accesskey ) { - tooltip += ' [' + accesskey + ']'; - } - $link.attr( 'title', tooltip ); - if ( accesskey ) { - util.updateTooltipAccessKeys( $link ); - } - } - if ( accesskey ) { $link.attr( 'accesskey', accesskey ); } + if ( tooltip ) { + $link.attr( 'title', tooltip ).updateTooltipAccessKeys(); + } + if ( nextnode ) { if ( nextnode.nodeType || typeof nextnode === 'string' ) { // nextnode is a DOM element (was the only option before MW 1.17, in wikibits.js) @@ -572,6 +484,32 @@ */ mw.log.deprecate( util, 'wikiGetlink', util.getUrl, 'Use mw.util.getUrl instead.' ); + /** + * @property {string} tooltipAccessKeyPrefix + * Access key prefix. Might be wrong for browsers implementing the accessKeyLabel property. + * @deprecated since 1.23 Use the module jquery.accessKeyLabel instead. + */ + mw.log.deprecate( util, 'tooltipAccessKeyPrefix', $.fn.updateTooltipAccessKeys.getAccessKeyPrefix(), 'Use jquery.accessKeyLabel instead.' ); + + /** + * @property {RegExp} tooltipAccessKeyRegexp + * Regex to match accesskey tooltips. + * + * Should match: + * + * - "ctrl-option-" + * - "alt-shift-" + * - "ctrl-alt-" + * - "ctrl-" + * + * The accesskey is matched in group $6. + * + * Will probably not work for browsers implementing the accessKeyLabel property. + * + * @deprecated since 1.23 Use the module jquery.accessKeyLabel instead. + */ + mw.log.deprecate( util, 'tooltipAccessKeyRegexp', /\[(ctrl-)?(option-)?(alt-)?(shift-)?(esc-)?(.)\]$/, 'Use jquery.accessKeyLabel instead.' ); + mw.util = util; }( mediaWiki, jQuery ) ); diff --git a/tests/qunit/QUnitTestResources.php b/tests/qunit/QUnitTestResources.php index cb9fa07402..e861967e11 100644 --- a/tests/qunit/QUnitTestResources.php +++ b/tests/qunit/QUnitTestResources.php @@ -44,6 +44,7 @@ return array( 'test.mediawiki.qunit.suites' => array( 'scripts' => array( 'tests/qunit/suites/resources/startup.test.js', + 'tests/qunit/suites/resources/jquery/jquery.accessKeyLabel.test.js', 'tests/qunit/suites/resources/jquery/jquery.autoEllipsis.test.js', 'tests/qunit/suites/resources/jquery/jquery.byteLength.test.js', 'tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js', @@ -77,6 +78,7 @@ return array( 'tests/qunit/suites/resources/mediawiki/mediawiki.cldr.test.js', ), 'dependencies' => array( + 'jquery.accessKeyLabel', 'jquery.autoEllipsis', 'jquery.byteLength', 'jquery.byteLimit', diff --git a/tests/qunit/suites/resources/jquery/jquery.accessKeyLabel.test.js b/tests/qunit/suites/resources/jquery/jquery.accessKeyLabel.test.js new file mode 100644 index 0000000000..d5c5d27e3b --- /dev/null +++ b/tests/qunit/suites/resources/jquery/jquery.accessKeyLabel.test.js @@ -0,0 +1,103 @@ +( function ( $ ) { + QUnit.module( 'jquery.accessKeyLabel', QUnit.newMwEnvironment() ); + + var getAccessKeyPrefixTestData = [ + //ua string, platform string, expected prefix + // Internet Explorer + ['Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)', 'Win32', 'alt-'], + ['Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)', 'Win32', 'alt-'], + ['Mozilla/5.0 (Windows NT 6.3; Win64; x64; Trident/7.0; rv:11.0) like Gecko', 'Win64', 'alt-'], + // Firefox + ['Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1.19) Gecko/20110420 Firefox/3.5.19', 'MacIntel', 'ctrl-'], + ['Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110422 Ubuntu/10.10 (maverick) Firefox/3.6.17', 'Linux i686', 'alt-shift-'], + ['Mozilla/5.0 (Windows NT 6.0; rv:2.0.1) Gecko/20100101 Firefox/4.0.1', 'Win32', 'alt-shift-'], + // Safari / Konqueror + ['Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; nl-nl) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7', 'MacIntel', 'ctrl-alt-'], + ['Mozilla/5.0 (Windows; U; Windows NT 6.0; cs-CZ) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7', 'Win32', 'alt-'], + ['Mozilla/5.0 (X11; Linux i686) KHTML/4.9.1 (like Gecko) Konqueror/4.9', 'Linux i686', 'ctrl-'], + // Opera + ['Opera/9.80 (Windows NT 5.1)', 'Win32', 'shift-esc-'], + ['Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.52 Safari/537.36 OPR/15.0.1147.130', 'Win32', 'shift-esc-'], + // Chrome + ['Mozilla/5.0 (Macintosh; Intel Mac OS X 10_5_8) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.112 Safari/534.30', 'MacIntel', 'ctrl-option-'], + ['Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.68 Safari/534.30', 'Linux i686', 'alt-shift-'] + ], + //strings appended to title to make sure updateTooltipAccessKeys handles them correctly + updateTooltipAccessKeysTestData = [ '', ' [a]', ' [test-a]', ' [alt-b]' ]; + + function makeInput ( title, accessKey ) { + //The properties aren't escaped, so make sure you don't call this function with values that need to be escaped! + return ''; + } + + QUnit.test( 'getAccessKeyPrefix', getAccessKeyPrefixTestData.length, function ( assert ) { + var i; + for ( i = 0; i < getAccessKeyPrefixTestData.length; i++ ) { + assert.equal( $.fn.updateTooltipAccessKeys.getAccessKeyPrefix( { + userAgent: getAccessKeyPrefixTestData[i][0], + platform: getAccessKeyPrefixTestData[i][1] + } ), getAccessKeyPrefixTestData[i][2], 'Correct prefix for ' + getAccessKeyPrefixTestData[i][0] ); + } + } ); + + QUnit.test( 'updateTooltipAccessKeys - current browser', 2, function ( assert ) { + var title = $( makeInput ( 'Title', 'a' ) ).updateTooltipAccessKeys().prop( 'title' ), + //The new title should be something like "Title [alt-a]", but the exact label will depend on the browser. + //The "a" could be capitalized, and the prefix could be anything, e.g. a simple "^" for ctrl- + //(no browser is known using such a short prefix, though) or "Alt+Umschalt+" in German Firefox. + result = /^Title \[(.+)[aA]\]$/.exec( title ); + assert.ok( result, 'title should match expected structure.' ); + assert.notEqual( result[1], 'test-', 'Prefix used for testing shouldn\'t be used in production.' ); + } ); + + QUnit.test( 'updateTooltipAccessKeys - no access key', updateTooltipAccessKeysTestData.length, function ( assert ) { + var i, oldTitle, $input, newTitle; + for ( i = 0; i < updateTooltipAccessKeysTestData.length; i++ ) { + oldTitle = 'Title' + updateTooltipAccessKeysTestData[i]; + $input = $( makeInput( oldTitle ) ); + $( '#qunit-fixture' ).append( $input ); + newTitle = $input.updateTooltipAccessKeys().prop( 'title' ); + assert.equal( newTitle, 'Title', 'title="' + oldTitle + '"' ); + } + } ); + + QUnit.test( 'updateTooltipAccessKeys - with access key', updateTooltipAccessKeysTestData.length, function ( assert ) { + $.fn.updateTooltipAccessKeys.setTestMode( true ); + var i, oldTitle, $input, newTitle; + for ( i = 0; i < updateTooltipAccessKeysTestData.length; i++ ) { + oldTitle = 'Title' + updateTooltipAccessKeysTestData[i]; + $input = $( makeInput( oldTitle, 'a' ) ); + $( '#qunit-fixture' ).append( $input ); + newTitle = $input.updateTooltipAccessKeys().prop( 'title' ); + assert.equal( newTitle, 'Title [test-a]', 'title="' + oldTitle + '"' ); + } + $.fn.updateTooltipAccessKeys.setTestMode( false ); + } ); + + QUnit.test( 'updateTooltipAccessKeys with label element', 2, function ( assert ) { + $.fn.updateTooltipAccessKeys.setTestMode( true ); + var html = '', + $label, $input; + $( '#qunit-fixture' ).html( html ); + $label = $( '#qunit-fixture label' ); + $input = $( '#qunit-fixture input' ); + $input.updateTooltipAccessKeys(); + assert.equal( $input.prop( 'title' ), '', 'No title attribute added to input element.' ); + assert.equal( $label.prop( 'title' ), 'Title [test-a]', 'title updated for associated label element.' ); + $.fn.updateTooltipAccessKeys.setTestMode( false ); + } ); + + QUnit.test( 'updateTooltipAccessKeys with label element as parent', 2, function ( assert ) { + $.fn.updateTooltipAccessKeys.setTestMode( true ); + var html = '', + $label, $input; + $( '#qunit-fixture' ).html( html ); + $label = $( '#qunit-fixture label' ); + $input = $( '#qunit-fixture input' ); + $input.updateTooltipAccessKeys(); + assert.equal( $input.prop( 'title' ), '', 'No title attribute added to input element.' ); + assert.equal( $label.prop( 'title' ), 'Title [test-a]', 'title updated for associated label element.' ); + $.fn.updateTooltipAccessKeys.setTestMode( false ); + } ); + +}( jQuery ) ); diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js index 9707ab9eb1..1e059e1f1c 100644 --- a/tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js +++ b/tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js @@ -1,11 +1,10 @@ ( function ( mw, $ ) { QUnit.module( 'mediawiki.util', QUnit.newMwEnvironment( { setup: function () { - this.taPrefix = mw.util.tooltipAccessKeyPrefix; - mw.util.tooltipAccessKeyPrefix = 'ctrl-alt-'; + $.fn.updateTooltipAccessKeys.setTestMode( true ); }, teardown: function () { - mw.util.tooltipAccessKeyPrefix = this.taPrefix; + $.fn.updateTooltipAccessKeys.setTestMode( false ); } } ) ); @@ -89,6 +88,8 @@ } ); QUnit.test( 'tooltipAccessKey', 4, function ( assert ) { + this.suppressWarnings(); + assert.equal( typeof mw.util.tooltipAccessKeyPrefix, 'string', 'tooltipAccessKeyPrefix must be a string' ); assert.equal( $.type( mw.util.tooltipAccessKeyRegexp ), 'regexp', 'tooltipAccessKeyRegexp is a regexp' ); assert.ok( mw.util.updateTooltipAccessKeys, 'updateTooltipAccessKeys is non-empty' ); @@ -96,6 +97,8 @@ 'Example [a]'.replace( mw.util.tooltipAccessKeyRegexp, function ( sub, m1, m2, m3, m4, m5, m6 ) { assert.equal( m6, 'a', 'tooltipAccessKeyRegexp finds the accesskey hint' ); } ); + + this.restoreWarnings(); } ); QUnit.test( '$content', 2, function ( assert ) { @@ -145,7 +148,7 @@ assert.ok( $.isDomElement( tbRL ), 'addPortletLink returns a valid DOM Element according to $.isDomElement' ); tbMW = mw.util.addPortletLink( 'p-test-tb', '//mediawiki.org/', - 'MediaWiki.org', 't-mworg', 'Go to MediaWiki.org ', 'm', tbRL ); + 'MediaWiki.org', 't-mworg', 'Go to MediaWiki.org', 'm', tbRL ); $tbMW = $( tbMW ); assert.propEqual( @@ -160,7 +163,7 @@ $tbMW.find( 'a' ).getAttrs(), { href: '//mediawiki.org/', - title: 'Go to MediaWiki.org [ctrl-alt-m]', + title: 'Go to MediaWiki.org [test-m]', accesskey: 'm' }, 'Validate attributes of anchor tag in created element' @@ -172,7 +175,7 @@ cuQuux = mw.util.addPortletLink( 'p-test-custom', '#', 'Quux', null, 'Example [shift-x]', 'q' ); $cuQuux = $( cuQuux ); - assert.equal( $cuQuux.find( 'a' ).attr( 'title' ), 'Example [ctrl-alt-q]', 'Existing accesskey is stripped and updated' ); + assert.equal( $cuQuux.find( 'a' ).attr( 'title' ), 'Example [test-q]', 'Existing accesskey is stripped and updated' ); assert.equal( $( '#p-test-custom #c-barmenu ul li' ).length,