Closed
Bug 115462
Opened 23 years ago
Closed 3 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•23 years ago
|
||
*** Bug 115351 has been marked as a duplicate of this bug. ***
Updated•23 years ago
|
Status: NEW → ASSIGNED
Target Milestone: --- → mozilla0.9.8
Reporter | ||
Comment 2•23 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•23 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•22 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•14 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•6 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•5 years ago
|
Component: DOM → DOM: Core & HTML
Comment 12•3 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: 3 years ago
Resolution: --- → WONTFIX
You need to log in
before you can comment on or make changes to this bug.
Description
•