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} 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 [[ https://doc.wikimedia.org/CodeMirror/master/js/js/CodeMirrorPreferences.html | 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.
```lang=json
{
"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 can take any form, such as serialized JSON.
```lang=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.