TinyMCE, inline link:

- Add audible confirmation when a link has been selected or inserted in the editor for both the inline dialog and the modal.
- Do not auto-search when the URL field is empty or already contains an URL.
- Remove a few redundant `tabindex`.

Props afercia, azaozz.
See #33301.

git-svn-id: https://develop.svn.wordpress.org/trunk@36984 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Andrew Ozz 2016-03-14 00:52:20 +00:00
parent 8f8b1001ad
commit bdbd792bfe
3 changed files with 85 additions and 27 deletions

View File

@ -56,7 +56,7 @@
renderHtml: function() {
return (
'<div id="' + this._id + '" class="wp-link-input">' +
'<input type="text" value="" tabindex="-1" placeholder="' + tinymce.translate('Paste URL or type to search') + '" />' +
'<input type="text" value="" placeholder="' + tinymce.translate( 'Paste URL or type to search' ) + '" />' +
'<input type="text" style="display:none" value="" />' +
'</div>'
);
@ -235,6 +235,11 @@
inputInstance.reset();
editor.nodeChanged();
// Audible confirmation message when a link has been inserted in the Editor.
if ( typeof window.wp !== 'undefined' && window.wp.a11y && typeof window.wpLinkL10n !== 'undefined' ) {
window.wp.a11y.speak( window.wpLinkL10n.linkInserted );
}
} );
editor.addCommand( 'wp_link_cancel', function() {
@ -371,11 +376,22 @@
},
focus: function( event, ui ) {
$input.attr( 'aria-activedescendant', 'mce-wp-autocomplete-' + ui.item.ID );
/*
* Don't empty the URL input field, when using the arrow keys to
* highlight items. See api.jqueryui.com/autocomplete/#event-focus
*/
event.preventDefault();
},
select: function( event, ui ) {
$input.val( ui.item.permalink );
$( element.firstChild.nextSibling ).val( ui.item.title );
if ( 9 === event.keyCode && typeof window.wp !== 'undefined' &&
window.wp.a11y && typeof window.wpLinkL10n !== 'undefined' ) {
// Audible confirmation message when a link has been selected.
window.wp.a11y.speak( window.wpLinkL10n.linkSelected );
}
return false;
},
open: function() {
@ -413,13 +429,21 @@
'aria-autocomplete': 'list',
'aria-expanded': 'false',
'aria-owns': $input.autocomplete( 'widget' ).attr( 'id' )
} )
} )
.on( 'focus', function() {
$input.autocomplete( 'search' );
var inputValue = $input.val();
/*
* Don't trigger a search if the URL field already has a link or is empty.
* Also, avoids screen readers announce `No search results`.
*/
if ( inputValue && ! /^https?:/.test( inputValue ) ) {
$input.autocomplete( 'search' );
}
} )
.autocomplete( 'widget' )
.addClass( 'wplink-autocomplete' )
.attr( 'role', 'listbox' );
.attr( 'role', 'listbox' )
.removeAttr( 'tabindex' ); // Remove the `tabindex=0` attribute added by jQuery UI.
}
tinymce.$( input ).on( 'keydown', function( event ) {
@ -483,7 +507,20 @@
var url = inputInstance.getURL() || null,
text = inputInstance.getLinkText() || null;
editor.focus(); // Needed for IE
/*
* Accessibility note: moving focus back to the editor confuses
* screen readers. They will announce again the Editor ARIA role
* `application` and the iframe `title` attribute.
*
* Unfortunately IE looses the selection when the editor iframe
* looses focus, so without returning focus to the editor, the code
* in the modal will not be able to get the selection, place the caret
* at the same location, etc.
*/
if ( tinymce.Env.ie ) {
editor.focus(); // Needed for IE
}
window.wpLink.open( editor.id, url, text, linkNode );
editToolbar.tempHide = true;

View File

@ -1,7 +1,7 @@
var wpLink;
( function( $, wpLinkL10n ) {
( function( $, wpLinkL10n, wp ) {
var editor, correctedURL, linkNode,
inputs = {},
isTouch = ( 'ontouchend' in document );
@ -76,6 +76,10 @@ var wpLink;
},
focus: function( event, ui ) {
$input.attr( 'aria-activedescendant', 'mce-wp-autocomplete-' + ui.item.ID );
/*
* Don't empty the URL input field, when using the arrow keys to
* highlight items. See api.jqueryui.com/autocomplete/#event-focus
*/
event.preventDefault();
},
select: function( event, ui ) {
@ -85,6 +89,9 @@ var wpLink;
inputs.text.val( ui.item.title );
}
// Audible confirmation message when a link has been selected.
wp.a11y.speak( wpLinkL10n.linkSelected );
return false;
},
open: function() {
@ -117,15 +124,21 @@ var wpLink;
$input.attr( {
'aria-owns': $input.autocomplete( 'widget' ).attr( 'id' )
} )
} )
.on( 'focus', function() {
$input.autocomplete( 'search' );
var inputValue = $input.val();
/*
* Don't trigger a search if the URL field already has a link or is empty.
* Also, avoids screen readers announce `No search results`.
*/
if ( inputValue && ! /^https?:/.test( inputValue ) ) {
$input.autocomplete( 'search' );
}
} )
.autocomplete( 'widget' )
.addClass( 'wplink-autocomplete' )
.attr( 'role', 'listbox' );
.attr( 'role', 'listbox' )
.removeAttr( 'tabindex' ); // Remove the `tabindex=0` attribute added by jQuery UI.
},
// If URL wasn't corrected last time and doesn't start with http:, https:, ? # or /, prepend http://
@ -170,7 +183,7 @@ var wpLink;
editor = null;
}
if ( editor && window.tinymce.isIE && ! editor.windowManager.wplinkBookmark ) {
if ( editor && window.tinymce.isIE ) {
editor.windowManager.wplinkBookmark = editor.selection.getBookmark();
}
}
@ -402,6 +415,9 @@ var wpLink;
wpLink.close();
textarea.focus();
// Audible confirmation message when a link has been inserted in the Editor.
wp.a11y.speak( wpLinkL10n.linkInserted );
},
mceUpdate: function() {
@ -450,6 +466,9 @@ var wpLink;
wpLink.close( 'noReset' );
editor.focus();
editor.nodeChanged();
// Audible confirmation message when a link has been inserted in the Editor.
wp.a11y.speak( wpLinkL10n.linkInserted );
},
keydown: function( event ) {
@ -511,4 +530,4 @@ var wpLink;
};
$( document ).ready( wpLink.init );
})( jQuery, window.wpLinkL10n );
})( jQuery, window.wpLinkL10n, window.wp );

