Page MenuHomePhabricator

VE plugins from user scripts not always loaded
Open, LowPublic8 Estimated Story Points

Description

Steps to reproduce:

  1. Add the following code to your common.js:
mw.loader.using( 'ext.visualEditor.desktopArticleTarget.init' ).done( function() {
	mw.libs.ve.addPlugin( function() {
		console.log( 'VE plugin' );
	} );
} );
  1. Start editing VE by

a) Opening it from read view in the same tab.
b) Opening it in a new tab and immediately switch to that tab.
c) Opening it in a new tab, wait, and switch to that tab later.

  1. Open the console.

Expected result:
The log entry "VE plugin" is always visible.

Actual result (at least in Firefox):
a) and b) as expected, but in c) the log entry (and actually all VE plugins from user scripts) is missing.

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript

This might be caused by some strange loading order: when all dependencies of ext.visualEditor.desktopArticleTarget.init are already ready when it loads, it will start initializing immediately, before marking itself as ready. So the hook from common.js will fire too late.

If this is the reason it will probably be fixed once jQuery is updated to 3.0, as this will make the initializing promise to work asynchronously, and will give the hook from common.js opportunity to execute early enough.

Jdforrester-WMF moved this task from To Triage to TR1: Releases on the VisualEditor board.
Jdforrester-WMF set the point value for this task to 8.

Is this the same as T156899?

No, this happens for the local common.js, for which VE currently explicitly waits, while it doesn't wait for global.js. So, the symptoms are the same, but the cause is definitely different.

Another way to reliably reproduce:

  1. Go to https://de.wikipedia.org/wiki/Spezial:Suche/Does_not_exist
  2. Click the red link labeled "erstellen" (normal left-click, to open it in the same tab).

This opens the page for creating in VE, but does not load any plugin from your common.js.

As far as I can tell, this is caused by a logical flaw in https://phabricator.wikimedia.org/diffusion/EVED/browse/master/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.init.js;cde2110722c831a78d28cebcb269471a788f6ba6$121:

targetPromise will be resolved only after the user scripts have been loaded, but calling mw.libs.ve.addPlugin there will just push the plugins in the plugins array, and this array is immediately in getTarget. Plugins that you try to register later are ignored.

Instead, after loading the user scripts, the plugins array should be evaluated again, adding all plugins that have been registered since, or some other way to ensure that plugins from user scripts registered via mw.libs.ve.addPlugin are passed on to mw.libs.ve.targetLoader.addPlugin.

I'm not sure it would be a good idea to run plugins that are loaded after target init. Plugins is designed to run before target init, and some plugins may depend on this behaviour. It sounds like the issue is user scripts loading too late, but that would be an issue with MW core?

I couldn't reproduce this though, maybe because browsers don't run JS queues in the background anymore.