Page MenuHomePhabricator

Add support for non-boolean CodeMirror preferences
Closed, ResolvedPublic

Description

Currently, all CodeMirror preferences (except colorblind mode) are saved under a single user option, codemirror-preferences. It is a JSON blob with the keys as the feature names (i.e. codeFolding, lint) and the values being either 1 or 0.

T419337: Allow CodeMirror preferences to differ between wikitext and non-wikitext takes it a step further and introduces "mode IDs" so the preferences can be applied to specific environments (though that's likely to remain only wikitext and non-wikitext). The storage for the values is still an integer, meaning we have a small footprint with still plenty of room left for more features to be added. It does however mean we can't then also use the value to store anything other than whether the feature is off, or where it is enabled.

We need to expand the CodeMirrorPreferences logic and storage schema to support something more than off/on values. For example, we'll need at least integers great than 1 to for theming (T163533) and linter options (T408729).

Preventing user_properties bloat (T286270, T54777) as I understand it is more about row count, but at scale we want to keep the storage footprint reasonable as well. In production it is a MariaDB BLOB, which gives us 64KB… so I think we can easily squeeze in whatever we need into the existing codemirror-preferences, and have it be backwards-compatible.

Keeping on with T419337, we'll want the same content model (aka mode) granularity too. Something like:

Old schema
Boolean-only, applies to all editing environments.

{
    "featureA": 0,
    "featureB": 1,
    "featureC": 0
}

After T419337
Same as before, but now with a separate user option codemirror-preferences-code that applies to non-wikitext.

New schema
Same as before, but in addition to 0 / 1 (disabled or enabled), a string value can be provided which implies enabled but with the given value. This value can take any form, such as serialized JSON.

{
    "featureA": 0,
    "featureB": "custom data",
    "featureC": "{\"foo\":1,\"bar\":2}"
}

In the future, we might have things like custom lint rules, custom highlighting of characters (T383285), so I'm trying to think ahead. So long as it's JSON-serializable, and we don't store any key where the value matches the same as the default, I think this will suffice.

Event Timeline

MusikAnimal changed the task status from Open to In Progress.Mar 30 2026, 8:50 PM

Change #1276111 had a related patch set uploaded (by MusikAnimal; author: MusikAnimal):

[mediawiki/extensions/CodeMirror@master] [WIP] API for setting CM prefs

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

Change #1276111 abandoned by MusikAnimal:

[mediawiki/extensions/CodeMirror@master] [WIP] API for setting CM prefs

Reason:

superseded by I09d19567a228e6049f4a94ef312ce8becfb5f0ad

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

Change #1277806 had a related patch set uploaded (by MusikAnimal; author: MusikAnimal):

[mediawiki/extensions/CodeMirror@master] [WIP] Add themes to preferences, and support for non-boolean prefs

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

Change #1278259 had a related patch set uploaded (by MusikAnimal; author: MusikAnimal):

[mediawiki/extensions/CodeMirror@master] CodeMirrorPreferences: add support for non-boolean preference values

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

Change #1278374 had a related patch set uploaded (by MusikAnimal; author: MusikAnimal):

[mediawiki/extensions/CodeMirror@master] CodeMirrorCodex: add a form specifier system

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

Change #1278259 merged by jenkins-bot:

[mediawiki/extensions/CodeMirror@master] CodeMirrorPreferences: add support for non-boolean preference values

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

Change #1278374 merged by jenkins-bot:

[mediawiki/extensions/CodeMirror@master] CodeMirrorCodex: add a form specifier system

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