Index: /trunk/src/wp-includes/class-wp-editor.php =================================================================== --- /trunk/src/wp-includes/class-wp-editor.php (revision 38896) +++ /trunk/src/wp-includes/class-wp-editor.php (revision 38897) @@ -27,4 +27,5 @@ private static $drag_drop_upload = false; private static $old_dfw_compat = false; + private static $translation; private function __construct() {} @@ -358,4 +359,11 @@ $no_captions = (bool) apply_filters( 'disable_captions', '' ); $ext_plugins = ''; + $shortcut_labels = array(); + + foreach ( self::get_translation() as $name => $value ) { + if ( is_array( $value ) ) { + $shortcut_labels[$name] = $value[1]; + } + } if ( $set['teeny'] ) { @@ -551,5 +559,6 @@ 'wpeditimage_html5_captions' => current_theme_supports( 'html5', 'caption' ), 'plugins' => implode( ',', $plugins ), - 'wp_lang_attr' => get_bloginfo( 'language' ) + 'wp_lang_attr' => get_bloginfo( 'language' ), + 'wp_shortcut_labels' => wp_json_encode( $shortcut_labels ), ); @@ -813,16 +822,7 @@ } - /** - * Translates the default TinyMCE strings and returns them as JSON encoded object ready to be loaded with tinymce.addI18n(). - * Can be used directly (_WP_Editors::wp_mce_translation()) by passing the same locale as set in the TinyMCE init object. - * - * @static - * @param string $mce_locale The locale used for the editor. - * @param bool $json_only optional Whether to include the JavaScript calls to tinymce.addI18n() and tinymce.ScriptLoader.markDone(). - * @return string Translation object, JSON encoded. - */ - public static function wp_mce_translation( $mce_locale = '', $json_only = false ) { - - $mce_translation = array( + private static function get_translation() { + if ( empty( self::$translation ) ) { + self::$translation = array( // Default TinyMCE strings 'New document' => __( 'New document' ), @@ -830,15 +830,15 @@ 'Headings' => _x( 'Headings', 'TinyMCE' ), - 'Heading 1' => __( 'Heading 1' ), - 'Heading 2' => __( 'Heading 2' ), - 'Heading 3' => __( 'Heading 3' ), - 'Heading 4' => __( 'Heading 4' ), - 'Heading 5' => __( 'Heading 5' ), - 'Heading 6' => __( 'Heading 6' ), + 'Heading 1' => array( __( 'Heading 1' ), 'access1' ), + 'Heading 2' => array( __( 'Heading 2' ), 'access2' ), + 'Heading 3' => array( __( 'Heading 3' ), 'access3' ), + 'Heading 4' => array( __( 'Heading 4' ), 'access4' ), + 'Heading 5' => array( __( 'Heading 5' ), 'access5' ), + 'Heading 6' => array( __( 'Heading 6' ), 'access6' ), /* translators: block tags */ 'Blocks' => _x( 'Blocks', 'TinyMCE' ), - 'Paragraph' => __( 'Paragraph' ), - 'Blockquote' => __( 'Blockquote' ), + 'Paragraph' => array( __( 'Paragraph' ), 'access7' ), + 'Blockquote' => array( __( 'Blockquote' ), 'accessQ' ), 'Div' => _x( 'Div', 'HTML tag' ), 'Pre' => _x( 'Pre', 'HTML tag' ), @@ -847,29 +847,29 @@ 'Inline' => _x( 'Inline', 'HTML elements' ), - 'Underline' => __( 'Underline' ), - 'Strikethrough' => __( 'Strikethrough' ), + 'Underline' => array( __( 'Underline' ), 'metaU' ), + 'Strikethrough' => array( __( 'Strikethrough' ), 'accessD' ), 'Subscript' => __( 'Subscript' ), 'Superscript' => __( 'Superscript' ), 'Clear formatting' => __( 'Clear formatting' ), - 'Bold' => __( 'Bold' ), - 'Italic' => __( 'Italic' ), - 'Code' => __( 'Code' ), + 'Bold' => array( __( 'Bold' ), 'metaB' ), + 'Italic' => array( __( 'Italic' ), 'metaI' ), + 'Code' => array( __( 'Code' ), 'accessX' ), 'Source code' => __( 'Source code' ), 'Font Family' => __( 'Font Family' ), 'Font Sizes' => __( 'Font Sizes' ), - 'Align center' => __( 'Align center' ), - 'Align right' => __( 'Align right' ), - 'Align left' => __( 'Align left' ), - 'Justify' => __( 'Justify' ), + 'Align center' => array( __( 'Align center' ), 'accessC' ), + 'Align right' => array( __( 'Align right' ), 'accessR' ), + 'Align left' => array( __( 'Align left' ), 'accessL' ), + 'Justify' => array( __( 'Justify' ), 'accessJ' ), 'Increase indent' => __( 'Increase indent' ), 'Decrease indent' => __( 'Decrease indent' ), - 'Cut' => __( 'Cut' ), - 'Copy' => __( 'Copy' ), - 'Paste' => __( 'Paste' ), - 'Select all' => __( 'Select all' ), - 'Undo' => __( 'Undo' ), - 'Redo' => __( 'Redo' ), + 'Cut' => array( __( 'Cut' ), 'metaX' ), + 'Copy' => array( __( 'Copy' ), 'metaC' ), + 'Paste' => array( __( 'Paste' ), 'metaV' ), + 'Select all' => array( __( 'Select all' ), 'metaA' ), + 'Undo' => array( __( 'Undo' ), 'metaZ' ), + 'Redo' => array( __( 'Redo' ), 'metaY' ), 'Ok' => __( 'OK' ), @@ -878,6 +878,6 @@ 'Visual aids' => __( 'Visual aids' ), - 'Bullet list' => __( 'Bulleted list' ), - 'Numbered list' => __( 'Numbered list' ), + 'Bullet list' => array( __( 'Bulleted list' ), 'accessU' ), + 'Numbered list' => array( __( 'Numbered list' ), 'accessO' ), 'Square' => _x( 'Square', 'list style' ), 'Default' => _x( 'Default', 'list style' ), @@ -905,5 +905,5 @@ // Media, image plugins - 'Insert/edit image' => __( 'Insert/edit image' ), + 'Insert/edit image' => array( __( 'Insert/edit image' ), 'accessM' ), 'General' => __( 'General' ), 'Advanced' => __( 'Advanced' ), @@ -939,6 +939,6 @@ 'Horizontal space' => __( 'Horizontal space' ), 'Restore last draft' => __( 'Restore last draft' ), - 'Insert/edit link' => __( 'Insert/edit link' ), - 'Remove link' => __( 'Remove link' ), + 'Insert/edit link' => array( __( 'Insert/edit link' ), 'metaK' ), + 'Remove link' => array( __( 'Remove link' ), 'accessS' ), 'Color' => __( 'Color' ), @@ -1044,9 +1044,9 @@ // WordPress strings - 'Toolbar Toggle' => __( 'Toolbar Toggle' ), - 'Insert Read More tag' => __( 'Insert Read More tag' ), - 'Insert Page Break tag' => __( 'Insert Page Break tag' ), + 'Toolbar Toggle' => array( __( 'Toolbar Toggle' ), 'accessZ' ), + 'Insert Read More tag' => array( __( 'Insert Read More tag' ), 'accessT' ), + 'Insert Page Break tag' => array( __( 'Insert Page Break tag' ), 'accessP' ), 'Read more...' => __( 'Read more...' ), // Title on the placeholder inside the editor (no ellipsis) - 'Distraction-free writing mode' => __( 'Distraction-free writing mode' ), + 'Distraction-free writing mode' => array( __( 'Distraction-free writing mode' ), 'accessW' ), 'No alignment' => __( 'No alignment' ), // Tooltip for the 'alignnone' button in the image toolbar 'Remove' => __( 'Remove' ), // Tooltip for the 'remove' button in the image toolbar @@ -1057,5 +1057,5 @@ // Shortcuts help modal - 'Keyboard Shortcuts' => __( 'Keyboard Shortcuts' ), + 'Keyboard Shortcuts' => array( __( 'Keyboard Shortcuts' ), 'accessH' ), 'Default shortcuts,' => __( 'Default shortcuts,' ), 'Additional shortcuts,' => __( 'Additional shortcuts,' ), @@ -1080,5 +1080,6 @@ 'The next group of formatting shortcuts are applied as you type or when you insert them around plain text in the same paragraph. Press Escape or the Undo button to undo.' => __( 'The next group of formatting shortcuts are applied as you type or when you insert them around plain text in the same paragraph. Press Escape or the Undo button to undo.' ), - ); + ); + } /** @@ -1093,6 +1094,27 @@ */ + return self::$translation; + } + + /** + * Translates the default TinyMCE strings and returns them as JSON encoded object ready to be loaded with tinymce.addI18n(). + * Can be used directly (_WP_Editors::wp_mce_translation()) by passing the same locale as set in the TinyMCE init object. + * + * @static + * @param string $mce_locale The locale used for the editor. + * @param bool $json_only optional Whether to include the JavaScript calls to tinymce.addI18n() and tinymce.ScriptLoader.markDone(). + * @return string Translation object, JSON encoded. + */ + public static function wp_mce_translation( $mce_locale = '', $json_only = false ) { if ( ! $mce_locale ) { $mce_locale = self::$mce_locale; + } + + $mce_translation = self::get_translation(); + + foreach ( $mce_translation as $name => $value ) { + if ( is_array( $value ) ) { + $mce_translation[$name] = $value[0]; + } } Index: /trunk/src/wp-includes/css/editor.css =================================================================== --- /trunk/src/wp-includes/css/editor.css (revision 38896) +++ /trunk/src/wp-includes/css/editor.css (revision 38897) @@ -589,4 +589,5 @@ .mce-menu .mce-menu-item-preview.mce-active { background: #0073aa; /* See color scheme. */ + color: #fff; } @@ -649,4 +650,13 @@ .mce-menu-has-icons i.mce-ico:before { margin-left: -2px; +} + +/* Keyboard shortcuts position */ +.mce-menu.mce-menu-align .mce-menu-item-normal { + position: relative; +} + +.mce-menu.mce-menu-align .mce-menu-shortcut { + bottom: 0.5em; } Index: /trunk/src/wp-includes/js/tinymce/plugins/wordpress/plugin.js =================================================================== --- /trunk/src/wp-includes/js/tinymce/plugins/wordpress/plugin.js (revision 38896) +++ /trunk/src/wp-includes/js/tinymce/plugins/wordpress/plugin.js (revision 38897) @@ -232,44 +232,71 @@ table1 = [], table2 = [], + row1 = {}, + row2 = {}, + i1 = 0, + i2 = 0, + labels = editor.settings.wp_shortcut_labels, header, html, dialog, $wrap; - each( [ - { c: 'Copy', x: 'Cut' }, - { v: 'Paste', a: 'Select all' }, - { z: 'Undo', y: 'Redo' }, - { b: 'Bold', i: 'Italic' }, - { u: 'Underline', k: 'Insert/edit link' } - ], function( row ) { - table1.push( tr( row ) ); + if ( ! labels ) { + return; + } + + function tr( row, columns ) { + var out = '