MediaWiki talk:Common.js/User:Pi zero/wndialog/sandbox2

Overview
Once completed, this code is meant to go in MediaWiki:common.js, so it can be used by any user on any page on the wiki.

Its function is to allow multiple input fields and buttons on the page. Currently it has text and textarea fields; other kinds of fields such as radio buttons should be added.

Layout of these objects on the page is expected to be aided by use of templates. A button sends some of the input values to a target page, which is expected to have its own page-specific javascript which it uses to do something with those values.

HTML5 sessionStorage is to be used to pass the input values to the button target, and perhaps also to make the input field values more robust against navigating away from the page and coming back (which can happen accidentally).

Security

 * The button target page must be in a certain area of project space, wikinews:wndialog/, rather than having an arbitrary name. This helps keep track of all possible button targets.  Admins are allowed button targets in user space, for secure testing.
 * The target must be fully protected (both edit and move). This guards against untrusted users modifying button actions.
 * The page-specific javascript of button targets must be carefully controlled. It isn't enough to say "only an admin can set up a target page, so we'll rely on admins to not create dangerous button targets"; there must be an infrastructure that makes it easy and natural for admins to build in safety measures when creating button targets.  This might be done by careful design of javascript for use in button targets, probably attached to a device for collecting the input values passed by the button.
 * A button target must be readily able to determine, securely, the origin page from which it was invoked. This is prerequisite for modular design: if a series of pages perform various checks that are then relied upon by another page that performs a sensitive action, such as saving a page or conceivably even publishing an article, the page at the end of the chain has to be sure that the earlier checks were actually carried out.
 * It is important in such cases to check that the origin page was also fully protected, since the behavior of the origin is being relied upon.
 * Modularity is meant to make tools more extensible and, to some extent, more robust. Robustness could come into play because when a module fails to load, the previous module should be still available so that previously accumulated work has not been lost.  Extensibility is envisioned through use of master coordinating tools into which an admin can plug separate modules for subtasks, easing development of additional modules as well as making them easier for users to operate.  (One might, for example, have a master review-assistant coordinating various more specialized assistants.)

From wiki markup to input objects
The user invokes templates to format the input fields and buttons on the page. These templates set up &lt;span&gt; elements containing the data needed to set up the fields/buttons. On page load, the javascript here finds these span elements and replaces them with actual fields/buttons.

From wiki markup to button-click handler
After the span elements are replaced by fields/buttons, the original span elements are no longer on the page. A field visibly contains all the significant information from the span element it replaces. However, a button must also latently contain the name of its target page and the names of the fields it will pass to the target page. This is stored in a field of the javascript object called wndialogButtonData. The button-click event handler retrieves this field from the event target using jquery method data.

Page reentrance
There is only one sessionStorage object per session, but for robustness the tools are meant to allow multiple instances of a page within a session, with persistent data unique to particular instances. The plan is to keep a button-click counter in sessionStorage under the name wndialogNextID, and at each button click, increment it and pass its pre-increment value to the target page as a GET parameter called wndialogID. The target page can then always determine its own unique id number by retrieving the get parameter, which is not vulnerable to loss of javascript state since GET parameters are built into the url. This unique id could then be included in the storage key for data in sessionStorage, identifying exactly which page instance the data belongs to.

Field-value persistence
It may make sense (further investigation warranted) to listen for page unload, and store in sessionStorage the current values of all input fields for the current page. On page load the javascript would then also look for saved values for the fields, which if found would override field defaults specified in the wiki markup.

This should, if done at all, be a separate mechanism from any means used to pass data through a button click from origin to target. Origin-to-target passing is logically separate from field-value persistence: the values passed are determined at the moment of passage, not to be affected by subsequent changes to input fields of either the origin page or target page. The mechanisms would also occur in different javascript files with different functions &mdash; persistence would be part of the code to be placed in common.js for use on all pages, while receipt of passed parameters is in general part of the function of page-specific javascript at the target, ought not to be dependent on whether that page-specific javascript is performed before or after the more general code, and, as noted above, is meant to be a required hook for security provisions on the target code.

From origin to target
Standard storage keys, including the target page's id, should be bound in sessionStorage to the origin page name, and a list of the names of the parameters passed. Each of the values passed should then be stored under a key combining its name with the target id.

Although it would be technically possible to provide the target with the origin's id, this may be undesirable as it could encourage excessive between origin and target pages.

sessionStorage keys:
 * &lt;id&gt;:origin &mdash; name of the page from which the page was called.
 * &lt;id&gt;:params &mdash; comma-separated list of names of parameters passed.
 * &lt;id&gt;:in:&lt;name&gt; &mdash; value passed for parameter &lt;name&gt;.