Closed
Bug 115462
Opened 24 years ago
Closed 4 years ago
Widgets should use out-of-band state for NS_THEMEing and pseudo-class styling, not attributes
Categories
(Core :: DOM: Core & HTML, defect, P5)
Core
DOM: Core & HTML
Tracking
()
RESOLVED
WONTFIX
People
(Reporter: ian, Unassigned)
References
Details
(Whiteboard: [Hixie-P5] [Hixie-CSSUI2])
(edited from bug 112980:)
I have issues with the isDisabled, isChecked and isSelected functions in
nsNativeThemeWin.cpp.
Using attributes directly like this IMHO is not going to work on the long term.
I think what we should do is bite the bullet and implement the pseudo-class
setting stuff that we've been talking about. Make the XBL for the widgets
toggled the :checked, :indeterminate (tri-state), :disabled, :enabled, etc,
pseudo-classes, then use those in the theme API to determine status instead of
hardcoding knowledge for every widget set we want to support.
This would make it easier to style the control in CSS and would make this API a
lot more resilient when it comes to implementing other controls in XBL (e.g. a
widget set that uses japanese attribute names).
Doing this would require us to add several functions to all elements. (Well,
actually it would require us to add these functions to the view, like
getComputedStyle, but for convenience a shortcut to these functions on the
default view would be added to the elements, yada yada.)
element.setPseudoClass('pseudo', bState)
bState = element.getPseudoClass('pseudo')
...which know how to toggle and return the states of:
:enabled, :disabled [1]
:checked, :indeterminate, :-moz-unchecked [1]
:-moz-open, :-moz-closed [1]
:-moz-vertical, :-moz-horizontal [1]
:focus [2]
:active [3]
:hover [3]
etc...
[1] these pseudo-classses are mutually exclusive. Something may be :-moz-open,
:-moz-closed, or neither, but not both.
[2] this may only be set on elements which take focus (see the XBL/UI2 spec to
see what takes focus). Only one element has focus at any time, although :focus
matches on any element that is a parent of the one with focus and which itself
takes focus.
[3] :active and :hover will never be set on more than one element at once,
although the pseudo-classes match all that elements' parents.
I'm unsure how to deal with progress bars, track bars and scrollbars. I really
would like them to use a "value" property on the element, rather than an
attribute. But that means the state of a checkbox depends on the view, and the
state of a progress bar depends on the element, which is inconsistent and thus
bad. Should the :checked/:indeterminate/:-moz-unchecked pseudos be a special
case that cannot be changed directly by the "setPseudoClass" API?
If we use that convention, that places the pseudo-classes in the following
categories:
:root, :first-child, and the other structural pseudos -- pseudos that are
intrinsic based on the DOM core.
:-moz-open, :-moz-closed, :-moz-vertical, :-moz-horizontal -- per element
togglable pseudos.
:enabled, :disabled, :checked, :indeterminate, :-moz-unchecked, :link,
:visited, -moz-any-link -- pseudos that are intrinsic based on other DOM
properties and/or attributes of the element. (Should :enabled and :disabled
be in this list or the previous one?)
:focus, :active, :hover -- per document togglable pseudos.
The problem with this though is that it means we have to explicitly define magic
mappings between (a) the :checked/:indeterminate/:-moz-unchecked pseudos and the
relevant DOM properties, and (b) the value of progress bars, track bars and
scrollbars and some DOM property. (The mapping from the DOM to :link/:visited/
:-moz-any-link is a complicated and already implemented one, so let's ignore
that here.)
Any better ideas for how to handle boolean, tri-state and unbounded values? Some
other API?
Comment 1•24 years ago
|
||
*** Bug 115351 has been marked as a duplicate of this bug. ***
Updated•24 years ago
|
Status: NEW → ASSIGNED
Target Milestone: --- → mozilla0.9.8
Reporter | ||
Comment 2•24 years ago
|
||
How about (on the ElementUI interface):
/* STATE */
const unsigned short STATE_GROUP_ENABLED = 0;
const unsigned short STATE_GROUP_CHECKED = 1;
const unsigned short STATE_GROUP_SELECTED = 2;
const unsigned short STATE_GROUP_VALUE = 3;
const unsigned short STATE_ENABLED_DISABLED = 0; // false
const unsigned short STATE_ENABLED_ENABLED = 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
void setMetadataState(in unsigned short group, in long value);
long getMetadataState(in unsigned short group);
/* DYNAMIC */
const unsigned short DYNAMIC_ACTIVE = 0;
const unsigned short DYNAMIC_HOVER = 1;
const unsigned short DYNAMIC_OPEN = 2;
void setDynamicState(in unsighed short pseudo, in bool value);
bool getDynamicState(in unsigned short group);
/* FOCUS */
const unsigned short FOCUSSED_BY_UNKNOWN = 0;
const unsigned short FOCUSSED_BY_KEYBOARD = 1;
const unsigned short FOCUSSED_BY_POINTER = 2;
void focus();
void blur();
void focusByMethod(in unsigned short method);
Where the constants are defined as:
STATE_GROUP_ENABLED
STATE_ENABLED_DISABLED
STATE_ENABLED_ENABLED
These constants are used to enable and disable user interface
elements. Every element is either STATE_ENABLED_ENABLED or
STATE_ENABLED_DISABLED. See the :enabled and :disabled
pseudo-classes. Elements all initially start with their
STATE_GROUP_ENABLED state set to STATE_ENABLED_ENABLED.
STATE_GROUP_CHECKED
STATE_CHECKED_UNCHECKED
STATE_CHECKED_CHECKED
STATE_CHECKED_INDETERMINATE
These constants are used to toggle the value of check box and radio
button interface elements. Every element has one of these values.
See the :checked, :unchecked and :indeterminate pseudo-classes.
Elements all initially start with their STATE_GROUP_CHECKED state
set to STATE_ENABLED_UNCHECKED.
STATE_GROUP_SELECTED
STATE_SELECTED_UNSELECTED
STATE_SELECTED_SELECTED
These constants are used to determine the selection state of entire
elements. (Note: This is distinct from text selection and focus.)
Every element is either STATE_SELECTED_SELECTED or
STATE_SELECTED_UNSELECTED. See the :selected and :unselected
pseudo-classes Elements all initially start with their
STATE_GROUP_SELECTED state set to
STATE_SELECTED_UNSELECTED.
STATE_GROUP_VALUE
This constant is used to access the generic integer value of user
interface elements. Every element has such a value, although it is
only typically used by scroll bars, track bars and progress bars.
Elements all initially start with their STATE_GROUP_VALUE state set
to zero.
DYNAMIC_ACTIVE
This constant is used to toggle the active state of elements. Only
one element per view may be active at any one time. Setting an
element to active automatically resets any other active element to
its non-active state. See the :active pseudo-class.
DYNAMIC_HOVER
This constant is used to toggle the hover state of elements. Only
one element per view may be in the hover state at any one time.
Setting an element's hover state to true automatically resets any
other element's hover state. See the :hover pseudo-class. User
agents may, in addition to changes triggered using the
setDynamicState() method, automatically set this state on elements
in response to user events (such as moving the mouse).
DYNAMIC_OPEN
This constant is used to toggle the open/closed state of elements.
Every element has an open/closed state for each view. Toggling the
open/closed state does not affect other elements or other views.
(Note: At the moment there is no way to change the open/closed state
of elements in any view other than the default view.) See the :open
and :closed pseudo-classes.
Then the pseudos are defined as follows:
:active
This pseudo-class matches the element that has its DYNAMIC_ACTIVE
state set, if any, as well as any ancestors of that element.
:hover
This pseudo-class matches the element that has its DYNAMIC_HOVER
state set, if any, as well as any ancestors of that element.
:focus
This pseudo-class matches the element which has focus, if any, as
well as all its ancestors with user-can-focus set to 'takes-focus'.
See the focus() and focusByMethod() methods.
:enabled
This pseudo-class matches all elements that have 'user-can-focus'
set to 'takes-focus', which have their STATE_GROUP_ENABLED state set
to STATE_ENABLED_ENABLED, and whose ancestors (including those that
are not focusable) all have their STATE_GROUP_ENABLED state set to
STATE_ENABLED_ENABLED.
:disabled
This pseudo-class matches all elements that have 'user-can-focus'
set to 'takes-focus' and which have either their STATE_GROUP_ENABLED
state set to STATE_ENABLED_DISABLED or which have an ancestor whose
STATE_GROUP_ENABLED state set to STATE_ENABLED_DISABLED (including
ancestors that cannot be focussed).
:checked
This element matches all elements which have 'user-can-focus' set to
'takes-focus' and their STATE_GROUP_CHECKED state set to
STATE_CHECKED_CHECKED.
:unchecked
This element matches all elements which have 'user-can-focus' set to
'takes-focus' and their STATE_GROUP_CHECKED state set to
STATE_CHECKED_UNCHECKED.
:indeterminate
This element matches all elements which have 'user-can-focus' set to
'takes-focus' and their STATE_GROUP_CHECKED state set to
STATE_CHECKED_INDETERMINATE.
:selected
This element matches all elements which have 'user-can-focus' set to
'takes-focus' and their STATE_GROUP_SELECTED state set to
STATE_CHECKED_SELECTED. This pseudo-class is unrelated to the
similarly named ::selection pseudo-element, which applies to the
text selection.
:unselected
This element matches all elements which have 'user-can-focus' set to
'takes-focus' and their STATE_GROUP_SELECTED state set to
STATE_CHECKED_UNSELECTED.
:open
This element matches all elements which have their DYNAMIC_OPEN
state set.
:closed
This element matches all elements which have their DYNAMIC_OPEN
state unset.
The appearance values would then look at the various dynamic and
metadata states to determine how to draw themselves. For example, a
inner progress indicator bar could look at its elements' value of
STATE_GROUP_VALUE and use it as a percentage, and a checkbox could
decide its checked state based on the STATE_GROUP_CHECKED state's
value.
Comments? I know it feels complex, but this is a complex problem. I think in
practice it would turn out to be a lot simpler than in looks.
Reporter | ||
Comment 3•24 years ago
|
||
Incidentally I'm not at all attached to the names. I just came up with them in a
hurry. It's the concept I'm concerned about.
Reporter | ||
Updated•23 years ago
|
Reporter | ||
Updated•23 years ago
|
Depends on: 112980
Summary: Widgets should use out-of-band state for theming and styling, not attributes → Widgets should use out-of-band state for NS_THEMEing and pseudo-class styling, not attributes
Reporter | ||
Comment 4•23 years ago
|
||
Note. Text fields aren't handled by any of this because text editing and
selection is handled in a way orthogonal to these metadata flags. You set a node
to 'user-modify: text' or 'user-modify: all' (default is 'user-modify:
real-only'), and that makes a node editable. Theme stuff should use
'user-modify' to determine the readonlyness of a field with '-moz-appearance'
set to 'text-field' like it uses the out of band data mentioned above to
determine the other states.
One suggestion hyatt gave is to add :default to match default buttons. I like
that idea. I think it should work like this:
const unsigned short STATE_GROUP_DEFAULT = 5;
const unsigned short STATE_DEFAULT_NORMAL = 0; // false
const unsigned short STATE_DEFAULT_DEFAULT = 1; // true
STATE_DEFAULT_NORMAL
This constant is used to toggle the default element of a document. Only
one element per document may be the default at any one time. Setting an
element to STATE_DEFAULT_DEFAULT automatically resets any other element
to the STATE_DEFAULT_NORMAL state. See the :default pseudo-class. Elements
all initially start with their STATE_GROUP_DEFAULT state set to
STATE_DEFAULT_NORMAL.
:default
This pseudo-class matches all elements that have their STATE_GROUP_DEFAULT
state set to STATE_DEFAULT_DEFAULT.
Note that I think my proposal above should be modified to not take focus into
account for most of the pseudo classes. "Focusability" is set by a property, and
pseudo-classes musn't depend on properties.
Reporter | ||
Comment 5•23 years ago
|
||
We could also do with an API for getting the current default element in the
document, and the current focused element in the view.
Reporter | ||
Comment 6•23 years ago
|
||
Note: the .cheched, .selected, and other DOM attributes would be defined as
mapping to these metadata states.
Updated•23 years ago
|
Target Milestone: mozilla0.9.8 → mozilla0.9.9
Reporter | ||
Comment 7•23 years ago
|
||
bryner, jke iser: This is how you would implement the XBL widgets without using
attributes. The C++ DOM <=> XUL DOM glue code in the XBL would simply forward
any changes of the metadata state to the XUL element, and vice versa, the HTML
element's DOM would use this metadata to return its state, and the
pseudo-classes would use this state information to determine whether or not they
apply.
this looks and sounds good, is there enough time for this before moz1.0?
Updated•23 years ago
|
Target Milestone: mozilla0.9.9 → mozilla1.2
Reporter | ||
Updated•23 years ago
|
Whiteboard: [Hixie-P5] [Hixie-CSSUI2]
Updated•23 years ago
|
Keywords: mozilla1.4
Updated•16 years ago
|
Assignee: hyatt → nobody
QA Contact: jrgmorrison → xbl
Target Milestone: mozilla1.2alpha → ---
![]() |
||
Comment 9•16 years ago
|
||
Not an XBL issue, not at all. Not sure whether it should be in DOM or Widget.
Component: XBL → DOM
QA Contact: xbl → general
Comment 10•15 years ago
|
||
This is a mass change. Every comment has "assigned-to-new" in it.
I didn't look through the bugs, so I'm sorry if I change a bug which shouldn't be changed. But I guess these bugs are just bugs that were once assigned and people forgot to change the Status back when unassigning.
Status: ASSIGNED → NEW
Comment 11•7 years ago
|
||
https://bugzilla.mozilla.org/show_bug.cgi?id=1472046
Move all DOM bugs that haven't been updated in more than 3 years and has no one currently assigned to P5.
If you have questions, please contact :mdaly.
Priority: -- → P5
Assignee | ||
Updated•6 years ago
|
Component: DOM → DOM: Core & HTML
Comment 12•4 years ago
|
||
Some of this might happen as part of Web Components work or Open UI I suppose, but this is no longer the place.
Status: NEW → RESOLVED
Closed: 4 years ago
Resolution: --- → WONTFIX
You need to log in
before you can comment on or make changes to this bug.
Description
•