Make WordPress Core

Opened 3 years ago

Closed 3 years ago

Last modified 2 years ago

#53437 closed defect (bug) (fixed)

Widgets Screen: wp.editor.initialize is not a function notice

Reported by: noisysocks's profile noisysocks Owned by: zieladam's profile zieladam
Milestone: 5.8 Priority: normal
Severity: normal Version:
Component: Widgets Keywords: has-patch commit fixed-major dev-reviewed
Focuses: Cc:

Description

From https://github.com/WordPress/gutenberg/issues/32598.

Description

When loading the Widgets Screen two error notices appear at the top with the message:

wp.editor.initialize is not a function

![image](https://user-images.githubusercontent.com/45363/121601718-2a626d80-c9fb-11eb-921b-cdf4280d28b4.png)

Step-by-step reproduction instructions

  • WordPress 5.8-beta1
  • No Gutenberg plugin
  • Twenty Twenty One Theme
  • Load Widgets Editor (no existing widgets)

Attachments (2)

Screenshot 2021-07-07 at 20.48.09.png (1.2 MB) - added by spacedmonkey 3 years ago.
Classic widget editor
Screenshot 2021-07-07 at 20.48.46.png (1.0 MB) - added by spacedmonkey 3 years ago.
Block based widget editor

Change History (58)

#1 @noisysocks
3 years ago

  • Owner set to noisysocks
  • Status changed from new to accepted

The problem is that the Text widget is calling wp.editor.initialize() and wp.editor refers to the wp-editor dependency, not the editor dependency which is available at wp.oldEditor.

#2 @Mamaduka
3 years ago

I think having a legacy "Text Widget" is also needed to reproduce this issue.

This ticket was mentioned in PR #1383 on WordPress/wordpress-develop by noisysocks.


3 years ago
#3

  • Keywords has-patch added

#4 @noisysocks
3 years ago

I added a fix but I'm not particularly happy with it. The problem is that when wp-editor is loaded it will will assign wp.oldEditor = wp.editor and then re-define wp.editor. This breaks widgets which rely on wp.editor. The widgets screen doesn't require wp-editor but it is loaded because it is a dependency of wp-block-library and wp-block-directory.

We can safely remove wp-block-directory as it's not used in the widgets screen. (For now.)

Removing wp-editor from wp-block-library is more tricky. It's safe to remove because only the Classic block uses wp-editor and this block is disabled in the widgets block editor. Ideally we would split the Classic block out of @wordpress/block-library so that only parts of WordPress which use it (the post editor) can enqueue it. I'm not sure if it's sensible to do this during the beta period, though. Instead I'm manually remove the wp-editor dep from wp-block-library which is very hacky.

@gziolo: I'd appreciate your guidance here. What do you think we should do?

#5 @noisysocks
3 years ago

Looking at the source for @wordpress/block-library, it might be safe to remove @wordpress/editor as a dependency altogether because the classic block doesn't use it if wp.oldEditor is undefined. Maybe that's a better option.

https://github.com/WordPress/gutenberg/blob/271d711908ab6883ad5a107372f5e9cfc750b7a2/packages/block-library/src/index.js#L145

#6 @gziolo
3 years ago

I think that https://github.com/WordPress/gutenberg/pull/32801 is a good approach to take at the moment. It's how it worked before 5.8. We can improve the implementation later.

#7 @noisysocks
3 years ago

Awesome. After packages are updated tomorrow to contain GB32801 I can commit only the remove_action part of the attached PR.

#8 @desrosj
3 years ago

  • Resolution set to fixed
  • Status changed from accepted to closed

In 51202:

Widgets: Stop loading wp-editor and the Block Directory assets on the widgets screen.

When using the text widget, a wp.editor.initialize is not a function notice is encountered. This happens when wp-editor is loaded as a dependency, which assigns wp.oldEditor = wp.editor and then redefines wp.editor.

wp-editor is only used for the Classic block, which is not supported in the new widgets editor. [51198-51199] updated @wordpress/block-library to remove wp-editor as a dependency, but it’s still listed as a dependency of the wp-block-directory script handle.

Since the Block directory is not supported within the widgets editor, the related assets can safely be blocked from enqueueing.

Props noisysocks, gziolo, Mamaduka, mkaz.
Fixes #53437. See #53397.

#9 @desrosj
3 years ago

To follow along with an extended effort to decouple the block directory and the block library from @wordpress/editor, you can monitor https://github.com/WordPress/gutenberg/issues/32842.

#10 follow-up: @knutsp
3 years ago

I still see this error message when loading the Widgets Screen with 5.8-beta3-51218.

This ticket was mentioned in Slack in #core by knutsp. View the logs.


3 years ago

#12 in reply to: ↑ 10 @knutsp
3 years ago

Replying to knutsp:

I still see this error message when loading the Widgets Screen with 5.8-beta3-51218.

Was due to a plugin CoBlocks that I had not deactivated after testing. All ok.

#13 @zieladam
3 years ago

I believe that, besides the script loading issue, a large part of this is in how we communicate with the user. I proposed a communication-oriented improvement here: https://github.com/WordPress/gutenberg/pull/33165

#14 @zieladam
3 years ago

Digging further into this one. I proposed a backwards-compatible solution for the root cause of the error in https://github.com/WordPress/wordpress-develop/pull/1481

It simply does this:

Object.assign(window.wp.editor, window.wp.oldEditor);

We need it because of the reasons mentioned in https://github.com/WordPress/gutenberg/issues/33203, most importantly there is quite some code in core and in plugins that expect wp.editor to be really wp.oldEditor. We can maybe patch the core, but it will break all the third party plugins. It would be convenient to deprecate the old wp.editor object, but for now we need to maintain BC in 5.8 and I think that PR is our best shot at that.

This ticket was mentioned in PR #1481 on WordPress/wordpress-develop by adamziel.


3 years ago
#15

## Description
Solves https://github.com/WordPress/gutenberg/issues/33203
Solves https://core.trac.wordpress.org/ticket/53437
Related to https://core.trac.wordpress.org/ticket/53569

Situation: packages/editor is exposed as window.wp.editor in wp-admin

Problem: there is quite some code expecting to see a different (legacy) object under window.wp.editor

Proposed solution: export all the members of legacy window.wp.editor from this new module to maintain backward compatibility

As @noisysocks noticed in https://github.com/WordPress/gutenberg/pull/33228:

Makes me wonder if a “fix” could be to add code to Core which fires off doing_it_wrong() if you enqueue wp-editor or wp-edit-post in the widgets screen.

This PR contains no such code, I will spin a new one to add these deprecations as there may be some discussion needed about the best way of adding them.

## How has this been tested?

  1. Activate classic widgets plugins.
  2. Insert text widget
  3. Add some text to widget.
  4. Deactivate classic widgets plugins.
  5. Go to widget screen.
  6. There is an error message if this PR is not applied.
  7. There are no error messages if this PR is applied.

## Screenshots

<img width="1904" alt="124498441-3f40df80-ddb4-11eb-99e1-581b287f96de" src="https://user-images.githubusercontent.com/205419/124633716-d9bd2380-de85-11eb-9228-742facbacaf9.png">

(Credits for the screenshot and the test plan to @spacedmonkey)

## Types of changes
Bug fix (non-breaking change which fixes an issue)

This ticket was mentioned in PR #1484 on WordPress/wordpress-develop by adamziel.


3 years ago
#16

Following up on https://github.com/WordPress/wordpress-develop/pull/1481, this PR addresses the following comment expressed by @noisysocks:

Makes me wonder if a “fix” could be to add code to Core which fires off doing_it_wrong() if you enqueue wp-editor or wp-edit-post in the widgets screen.

Related to:

#17 @spacedmonkey
3 years ago

For what is worth, I have tested #1481 and it fixed the issue. I would recommend it as the solution.

#18 @spacedmonkey
3 years ago

I also believe we should update the references to wp.editor in the text widget.
There are 4 references. 1, 2, 3 and 4. The text widget should not use wp.editor for tinymce, it should be a good example.

This ticket was mentioned in PR #1488 on WordPress/wordpress-develop by spacedmonkey.


3 years ago
#19

The text widget, uses the tinymce editor. This used to be on wp.editor, but now widget screen uses the gutenberg editor, wp.editor is used by gutenberg. Use wp.oldEditor to get the legacy editor back.

Trac ticket: https://core.trac.wordpress.org/ticket/53437

#20 @TimothyBlynJacobs
3 years ago

Is wp.oldEditor always present? Even if the block-based widgets editor isn't being used?

@spacedmonkey
3 years ago

Classic widget editor

@spacedmonkey
3 years ago

Block based widget editor

#21 @spacedmonkey
3 years ago

@TimothyBlynJacobs See my attached screenshots. It seems like wp.oldeditor is always present.

#22 @TimothyBlynJacobs
3 years ago

Nice, this makes a lot of sense to me then.

#23 @noisysocks
3 years ago

Testing https://github.com/WordPress/wordpress-develop/pull/1481:

  • ✅ No error when loading new widgets screen with a Text legacy widget, 5.8, patch not applied, no plugins. (Because it was fixed in [51202].)
  • ✅ No error when loading new widgets screen with a Text legacy widget, 5.8, patch applied, no plugins.
  • wp.editor.initialize error when loading new widgets screen with a Text legacy widget, 5.8, patch not applied, CoBlocks plugin. (This is what we're aiming to fix.)
  • ✅ No error when loading new widgets screen with a Text legacy widget, 5.8, patch applied, CoBlocks plugin.
  • ✅ When I visit the classic widgets screen, I can see that wp.oldEditor === wp.editor is true in DevTools.
  • ✅ When I visit the new widgets screen, I can see that wp.oldEditor === wp.editor is false and that wp.editor.initialize is defined in DevTools.
  • ✅ When I visit the post block editor, I can see that wp.oldEditor === wp.editor is false and that wp.editor.initialize is defined in DevTools.

So, all seems good! I think it's a neat solution. It stops user-facing errors caused by a plugin incorrectly enqueuing wp-editor on the widgets screen.

However, we also ought to encourage plugins to not enqueue wp-editor on the widgets screen. Doing so does not make sense as wp-editor provides functions for working with a post editor. The widgets screen has no post object. Usually this happens because wp-editor is a dependency of some other script and the plugin a author is unaware. This is where https://github.com/WordPress/wordpress-develop/pull/1484 comes in, which calls _doing_it_wrong() when wp-editor is enqueued alongside wp-edit-post.

Testing https://github.com/WordPress/wordpress-develop/pull/1484:

  • ✅ No warning when loading new widgets screen, 5.8, patch applied, no plugins.
  • _doing_it_wrong() warning when loading new widgets screen, 5.8, patch applied, CoBlocks plugin, WP_DEBUG enabled.
  • ✅ No warning when loading new widgets screen, 5.8, patch applied, CoBlocks plugin, WP_DEBUG disabled.

So, all seems good there too! Two bits of feedback on the code:

  • To clarify, does this check style deps as well? If so it should fix #53569.
  • Placing this very specific bit of logic in WP_Dependencies::recurse_deps() doesn't feel right to me. It's a low level "system" function. Can we move the check to a late-firing hook (wp_loaded?) and use the public$wp_scripts->query() method instead?

noisysocks commented on PR #1484:


3 years ago
#24

To clarify, does this check style deps as well?

Placing this very specific bit of logic in WP_Dependencies::recurse_deps() doesn't feel right to me. It's a low level "system" function. Can we move the check to a late-firing hook (wp_loaded?) and use the public $wp_scripts->query() method instead?

Something like this (haven't tested):

{{{php
add_action( 'wp_loaded', 'wp_check_widget_editor_deps' );
function wp_check_editor_deps() {

global $wp_scripts, $wp_styles;
foreach ( array( $wp_scripts, $wp_styles ) as $deps ) {

if (

$deps->query( 'wp-editor' ) && (

$deps->query( 'wp-edit-widgets' )

$deps->query( 'wp-customize-widgets' )

)

) {

_doing_it_wrong( ... );

}

}

}
}}}

#25 @noisysocks
3 years ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

#26 @noisysocks
3 years ago

  • Owner changed from noisysocks to zieladam
  • Status changed from reopened to assigned

spacedmonkey commented on PR #1488:


3 years ago
#27

CC @noisysocks @adamziel

#28 @andraganescu
3 years ago

  • Keywords commit added

This change tracks the solution in the corresponding Gutenberg PR and it looks like the best way forward. Great work!

adamziel commented on PR #1488:


3 years ago
#29

I like the change, it should work well because oldEditor is set this way in script-loader.php:

{{{js

$scripts->add_inline_script(

'editor',
'window.wp.oldEditor = window.wp.editor;',
'after'

);

}}}

and text-widgets has editor set as a dependency (also in script-loader.php):

{{{js
$scripts->add( 'text-widgets', "/wp-admin/js/widgets/text-widgets$suffix.js", array( 'jquery', 'backbone', 'editor', 'wp-util', 'wp-a11y' ) );
}}}

👍

#30 @spacedmonkey
3 years ago

@zieladam Has approved PR #1488, it will need to commited to core along with other changes.

adamziel commented on PR #1484:


3 years ago
#31

@noisysocks I agree it shouldn't live in that internal function. Also the query is a good idea, thank you!

The problem with wp_loaded hook is that, at least in case of Jetpack, wp-editor is not yet enqueued when wp_loaded is dispatched runs (it's enqueued in response to enqueue_block_editor_assets). I guess plugins may enqueue wp-editor arbitrarily late, even in response to wp_footer action – this complicates this deprecation notice.

The most resilient solution would be dispatching an action or a filter whenever script/styles dependencies are recalculated, this way it would be impossible to overlook that conflict. The second best thing is do it as some late stage while we can still display the notice at the top of the screen – if we only do it at the bottom, I bet most people won't even notice. wp_print_scripts sounds like a good candidate to me, alternatively we could assume this is an admin-only thing and move forward with admin_head or admin_menu.

adamziel commented on PR #1484:


3 years ago
#32

@noisysocks I updated this PR, LMK if it looks good for you now!

noisysocks commented on PR #1484:


3 years ago
#33

I pushed up some fixes. I also tested this again and it's still looking good!

I think using admin_head makes the most sense to me as:

  • It fires after enqueue_block_editor_assets and admin_enqueue_scripts-$hook_suffix which is where most of the problematic examples we've seen in the wild are enqueued.
  • It only runs on the admin pages, which is all we need. Don't want to unnecessarily slow the frontend down.
  • It isn't specific to either scripts or styles.
  • Developers will see the error message because it's at the top of the page.

#34 @noisysocks
3 years ago

In 51387:

Editor: Merge conflicting wp.editor objects into single, non-conflicting object

The wp-editor script (@wordpress/editor npm package) is exposed as
window.wp.editor in WP Admin. This causes problems, though, as many older
scripts expect to see the older editor script available at window.wp.editor.

The solution is to export all the members of the older window.wp.editor module
in the newer module to maintain backwards compatibility.

See #53437.
Props zieladam, spacedmonkey, TimothyBlynJacobs, andraganescu.

#35 @noisysocks
3 years ago

In 51388:

Widgets: Warn when wp-editor script or wp-edit-post style is enqueued in widgets editor

It is common that plugins erroneously have wp-editor or wp-edit-post as a
dependency in a script that is loaded in the new widgets editor. This is a smell
since both @wordpress/editor and @wordpress/edit-post assume the existence
of a global "post" object which the widgets editor does not have.

[51387] fixes the user-facing errors typically caused by this mistake, but we
can go a step further and warn developers about this by calling
_doing_it_wrong() when we detect that the wp-editor script or wp-edit-post
style is enqueued alongside wp-edit-widgets or wp-customize-widgets.

See #53437.
Fixes #53569.
Props zieladam, spacedmonkey, TimothyBlynJacobs, andraganescu, dlh.

#36 @noisysocks
3 years ago

  • Keywords fixed-major added

I am leaving this ticket open for [51387] and [51388] to be backported.

#37 @noisysocks
3 years ago

  • Keywords dev-feedback added

#38 @SergeyBiryukov
3 years ago

In 51390:

Docs: Some documentation improvements for wp_check_widget_editor_deps():

  • Add missing short description for the function.
  • Correct function names in _doing_it_wrong() calls.
  • Document the usage of $wp_scripts and $wp_styles globals.
  • Update syntax for multi-line comment per the documentation standards.

Follow-up to [51387], [51388].

See #53437, #53569.

#39 @SergeyBiryukov
3 years ago

In 51391:

I18N: Translate _doing_it_wrong() messages in wp_check_widget_editor_deps().

This makes them consistent with other similar messages in core.

Follow-up to [51387], [51388], [51390].

See #53437, #53569.

#40 @SergeyBiryukov
3 years ago

  • Keywords dev-reviewed added; dev-feedback removed

[51387], [51388], and [51390] should be good to backport.

[51391] does not need backporting at this time, as we're in string freeze. It can wait for 5.8.1 or 5.9.

#41 @zieladam
3 years ago

Heads up that there are some references to wp.editor in https://github.com/WordPress/wordpress-develop/blob/2382765afa36e10bf3c74420024ad4e85763a47c/src/js/_enqueues/vendor/tinymce/plugins/wordpress/plugin.js#L15 as well and this is why it matters: https://github.com/WordPress/gutenberg/pull/33228#discussion_r666897885

If we keep updating the wp.editor references to wp.oldEditor ones, we should do an exhaustive grep over all the JS files in trunk.

#42 @spacedmonkey
3 years ago

@noisysocks Can you review / comment my PR as well. PR 1488

desrosj commented on PR #1484:


3 years ago
#43

This was merged into Core in https://core.trac.wordpress.org/changeset/51388.

#44 @desrosj
3 years ago

In 51392:

Editor: Merge conflicting wp.editor objects into single, non-conflicting object

The wp-editor script (@wordpress/editor npm package) is exposed as
window.wp.editor in WP Admin. This causes problems, though, as many older
scripts expect to see the older editor script available at window.wp.editor.

The solution is to export all the members of the older window.wp.editor module
in the newer module to maintain backwards compatibility.

Props zieladam, spacedmonkey, TimothyBlynJacobs, andraganescu, noisysocks.
Merges [51387] to the 5.8 branch.
See #53437.

#45 @desrosj
3 years ago

In 51393:

Widgets: Warn when wp-editor script or wp-edit-post style is enqueued in widgets editor

It is common that plugins erroneously have wp-editor or wp-edit-post as a
dependency in a script that is loaded in the new widgets editor. This is a smell
since both @wordpress/editor and @wordpress/edit-post assume the existence
of a global "post" object which the widgets editor does not have.

[51387] fixes the user-facing errors typically caused by this mistake, but we
can go a step further and warn developers about this by calling
_doing_it_wrong() when we detect that the wp-editor script or wp-edit-post
style is enqueued alongside wp-edit-widgets or wp-customize-widgets.

Props zieladam, spacedmonkey, TimothyBlynJacobs, andraganescu, dlh, noisysocks.
Merges [51388] to the 5.8 branch.
Fixes #53569. See #53437.

#46 @desrosj
3 years ago

In 51394:

Docs: Some documentation improvements for wp_check_widget_editor_deps():

  • Add missing short description for the function.
  • Correct function names in _doing_it_wrong() calls.
  • Document the usage of $wp_scripts and $wp_styles globals.
  • Update syntax for multi-line comment per the documentation standards.

Follow-up to [51387], [51388].

Props SergeyBiryukov.
Merges [51390] to the 5.8 branch.
See #53437, #53569.

#47 @desrosj
3 years ago

  • Resolution set to fixed
  • Status changed from assigned to closed

In 51409:

Widgets: Replace wp.editor references in the legacy text widget.

This changes the references to wp.editor in the text widget’s JavaScript to wp.oldEditor, which is the new location for the old editor script that was previously available at window.wp.editor.

Follow up to [51387-51388,51390].

Props spacedmonkey, zieladam.
Fixes #53437.

#48 @desrosj
3 years ago

  • Keywords dev-feedback added; dev-reviewed removed
  • Resolution fixed deleted
  • Status changed from closed to reopened

Reopening to backport [51409] after a second committer review.

#50 @SergeyBiryukov
3 years ago

  • Keywords dev-reviewed added; dev-feedback removed

[51409] looks good to backport.

#51 @desrosj
3 years ago

  • Resolution set to fixed
  • Status changed from reopened to closed

In 51416:

Widgets: Replace wp.editor references in the legacy text widget.

This changes the references to wp.editor in the text widget’s JavaScript to wp.oldEditor, which is the new location for the old editor script that was previously available at window.wp.editor.

Follow up to [51387-51388,51390].

Props spacedmonkey, zieladam, SergeyBiryukov.
Merges [51409] to the 5.8 branch.
Fixes #53437.

This ticket was mentioned in Slack in #core-editor by zieladam. View the logs.


3 years ago

spacedmonkey commented on PR #1516:


3 years ago
#55

👍

adamziel commented on PR #1516:


2 years ago
#56

I'm not pursuing this work anymore so I'm closing this PR. Feel free to take over!

Note: See TracTickets for help on using tickets.