-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Try: Aggressive TinyMCE deprecation #50387
Changes from 30 commits
12f8647
fc80223
6183e67
4ed42c5
fa36172
b2f58f7
fa0cea3
ef79a75
f52d567
6599db7
8084674
1ee79d8
ddd9dfe
cf08033
e054060
1799b8a
f06c648
b782ce2
853d0bc
6c7edf6
044cd66
1c9fb52
72cf3df
57ff691
d4d6366
7fc9a82
797093a
ddfec41
66ed611
d448cac
e5ce4e9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
async function reloadWithTinymce() { | ||
const currentUrl = new URL( window.location.href ); | ||
currentUrl.searchParams.set( 'requiresTinymce', '1' ); | ||
window.location.href = currentUrl; | ||
} | ||
tyxla marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
window.tinymce = new Proxy( | ||
{}, | ||
{ | ||
get: reloadWithTinymce, | ||
set: reloadWithTinymce, | ||
apply: reloadWithTinymce, | ||
} | ||
); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?php | ||
/** | ||
* Contains the placeholder class to replace the default `_WP_Editors`. | ||
* | ||
* @package gutenberg | ||
* @since 6.3.0 | ||
*/ | ||
|
||
// phpcs:disable PEAR.NamingConventions.ValidClassName.StartWithCapital | ||
|
||
/** | ||
* Placeholder class. | ||
* Used to disable loading of TinyMCE assets. | ||
* | ||
* @access public | ||
*/ | ||
final class _WP_Editors { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Much of the TinyMCE assets are hardcoded to be loaded and not enqueued in a pluggable way. So we're creating a new class and requiring it conditionally, in which case it just doesn't load them anymore. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure I understand this part? How does loading this class prevents TinyMCE from loading? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This, by default, is a core WP class that takes care of generating and "enqueueing" the editor assets. The problem is that for some of the scripts it doesn't use the traditional way to enqueue scripts, rather it will just output a huge blob of them inline, see: So the only way to not spit that blob of scripts out is to override this class. This is actually an optimization because none of what it does will even get enqueued that way (look around the class I linked above, it also enqueued some assets), so we won't need to dequeue them either. Luckily, redeclaring the class is possible because of the way that we check if the class is declared before being required, for example: and: I realize this is a bold approach, but it makes it so straightforward to remove all editor assets that would otherwise be either enqueued or plainly spit out as inline scripts in the admin. This is one of the main reasons why I prefer having this whole thing wrapped as an experiment before releasing it to the public. |
||
/** | ||
* Necessary to ensure no additional TinyMcE assets are enqueued. | ||
*/ | ||
public static function enqueue_default_editor() {} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
<?php | ||
/** | ||
* Experiment to disable TinyMCE and the Classic block. | ||
* | ||
* @package gutenberg | ||
*/ | ||
|
||
// add_action( 'admin_footer', 'gutenberg_test_tinymce_access' ); // Uncomment the following line to force an external TinyMCE usage. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Uncomment this line to force usage of TinyMCE. That can be used to test the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm going to keep that for now, just in case we'd like to test 3rd party global usage. |
||
|
||
/** | ||
* Render a variable that we'll use to declare that the editor will need the classic block. | ||
*/ | ||
function gutenberg_declare_classic_block_necessary() { | ||
if ( ! gutenberg_post_being_edited_requires_classic_block() ) { | ||
return; | ||
} | ||
echo '<script type="text/javascript">window.wp.needsClassicBlock = true;</script>'; | ||
} | ||
add_action( 'admin_footer', 'gutenberg_declare_classic_block_necessary' ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can't we use an "editor" specific hook here like block_assets or thing like that? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, because we need an action that actually is executed later and prepared to render an inline script. If we render during |
||
|
||
// If user has already requested TinyMCE, we're ending the experiment. | ||
if ( ! empty( $_GET['requiresTinymce'] ) || gutenberg_post_being_edited_requires_classic_block() ) { | ||
return; | ||
} | ||
|
||
|
||
/** | ||
* Disable TinyMCE by introducing a placeholder `_WP_Editors` class. | ||
*/ | ||
function gutenberg_disable_tinymce() { | ||
require __DIR__ . '/class--wp-editors.php'; | ||
} | ||
|
||
add_action( 'admin_init', 'gutenberg_disable_tinymce' ); | ||
|
||
/** | ||
* Enqueue TinyMCE proxy script. | ||
* Detects TinyMCE usage and sets the `requiresTinymce` query argument to stop disabling TinyMCE loading. | ||
*/ | ||
function gutenberg_enqueue_tinymce_proxy() { | ||
wp_enqueue_script( 'gutenberg-tinymce-proxy', plugins_url( 'assets/tinymce-proxy.js', __FILE__ ) ); | ||
} | ||
|
||
add_action( 'admin_enqueue_scripts', 'gutenberg_enqueue_tinymce_proxy' ); | ||
|
||
/** | ||
* Example TinyMCE usage used for testing. | ||
* Uncomment line 8 in this file to enable. | ||
*/ | ||
function gutenberg_test_tinymce_access() { | ||
echo '<script type="text/javascript">const a = window.tinymce.$;</script>'; | ||
} | ||
|
||
/** | ||
* Whether the current editor contains a classic block instance. | ||
* | ||
* @return bool True if the editor contains a classic block, false otherwse. | ||
*/ | ||
function gutenberg_post_being_edited_requires_classic_block() { | ||
if ( ! is_admin() ) { | ||
return false; | ||
} | ||
|
||
// Handle the post editor. | ||
if ( ! empty( $_GET['post'] ) && ! empty( $_GET['action'] ) && 'edit' === $_GET['action'] ) { | ||
$current_post = get_post( intval( $_GET['post'] ) ); | ||
if ( ! $current_post || is_wp_error( $current_post ) ) { | ||
return false; | ||
} | ||
|
||
$content = $current_post->post_content; | ||
} | ||
|
||
if ( empty( $content ) ) { | ||
return false; | ||
} | ||
|
||
$parsed_blocks = parse_blocks( $content ); | ||
foreach ( $parsed_blocks as $block ) { | ||
if ( empty( $block['blockName'] ) && strlen( trim( $block['innerHTML'] ) ) > 0 ) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -90,6 +90,9 @@ function gutenberg_enable_experiments() { | |
wp_add_inline_script( 'wp-block-editor', 'window.__experimentalInteractivityAPI = true', 'before' ); | ||
} | ||
|
||
if ( gutenberg_is_experiment_enabled( 'gutenberg-no-tinymce' ) ) { | ||
wp_add_inline_script( 'wp-block-library', 'window.__experimentalDisableTinymce = true', 'before' ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the global variable that we use to pass the experiment to the client side. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the thinking here? making this an experiment for some time to see the impact? What about removing the experiment but leaving this as a plugin-only (no backport to core) feature until we're certain. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I prefer adding it as an experiment just in case, so we can further polish it without breaking the experience for anyone. I've also explained some of the rationale here. After I have more confidence, I'm happy to remove the experiment wrapper altogether. |
||
} | ||
} | ||
|
||
add_action( 'admin_init', 'gutenberg_enable_experiments' ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -108,6 +108,11 @@ function gutenberg_is_experiment_enabled( $name ) { | |
require __DIR__ . '/experimental/navigation-theme-opt-in.php'; | ||
require __DIR__ . '/experimental/kses.php'; | ||
require __DIR__ . '/experimental/l10n.php'; | ||
|
||
if ( gutenberg_is_experiment_enabled( 'gutenberg-no-tinymce' ) ) { | ||
require __DIR__ . '/experimental/disable-tinymce.php'; | ||
} | ||
Comment on lines
+112
to
+114
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right now, this functionality is powered by a Gutenberg experiment. The experiment is supposed to work as a primary on/off button for the tinyMCE deprecation. |
||
|
||
if ( gutenberg_is_experiment_enabled( 'gutenberg-interactivity-api-core-blocks' ) ) { | ||
require __DIR__ . '/experimental/interactivity-api/blocks.php'; | ||
} | ||
|
@@ -123,7 +128,6 @@ function gutenberg_is_experiment_enabled( $name ) { | |
require __DIR__ . '/experimental/interactivity-api/directives/wp-style.php'; | ||
require __DIR__ . '/experimental/interactivity-api/directives/wp-text.php'; | ||
|
||
|
||
// Fonts API. | ||
if ( ! class_exists( 'WP_Fonts' ) ) { | ||
// Fonts API files. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're using a query argument in order to be able to detect we need TinyMCE from the server.