|
| 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