-
Notifications
You must be signed in to change notification settings - Fork 2
/
jquery.bemhelpers.js
129 lines (110 loc) · 4.52 KB
/
jquery.bemhelpers.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/**
* jQuery plugin for basic BEM manipulations.
*
* @author Max Shirshin
* @version 2.2.1
*
* @thanks K. for the inspiration <3
*
*/
(function($, undefined) {
var BEMsyntax = {
elem: '__',
modBefore: '_',
modKeyVal: '_'
},
getEventPattern = function(block, elem, modName, modVal) {
return block + (elem !== undefined ? BEMsyntax.elem + elem : '') +
BEMsyntax.modBefore + modName + BEMsyntax.modKeyVal +
(typeof modVal === 'boolean' ? '*' : (modVal || '*'));
},
getElemClasses = function(domEl) {
if (domEl.classList) {
return $.makeArray(domEl.classList);
} else {
return $.trim(domEl.className).split(/\s+/);
}
};
$.BEMsyntax = function(props) {
if (typeof props !== 'object') props = {};
for (var prop in props) {
if (props.hasOwnProperty(prop) && BEMsyntax.hasOwnProperty(prop)) {
BEMsyntax[prop] = props[prop];
}
}
return $.extend({}, BEMsyntax);
};
$.extend($.fn, {
getMod: function(block, elem, modName) {
if (modName === undefined) {
modName = elem;
elem = undefined;
}
if (this.length) {
var classPattern = block + (elem !== undefined ? BEMsyntax.elem + elem : '') +
BEMsyntax.modBefore + modName,
modVal = false;
$.each(getElemClasses(this.get(0)), function(i, c) {
if (c === classPattern) {
modVal = true;
return false;
} else if (c.indexOf(classPattern) === 0
&& c.substr(classPattern.length, BEMsyntax.modKeyVal.length) === BEMsyntax.modKeyVal) {
modVal = c.substr(classPattern.length + BEMsyntax.modKeyVal.length);
return false;
}
});
return modVal;
} else return undefined;
},
setMod: function(block, elem, modName, modVal) {
if (modVal === undefined) {
modVal = modName;
modName = elem;
elem = undefined;
}
return this.each(function() {
var $this = $(this),
classPattern = block + (elem !== undefined ? BEMsyntax.elem + elem : '') +
BEMsyntax.modBefore + modName;
if (modVal === false) {
$this.removeClass(classPattern);
} else if (modVal === true) {
$this.addClass(classPattern);
} else {
$.each(getElemClasses(this), function(i, c) {
if (c.indexOf(classPattern) === 0
&& c.substr(classPattern.length, BEMsyntax.modKeyVal.length) === BEMsyntax.modKeyVal) {
$this.removeClass(c);
}
});
// We have removed the modifier class above, now check only
// if 'modVal' is NOT an empty string, then set a new
// modifier class according to its value. Otherwise
// (if 'modVal' is an empty String) don't do anything!
// Because user liked to remove the modifier class totally
if (modVal !== '') {
$this.addClass(classPattern + BEMsyntax.modKeyVal + modVal);
}
}
// after the modifier is set, run the corresponding custom event
var args = {
block: block,
elem: elem,
modName: modName,
modVal: modVal
};
// trigger the wildcard event pattern first
$this.trigger('setMod:' + getEventPattern(block, elem, modName), args);
// for boolean modifiers, one can only use the wildcard pattern,
// so no need to trigger the same event twice
if (typeof modVal !== 'boolean' && modVal !== '') {
$this.trigger('setMod:' + getEventPattern(block, elem, modName, modVal), args);
}
});
},
hasMod: function(block, elem, modName) {
return !! this.getMod(block, elem, modName);
}
});
})(jQuery);