Page MenuHomePhabricator

Stop using ve.init.target
Open, Needs TriagePublic

Description

ve.init.target is a global variable that refers to the VisualEditor instance on the page. This is fine, until instead of the instance, you have two.

We ran into issues caused by this when working on DiscussionTools, when both the DiscussionTools reply widgets and the normal VisualEditor tried to control it. Instead of solving it properly (or documenting…) we piled up more hacks on top (rEVEDbcfb250f5648: Ensure that ve.init.target is correct when re-activating an ArticleTarget).

It also causes issues in ContentTranslation, where some code is impossible to unit test without setting up a global target (see e.g. 0b2a839ea9a91e9cc0c1615bfc4528c23374dee0, T220314), and for Flow, which uses multiple Targets on a page and sometimes ve.init.target goes null somehow (T303960).

Any code that needs to call some methods on a Target should be passed one explicitly, instead of grabbing the global one.

We might need to leave the code that writes to ve.init.target intact, for compatiblity with gadgets etc. that already use it (it's also nice to have for debugging), but we should never read it in our code.

Remaining uses:

core (lib/ve/src)

  • ve.ui.CommandHelpDialog, for working out which keyboard shortcuts have been registered

ve-mw

  • Users of getWikitextFragment (and getContentApi/getLocalApi), which needs to know the current page title, host (via getContentApi) and revision ID to parse fragments correctly. Different hosts is used by ContentTranslation which shows 2 VE instances with documents from different language wikis. If you were able to edit the "source" document, this would expose some bugs but at the moment you will only call getWikitextFragment from one side.

Event Timeline

In some places we have avoided pointers to containers, to encourage relevant data to be passed to contained objects (e.g. pass data from target to surface, instead of having surface "reach" into the target)

There are also many places where we do have upwards pointers (e.g. DocumentNode -> Surface). I think in general this is ok and it would be up to code reviewers decide if an object is doing to much "reaching up" instead of having data passed to it.

Having a pointer from surface to the containing target allow us to remove most references to ve.init.target.

ve.init.target usage:

In core (lib/ve/src)

  • ve.ui.CommandHelpDialog, for working out which keyboard shortcuts have been registered

In ve-mw

  • Multiple users of getWikitextFragment (and getContentApi/getLocalApi), which needs to know the current page title, host (via getContentApi) and revision ID to parse fragments correctly. Different hosts is used by ContentTranslation which shows 2 VE instances with documents from different language wikis. If you were able to edit the "source" document, this would expose some bugs but at the moment you will only call getWikitextFragment from one side.

Change 884044 had a related patch set uploaded (by Esanders; author: Esanders):

[VisualEditor/VisualEditor@master] Pass surface to all dialogs, and use in CommandHelpDialog

https://gerrit.wikimedia.org/r/884044

Change 884284 had a related patch set uploaded (by Esanders; author: Esanders):

[VisualEditor/VisualEditor@master] [BREAKING CHANGE] Pass Target to UI Surface and use instead of ve.init.target

https://gerrit.wikimedia.org/r/884284

Change 884044 merged by jenkins-bot:

[VisualEditor/VisualEditor@master] Pass surface to all dialogs, and use in CommandHelpDialog

https://gerrit.wikimedia.org/r/884044

Change 886158 had a related patch set uploaded (by Bartosz Dziewoński; author: Bartosz Dziewoński):

[mediawiki/extensions/VisualEditor@master] Update VE core submodule to master (b8cc71bdc)

https://gerrit.wikimedia.org/r/886158

Change 886158 merged by jenkins-bot:

[mediawiki/extensions/VisualEditor@master] Update VE core submodule to master (b8cc71bdc)

https://gerrit.wikimedia.org/r/886158

Change 884284 merged by jenkins-bot:

[VisualEditor/VisualEditor@master] [BREAKING CHANGE] Pass Target to UI Surface and use instead of ve.init.target

https://gerrit.wikimedia.org/r/884284

Change 884419 had a related patch set uploaded (by Bartosz Dziewoński; author: Esanders):

[mediawiki/extensions/VisualEditor@master] Update VE core submodule to master (b5c670c7a)

https://gerrit.wikimedia.org/r/884419

Change 884857 had a related patch set uploaded (by Bartosz Dziewoński; author: Esanders):

[mediawiki/extensions/ContentTranslation@master] Adjust target constructor for recent change (pass target to surface)

https://gerrit.wikimedia.org/r/884857

Change 884419 merged by jenkins-bot:

[mediawiki/extensions/VisualEditor@master] Update VE core submodule to master (b5c670c7a)

https://gerrit.wikimedia.org/r/884419

Change 884857 merged by jenkins-bot:

[mediawiki/extensions/ContentTranslation@master] Adjust target constructor for recent change (pass target to surface)

https://gerrit.wikimedia.org/r/884857

matmarex removed a project: Patch-For-Review.

Once these changes ride the deployment train, and if they don't break anything for anyone that would necessitate reverting them, we should start working on changes to actually stop using ve.init.target.

(The changes here caused T329439, luckily easily fixed.)