User:Salvatore Ingala/Notes

= Intro = Scope of the project is to make gadgets customizable, that is:
 * Allow gadget writers to easily export their gadget's customization variables.
 * Provide the users with a nice UI for customizing those variables.

This page contains a newer design than the one I proposed in my application, since the scope of the project has slightly changed.

Places
I'm working on this branch: http://svn.wikimedia.org/viewvc/mediawiki/branches/salvatoreingala/Gadgets/ Previous brainstorming was done on EtherPad. This is the last useful revision.

= Features definition = These are the needed features:
 * 1) Ability to specify what preferences do we have for a gadget;
 * 2) *Will do this in JSON format.
 * 3) *Where? For now, I'm using a fixed page MediaWiki:Gadget-mygadget.preferences or something similar. Likely to change (with low impact)
 * 4) *STATUS: implemented ('boolean', 'string', 'number', 'select' and 'range' options; more will be added); server-side validation done (needs refinements); client site validation done with jquery.validate (link).
 * 5) Hooking up to Special:Preferences to add per-gadget prefs
 * 6) *Currently done like this: every enabled gadget shows a "configure" link near his checkbox in Special:Preferences. Clicking on the link pops up a modal dialog with the configuration interface. Saving preferences for that specific gadget could be done when closing the dialog. This should be robust against future changes of Special:Preferences.
 * 7) *STATUS: working UI mock-up
 * 8) Store preferences somewhere
 * 9) *Using the existing user_properties table. Gadget preferences are retrieved and then hidden in UserLoadOptions hook, and reinserted in UserSaveOptions.
 * 10) *Unused preferences need to be deleted (lazily is good enough). Saving policy to maintain coherency:
 * 11) **When saving the configuration of a gadget, throw away any previous configuration for that gadget (so to clean up old values for no-longer-existing settings).
 * 12) **When reading the configuration of a gadget, check it against its specification and assume default for missing values or values that fail validation (if specifications changed).
 * 13) *STATUS: implemented
 * 14) Provide the preferences to gadgets. Concepts:
 * 15) *mw.gadgets.options.get( 'gadgetname' )?
 * 16) *mw.loader.options.get( 'modulename' )?
 * 17) *binding the configuration to this in gadget's context. (may have issues with RL2, unreliable for now)
 * 18) *STATUS: implemented, currently binding the configuration to this, which is my preferred solution :P - It's easy to switch to any other version.
 * 19) Internationalization of strings used by the gadget
 * 20) *There are two types of "messages" to handle:
 * 21) *#messages shown in the configuration dialog; these don't need to be passed to the gadget's module, and may be interpreted server-side, when building the dialog code during the AJAX request. Should fetch their names form the configuration JSON (maybe adding some common prefix);
 * 22) *#other messages used by the gadget; this is in the scope of RL2.
 * 23) *STATUS: implemented (with some issues to fix)

= Preference description syntax =

The "preference description" is an object in JSON format which describes all relevant info about gadget's settings (and some other settings related to the configuration system); when all the rest of the project will be finished, a tool to create and maintain preference descriptions may be built, so to relieve gadget developers from the annoyance of learning its syntax.

The general format is this:

"global" settings will be settings that apply to the preference dialog (e.g.: min/max width, min/max height, title...). It will be useful for future advanced features, too.

is an object containing gadget's settings along with their option description objects.

The syntax of a single option description object is as follows:

,, and   are compulsory for any option description. According to, more fields may be allowed (or needed).

must be a valid JavaScript (that is, it must start with a letter or '_', then contain only letters, numbers or '_') identifier, and must not be more than 40 characters long.

Raw strings and messages
The ability to specify messages in the "MediaWiki:" namespace is absolutely necessary; nevertheless, sometimes raw strings are needed. Instead of making complex syntaxes to distinguish between raw strings and messages, a preprocessing of strings is done: if the string starts with "@", then it's intended as a message prefixed by "MediaWiki:Gadget-mygadget" (where  is the name of the gadget, case-sensitive); otherwise, it's a raw string. Two "@" at the beginning escape for a single "@". This currently applies to  fields and to options of   fields.

intro
A string or message placed on top of the dialog's content.

Option definition specifications
This section describes additional fields allowed for each option.

boolean
This type will be shown as a checkbox. No additional fields are allowed.

string</tt>
This will be shown as a single-line text field. There are additional fields:


 * required</tt>: (optional boolean, defaults to false</tt>). If true</tt>, a zero-length string will never be accepted; if false</tt>, a zero-length string will always be accepted (even when minlength</tt> is given).
 * minlength</tt> (optional integer, defaults to 0): an integer number specifying the minimum length allowed for this option.
 * maxlength</tt> (optional integer, defaults to a big integer): an integer number specifying the minimum length allowed for this option.

number</tt>
This will be shown as a single-line text field. The javascript representation of values of this field is as numeric datatypes (or null). There are additional fields:


 * required</tt>: (optional boolean, defaults to true</tt>). If true</tt>, a valid number must be given. If false</tt>, an empty string will be accepted (and will be delivered as null</tt>).
 * min</tt> (optional number): a number specifying the minimum allowed value.
 * max</tt> (optional number): a number specifying the maximum allowed value.
 * <tt>integer</tt> (optional boolean, defaults to <tt>false</tt>). If <tt>true</tt>, only integer numbers will be accepted (<tt>min</tt> and <tt>max</tt> must honor this, too). If <tt>false</tt>, decimal number will be allowed, too.

<tt>select</tt>
This will be shown as an HTML <tt>select</tt> element. There is only an additional compulsory field:


 * <tt>options</tt>: (compulsory object): an object with fields of the type <tt>"msg": value</tt>, where <tt>msg</tt> behaves like labels, and <tt>value</tt> is an arbitrary javascript value (allowed values are <tt>null</tt>, booleans, numbers or strings. Different option values may have different types. All values should be different (according to the <tt>===</tt> operator). No two <tt>"msg"</tt>s may be equal, of course.

<tt>range</tt>
Shown as a jQuery.UI Slider, even if only its basic functionality is currently supported. There are other fields:


 * <tt>min</tt>: (compulsory number): Minimum allowed number.
 * <tt>max</tt>: (compulsory number): Maximum allowed number.
 * <tt>step</tt>: (optional number, defaults to 1): Gap between allowed numbers.

Negative or decimal numbers are valid values for <tt>min</tt>, <tt>max</tt> and <tt>step</tt>.

Note that <tt>max</tt> must be coherent with <tt>min</tt> and <tt>step</tt> (that is, the difference between <tt>min</tt> and <tt>max</tt> must be an integer multiple of <tt>step</tt>).