| Daniel@0 | 1 /** | 
| Daniel@0 | 2  * jQuery plugin for basic BEM manipulations. | 
| Daniel@0 | 3  * | 
| Daniel@0 | 4  * @author Max Shirshin | 
| Daniel@0 | 5  * @version 2.1.3 | 
| Daniel@0 | 6  * | 
| Daniel@0 | 7  */ | 
| Daniel@0 | 8 (function($, undefined) { | 
| Daniel@0 | 9 | 
| Daniel@0 | 10     var getEventPattern = function(block, elem, modName, modVal) { | 
| Daniel@0 | 11             return block + (elem !== undefined ? '__' + elem : '') + '_' + modName + '_' + (typeof modVal === 'boolean' ? '*' : (modVal || '*')); | 
| Daniel@0 | 12         }, | 
| Daniel@0 | 13         getElemClasses = function(domEl) { | 
| Daniel@0 | 14             if (domEl.classList) { | 
| Daniel@0 | 15                 return $.makeArray(domEl.classList); | 
| Daniel@0 | 16             } else { | 
| Daniel@0 | 17                 return $.trim(domEl.className).split(/\s+/); | 
| Daniel@0 | 18             } | 
| Daniel@0 | 19         }; | 
| Daniel@0 | 20 | 
| Daniel@0 | 21     $.extend($.fn, { | 
| Daniel@0 | 22         getMod: function(block, elem, modName) { | 
| Daniel@0 | 23             if (modName === undefined) { | 
| Daniel@0 | 24                 modName = elem; | 
| Daniel@0 | 25                 elem = undefined; | 
| Daniel@0 | 26             } | 
| Daniel@0 | 27 | 
| Daniel@0 | 28             if (this.length) { | 
| Daniel@0 | 29                 var classPattern = block + (elem !== undefined ? '__' + elem : '') + '_' + modName, | 
| Daniel@0 | 30                     modVal = false; | 
| Daniel@0 | 31 | 
| Daniel@0 | 32                 $.each(getElemClasses(this.get(0)), function(i, c) { | 
| Daniel@0 | 33                     if (c === classPattern) { | 
| Daniel@0 | 34                         modVal = true; | 
| Daniel@0 | 35                         return false; | 
| Daniel@0 | 36                     } else if (c.indexOf(classPattern) === 0 && c.substr(classPattern.length, 1) === '_') { | 
| Daniel@0 | 37                         modVal = c.substr(classPattern.length + 1); | 
| Daniel@0 | 38                         return false; | 
| Daniel@0 | 39                     } | 
| Daniel@0 | 40                 }); | 
| Daniel@0 | 41 | 
| Daniel@0 | 42                 return modVal; | 
| Daniel@0 | 43 | 
| Daniel@0 | 44             } else return undefined; | 
| Daniel@0 | 45         }, | 
| Daniel@0 | 46 | 
| Daniel@0 | 47         setMod: function(block, elem, modName, modVal) { | 
| Daniel@0 | 48             if (modVal === undefined) { | 
| Daniel@0 | 49                 modVal = modName; | 
| Daniel@0 | 50                 modName = elem; | 
| Daniel@0 | 51                 elem = undefined; | 
| Daniel@0 | 52             } | 
| Daniel@0 | 53 | 
| Daniel@0 | 54             return this.each(function() { | 
| Daniel@0 | 55                 var $this = $(this), | 
| Daniel@0 | 56                     classPattern = block + (elem !== undefined ? '__' + elem : '') + '_' + modName; | 
| Daniel@0 | 57 | 
| Daniel@0 | 58                 if (modVal === false) { | 
| Daniel@0 | 59                     $this.removeClass(classPattern); | 
| Daniel@0 | 60                 } else if (modVal === true) { | 
| Daniel@0 | 61                     $this.addClass(classPattern); | 
| Daniel@0 | 62                 } else { | 
| Daniel@0 | 63                     $.each(getElemClasses(this), function(i, c) { | 
| Daniel@0 | 64                         if (c.indexOf(classPattern) === 0 && c.substr(classPattern.length, 1) === '_') { | 
| Daniel@0 | 65                             $this.removeClass(c); | 
| Daniel@0 | 66                         } | 
| Daniel@0 | 67                     }); | 
| Daniel@0 | 68 | 
| Daniel@0 | 69                     $this.addClass(classPattern + '_' + modVal); | 
| Daniel@0 | 70                 } | 
| Daniel@0 | 71 | 
| Daniel@0 | 72                 // after the modifier is set, run the corresponding custom event | 
| Daniel@0 | 73                 var args = { | 
| Daniel@0 | 74                     block: block, | 
| Daniel@0 | 75                     elem: elem, | 
| Daniel@0 | 76                     modName: modName, | 
| Daniel@0 | 77                     modVal: modVal | 
| Daniel@0 | 78                 }; | 
| Daniel@0 | 79 | 
| Daniel@0 | 80                 // trigger the wildcard event pattern first | 
| Daniel@0 | 81                 $this.trigger('setMod:' + getEventPattern(block, elem, modName), args); | 
| Daniel@0 | 82                 // for boolean modifiers, one can only use the wildcard pattern, | 
| Daniel@0 | 83                 // so no need to trigger the same event twice | 
| Daniel@0 | 84                 if (typeof modVal !== 'boolean') { | 
| Daniel@0 | 85                     $this.trigger('setMod:' + getEventPattern(block, elem, modName, modVal), args); | 
| Daniel@0 | 86                 } | 
| Daniel@0 | 87             }); | 
| Daniel@0 | 88         }, | 
| Daniel@0 | 89 | 
| Daniel@0 | 90         hasMod: function(block, elem, modName) { | 
| Daniel@0 | 91             return !! this.getMod(block, elem, modName); | 
| Daniel@0 | 92         } | 
| Daniel@0 | 93     }); | 
| Daniel@0 | 94 | 
| Daniel@0 | 95 })(jQuery); |