1 // ==========================================================================
  2 // Project:   SproutCore - JavaScript Application Framework
  3 // Copyright: ©2006-2011 Strobe Inc. and contributors.
  4 //            ©2008-2011 Apple Inc. All rights reserved.
  5 // License:   Licensed under MIT license (see license.js)
  6 // ==========================================================================
  7 
  8  SC.mixin(SC.$.fn, /** @scope SC.$.prototype */ {
  9 
 10   /**
 11     You can either pass a single class name and a boolean indicating whether
 12     the value should be added or removed, or you can pass a hash with all
 13     the class names you want to add or remove with a boolean indicating
 14     whether they should be there or not.
 15 
 16     This is far more efficient than using addClass/removeClass.
 17 
 18     @param {String|Hash} className class name or hash of classNames + bools
 19     @param {Boolean} shouldAdd for class name if a string was passed
 20     @returns {SC.CoreQuery} receiver
 21   */
 22   setClass: function(className, shouldAdd) {
 23     if (SC.none(className)) { return this; } //nothing to do
 24     var isHash = SC.typeOf(className) !== SC.T_STRING,
 25         fix = this._fixupClass, key;
 26 
 27     this.each(function() {
 28       if (this.nodeType !== 1) { return; } // nothing to do
 29 
 30       // collect the class name from the element and build an array
 31       var classNames = this.className.split(/\s+/), didChange = NO;
 32 
 33       // loop through hash or just fix single className
 34       if (isHash) {
 35         for(var key in className) {
 36           if (className.hasOwnProperty(key)) {
 37             didChange = fix(classNames, key, className[key]) || didChange;
 38           }
 39         }
 40       } else {
 41         didChange = fix(classNames, className, shouldAdd);
 42       }
 43 
 44       // if classNames were changed, join them and set...
 45       if (didChange) { this.className = classNames.join(' '); }
 46     });
 47     return this ;
 48   },
 49 
 50   /** @private used by setClass */
 51   _fixupClass: function(classNames, name, shouldAdd) {
 52     var indexOf = classNames.indexOf(name);
 53     // if should add, add class...
 54     if (shouldAdd) {
 55       if (indexOf < 0) { classNames.push(name); return YES ; }
 56 
 57     // otherwise, null out class name (this will leave some extra spaces)
 58     } else if (indexOf >= 0) { classNames[indexOf]=null; return YES; }
 59     return NO ;
 60   }
 61 
 62 
 63 });
 64