Skip to content

Commit e701ae5

Browse files
author
Gabriel Schulhof
committed
optionsToClasses: Concentrate deprecated code in a single extension
1 parent c290839 commit e701ae5

File tree

2 files changed

+138
-0
lines changed

2 files changed

+138
-0
lines changed

js/index.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
'helpers.js',
2323
'data.js',
2424
'animationComplete.js',
25+
'widgets/optionsToClasses.js',
2526
'widgets/page.js',
2627
'widgets/page.dialog.js',
2728
'widgets/loader.js',

js/widgets/optionsToClasses.js

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
2+
//>>description: Behavior mixin to mark first and last visible item with special classes.
3+
//>>label: First & Last Classes
4+
//>>group: Widgets
5+
6+
define( [ "jquery", "../helpers" ], function( jQuery ) {
7+
//>>excludeEnd("jqmBuildExclude");
8+
(function( $, undefined ) {
9+
$.mobile.behaviors._optionsToClasses = {
10+
11+
// BEGIN DEPRECATED CODE - TO BE REMOVED IN 1.6.0
12+
13+
// During _create(), the initial value of the classes option reflects the initial values of the
14+
// various style options. However, if the user modifies the style options via data-* attributes
15+
// or by instantiating the widget with options, then, before using the classes option to add
16+
// classes to the various widget elements, we must update the contents of the classes option to
17+
// reflect the non-default style options values the user has chosen for this widget.
18+
//
19+
// Thus, for your widget implementation, you should maintain a hash with the default values of
20+
// the various style options, and you should pass that hash as the first parameter to this
21+
// function. The second parameter is this.options, because that hash contains the user's
22+
// potentially non-default style option values. Call this function as early as possible in your
23+
// widget's _create(), before ever using this._classes() to add classes to an element.
24+
_updateClassesOption: function( defaultStyleOptions, currentOptions ) {
25+
var optionName,
26+
modifiedOptions = {};
27+
28+
// Check against the default style option values to see if any of them have changed for
29+
// this instance of the widget
30+
for ( optionName in defaultStyleOptions ) {
31+
if ( defaultStyleOptions[ optionName ] !== currentOptions[ optionName ] ) {
32+
modifiedOptions[ optionName ] = currentOptions[ optionName ];
33+
}
34+
}
35+
36+
// Update classes option to reflect the non-default style option values to be used for
37+
// this instance of the widget
38+
this._optionsToClasses( defaultStyleOptions, modifiedOptions );
39+
},
40+
41+
// This function simply converts a space-separated list of classes to a hash where the key is
42+
// the class name and the value is true. This allows constant-time lookup. It is used for
43+
// updating the value of one of the classes option keys in response to changes of the
44+
// wrapperClass option.
45+
_convertClassesToHash: function( classValue ) {
46+
var index,
47+
returnValue = {};
48+
49+
classValue = classValue ? classValue.split( " " ) : [];
50+
for ( index in classValue ) {
51+
returnValue[ classValue[ index ] ] = true;
52+
}
53+
54+
return returnValue;
55+
},
56+
57+
// This code is used very often in the _optionsToClasses() extension point which contains
58+
// the widget-specific portions of the code. Basically, based on the value of option, you
59+
// decide whether the corresponding class (like ui-corner-all or ui-shadow ui-listview-inset)
60+
// is to be added to the hash of classes that need to be removed from the class string
61+
// (oldClasses) or whether it is to be added to the hash of classes that need to be added to
62+
// the class string (newClasses). These hashes are then used in the function
63+
// _calculateClassKeyValue() below to update the value of a single key under the classes
64+
// option.
65+
//
66+
// The return value of the function serves to indicate whether the option is present at all.
67+
// Giving this information in the return value allows you to place a call for each option in
68+
// and if-statement, and if any option has changed, you can then, in the body of the
69+
// if-statement, update the corresponding classes key.
70+
_booleanOptionToClass: function( option, className, oldClasses, newClasses, condition ) {
71+
72+
// If the option is not defined, the corresponding classes option key does not need to be
73+
// updated, so we forget the whole thing and return false.
74+
if ( option !== undefined ) {
75+
76+
// If we have been passed the boolean result of a custom condition, we decide based on
77+
// that whether the className is to be added to the hash of oldClasses vs. the hash of
78+
// newClasses. Otherwise, we assume that the option is boolean and decide on the right
79+
// hash based on its value.
80+
( ( condition === undefined ? option : condition ) ?
81+
newClasses : oldClasses )[ className ] = true;
82+
return true;
83+
}
84+
85+
return false;
86+
},
87+
88+
// This is the function that saves you from having to do regex replacement on the value of one
89+
// of the classes keys. Instead of regex, it splits the value of the classes key into an array,
90+
// and prunes it of the entries corresponding to keys in the hash classesToRemove, and adds
91+
// those keys of the hash classesToAdd which are not already in the array.
92+
_calculateClassKeyValue: function( currentValue, classesToRemove, classesToAdd ) {
93+
var currentValueIndex, oneClass,
94+
newValue = [];
95+
96+
// Convert the space-separated class list to an array
97+
currentValue = currentValue ? currentValue.split( " " ) : [];
98+
99+
// Copy the classes from the current value to the new value, while examining each as to
100+
// whether it should be present in the new value
101+
for ( currentValueIndex in currentValue ) {
102+
oneClass = currentValue[ currentValueIndex ];
103+
104+
// If this class was supposed to be added but is already present in the array, well,
105+
// then it's already added, so no need to add it again. Therefore remove it from the
106+
// hash of classes to add.
107+
if ( oneClass in classesToAdd ) {
108+
delete classesToAdd[ currentValue[ currentValueIndex ] ];
109+
}
110+
111+
// If we're supposed to remove this class, don't add it to the result
112+
if ( oneClass in classesToRemove ) {
113+
continue;
114+
}
115+
116+
// Finally, add the class to the list of classes that will be space-joined to become
117+
// the new value of the classes option key
118+
newValue.push( oneClass );
119+
}
120+
121+
// Add the classes which needed to be added and which were not already present in the
122+
// current value
123+
for ( oneClass in classesToAdd ) {
124+
newValue.push( oneClass );
125+
}
126+
127+
// Construct the new value of the classes option key by space-joining the array we've
128+
// constructed.
129+
return newValue.join( " " );
130+
}
131+
};
132+
133+
// END DEPRECATED CODE
134+
})( jQuery );
135+
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
136+
});
137+
//>>excludeEnd("jqmBuildExclude");

0 commit comments

Comments
 (0)