© Copyright 2004 Opera Software.
...
This is a work in progress! This document is changing on a daily if not hourly basis in response to comments and as a general part of its development process. Comments are very welcome, please send them to webapps@damowmow.com and cc www-archive@w3.org. Thank you.
It is very wrong to cite this as anything other than a work in progress. Do not implement this in a production product. It is not ready yet! At all!
This document currently has no official standing within the W3C at all. It is the result of loose collaboration between interested parties over dinner, in various mailing lists, on IRC, and in private e-mail. To become involved in the development of this document, please send comments to the address given above. Your input will be taken into consideration.
This is a working draft and may therefore be updated, replaced or rendered obsolete by other documents at any time. It is inappropriate to use Working Drafts as reference material or to cite them as other than "work in progress".
This draft may contain namespaces that use the data: URI
scheme. These are temporary and will be changed before this specification
is ready to be implemented.
To find the latest version of this working draft, please follow the "Latest version" link above.
The World Wide Web's markup language has always been HTML. HTML is a language designed primarily for semantically describing scientific documents, although its general design and adaptations over the years has enabled it to be used to describe a number of other types of documents. XHTML2 [XHTML2] updates HTML with better features for hyperlinks, multimedia content, annotating document edits, and introduces elements for better describing the semantics of human literary works such as poems.
Unfortunately, it lacks elements to express the semantics of many of the non-document types of content most often seen on the Web. For instance, the very popular forum sites, auction sites, search engines, online shops, and the like, do not fit the document metaphor well.
This specification aims to extend HTML so that it is more suitable in these contexts.
display:none, but that's not semantically correct, and it
breaks when you disable stylesheets, which it shouldn't. Having markup
that actually means "hide this until it is activated" would solve this.
divs, but that breaks down when the stylesheet is
disabled, and is semantically dubious at best. (Any time a
div is the answer, there's a hole in HTML.) The idea would
be to introduce the idea of a native "subwindow" element which would work
as a movable window within the content area, which can be dragged,
resized, etc, as required.
iframe to a document that the
server doesn't close and into which it keeps dripping script
blocks, but that's a hack to say the least. What would be nice is a way
of letting a remote server trigger DOM events that standard DOM3 Event
technologies could hook into.
Should the basic unit of a web application be something other than a document? XAML, for instance, lets you use a manifest as the base file (as I understand it).
Annotations? (Probably not: it failed with HTML1, why should it work now?)
This specification adds a number of features to HTML. For XML-based documents, these are added to the XHTML 1.x namespace. This ensures backwards compatibility with, and a simple migration path from, existing HTML and XHTML content.
XHTML2 and this specification address the needs of two different authoring scenarios, and are expected to be used side by side. XHTML2 is optimised for documents — for example help files, essays, articles — whereas this specification is optimised for applications.
This specification is designed to complement Web Forms 2.0. [WF2] Where Web Forms concentrates on input controls, data validation, and form submission, this specification concentrates on client-side user interface features needed to create modern applications.
The CSS3 UI specification [CSS3UI] introduces a number of properties suitable for Web-based application development. This specification expands on those properties and specifies their interaction with scripting-based environments and the DOM.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119].
Diagrams, examples, and notes are non-normative. All other content in this specification is intended to be normative.
Documents that use the new features described in this specification
using HTML over HTTP must be served as text/html. Documents
that use the new features described in this specification using XHTML or
other XML languages over HTTP must be served using an XML MIME type such
as application/xml or application/xhtml+xml. [RFC3023]
(In other words, for the purposes of [RFC2854], documents conforming to this specification using its HTML formulation should be considered HTML documents, but documents using the XML formulation should not be considered HTML-compatible.)
...
...
CSS3 UI [CSS3UI]
The exact appearance used will vary based on other properties and out of band data. In particular, the metadata and dynamic states described in the section on the ElementUI DOM interface directly affect how widgets are rendered. For example, a checkbox will look different based on whether the STATE_GROUP_CHECKED state is set to STATE_CHECKED_UNCHECKED, STATE_CHECKED_CHECKED, or STATE_CHECKED_INDETERMINATE. Progress bars, scroll bars and sliders (track bars) use the STATE_GROUP_VALUE metadata state to determine their position. The value 0 represents the lowest progress/scroll position/slider position, and the value 216-1 (65535) represents the highest progress/scroll position/slider position.
The following dynamic pseudo-classes are defined in terms of state information that can be manipulated through the DOM.
focus() and focusByMethod() methods.
See the ElementUI section for details explaining how to toggle these pseudo-classes.
When the UI module is in CR, this draft will need to be updated to take into account the other pseudo-classes from that module.
In UAs that implement this module, the 'nav-index' property doesn't do anything directly. It is used by methods on the DocumentUI interface to determine the order used for sequential focus changing (what is commonly referred to as "tab order").
The value none means that the element is not part of the normal tab order, regardless of the value of 'user-can-focus'.
The value 'auto' means that the UA may decide where in the tab order the element goes.
The directional navigational properties ('nav-up' and so forth) similarly work in terms of the directional focus methods.
The 'key-equivalent' property doesn't do anything directly. It is used by in XBL as a filter for key events. The idea is that if the window receives a key event that matches an element's key-equivalent, that element will be sent a separate event.
A further draft will explain this in more detail.
Unlike the UI module properties, which apply to non-scriptable environments as well as dynamic, scriptable UAs, these properties control features that are directly related to the DOM.
| Value: | never | always | only-with-modifier |
| Initial: | always |
| Applies To: | all elements and generated content |
| Inherited: | yes |
| Percentages: | n/a |
| Media: | visual |
| Computed Value: | specified value |
A property to decide if the UA should allow inline selection. Note that this is a distinct concept from element selection -- an element can be flagged as selected independently of its contents being selected.
For example, if by default a UA uses mouse dragging as a selection mechanism, then with 'user-can-select' is set to 'only-with-modifier' the same UA could change to mouse dragging with the shift key held down. The name 'only-with-modifier' is not meant to restrict the alternate mechanism, only to indicate that the UA should not enable the default selection mechanism.
When an elements' contents are selected (in part, in whole, or as part of a greater selection), that element contains a ::selection pseudo-element which applies to that selection.
User agents may treat the never value as only-with-modifier in untrusted documents, which typically would cover any document on the web, although the exact definition of 'trusted' is UA-defined and may be dependent on user preferences.
| Value: | takes-focus | leaves-focus | resets-focus |
| Initial: | leaves-focus |
| Applies To: | all elements (but not pseudo-elements) |
| Inherited: | no |
| Percentages: | n/a |
| Media: | visual |
| Computed Value: | specified value |
These properties decide if the UA should allow an element to gain focus.
In this definition, the window is a user-agent-defined construct, typically related to the viewport. When the window has focus, the user is typically able to scroll the document using arrow keys on a keyboard.
Note that this property has no direct effect on the :focus pseudo-class. This property merely determines whether an element can gain focus in a particular view, not whether it can retain focus.
| Value: | all | reset | ignore |
| Initial: | ignore |
| Applies To: | all elements with user-can-focus: takes-focus and user-can-select: always |
| Inherited: | no |
| Percentages: | n/a |
| Media: | visual |
| Computed Value: | specified value |
| Value: | all | reset | ignore |
| Initial: | ignore |
| Applies To: | all elements with user-can-focus: takes-focus and user-can-select: always |
| Inherited: | no |
| Percentages: | n/a |
| Media: | visual |
| Computed Value: | specified value |
| Value: | all | reset | ignore |
| Initial: | ignore |
| Applies To: | all elements with user-can-focus: takes-focus and user-can-select: always |
| Inherited: | no |
| Percentages: | n/a |
| Media: | visual |
| Computed Value: | specified value |
| Value: | all | reset | ignore |
| Initial: | not defined for shorthand properties |
| Applies To: | see prose |
| Inherited: | no |
| Percentages: | n/a |
| Media: | visual |
| Computed Value: | specified value |
These properties explain what part of the contents of the element should be selected when focussing the element.
The property 'user-focus-select-key' applies when the focus change was requested via a keyboard event, the property 'user-focus-select-pointer' applies when the focus change was requested via a pointer event, and the property 'user-focus-select-unknown' applies in other cases. The property 'user-focus-select' can be used as a shorthand for setting the other two properties.
| Value: | read-only | all | [ add-text || edit-text || add-elements || move-elements || attributes || deletable ] |
| Initial: | read-only |
| Applies To: | all elements that can obtain focus |
| Inherited: | yes |
| Percentages: | n/a |
| Media: | interactive |
| Computed Value: | specified value |
This property establishes whether the UA should allow editing of the node and its children.
This property is inherited, but only applies to editing the element
itself and its immediate children. The following makes an element
foo and its children all completely editable:
foo, foo * { user-modify: all; }
That would also allow the element itself to be deleted, however. In order to disallow that, the following rules would be used:
foo { user-modify: children; }
foo * { user-modify: all; }
The exact mechanisms used to enable editing is up to the UA.
The 'text-transform' property is modified to allow a string value to be used. When a string value is specified, all characters in the string are replaced with this string. For example:
input[type=password] { text-transform: '*'; }
This would replace each character in an input field with an asterisk, as seen in many existing web browsers.
The value popup is added to the 'position' property. When this value is applied to an element, the following changes apply:
The ElementUI interface can then be used to actually trigger the popup.
The DocumentUI interface contains methods for
moving focus around the document.
interface DocumentUI {
void moveFocusForward()
void moveFocusBackward()
void moveFocusUp()
void moveFocusRight()
void moveFocusDown()
void moveFocusLeft()
};
moveFocusForward
moveFocusBackward
moveFocusUp
moveFocusLeft
moveFocusDown
moveFocusRight
The ElementUI interface contains methods for
displaying popups and toggling the state of dynamic pseudo-classes.
interface ElementUI {
/* POPUPS */
const unsigned short BEFORE_START = 0;
const unsigned short BEFORE_END = 1;
const unsigned short AFTER_START = 2;
const unsigned short AFTER_END = 3;
const unsigned short START_BEFORE = 4;
const unsigned short START_AFTER = 5;
const unsigned short END_BEFORE = 6;
const unsigned short END_AFTER = 7;
const unsigned short OVERLAP = 8;
const unsigned short AFTER_POINTER = 9;
void showPopup(in unsigned short alignment,
in Element target, in Element anchor);
void hidePopup();
/* METADATA STATE */
/* Metadata states are the same in all views */
const unsigned short STATE_GROUP_ENABLED = 0; // allowed values are STATE_ENABLED_*
const unsigned short STATE_GROUP_DEFAULT = 1; // allowed values are STATE_DEFAULT_*
const unsigned short STATE_GROUP_CHECKED = 2; // allowed values are STATE_CHECKED_*
const unsigned short STATE_GROUP_SELECTED = 3; // allowed values are STATE_SELECTED_*
const unsigned short STATE_GROUP_VALID = 4; // allowed values are STATE_VALID_*
const unsigned short STATE_GROUP_REQUIRED = 5; // allowed values are STATE_REQUIRED_*
const unsigned short STATE_GROUP_DATA = 6; // allowed values are STATE_DATA_*
const unsigned short STATE_GROUP_VALUE = 10; // allowed values are any integer
const unsigned short STATE_ENABLED_DISABLED = 0; // false
const unsigned short STATE_ENABLED_ENABLED = 1; // true
const unsigned short STATE_DEFAULT_NORMAL = 0; // false
const unsigned short STATE_DEFAULT_DEFAULT = 1; // true
const unsigned short STATE_CHECKED_UNCHECKED = 0; // false
const unsigned short STATE_CHECKED_CHECKED = 1; // true
const unsigned short STATE_CHECKED_INDETERMINATE = 2;
const unsigned short STATE_SELECTED_UNSELECTED = 0; // false
const unsigned short STATE_SELECTED_SELECTED = 1; // true
const unsigned short STATE_VALID_INVALID = 0; // false
const unsigned short STATE_VALID_VALID = 1; // true
const unsigned short STATE_REQUIRED_OPTIONAL = 0; // false
const unsigned short STATE_REQUIRED_REQUIRED = 1; // true
const unsigned short STATE_DATA_INACCESSIBLE = 0; // none
const unsigned short STATE_DATA_READABLE = 1; // 0x01
const unsigned short STATE_DATA_WRITABLE = 2; // 0x02
const unsigned short STATE_DATA_EDITABLE = 3; // 0x01 || 0x02
void setMetadataState(in unsigned short state, in long value);
long getMetadataState(in unsigned short state);
/* DYNAMIC STATE */
/* Dynamic states are defined on a per-view basis */
const unsigned short DYNAMIC_ACTIVE = 0;
const unsigned short DYNAMIC_HOVER = 1;
const unsigned short DYNAMIC_OPEN = 2;
void setDynamicState(in unsighed short state, in bool value);
bool getDynamicState(in unsigned short state);
/* FOCUS */
const unsigned short FOCUSED_BY_UNKNOWN = 0;
const unsigned short FOCUSED_BY_KEYBOARD = 1;
const unsigned short FOCUSED_BY_POINTER = 2;
void focus();
void focusByMethod(in unsigned short method);
};
showPopup
alignment of type unsigned short
target of type Element
target is null, then the point representing the (last
known) position of the pointing device is used instead. If the
target element is not visible, or if there
is it is null but there is no pointing
device, then the viewport is used instead. If the viewport is not
visible, then the whole screen is used. This ensures that the popup
will appear, regardless of how it was triggered.
anchor of type Element
null is used, then that implies the
element. If the anchor has no defined
position (which can happen if is hidden using CSS for example) then
its closest ancestor which will have a position when the popup is
shown is used instead.
UIException NOT_A_POPUP_ERR
UIException HIERARCHY_ERR
anchor is not a
descendant of the element or if it is an annoymous descendant that
is not in the default view.
hidePopup
setMetadataState
state of type unsigned short
value of type long
getMetadataState
state of type unsigned short
long
setDynamicState
state of type unsigned short
value of type boolean
getDynamicState
state of type unsigned short
long
focus
focusByMethod
method of type unsigned short
BEFORE_START
The "before"
side of the target is made adjacent to the "after" side of the anchor,
and the "start" sides of the target and anchor are aligned.
BEFORE_END
The "before"
side of the target is made adjacent to the "after" side of the anchor,
and the "end" sides of the target and anchor are aligned.
AFTER_START
The "after"
side of the target is made adjacent to the "before" side of the anchor,
and the "start" sides of the target and anchor are aligned.
AFTER_END
The "after"
side of the target is made adjacent to the "before" side of the anchor,
and the "end" sides of the target and anchor are aligned.
START_BEFORE
The "start"
side of the target is made adjacent to the "end" side of the anchor,
and the "before" sides of the target and anchor are aligned.
START_AFTER
The "start"
side of the target is made adjacent to the "end" side of the anchor,
and the "after" sides of the target and anchor are aligned.
END_BEFORE
The "end" side
of the target is made adjacent to the "start" side of the anchor, and
the "before" sides of the target and anchor are aligned.
END_AFTER
The "end" side
of the target is made adjacent to the "start" side of the anchor, and
the "after" sides of the target and anchor are aligned.
OVERLAP
The before/start
corners of the target and anchor elements are overlapped so that (if
they have the same size) they appear over each other.
AFTER_POINTER
The "after"
side of the target is made adjacent to the "before" side of the anchor,
and the "start" side of the anchor is aligned with the last known
position of the pointing device, if any, or with the "start" side of
the target, if there is no pointing device.
If the target is null and there
is a pointing device, then the last known position of the pointer is
used as the target in the cases above. So for example, if alignment is set to BEFORE_START or END_AFTER,
then the before/start corner of the popup is positioned at the
pointer.
When the target is a point and not a region, the following constants become equivalent:
If the popup is smaller than the screen, then the popup must appear completely on the screen. If, after aligning the popup as specified by the arguments to the showPopup method, the popup would overflow the screen, then the following algorithm should be used. The algorithm should be followed step by step until the popup fits on the screen.
'overflow' property
applies).
OVERLAP and the
anchor is not the popup element itself, then position the anchor as
required, then shift the popup such that it touches the sides of the
screen where the anchor overflows the screen (if that is in only one
direction, the other axis therefore remains unaffected), and apply
the 'overflow' property at that scroll
position.
STATE_GROUP_ENABLED
STATE_ENABLED_DISABLED
STATE_ENABLED_ENABLED
STATE_GROUP_DEFAULT
STATE_DEFAULT_NORMAL
STATE_DEFAULT_DEFAULT
STATE_GROUP_CHECKED
STATE_CHECKED_UNCHECKED
STATE_CHECKED_CHECKED
STATE_CHECKED_INDETERMINATE
STATE_GROUP_SELECTED
STATE_SELECTED_UNSELECTED
STATE_SELECTED_SELECTED
STATE_GROUP_VALID
STATE_VALID_INVALID
STATE_VALID_VALID
STATE_GROUP_REQUIRED
STATE_REQUIRED_OPTIONAL
STATE_REQUIRED_REQUIRED
STATE_GROUP_DATA
STATE_DATA_INACCESSIBLE
STATE_DATA_READABLE
STATE_DATA_WRITABLE
STATE_DATA_EDITABLE
STATE_GROUP_VALUE
DYNAMIC_ACTIVE
DYNAMIC_HOVER
DYNAMIC_OPEN
FOCUSED_BY_UNKNOWN
FOCUSED_BY_KEYBOARD
FOCUSED_BY_MOUSE
Four new events are introduced, all related to popups. These use the base DOM Event interface to pass contextual information. The different types of such events that can occur are:
popupShow method is called. This event is only valid
for elements whose 'position' property has
the value popup. If the event is cancelled, then
the popup will not be shown.
popupHide method is called. This event is only valid
for elements whose 'position' property has
the value popup and which are currently
displayed. If the event is cancelled, then the popup will remain visible.
This section defines some error codes used by the ElementUI interface.
exception UIException {
// UIExceptionCode
const unsigned short NOT_A_POPUP_ERR = 1;
const unsigned short HIERARCHY_ERR = 2;
unsigned short code;
};
NOT_A_POPUP_ERR
HIERARCHY_ERR
This section will define some aspects of the DOM Level 0 "window" interface. In particular, window.open (with all its flags), resizing, possibly window.location and other features.
A great emphasis should be placed here on backwards compatibility. Only the parts that are needed for UI should be defined here.
The Window interface only applies to the default view. There is currently no defined way of obtaining the window interface for another view.
Thanks to Håkon Wium Lie, David Hyatt and Brendan Eich for their important support. Thanks to Matthew Mastracci and Steven Garrity for their useful and substantial comments.
Thanks also to the Microsoft blogging community for some ideas, and to the #mozilla crew, the #opera crew, and the #mrt crew for their ideas and support.