View File

@ -204,7 +204,7 @@ function wp_default_scripts( &$scripts ) {
$scripts->add( 'jquery-effects-transfer', "/wp-includes/js/jquery/ui/effect-transfer$dev_suffix.js", array('jquery-effects-core'), '1.11.4', 1 );
$scripts->add( 'jquery-ui-accordion', "/wp-includes/js/jquery/ui/accordion$dev_suffix.js", array('jquery-ui-core', 'jquery-ui-widget'), '1.11.4', 1 );
$scripts->add( 'jquery-ui-autocomplete', "/wp-includes/js/jquery/ui/autocomplete$dev_suffix.js", array('jquery-ui-menu'), '1.11.4', 1 );
$scripts->add( 'jquery-ui-autocomplete', "/wp-includes/js/jquery/ui/autocomplete$dev_suffix.js", array( 'jquery-ui-menu', 'wp-a11y' ), '1.11.4', 1 );
$scripts->add( 'jquery-ui-button', "/wp-includes/js/jquery/ui/button$dev_suffix.js", array('jquery-ui-core', 'jquery-ui-widget'), '1.11.4', 1 );
$scripts->add( 'jquery-ui-datepicker', "/wp-includes/js/jquery/ui/datepicker$dev_suffix.js", array('jquery-ui-core'), '1.11.4', 1 );
$scripts->add( 'jquery-ui-dialog', "/wp-includes/js/jquery/ui/dialog$dev_suffix.js", array('jquery-ui-resizable', 'jquery-ui-draggable', 'jquery-ui-button', 'jquery-ui-position'), '1.11.4', 1 );
@ -226,10 +226,10 @@ function wp_default_scripts( &$scripts ) {
// Strings for 'jquery-ui-autocomplete' live region messages
did_action( 'init' ) && $scripts->localize( 'jquery-ui-autocomplete', 'uiAutocompleteL10n', array(
'noResults' => __( 'No search results.' ),
/* translators: Number of results found when using jQuery UI Autocomplete */
'oneResult' => __( '1 result found. Use up and down arrow keys to navigate.' ),
'manyResults' => __( '%d results found. Use up and down arrow keys to navigate.' ),
'noResults' => __( 'No search results.' ),
/* translators: Number of results found when using jQuery UI Autocomplete */
'oneResult' => __( '1 result found. Use up and down arrow keys to navigate.' ),
'manyResults' => __( '%d results found. Use up and down arrow keys to navigate.' ),
) );
// deprecated, not used in core, most functionality is included in jQuery 1.3
@ -252,13 +252,13 @@ function wp_default_scripts( &$scripts ) {
$scripts->add( 'thickbox', "/wp-includes/js/thickbox/thickbox.js", array('jquery'), '3.1-20121105', 1 );
did_action( 'init' ) && $scripts->localize( 'thickbox', 'thickboxL10n', array(
'next' => __('Next &gt;'),
'prev' => __('&lt; Prev'),
'image' => __('Image'),
'of' => __('of'),
'close' => __('Close'),
'noiframes' => __('This feature requires inline frames. You have iframes disabled or your browser does not support them.'),
'loadingAnimation' => includes_url('js/thickbox/loadingAnimation.gif'),
'next' => __('Next &gt;'),
'prev' => __('&lt; Prev'),
'image' => __('Image'),
'of' => __('of'),
'close' => __('Close'),
'noiframes' => __('This feature requires inline frames. You have iframes disabled or your browser does not support them.'),
'loadingAnimation' => includes_url('js/thickbox/loadingAnimation.gif'),
) );
$scripts->add( 'jcrop', "/wp-includes/js/jcrop/jquery.Jcrop.min.js", array('jquery'), '0.9.12');
@ -401,13 +401,15 @@ function wp_default_scripts( &$scripts ) {
$scripts->add( 'admin-bar', "/wp-includes/js/admin-bar$suffix.js", array(), false, 1 );
$scripts->add( 'wplink', "/wp-includes/js/wplink$suffix.js", array( 'jquery' ), false, 1 );
$scripts->add( 'wplink', "/wp-includes/js/wplink$suffix.js", array( 'jquery', 'wp-a11y' ), false, 1 );
did_action( 'init' ) && $scripts->localize( 'wplink', 'wpLinkL10n', array(
'title' => __('Insert/edit link'),
'update' => __('Update'),
'save' => __('Add Link'),
'noTitle' => __('(no title)'),
'noMatchesFound' => __('No results found.')
'noMatchesFound' => __('No results found.'),
'linkSelected' => __( 'Link selected.' ),
'linkInserted' => __( 'Link inserted.' ),
) );
$scripts->add( 'wpdialogs', "/wp-includes/js/wpdialog$suffix.js", array( 'jquery-ui-dialog' ), false, 1 );