Page MenuHomePhabricator

Provide a standard way for clients to know that they are viewing the mobile version of the site (regardless of skin)
Closed, ResolvedPublic

Description

Background

There are a number of RL modules that use the wgMFMode client-side global configuration variable as a proxy for "is the user viewing the mobile version of the site", e.g.

var isMobile = mw.config.get( 'wgMFMode' ) !== null;

Open Questions

  1. Is this an acceptable use of wgMFMode?
    • If so, could this be document where it's added to the output so that it doesn't get removed?
    • If not, could we introduce a new stable variable to use, e.g. wgMFIsMobile?

Event Timeline

Could this be done using a class on the body element?

Yes, provided that it was considered stable (i.e. it would have to go through some deprecation process to change its name/value(s) or remove it).

Is this an acceptable use of wgMFMode?

In answer to this, I think no. wgMFMode was meant to tell the client whether the user was in beta mode or normal mobile mode. It got repurposed to mean mobile.

Yes, provided that it was considered stable (i.e. it would have to go through some deprecation process to change its name/value(s) or remove it).

I think to make it stable ideally we'd use a mw.util function allowing for us to change the class name in future.

Perhaps this work could be a precursor to feature management. "Mobile mode" is actually a feature, that's enabled in a certain situation (You are on a mobile device).

Perhaps we could use this as task to add some lightweight foundations for feature management in core (T242835)?

  1. A mediawiki.util function to check if features are enabled:
mw.util.isFeatureEnabled('mobile')

Used by WikimediaEvents
Internally checks for classes on the body, that are added by the feature management system. e.g. mobile and visualeditor features may have the associated classes mw-feature-enabled-mobile and mw-feature-enabled-visualeditor

  1. MobileRequirement and MobileFeature

Utilized by MobileFrontend to check the requirement is met and to add it to the page.

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

[mediawiki/extensions/MobileFrontend@master] Add a body class indicating mobilefrontend is active

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

Change 782758 merged by jenkins-bot:

[mediawiki/extensions/MobileFrontend@master] Add a body class indicating mobilefrontend is active

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

To spell out the solution: that patch added mw-mf as a class on the body element, which will only be present if the site is in MobileFrontend mode (regardless of skins, etc). Anything that wants a binary "is MF active" can check for that, and TemplateStyles can hang themselves from it.

Change 809619 had a related patch set uploaded (by Phuedx; author: Phuedx):

[mediawiki/extensions/MobileFrontend@master] Hooks: Add wgMFIsActive client-side config variable

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

Jdlrobson triaged this task as Medium priority.Jul 5 2022, 7:10 PM

I've discussed this task further with @Jdlrobson and we both agree that:

  1. The use of mw.config.get( 'wgMFMode' ) !== null only signals that the MobileFrontend extension is active
  2. Adding another config variable (e.g. wgMFIsActive) only replicates this signal
  3. The PHP and JS Metrics Platform Clients should be updated to reflect the above (already captured in T311629: Change agent_client_platform_family context attribute values)
  4. The JS Metrics Platform Client should be updated to provided a bucketed viewport width

I'm being bold and closing this task as Resolved.

Change 809619 abandoned by Phuedx:

[mediawiki/extensions/MobileFrontend@master] Hooks: Add wgMFIsActive client-side config variable

Reason:

Per https://phabricator.wikimedia.org/T299772#8109026

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

Two things:

  1. The way to tell MobileFrontend from Minerva doesn't seem to be documented anywhere. I've been the second user script maintainer on Wikimedia's Discord server after @Ioaxxere (ping in case he is interested) to wonder why that is the case.
  2. For 3 years that passed after adding mw-mf, I see only one mention of mw-mf added to the global code:
	// TODO: Replace this with whatever config variable is decided on in
	//  https://phabricator.wikimedia.org/T299772.
	//
	// This used to be determined by checking whether <body> had the "mw-mf" class. However, this
	// was determined to be a non-trivial read from the DOM and one that could cause a forced style
	// recalculation in certain situations.
	//
	// See https://gerrit.wikimedia.org/r/c/mediawiki/extensions/WikimediaEvents/+/799353/1#message-21b63aebf69dc330933ef27deb11279b226656b8
	// for a detailed explanation.
	const isMobileFrontendActive = c( 'wgMFMode' ) !== null;

Since this claims mw-mf is suboptimal, I'll reopen. If the comment is wrong, then please document whatever solution that is correct, so that user script maintainers are able to pick up.

Why can't you use mw.config.get('skin') for your use case? What specifically are you trying to detect?

mw-mf is a more intended for use in CSS, it's true -- and it is being used there in a number of places. (Though I do kinda think that caring about document.body.classList.contains('mw-mf') is a bit overzealous in user scripts -- it mostly matters for the WikimediaEvents case because it's really likely to trigger during the critical initial render flow, and for all users.)

