This is an experimental draft markup language for controlling desktop and/or CrudScreen
style GUIs and get around the LimitsOfHtmlStack
. The purpose is to explore possibilities and limits for desktop/crud-style GUIs as markup. HTML widgets, such the INPUT tag, are assumed if not stated otherwise and if they don't contradict anything here. This is not reinventing the wheel, only the spokes, hub, lug-nuts, and connection to the axle. WebBrowserMissingWidgetWorkArounds
suggests specific widgets that perhaps should be added; but this topic tends not to focus on specific widgets below the windowing level except where the updating mechanism needs explicit explanation.
Note that we are getting rid of the one-file-per-window concept. A given stream or "text transaction" could contain the definition and/or activation of multiple windows.
Let's start with an example that re-creates the basic panels of a typical email-and-planner client with grouped menu listings on the left panel (Mail, Calendar, Planner), which is a kind of collapsible navigation panel. The center top panel lists the messages and the center bottom panel displays contents of the message selected in panel above it. Here's a rough Ascii-art representation:
|..Menus or Tool-bar......|
|Mail.....|.Email Title A.|
|.(stuff).|>Email Title B<|
|Calendar.|.Email Title C.|
(Dots to prevent TabMunging
. Please do not remove. A "PRE" bug in the wiki also displays extra blank lines for some examples on Mozilla-based browsers.)
<!-- Listing A -->
<menuFrame> <!-- menus or tool-bars -->
<frameSet cols="25%, 75%" name="outer">
<frameSet rows="33%,33%,33%" resizable="yes" name="navig"
minimizable="yes" maximizable="yes" windowStyles="stack,mdi,tab">
<frame name="mail_folders" document="mail" title="Mail" icon="mail.gif"/>
<frame document="calendar" title="Calendar"/>
<frame document="planner" title="Planner"/>
<frameSet rows="50%,50%" name="content">
<document name="dialog_1" modal="yes" visible="no"/> <!-- modal dialog box for later -->
The "frameSet" is similar to HTML frame-sets, but more flexible. It can be of the "collapsable" (minimizable) kind as found in the left category panes of many desk-top apps these days. It can have a title and icon in it (besides the chevron min/max icons if enabled) .
And, it can also be switched to be MDI (overlapping sub-windows) or tabs. ("stacked" is the kind already described.) And optionally the user can switch between these by clicking a small control button in the upper right of the frame-box that appears if the user is given a choice via the "windowStyles" attribute with more than one option (or upper-left if vertical "slicing" is chosen).
"_all" is a short-cut to listing all three. (Switching can also be tied to a custom menu option.) This three-way ability gives GUI designers and users potentially lots of flexibility in app layout. If one multi-window style is not working, the designer and/or user can just change it to one of the others. I consider this one of the best features
of this proposal. The fight over MDI versus tabbed versus stacked can now end because one can have an instant choice .
The "menuFrame" is a special kind of frame for menus, toolbars, and "ribbons" that is similar to any other frame, except that it sizes to the content (menus, toolbars, etc.) and is generally not re-sizable (drag-able) in relation to other frames. If you really want a re-sizable or minimizable menu/toolbar area, then you can put menus/toolbars into a regular frame, or visa-versa. The menu and tool-bar widgets can in theory be put into any frame (sub-widow). (Arguably it could be called something like "fixedFrame" instead, or even have regular frames have a "fixed" option. But "menuFrame" is better self-documenting for its primary use.)
One can "emulate" the newer "ribbon" style menus by doing this:
<!-- Ribbon Emulation Example -->
<frameSet windowStyles="tab" cols="*,*,*,*"> <!-- 4 menu items. Asterisk idiom from HTML -->
<frame title="Create" .../> <!-- menu item set 1 -->
<frame title="Import" .../> <!-- menu item set 2 ... -->
<frame title="Export" .../>
<frame title="Format" .../>
A ribbon interface is essentially a tabbed windowing sub-system. Each frame can also have it's own "menuFrame" by using nested frame-sets if you want sub-menus or sub-tool-bars for some purpose, such as a text editing window with it's own tool-bar, similar to WikiPedia
's text editor interface.
A "footerFrame" is similar to a "menuFrame" except that it's at the bottom (or right if configable to diff conventions). They both share the property that they are not normally scrollable or re-sizable. A status bar would be a typical use of a "footerFrame". If mixed in with a "tool tray" convention, it may resemble:
<frameSet cols="60%,40%" resizable=yes minimizable="no" maximizable="no">
<frame name="status_bar" document="status_bar_doc"/>
<frame name="tool_tray" document="tool_tray_doc"/>
A "document" is similar to an HTML page, but doesn't have to be a file . A "form" is merely an optional grouping mechanism. However, it is weaker than in HTML because one can use Document scope exclusively. Think of a "form" as roughly similar to the SPAN tag in that it is mostly used to identify groupings. Forms can be nested, but must have unique names within the document. This Form convention can help reduce network traffic by fine-tuning the target widgets being analyzed for content. Events can choose to send data in the document or at the form level within a document.
All documents must have unique names within the application and widgets must be unique within a form . If a document has no form, then a single form named "default" is assumed for that document. Thus, any given widget can be uniquely addressed by document name, form name, and widget name
. Unlike HTML, duplicate widget names are not allowed (radio-buttons and checkboxes are possible exceptions, depending on their design).
<!-- Example: Event 1 -->
<input type="button" value="Click Me!" onclick="event01">
<sendContent document="my_doc_2" form="my_form_A">
<sendContent document="my_doc_2" form="my_form_B" widget="my_text">
<sendContent document="my_doc_3" form="my_form_C" scope="full">
<sendContent document="my_doc_3" form="my_form_C" widget="my_grid" scope="changemarked">
<setFocus document="dialog_save_confirm"> <!-- (normally sent by server, not client event) -->
The 'scope="full"' tag indicates that complex widget content is sent, such as individual cells in a data grid. 'scope="changmarked"' means that only marked content is sent. Changing content will set its "change mark" to "yes". When the server processes the content and is happy with it, it can set the change marks back to "no":
<document="foo" widget="grid_2" row="7" changeMark="no">
<document="foo" widget="grid_2" row="8" changeMark="no">
Or optionally just send an acknowledgment that the update package was received, at which time the browser can automatically reset the markers.
If client-side scripting is allowed, then trigger tags such as "onClick" could also contain scripting language references. But these are normally explicitly marked by the language name/type before a colon:
Without a colon-ized language name, the markup's own events are assumed. Event "lists" don't normally have loops and conditionals. Also, which commands are permitted in the lists can be controlled. More on permissions is given later.
The "update" attribute for a given tag has one of 3 values:
- Attribute (default if UPDATE attribute not given)
Under "attribute", any attribute values just replace any existing values, or create new attributes if they don't already exist. This is called the Delta Approach
in some topics. To illustrate, suppose this was initially sent:
<foo name="glob" flib="QWERTY">
<bar name="zerg" value=7>
Now suppose later the server sent this to the client:
<foo name="glob" grat="vib">
<bar name="zerg" value=8>
<bar name="feep" value=47">
The browser would then assume this as its GUI layout state:
<foo name="glob" flib="QWERTY" grat="vib">
<bar name="zerg" value=8>
<bar name="feep" value=47>
As you can see, the "flib" attribute was not changed or removed, but "grat" added. Any attribute remains in place unless replaced by another value, such as with the "value=8" designation in the second tag, or unless the 'update="delete"' or 'update="tag"' is used for a given tag. For example:
<foo name="glob" update="tag" newthing="yipyip">
Would result in a GUI state of:
<foo name="glob" newthing="yipyip">
<bar name="zerg" value=8>
<bar name="feep" value=47>
As you can see, the "flib" and "grat" attributes have been removed. 'update="tag"' clears out any prior attributes of that tag. It's a "soft delete", unlike the next one:
The 'update="delete"' is a "deep delete", meaning that it would remove all child tags also. The "update" attribute is not normally "kept" in the browser GUI state. In other words, if one "dumped" the browser GUI state as markup text, they wouldn't see any "update" attributes. A possible exception would be in events if permissions allowed such. (A "shallow" delete is unnecessary, as you would find out if you experimented with some examples; for the "tag" update level covers such cases sufficiently.)
Although not shown here, each update packet should identify by name the document, form, and widget, if applicable, per above uniqueness rules.
If the sequence matters, then the first defined tag is normally the first assumed. But if one wants to change the order or insert into the middle of a set later, then every tag has a "sequence" attribute implied that can be used. Thus, if this is sent:
<bar name="zerg" sequence=5>
<bar name="feep" sequence=4>
then "feep" is assumed to come before "zerg". They don't have to be contiguous and don't have to start with "1".
The order of the above can be changed by sending:
<bar name="zerg" sequence=1>
<bar name="feep" sequence=2>
Decimal portions are also allowed, but not recommended.
To reduce code size and redundancy, tag templates can be used.
<template name="frameX" resizable="yes" minimizable="yes"
<frameset name="A" refTemplate="frameX" cols="*,*">...</frameset>
<frameset name="B" refTemplate="frameX" cols="*,*,*">...</frameset>
<frameset name="C" refTemplate="frameX" rows="*,*" resizable="no">...</frameset>
This example allows one to avoid having to set commonly-used attributes for our frame-sets. One can still explicitly override any given attribute that's in the template, as frame-set "C" illustrates with a different "resizable" attribute. Thus, using templates does not require one to accept every template attribute as-is. Only one level of templating is currently supported by the draft standard, although the templates can be listed in priority: reftemplate="frameX,frameY,frameEtc".
for an alternative syntax idea for templating.
Tree and Data-Grid Widgets
 MS-Access 2007's navigational panel looks like such, but actually behaves more like a tree widget because it does not show all groups if the lists are large and expended. But our convention always shows at least the group's/sub-window's bar. One could use a tree widget instead to emulate Access 2007. The table/view properties could be the 3rd level. The 2003 style would match a tree/table hybrid widget. They exist, but are expensive.
 Tabbed "windows" are not normally min- and maximizable, so such attributes would be ignored if in tabbed mode. Also "stacking" can be vertical, not just horizontal, depending on whether "rows" or "cols" are specified for frame-sets. Maybe "stack" is not the right word. Alternatives welcome. Having a horizontal or vertical orientation doesn't matter for MDI. Perhaps the tab style should also ignore the verticle/horizonal setting. A left navigational pane is preferred over left-side tabs from a design viewpoint. However, if the tab quantity is dynamic and grows high, then having the option of switching to left-side tabs may be nice. Something to think about. Sizability of tabs is also of questionable value. "Resizable" also assumes the order of tabs and sub-window bars can be changed. Perhaps a "reordable" attribute is also needed. The chart below helps one see the differences in the 3 windowing modes.
