-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Widget Review
Is it feasible to have option-driven widget initialization? That is, during _create() we merely arrange the DOM element, and we do not consult the options at all. Then, we loop over all the options and set each one. This has the effect of initializing the widget while reusing the option-setting code at initialization time and forcing us to make each option settable on-the-fly.
During _create(), all options must be applied unconditionally. This can be done by calling _setOption() for each this.options. If two options are not orthogonal, - the same code will be executed twice - the values may not be consistent (i.e., if option1 = x, option2 cannot = y -> which one takes precedence? We need to decide and then document)
During refresh(), we take data-* attributes from the DOM and we synch this.options. We must only set those options which have changed. Do we blindly call _setOption() for each, or do we execute internal, optimized code. Is there an opportunity to write a function that figures out which options need changing? A function to be placed in the superclass/into an extension? If we write such a function, and then loop over the options that need changing, we run into the same problem of non-orthogonal options.
During _set<Option>() we must set a second option or execute some common code if two options are not orthogonal. If the new option value would cause the non-orthogonal second option value to become invalid, we need to calculate a new value for the second option to bring it back to validity, or error out. We need to decide which we wish to do and then document that.
Option demultiplexing is generally OK, but we need to get rid of the exceptions.
Possible solution for non-orthogonal options: During _create(): We copy this.options, then we null-out all its values, and we call this._setOptions( copyOfOptions ). That will result in unconditionality and widgets that have non-orthogonal options can override the default implementation of _setOptions() which, as implemented in the widget factory simply iterates over the options and calls _setOption() with each option. This subclassed version of _setOptions() can then chain up to the superclass with the reduced set of options (those that are orthogonal).
This is not good performance-wise, because we do a lot of going through a lot of functions in various widgets instead of dealing with the options in-widget. OTOH, it's much cleaner and more consistent.
We should not assume that the widget is based on an input like we do with slider. Currently, to use the slider with a div you have to add attributes min, max, and step, which are invalid for a div. Does the spec forbid us from using such attributes, or does it simply stipulate that they be ignored if present?
If it's not based on a div, where does the value go? Do we sync a DOM attribute with the value?
We should have a standard for creating the outermost div:
- if the widget is based on a div, use that div, otherwise
- if the widget is based on an input, wrap that input in the widget's outermost div
using on vs _on for elements which will be destroyed
how to do one with _on ?
- Implement widget() for all widgets, because we also need to
- Rename ui-disabled to ui-state-disabled, because the widget factory automatically adds that class to the element returned by widget() when the disabled option is turned on. The class is removed when the disabled option becomes false.
- The widget factory provides two methods: enable() and disable() - both are implemented via calls to _setOption( "disabled", newValue ). So, instead of writing our own enable() and disable() functions, we should write our own handler for the "disabled" option, if the above facilities are insufficient for a widget.