Why can't you use mw.config.get('skin') for your use case? What specifically are you trying to detect?

Thanks for the examples! Those are helpful.

Note: there is an "Edit full page" link in the Minerva menu so this might not even be needed on this skin? Maybe @DLynch has thoughts around this.

Screenshot 2025-05-23 at 11.29.24 AM.png (998×2 px, 254 KB)

We've got T387180 for making that more-obvious, though it's stalled on @ppelberg currently. I'm advocating for just having the mobile top-level edit icon be full-page by default, and pushing the edit-lead-section functionality off into that menu.

Note: there is an "Edit full page" link in the Minerva menu so this might not even be needed on this skin? Maybe @DLynch has thoughts around this.

Screenshot 2025-05-23 at 11.29.24 AM.png (998×2 px, 254 KB)

(This behavior was added in this edit by @Esanders with a link to T203151#9037412.)

mw-mf is a more intended for use in CSS, it's true -- and it is being used there in a number of places. (Though I do kinda think that caring about document.body.classList.contains('mw-mf') is a bit overzealous in user scripts -- it mostly matters for the WikimediaEvents case because it's really likely to trigger during the critical initial render flow, and for all users.)

Getting back on topic of this bug: I think wgMFMode should be replaced with something more explicit to reflect what's being tested for as it's often used inappropriately.

What do you want to test forHow to test
the user being on an actually mobile device?Look at the user agent
the user having a small screenLook at the screen width
the skin is MinervaLook at mw.config.get('skin')
a certain menu is availablecheck the DOM for existence or call function like mw.util.addPortletLink and inspect the result
the content has been transformed by MobileFormatter??

If the latter is what we are doing I think we should provide a dedicated config variable for this. Particularly since with Parsoid a lot of this is going to be removed.

Would we be happy if I create a new ticket with that outline and merging this and T395079 into it?

Jdlrobson-WMF renamed this task from Make MobileFrontend signal the user is viewing the mobile version of the site to Provide a standard way for clients to know that they are viewing the mobile version of the site (regardless of skin).May 30 2025, 2:32 PM

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

[mediawiki/extensions/EventLogging@master] The client_platform_family field should correspond with whether the skin is responsive or not

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

Change #1152310 abandoned by Jdlrobson:

[mediawiki/extensions/EventLogging@master] The client_platform_family field should correspond with whether the skin is responsive or not

Reason:

Clearing out open tickets before I leave.

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

Krinkle subscribed.

Per T390923 and from chatting with Jon, I've retroactively documented this at https://www.mediawiki.org/wiki/Manual:Interface/JavaScript#mw.config. This has become a de-facto stable interface widely adopted across the ecosystem in extensions and even inside MediaWiki core itself, in components maintained by multiple WMF and WMDE teams and in volunteer-maintained extensions. That kind of usage demands stability. Stable interfaces can be changed of course, at an implementation, migration, and maintenance cost that one would weigh pros/cons over.

The current variable already follows the current best practices (the standard mw.config mechanism, since gerrit change 52270, which avoids coupling to specific module names or extensions, avoids race conditions, and avoids performance anti-patterns like relying on DOM reads to obtain application state).

Longer-term it sounds like MobileFrontend may be phased out in favor of a responsive skin, however so long as it exists, there'll be a need to detect it. An alternative way to detect it would therefore work the same as what we have, except perhaps under a slightly different name. To re-implement the same as what we have seems not worth the churn, busywork, and disruption.

Caveats:

1: As also mentioned by Jon in T395079#10871118, and in the task description at T390923, more often than not, code probably should not have to detect MobileFrontend and would in fact benefit from not doing so. For example, the HTML layout is actually part of the skin, so code that varies between mobile/desktop instead of by skin is likely broken for users that select the Timeless, Monobook, or the Minerva skin on desktop (instead of Vector). See also: https://www.mediawiki.org/wiki/Extension:MobileFrontend#Q:_How_do_I_detect_the_mobile_site_in_frontend_code

The audit at T390923 showed that the vast majority of our ecosystem already does this correctly (i.e. detect the skin for layout-variable code, and detect MobileFrontend only for things that specific to mobile URLs or mobile formatting). I'm pointing it out here not to correct current practices, but to maintain it and avoid regressions from future misuse.

2: Only boolean usage of wgMFMode is considered stable. The exact string value remains internal, unstable, and subject to change without warning. It may become a real boolean in in the future. I'd also be happy to host it within the MediaWiki core as part of ResourceLoader integration, for long-term support if/when it is no longer needed within MobileFrontend. Note that even longer-term, the value undefined casts to false, and nothing about mw.config itself depends on MobileFrontend, so it does not affect portability or long-term compatibility to use it. Even when MobileFrontend is not installed on a wiki today and/or if it were no longer installed in the future, the code naturally degrades to the right conditional branch.