* short-hand or simplified
 One can reference other files via an INCLUDE tag.
If permissions allow, URL's can also be used. One could argue that an explicit "file" attribute is not needed because URL's can reference files also, but such can be a bit long-winded.
 Form-level was chosen as the unique name-space for widgets over document-level to allow modularization and reuse of widget groups. If the name scope was instead at document-level, then name-space collision concerns would be much larger. Using form-level means that one normally only has to manage the form's naming to ensure unique widget addressing, not each widget. It also allows repeating widget markup on each document without widget renaming.
 A relatively new kind of multi-window mechanism is popping up (pun). It's kind of like a static menu in which the windows pop open to the side, below, or above. It's kind of like roll-over pop-ups or nested menus, but with windows or forms instead of lists. This could be a fourth windowing choice. A variation is to have a "tag" that sticks out, and clicking on the tag pops or slides out the window. However, such should perhaps be treated as event-triggered windows instead of a multi-window container. The same or similar effect can be obtained by just launching a new window, but with a kind of "slide expand" animation to make it appear sliding out. However, a new window is generally not considered part of the underlying frame-set, while the actual witnessed slider mechanisms generally are. For example, they stay visible even when they don't have focus. Whether they need to be, needs further exploration to see if it's useful or a fad. Help wizards even from way back have kind of had a similar feel in that they stay in place so that you can read them while doing a task. They are kind of "embedded but floating" windows. Is this merely an "amodal" window? It's a kind of an app-wide MDI model outside of an explicit container or frame. Perhaps an existing window in a given frame-set could be allowed to be "docked" to the side if one wants it to be one of these "slide-pop" windows. In that case, it's not really a 4th "kind" of windowing scheme, but rather a feature/attribute that any window in a given frame-set can be given. Thus, an existing window in a MDI, tab, or stacked window set could potentially be set as a "slide-pop" window by the user and/or designer. These attributes could be added to a given window or window template to handle this: sidePopOrient=<top,bottom,left,right>, sidePopAllow=<none,active,optional> ("active" means the side-tag starts in place, while "optional" means user can turn it into a side-pop window by right-clicking the options menu on the window title), sidePopOrientChange=<yes,no> (controls if user can change the orientation. May be overkill.) The default is: sidePopOrient="left" sidePopAllow="optional" sidePopOrientChange="yes". Related: WhatIsaWindow
 A globally-sequential name of "object_N" is automatically assigned to any tag without an explicit name, where N is the sequential number. While useful for debugging, it's not very app-friendly for dynamic updating. Perhaps a separate "objectID" attribute should be assigned to every object regardless of any existing names. Unique reference numbers are handy for many reasons.
Event Syntax Style
Somebody changed this:
<input type="button" value="Click Me!" myJsEvent()>
I don't have a strong preference either way, but I figure the first will work better with existing XML parsers and tools. I'm trying to reinvent GUI coding, not XML :-)
Another issue is different events. We may have an "onClick" event, an "onRollover" event, "onFocus" event, etc. I don't see how the second one accommodates this, other than saying the shortcut syntax only applies to the "default" event, but this may be confusing. -t
See Also: AddressingGuiElements