Page MenuHomePhabricator

Don't register mediawiki.router routes that are catch-alls
Closed, ResolvedPublic

Description

Currently there are a few routes registered which are catch-alls -- a regexp that matches any string. They're being used as a "navigated away" faux-event.

This is bad, because only one route will ever be executed, so the instant we have multiple registered on the same pageload that cleanup-path will be completely broken.

From another ticket there was discussion of alternatives, but we should just clean these up first with the existing "routing is happening" event since they're broken now.

There is some discussion on https://gerrit.wikimedia.org/r/c/mediawiki/extensions/MultimediaViewer/+/1080061 on the best way to register functions for closing apps, i.e. when the path no longer matches your app, or is empty.

@Jdlrobson has proposed a second callback:
router.addRoute( Config.ROUTE_REGEXP, this.route.bind( this ), destroyMMV );

although I think this not quite flexible enough, you may have two paths within one app and exiting either would not destroy the app, but exiting both would.

@Jdlrobson's second proposal is:
router.addDestroyRoute( / list of routes not to apply to / [ Config.ROUTE_REGEXP ] () => {} )

I think this is more promising as syntactic sugar around the general approach in https://gerrit.wikimedia.org/r/c/mediawiki/extensions/MultimediaViewer/+/1080061.

In general it might be a good idea to move Router away from being a registry, as I don't see much value from being abe to silently overwrite a path registration - it is far more likely we would have multiple apps listening to the same path.

To do

  • TypeAheadSearch
  • MultimediaViewer

[x ] NearbyPages

Event Timeline

Change #1175547 had a related patch set uploaded (by DLynch; author: DLynch):

[mediawiki/core@master] Typeaheadsearch: don't add an empty route

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

Change #1175547 merged by jenkins-bot:

[mediawiki/core@master] Typeaheadsearch: don't add an empty route

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

Change #1080061 had a related patch set uploaded (by DLynch; author: Esanders):

[mediawiki/extensions/MultimediaViewer@master] Routing: Don't register a path for closing MMV

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

Change #1080061 merged by jenkins-bot:

[mediawiki/extensions/MultimediaViewer@master] Routing: Don't register a path for closing MMV

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

To protect against this in the future, addRoute should log a warning or throw when trying to register a path that matches empty string or /.

To protect against this in the future, addRoute should log a warning or throw when trying to register a path that matches empty string or /.

That seems sensible. I do think given the widespread usage we should consider creating router.addDestroyRoute or router.addCatchAll to make this easier to understand. We can also make the error point to this method.

FWIW I recently used Vue router which does it using the following route:

{
       path: '/:catchAll(.*)',
       component
   }

FWIW I can review a Nearby patch but I'm still getting up to speed on what we're doing here.

Change #1179216 had a related patch set uploaded (by DLynch; author: DLynch):

[mediawiki/core@master] mediawiki.router: add a teardown callback to addRoute

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

I think I like the second argument to addRoute the most, so here's a patch implementing it, plus the warning on an empty route.

Change #1180629 had a related patch set uploaded (by Jdlrobson; author: Jdlrobson):

[mediawiki/extensions/NearbyPages@master] Don't register mediawiki.router routes that are catch-alls

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

Change #1179216 merged by jenkins-bot:

[mediawiki/core@master] mediawiki.router: add a teardown callback to addRoute

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

Change #1180629 merged by jenkins-bot:

[mediawiki/extensions/NearbyPages@master] Don't register mediawiki.router routes that are catch-alls

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

As we went with the teardown argument, I'll note that using that syntax you could work around the limitation I described in the description above, e.g.

const noop = () => {};
router.addRoute( /subfeature1\/.*, loadSubFeature1 );
router.addRoute( /subfeature2\/.*, loadSubFeature2 );
router.addRoute( /subfeature1|subfeature2\/.*, noop, closeApp );

this would allow you to switch between two different routes of an app, and only call closeApp when a route matching neither is detected.