Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Asynchronously load tinyMCE the first time a classic block is edited #21684

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions lib/class-wp-rest-tinymce-i18n-controller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php
/**
* TinyMCE i18n controller.
*
* @package gutenberg
*/

/**
* Endpoint for retrieving TinyMCE translations needed to initialize the library
* on the frontend. Used by the classic block's edit LazyLoad wrapper.
*
* Class WP_REST_TinyMCE_I18n_Controller
*
* @see WP_REST_Controller
*/
class WP_REST_TinyMCE_I18n_Controller extends WP_REST_Controller {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still POCing, needs tests and an actually correct schema!


/**
* Register routes.
*/
public function register_routes() {
register_rest_route(
'wp/v2',
'/tinymce-i18n',
[
[
'methods' => WP_REST_Server::READABLE,
'callback' => [ $this, 'get_translations' ],
'permission_callback' => [ $this, 'check_permissions' ],
'args' => [],
],
'schema' => array( $this, 'get_item_schema' ),
]
);
}

/**
* Get the translations for the current user's locale.
*
* _WP_Editors is not included by default so we need to require it
* if the class isn't available. We should probably refactor all the
* TinyMCE translation files out of _WP_Editors. This shouldn't be
* too hard considering they're already all static functions.
*
* @param WP_REST_Request $request Request.
*
* @return array
*/
public function get_translations( $request ) {
if ( ! class_exists( '_WP_Editors', false ) ) {
require ABSPATH . WPINC . '/class-wp-editor.php';
}

$mce_locale = _WP_Editors::get_mce_locale();
$json_only = true;
$baseurl = _WP_Editors::get_baseurl();

return [
"translations" => _WP_Editors::wp_mce_translation( $mce_locale, $json_only ),
"locale" => $mce_locale,
"locale_script_handle" => "$baseurl/langs/$mce_locale.js",
];
}

/**
* This endpoint is only mean to be used from the editor so it can be safely
* restricted only to users that can edit posts.
*
* @param WP_REST_Request $request Request.
*
* @return bool|true|WP_Error
*/
public function check_permissions( $request ) {
return current_user_can( 'edit_posts' );
}
}
3 changes: 3 additions & 0 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ function gutenberg_is_experiment_enabled( $name ) {
if ( ! class_exists( 'WP_REST_Styles_Controller' ) ) {
require_once dirname( __FILE__ ) . '/class-wp-rest-styles-controller.php';
}
if ( ! class_exists( 'WP_REST_TinyMCE_I81n_Controller' ) ) {
require_once dirname( __FILE__ ) . '/class-wp-rest-tinymce-i18n-controller.php';
}
/**
* End: Include for phase 2
*/
Expand Down
4 changes: 4 additions & 0 deletions lib/rest-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ function gutenberg_register_script_style() {
// Styles.
$controller = new WP_REST_Styles_Controller();
$controller->register_routes();

// TinyMCE translations
$controller = new WP_REST_TinyMCE_I18n_Controller();
$controller->register_routes();
}
add_action( 'rest_api_init', 'gutenberg_register_script_style' );

Expand Down
18 changes: 12 additions & 6 deletions packages/block-library/src/classic/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { BACKSPACE, DELETE, F10 } from '@wordpress/keycodes';
* Internal dependencies
*/
import LazyLoad from './lazy';
import apiFetch from '@wordpress/api-fetch';

const { wp } = window;

Expand Down Expand Up @@ -225,12 +226,17 @@ class ClassicEdit extends Component {
const LazyClassicEdit = ( props ) => (
<LazyLoad
scripts={ [ 'wp-tinymce' ] }
onLoaded={ () =>
new Promise( ( resolve ) => {
window.wpMceTranslation();
resolve();
} )
}
onLoaded={ async () => {
const {
translations,
locale,
locale_script_handle: localeScriptHandle,
} = await apiFetch( { path: '/wp/v2/tinymce-i18n' } );

const { tinymce } = window;
tinymce.addI18n( locale, JSON.stringify( translations ) );
tinymce.ScriptLoader.markDone( localeScriptHandle );
} }
Comment on lines +229 to +239
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gziolo I think these changes will be interesting to you 😊

cc @griffbrad because we'd also discussed using an endpoint to retrieve the translation json.

placeholder={ <div>Loading...</div> }
>
<ClassicEdit { ...props } />
Expand Down