Editor: Provide API for the editor to be dynamically instantiated via JS. First run.

See: #35760
Built from https://develop.svn.wordpress.org/trunk@40476


git-svn-id: http://core.svn.wordpress.org/trunk@40352 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Andrew Ozz 2017-04-19 02:38:44 +00:00
parent c58cb3af9e
commit d0e4448257
10 changed files with 479 additions and 152 deletions

View File

@ -1497,7 +1497,10 @@ function wp_ajax_wp_link_ajax() {
$args['pagenum'] = ! empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1; $args['pagenum'] = ! empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1;
if ( ! class_exists( '_WP_Editors', false ) ) {
require( ABSPATH . WPINC . '/class-wp-editor.php' ); require( ABSPATH . WPINC . '/class-wp-editor.php' );
}
$results = _WP_Editors::wp_link_query( $args ); $results = _WP_Editors::wp_link_query( $args );
if ( ! isset( $results ) ) if ( ! isset( $results ) )

View File

@ -1,5 +1,8 @@
window.wp = window.wp || {};
( function( $, wp ) {
wp.editor = wp.editor || {};
( function( $ ) {
/** /**
* @summary Utility functions for the editor. * @summary Utility functions for the editor.
* *
@ -484,10 +487,8 @@
} ); } );
} }
window.wp = window.wp || {}; wp.editor.autop = wpautop;
window.wp.editor = window.wp.editor || {}; wp.editor.removep = pre_wpautop;
window.wp.editor.autop = wpautop;
window.wp.editor.removep = pre_wpautop;
exports = { exports = {
go: switchEditor, go: switchEditor,
@ -505,4 +506,143 @@
* Expose the switch editors to be used globally. * Expose the switch editors to be used globally.
*/ */
window.switchEditors = new SwitchEditors(); window.switchEditors = new SwitchEditors();
}( window.jQuery ));
/**
* Initialize TinyMCE and/or Quicktags. For use with wp_enqueue_editor() (PHP).
*
* Intended for use with an existing textarea that will become the Text editor tab.
* The editor width will be the width of the textarea container, height will be adjustable.
*
* Settings for both TinyMCE and Quicktags can be passed on initialization, and are "filtered"
* with custom jQuery events on the document element, wp-before-tinymce-init and wp-before-quicktags-init.
*
* @since 4.8
*
* @param {string} id The HTML id of the textarea that is used for the editor.
* Has to be jQuery compliant. No brackets, special chars, etc.
* @param {object} settings Example:
* settings = {
* // See https://www.tinymce.com/docs/configure/integration-and-setup/.
* // Alternatively set to `true` to use the defaults.
* tinymce: {
* setup: function( editor ) {
* console.log( 'Editor initialized', editor );
* }
* }
*
* // Alternatively set to `true` to use the defaults.
* quicktags: {
* buttons: 'strong,em,link'
* }
* }
*/
wp.editor.initialize = function( id, settings ) {
var init;
var defaults;
if ( ! $ || ! id || ! wp.editor.getDefaultSettings ) {
return;
}
defaults = wp.editor.getDefaultSettings();
// Initialize TinyMCE by default
if ( ! settings ) {
settings = {
tinymce: true
};
}
// Add wrap and the Visual|Text tabs.
if ( settings.tinymce && settings.quicktags ) {
var $textarea = $( '#' + id );
var $wrap = $( '<div>' ).attr( {
'class': 'wp-core-ui wp-editor-wrap tmce-active',
id: 'wp-' + id + '-wrap'
} );
var $editorContainer = $( '<div class="wp-editor-container">' );
var $button = $( '<button>' ).attr( {
type: 'button',
'data-wp-editor-id': id
} );
$wrap.append(
$( '<div class="wp-editor-tools">' )
.append( $( '<div class="wp-editor-tabs">' )
.append( $button.clone().attr({
id: id + '-tmce',
'class': 'wp-switch-editor switch-tmce'
}).text( window.tinymce.translate( 'Visual' ) ) )
.append( $button.attr({
id: id + '-html',
'class': 'wp-switch-editor switch-html'
}).text( window.tinymce.translate( 'Text' ) ) )
).append( $editorContainer )
);
$textarea.after( $wrap );
$editorContainer.append( $textarea );
}
if ( window.tinymce && settings.tinymce ) {
if ( typeof settings.tinymce !== 'object' ) {
settings.tinymce = {};
}
init = $.extend( {}, defaults.tinymce, settings.tinymce );
init.selector = '#' + id;
$( document ).trigger( 'wp-before-tinymce-init', init );
window.tinymce.init( init );
if ( ! window.wpActiveEditor ) {
window.wpActiveEditor = id;
}
}
if ( window.quicktags && settings.quicktags ) {
if ( typeof settings.quicktags !== 'object' ) {
settings.quicktags = {};
}
init = $.extend( {}, defaults.quicktags, settings.quicktags );
init.id = id;
$( document ).trigger( 'wp-before-quicktags-init', init );
window.quicktags( init );
if ( ! window.wpActiveEditor ) {
window.wpActiveEditor = init.id;
}
}
};
/**
* Get the editor content.
*
* Intended for use with editors that were initialized with wp.editor.initialize().
*
* @since 4.8
*
* @param {string} id The HTML id of the editor textarea.
* @return The editor content.
*/
wp.editor.getContent = function( id ) {
var editor;
if ( ! $ || ! id ) {
return;
}
if ( window.tinymce ) {
editor = window.tinymce.get( id );
if ( editor && ! editor.isHidden() ) {
editor.save();
}
}
return $( '#' + id ).val();
};
}( window.jQuery, window.wp ));

File diff suppressed because one or more lines are too long

View File

@ -27,6 +27,8 @@ final class _WP_Editors {
private static $drag_drop_upload = false; private static $drag_drop_upload = false;
private static $old_dfw_compat = false; private static $old_dfw_compat = false;
private static $translation; private static $translation;
private static $tinymce_scripts_printed = false;
private static $link_dialog_printed = false;
private function __construct() {} private function __construct() {}
@ -350,21 +352,9 @@ final class _WP_Editors {
if ( self::$this_tinymce ) { if ( self::$this_tinymce ) {
if ( empty( self::$first_init ) ) { if ( empty( self::$first_init ) ) {
self::$baseurl = includes_url( 'js/tinymce' ); $baseurl = self::get_baseurl();
$mce_locale = self::get_mce_locale();
$mce_locale = get_user_locale();
self::$mce_locale = $mce_locale = empty( $mce_locale ) ? 'en' : strtolower( substr( $mce_locale, 0, 2 ) ); // ISO 639-1
/** This filter is documented in wp-admin/includes/media.php */
$no_captions = (bool) apply_filters( 'disable_captions', '' );
$ext_plugins = ''; $ext_plugins = '';
$shortcut_labels = array();
foreach ( self::get_translation() as $name => $value ) {
if ( is_array( $value ) ) {
$shortcut_labels[$name] = $value[1];
}
}
if ( $set['teeny'] ) { if ( $set['teeny'] ) {
@ -376,7 +366,7 @@ final class _WP_Editors {
* @param array $plugins An array of teenyMCE plugins. * @param array $plugins An array of teenyMCE plugins.
* @param string $editor_id Unique editor identifier, e.g. 'content'. * @param string $editor_id Unique editor identifier, e.g. 'content'.
*/ */
self::$plugins = $plugins = apply_filters( 'teeny_mce_plugins', array( 'colorpicker', 'lists', 'fullscreen', 'image', 'wordpress', 'wpeditimage', 'wplink' ), $editor_id ); $plugins = apply_filters( 'teeny_mce_plugins', array( 'colorpicker', 'lists', 'fullscreen', 'image', 'wordpress', 'wpeditimage', 'wplink' ), $editor_id );
} else { } else {
/** /**
@ -521,65 +511,23 @@ final class _WP_Editors {
self::$plugins = $plugins; self::$plugins = $plugins;
self::$ext_plugins = $ext_plugins; self::$ext_plugins = $ext_plugins;
self::$first_init = array( $settings = self::default_settings();
'theme' => 'modern', $settings['plugins'] = implode( ',', $plugins );
'skin' => 'lightgray',
'language' => self::$mce_locale,
'formats' => '{' .
'alignleft: [' .
'{selector: "p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li", styles: {textAlign:"left"}},' .
'{selector: "img,table,dl.wp-caption", classes: "alignleft"}' .
'],' .
'aligncenter: [' .
'{selector: "p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li", styles: {textAlign:"center"}},' .
'{selector: "img,table,dl.wp-caption", classes: "aligncenter"}' .
'],' .
'alignright: [' .
'{selector: "p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li", styles: {textAlign:"right"}},' .
'{selector: "img,table,dl.wp-caption", classes: "alignright"}' .
'],' .
'strikethrough: {inline: "del"}' .
'}',
'relative_urls' => false,
'remove_script_host' => false,
'convert_urls' => false,
'browser_spellcheck' => true,
'fix_list_elements' => true,
'entities' => '38,amp,60,lt,62,gt',
'entity_encoding' => 'raw',
'keep_styles' => false,
'cache_suffix' => 'wp-mce-' . $tinymce_version,
// Limit the preview styles in the menu/toolbar
'preview_styles' => 'font-family font-size font-weight font-style text-decoration text-transform',
'end_container_on_empty_block' => true,
'wpeditimage_disable_captions' => $no_captions,
'wpeditimage_html5_captions' => current_theme_supports( 'html5', 'caption' ),
'plugins' => implode( ',', $plugins ),
'wp_lang_attr' => get_bloginfo( 'language' ),
'wp_shortcut_labels' => wp_json_encode( $shortcut_labels ),
);
if ( ! empty( $mce_external_plugins ) ) { if ( ! empty( $mce_external_plugins ) ) {
self::$first_init['external_plugins'] = wp_json_encode( $mce_external_plugins ); $settings['external_plugins'] = wp_json_encode( $mce_external_plugins );
} }
$suffix = SCRIPT_DEBUG ? '' : '.min'; /** This filter is documented in wp-admin/includes/media.php */
$version = 'ver=' . get_bloginfo( 'version' ); if ( apply_filters( 'disable_captions', '' ) ) {
$dashicons = includes_url( "css/dashicons$suffix.css?$version" ); $settings['wpeditimage_disable_captions'] = true;
}
// WordPress default stylesheet and dashicons
$mce_css = array(
$dashicons,
self::$baseurl . '/skins/wordpress/wp-content.css?' . $version
);
$mce_css = $settings['content_css'];
$editor_styles = get_editor_stylesheets(); $editor_styles = get_editor_stylesheets();
if ( ! empty( $editor_styles ) ) { if ( ! empty( $editor_styles ) ) {
foreach ( $editor_styles as $style ) { $mce_css .= ',' . implode( ',', $editor_styles );
$mce_css[] = $style;
}
} }
/** /**
@ -589,10 +537,15 @@ final class _WP_Editors {
* *
* @param string $stylesheets Comma-delimited list of stylesheets. * @param string $stylesheets Comma-delimited list of stylesheets.
*/ */
$mce_css = trim( apply_filters( 'mce_css', implode( ',', $mce_css ) ), ' ,' ); $mce_css = trim( apply_filters( 'mce_css', $mce_css ), ' ,' );
if ( ! empty($mce_css) ) if ( ! empty( $mce_css ) ) {
self::$first_init['content_css'] = $mce_css; $settings['content_css'] = $mce_css;
} else {
unset( $settings['content_css'] );
}
self::$first_init = $settings;
} }
if ( $set['teeny'] ) { if ( $set['teeny'] ) {
@ -697,14 +650,12 @@ final class _WP_Editors {
$mceInit = array ( $mceInit = array (
'selector' => "#$editor_id", 'selector' => "#$editor_id",
'resize' => 'vertical',
'menubar' => false,
'wpautop' => (bool) $set['wpautop'], 'wpautop' => (bool) $set['wpautop'],
'indent' => ! $set['wpautop'], 'indent' => ! $set['wpautop'],
'toolbar1' => implode($mce_buttons, ','), 'toolbar1' => implode( ',', $mce_buttons ),
'toolbar2' => implode($mce_buttons_2, ','), 'toolbar2' => implode( ',', $mce_buttons_2 ),
'toolbar3' => implode($mce_buttons_3, ','), 'toolbar3' => implode( ',', $mce_buttons_3 ),
'toolbar4' => implode($mce_buttons_4, ','), 'toolbar4' => implode( ',', $mce_buttons_4 ),
'tabfocus_elements' => $set['tabfocus_elements'], 'tabfocus_elements' => $set['tabfocus_elements'],
'body_class' => $body_class 'body_class' => $body_class
); );
@ -765,16 +716,20 @@ final class _WP_Editors {
private static function _parse_init( $init ) { private static function _parse_init( $init ) {
$options = ''; $options = '';
foreach ( $init as $k => $v ) { foreach ( $init as $key => $value ) {
if ( is_bool($v) ) { if ( is_bool( $value ) ) {
$val = $v ? 'true' : 'false'; $val = $value ? 'true' : 'false';
$options .= $k . ':' . $val . ','; $options .= $key . ':' . $val . ',';
continue; continue;
} elseif ( !empty($v) && is_string($v) && ( ('{' == $v{0} && '}' == $v{strlen($v) - 1}) || ('[' == $v{0} && ']' == $v{strlen($v) - 1}) || preg_match('/^\(?function ?\(/', $v) ) ) { } elseif ( ! empty( $value ) && is_string( $value ) && (
$options .= $k . ':' . $v . ','; ( '{' == $value{0} && '}' == $value{strlen( $value ) - 1} ) ||
( '[' == $value{0} && ']' == $value{strlen( $value ) - 1} ) ||
preg_match( '/^\(?function ?\(/', $value ) ) ) {
$options .= $key . ':' . $value . ',';
continue; continue;
} }
$options .= $k . ':"' . $v . '",'; $options .= $key . ':"' . $value . '",';
} }
return '{' . trim( $options, ' ,' ) . '}'; return '{' . trim( $options, ' ,' ) . '}';
@ -784,16 +739,17 @@ final class _WP_Editors {
* *
* @static * @static
*/ */
public static function enqueue_scripts() { public static function enqueue_scripts( $default_scripts = false ) {
if ( self::$has_tinymce ) if ( $default_scripts || self::$has_tinymce ) {
wp_enqueue_script( 'editor' ); wp_enqueue_script( 'editor' );
}
if ( self::$has_quicktags ) { if ( $default_scripts || self::$has_quicktags ) {
wp_enqueue_script( 'quicktags' ); wp_enqueue_script( 'quicktags' );
wp_enqueue_style( 'buttons' ); wp_enqueue_style( 'buttons' );
} }
if ( in_array('wplink', self::$plugins, true) || in_array('link', self::$qt_buttons, true) ) { if ( $default_scripts || in_array( 'wplink', self::$plugins, true ) || in_array( 'link', self::$qt_buttons, true ) ) {
wp_enqueue_script( 'wplink' ); wp_enqueue_script( 'wplink' );
wp_enqueue_script( 'jquery-ui-autocomplete' ); wp_enqueue_script( 'jquery-ui-autocomplete' );
} }
@ -806,6 +762,8 @@ final class _WP_Editors {
add_thickbox(); add_thickbox();
wp_enqueue_script( 'media-upload' ); wp_enqueue_script( 'media-upload' );
wp_enqueue_script( 'wp-embed' ); wp_enqueue_script( 'wp-embed' );
} elseif ( $default_scripts ) {
wp_enqueue_script( 'media-upload' );
} }
/** /**
@ -817,11 +775,198 @@ final class _WP_Editors {
* and Quicktags are being loaded. * and Quicktags are being loaded.
*/ */
do_action( 'wp_enqueue_editor', array( do_action( 'wp_enqueue_editor', array(
'tinymce' => self::$has_tinymce, 'tinymce' => ( $default_scripts || self::$has_tinymce ),
'quicktags' => self::$has_quicktags, 'quicktags' => ( $default_scripts || self::$has_quicktags ),
) ); ) );
} }
/**
* Enqueue all editor scripts.
* For use when the editor is going to be initialized after page load.
*
* @since 4.8.0
*/
public static function enqueue_default_editor() {
// We are past the point where scripts can be enqueued properly.
if ( did_action( 'wp_enqueue_editor' ) ) {
return;
}
self::enqueue_scripts( true );
// Also add wp-includes/css/editor.css
wp_enqueue_style( 'editor-buttons' );
if ( is_admin() ) {
add_action( 'admin_print_footer_scripts', array( __CLASS__, 'print_default_editor_scripts' ), 45 );
} else {
add_action( 'wp_print_footer_scripts', array( __CLASS__, 'print_default_editor_scripts' ), 45 );
}
}
/**
* Print (output) all editor scripts and default settings.
* For use when the editor is going to be initialized after page load.
*
* @since 4.8.0
*
*/
public static function print_default_editor_scripts() {
$settings = self::default_settings();
$settings['toolbar1'] = 'bold,italic,bullist,numlist,link';
$settings['wpautop'] = false;
$settings['indent'] = true;
$settings['elementpath'] = false;
// In production all plugins are loaded (they are in wp-editor.js.gz)
// but only these will be initialized by default.
$settings['plugins'] = implode( ',', array(
'charmap',
'colorpicker',
'hr',
'lists',
// 'media',
'paste',
'tabfocus',
'textcolor',
'fullscreen',
'wordpress',
'wpautoresize',
'wpeditimage',
'wpemoji',
'wpgallery',
'wplink',
// 'wpdialogs',
'wptextpattern',
// 'wpview',
) );
$settings = self::_parse_init( $settings );
$suffix = SCRIPT_DEBUG ? '' : '.min';
$baseurl = self::get_baseurl();
?>
<script type="text/javascript">
window.wp = window.wp || {};
window.wp.editor = window.wp.editor || {};
window.wp.editor.getDefaultSettings = function() {
return {
tinymce: <?php echo $settings; ?>,
quicktags: {
buttons: 'strong,em,link,ul,ol,li,code'
}
};
};
var tinyMCEPreInit = {
baseURL: "<?php echo $baseurl; ?>",
suffix: "<?php echo $suffix; ?>",
mceInit: {},
qtInit: {},
load_ext: function(url,lang){var sl=tinymce.ScriptLoader;sl.markDone(url+'/langs/'+lang+'.js');sl.markDone(url+'/langs/'+lang+'_dlg.js');}
};
</script>
<?php
self::print_tinymce_scripts();
/**
* Fires when the editor scripts are loaded for later initialization,
* after all scripts and settings are printed.
*
* @since 4.8.0
*/
do_action( 'print_default_editor_scripts' );
self::wp_link_dialog();
}
public static function get_mce_locale() {
if ( empty( self::$mce_locale ) ) {
$mce_locale = get_user_locale();
self::$mce_locale = empty( $mce_locale ) ? 'en' : strtolower( substr( $mce_locale, 0, 2 ) ); // ISO 639-1
}
return self::$mce_locale;
}
public static function get_baseurl() {
if ( empty( self::$baseurl ) ) {
self::$baseurl = includes_url( 'js/tinymce' );
}
return self::$baseurl;
}
/**
* Returns the default TinyMCE settings.
* Doesn't include plugins, buttons, editor selector.
*
* @return array
*/
private static function default_settings() {
global $tinymce_version;
$shortcut_labels = array();
foreach ( self::get_translation() as $name => $value ) {
if ( is_array( $value ) ) {
$shortcut_labels[$name] = $value[1];
}
}
$settings = array(
'theme' => 'modern',
'skin' => 'lightgray',
'language' => self::get_mce_locale(),
'formats' => '{' .
'alignleft: [' .
'{selector: "p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li", styles: {textAlign:"left"}},' .
'{selector: "img,table,dl.wp-caption", classes: "alignleft"}' .
'],' .
'aligncenter: [' .
'{selector: "p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li", styles: {textAlign:"center"}},' .
'{selector: "img,table,dl.wp-caption", classes: "aligncenter"}' .
'],' .
'alignright: [' .
'{selector: "p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li", styles: {textAlign:"right"}},' .
'{selector: "img,table,dl.wp-caption", classes: "alignright"}' .
'],' .
'strikethrough: {inline: "del"}' .
'}',
'relative_urls' => false,
'remove_script_host' => false,
'convert_urls' => false,
'browser_spellcheck' => true,
'fix_list_elements' => true,
'entities' => '38,amp,60,lt,62,gt',
'entity_encoding' => 'raw',
'keep_styles' => false,
'cache_suffix' => 'wp-mce-' . $tinymce_version,
'resize' => 'vertical',
'menubar' => false,
// Limit the preview styles in the menu/toolbar
'preview_styles' => 'font-family font-size font-weight font-style text-decoration text-transform',
'end_container_on_empty_block' => true,
'wpeditimage_html5_captions' => true,
'wp_lang_attr' => get_bloginfo( 'language' ),
'wp_shortcut_labels' => wp_json_encode( $shortcut_labels ),
);
$suffix = SCRIPT_DEBUG ? '' : '.min';
$version = 'ver=' . get_bloginfo( 'version' );
// Default stylesheets
$settings['content_css'] = includes_url( "css/dashicons$suffix.css?$version" ) . ',' .
includes_url( "js/tinymce/skins/wordpress/wp-content.css?$version" );
return $settings;
}
private static function get_translation() { private static function get_translation() {
if ( empty( self::$translation ) ) { if ( empty( self::$translation ) ) {
self::$translation = array( self::$translation = array(
@ -1028,11 +1173,16 @@ final class _WP_Editors {
/* translators: word count */ /* translators: word count */
'Words: {0}' => sprintf( __( 'Words: %s' ), '{0}' ), 'Words: {0}' => sprintf( __( 'Words: %s' ), '{0}' ),
'Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.' => __( 'Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.' ) . "\n\n" . __( 'If you&#8217;re looking to paste rich content from Microsoft Word, try turning this option off. The editor will clean up text pasted from Word automatically.' ), 'Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.' =>
'Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help' => __( 'Rich Text Area. Press Alt-Shift-H for help.' ), __( 'Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.' ) . "\n\n" .
__( 'If you&#8217;re looking to paste rich content from Microsoft Word, try turning this option off. The editor will clean up text pasted from Word automatically.' ),
'Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help' =>
__( 'Rich Text Area. Press Alt-Shift-H for help.' ),
'Rich Text Area. Press Control-Option-H for help.' => __( 'Rich Text Area. Press Control-Option-H for help.' ), 'Rich Text Area. Press Control-Option-H for help.' => __( 'Rich Text Area. Press Control-Option-H for help.' ),
'You have unsaved changes are you sure you want to navigate away?' => __( 'The changes you made will be lost if you navigate away from this page.' ), 'You have unsaved changes are you sure you want to navigate away?' =>
'Your browser doesn\'t support direct access to the clipboard. Please use the Ctrl+X/C/V keyboard shortcuts instead.' => __( 'Your browser does not support direct access to the clipboard. Please use keyboard shortcuts or your browser&#8217;s edit menu instead.' ), __( 'The changes you made will be lost if you navigate away from this page.' ),
'Your browser doesn\'t support direct access to the clipboard. Please use the Ctrl+X/C/V keyboard shortcuts instead.' =>
__( 'Your browser does not support direct access to the clipboard. Please use keyboard shortcuts or your browser&#8217;s edit menu instead.' ),
// TinyMCE menus // TinyMCE menus
'Insert' => _x( 'Insert', 'TinyMCE menu' ), 'Insert' => _x( 'Insert', 'TinyMCE menu' ),
@ -1055,6 +1205,8 @@ final class _WP_Editors {
'Paste URL or type to search' => __( 'Paste URL or type to search' ), // Placeholder for the inline link dialog 'Paste URL or type to search' => __( 'Paste URL or type to search' ), // Placeholder for the inline link dialog
'Apply' => __( 'Apply' ), // Tooltip for the 'apply' button in the inline link dialog 'Apply' => __( 'Apply' ), // Tooltip for the 'apply' button in the inline link dialog
'Link options' => __( 'Link options' ), // Tooltip for the 'link options' button in the inline link dialog 'Link options' => __( 'Link options' ), // Tooltip for the 'link options' button in the inline link dialog
'Visual' => __( 'Visual' ), // Editor switch tab label
'Text' => __( 'Text' ), // Editor switch tab label
// Shortcuts help modal // Shortcuts help modal
'Keyboard Shortcuts' => array( __( 'Keyboard Shortcuts' ), 'accessH' ), 'Keyboard Shortcuts' => array( __( 'Keyboard Shortcuts' ), 'accessH' ),
@ -1098,8 +1250,8 @@ final class _WP_Editors {
} }
/** /**
* Translates the default TinyMCE strings and returns them as JSON encoded object ready to be loaded with tinymce.addI18n(). * 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. * or as JS snippet that should run after tinymce.js is loaded.
* *
* @static * @static
* @param string $mce_locale The locale used for the editor. * @param string $mce_locale The locale used for the editor.
@ -1108,7 +1260,7 @@ final class _WP_Editors {
*/ */
public static function wp_mce_translation( $mce_locale = '', $json_only = false ) { public static function wp_mce_translation( $mce_locale = '', $json_only = false ) {
if ( ! $mce_locale ) { if ( ! $mce_locale ) {
$mce_locale = self::$mce_locale; $mce_locale = self::get_mce_locale();
} }
$mce_translation = self::get_translation(); $mce_translation = self::get_translation();
@ -1150,39 +1302,63 @@ final class _WP_Editors {
return wp_json_encode( $mce_translation ); return wp_json_encode( $mce_translation );
} }
$baseurl = self::$baseurl ? self::$baseurl : includes_url( 'js/tinymce' ); $baseurl = self::get_baseurl();
return "tinymce.addI18n( '$mce_locale', " . wp_json_encode( $mce_translation ) . ");\n" . return "tinymce.addI18n( '$mce_locale', " . wp_json_encode( $mce_translation ) . ");\n" .
"tinymce.ScriptLoader.markDone( '$baseurl/langs/$mce_locale.js' );\n"; "tinymce.ScriptLoader.markDone( '$baseurl/langs/$mce_locale.js' );\n";
} }
/** /**
* Print (output) the main TinyMCE scripts.
*
* @since 4.8
* *
* @static * @static
* @global string $tinymce_version * @global string $tinymce_version
* @global bool $concatenate_scripts * @global bool $concatenate_scripts
* @global bool $compress_scripts * @global bool $compress_scripts
*/ */
public static function editor_js() { public static function print_tinymce_scripts() {
global $tinymce_version, $concatenate_scripts, $compress_scripts; global $tinymce_version, $concatenate_scripts, $compress_scripts;
/** if ( self::$tinymce_scripts_printed ) {
* Filters "tiny_mce_version" is deprecated return;
* }
* The tiny_mce_version filter is not needed since external plugins are loaded directly by TinyMCE.
* These plugins can be refreshed by appending query string to the URL passed to "mce_external_plugins" filter.
* If the plugin has a popup dialog, a query string can be added to the button action that opens it (in the plugin's code).
*/
$version = 'ver=' . $tinymce_version;
$tmce_on = !empty(self::$mce_settings);
if ( ! isset($concatenate_scripts) ) self::$tinymce_scripts_printed = true;
if ( ! isset( $concatenate_scripts ) ) {
script_concat_settings(); script_concat_settings();
}
$version = 'ver=' . $tinymce_version;
$baseurl = self::get_baseurl();
$compressed = $compress_scripts && $concatenate_scripts && isset($_SERVER['HTTP_ACCEPT_ENCODING']) $compressed = $compress_scripts && $concatenate_scripts && isset($_SERVER['HTTP_ACCEPT_ENCODING'])
&& false !== stripos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip'); && false !== stripos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip');
// Load tinymce.js when running from /src, else load wp-tinymce.js.gz (production) or tinymce.min.js (SCRIPT_DEBUG)
$mce_suffix = false !== strpos( get_bloginfo( 'version' ), '-src' ) ? '' : '.min';
if ( $compressed ) {
echo "<script type='text/javascript' src='{$baseurl}/wp-tinymce.php?c=1&amp;$version'></script>\n";
} else {
echo "<script type='text/javascript' src='{$baseurl}/tinymce{$mce_suffix}.js?$version'></script>\n";
echo "<script type='text/javascript' src='{$baseurl}/plugins/compat3x/plugin{$suffix}.js?$version'></script>\n";
}
echo "<script type='text/javascript'>\n" . self::wp_mce_translation() . "</script>\n";
}
/**
* Print (output) the TinyMCE configuration and initialization scripts.
*
* @static
*/
public static function editor_js() {
$tmce_on = ! empty( self::$mce_settings );
$mceInit = $qtInit = ''; $mceInit = $qtInit = '';
if ( $tmce_on ) { if ( $tmce_on ) {
foreach ( self::$mce_settings as $editor_id => $init ) { foreach ( self::$mce_settings as $editor_id => $init ) {
$options = self::_parse_init( $init ); $options = self::_parse_init( $init );
@ -1210,6 +1386,7 @@ final class _WP_Editors {
); );
$suffix = SCRIPT_DEBUG ? '' : '.min'; $suffix = SCRIPT_DEBUG ? '' : '.min';
$baseurl = self::get_baseurl();
/** /**
* Fires immediately before the TinyMCE settings are printed. * Fires immediately before the TinyMCE settings are printed.
@ -1223,7 +1400,7 @@ final class _WP_Editors {
<script type="text/javascript"> <script type="text/javascript">
tinyMCEPreInit = { tinyMCEPreInit = {
baseURL: "<?php echo self::$baseurl; ?>", baseURL: "<?php echo $baseurl; ?>",
suffix: "<?php echo $suffix; ?>", suffix: "<?php echo $suffix; ?>",
<?php <?php
@ -1240,19 +1417,8 @@ final class _WP_Editors {
</script> </script>
<?php <?php
$baseurl = self::$baseurl;
// Load tinymce.js when running from /src, else load wp-tinymce.js.gz (production) or tinymce.min.js (SCRIPT_DEBUG)
$mce_suffix = false !== strpos( get_bloginfo( 'version' ), '-src' ) ? '' : '.min';
if ( $tmce_on ) { if ( $tmce_on ) {
if ( $compressed ) { self::print_tinymce_scripts();
echo "<script type='text/javascript' src='{$baseurl}/wp-tinymce.php?c=1&amp;$version'></script>\n";
} else {
echo "<script type='text/javascript' src='{$baseurl}/tinymce{$mce_suffix}.js?$version'></script>\n";
echo "<script type='text/javascript' src='{$baseurl}/plugins/compat3x/plugin{$suffix}.js?$version'></script>\n";
}
echo "<script type='text/javascript'>\n" . self::wp_mce_translation() . "</script>\n";
if ( self::$ext_plugins ) { if ( self::$ext_plugins ) {
// Load the old-format English strings to prevent unsightly labels in old style popups // Load the old-format English strings to prevent unsightly labels in old style popups
@ -1434,6 +1600,13 @@ final class _WP_Editors {
* @static * @static
*/ */
public static function wp_link_dialog() { public static function wp_link_dialog() {
// Run once
if ( self::$link_dialog_printed ) {
return;
}
self::$link_dialog_printed = true;
// display: none is required here, see #WP27605 // display: none is required here, see #WP27605
?> ?>
<div id="wp-link-backdrop" style="display: none"></div> <div id="wp-link-backdrop" style="display: none"></div>

View File

@ -608,16 +608,12 @@ div.mce-path {
} }
/* Menubar */ /* Menubar */
.mce-menubar { div.mce-menubar {
border-color: #e5e5e5; border-color: #e5e5e5;
background: #fff; background: #fff;
border-width: 0px 0px 1px; border-width: 0px 0px 1px;
} }
.mce-menubar .mce-menubtn {
margin: 2px;
}
.mce-menubar .mce-menubtn:hover, .mce-menubar .mce-menubtn:hover,
.mce-menubar .mce-menubtn.mce-active, .mce-menubar .mce-menubtn.mce-active,
.mce-menubar .mce-menubtn:focus { .mce-menubar .mce-menubtn:focus {
@ -1091,6 +1087,7 @@ i.mce-i-wp_code:before {
.wp-editor-container { .wp-editor-container {
clear: both; clear: both;
border: 1px solid #e5e5e5;
} }
.wp-editor-area { .wp-editor-area {

File diff suppressed because one or more lines are too long

View File

@ -608,16 +608,12 @@ div.mce-path {
} }
/* Menubar */ /* Menubar */
.mce-menubar { div.mce-menubar {
border-color: #e5e5e5; border-color: #e5e5e5;
background: #fff; background: #fff;
border-width: 0px 0px 1px; border-width: 0px 0px 1px;
} }
.mce-menubar .mce-menubtn {
margin: 2px;
}
.mce-menubar .mce-menubtn:hover, .mce-menubar .mce-menubtn:hover,
.mce-menubar .mce-menubtn.mce-active, .mce-menubar .mce-menubtn.mce-active,
.mce-menubar .mce-menubtn:focus { .mce-menubar .mce-menubtn:focus {
@ -1091,6 +1087,7 @@ i.mce-i-wp_code:before {
.wp-editor-container { .wp-editor-container {
clear: both; clear: both;
border: 1px solid #e5e5e5;
} }
.wp-editor-area { .wp-editor-area {

File diff suppressed because one or more lines are too long

View File

@ -3056,6 +3056,23 @@ function wp_editor( $content, $editor_id, $settings = array() ) {
_WP_Editors::editor($content, $editor_id, $settings); _WP_Editors::editor($content, $editor_id, $settings);
} }
/**
* Outputs the editor scripts, stylesheets, and default settings.
*
* The editor can be initialized when needed after page load.
* See wp.editor.initialize() in wp-admin/js/editor.js for initialization options.
*
* @uses _WP_Editors
* @since 4.8.0
*/
function wp_enqueue_editor() {
if ( ! class_exists( '_WP_Editors', false ) ) {
require( ABSPATH . WPINC . '/class-wp-editor.php' );
}
_WP_Editors::enqueue_default_editor();
}
/** /**
* Retrieves the contents of the search WordPress query variable. * Retrieves the contents of the search WordPress query variable.
* *

View File

@ -4,7 +4,7 @@
* *
* @global string $wp_version * @global string $wp_version
*/ */
$wp_version = '4.8-alpha-40472'; $wp_version = '4.8-alpha-40476';
/** /**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.