This repository has been archived by the owner on Dec 7, 2017. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 145
/
bem-conventions.js
114 lines (101 loc) · 3.03 KB
/
bem-conventions.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
// ============================================================
// There are several different BEM naming conventions that
// I'm aware of. To make things easier, I refer to the
// methodologies by the name of projects that utilize them.
//
// suit: http://suitcss.github.io/
// -------------------------------------
// BlockName
// BlockName--modifierName
// BlockName-elementName
// BlockName-elementName--modifierName
//
// inuit: http://inuitcss.com/
// ---------------------------
// block-name
// block-name--modifier-name
// block-name__element-name
// block-name__element-name--modifier-name
//
// yandex: http://bem.info/
// ------------------------
// block-name
// block-name_modifier_name
// block-name__element-name
// block-name__element-name_modifier_name
//
// ============================================================
var methodologies = {
"suit": {
modifier: /^([A-Z][a-zA-Z]*(?:\-[a-zA-Z]+)?)\-\-[a-zA-Z]+$/,
element: /^([A-Z][a-zA-Z]*)\-[a-zA-Z]+$/
},
"inuit": {
modifier: /^((?:[a-z]+\-)*[a-z]+(?:__(?:[a-z]+\-)*[a-z]+)?)\-\-(?:[a-z]+\-)*[a-z]+$/,
element: /^((?:[a-z]+\-)*[a-z]+)__(?:[a-z]+\-)*[a-z]+$/
},
"yandex": {
modifier: /^((?:[a-z]+\-)*[a-z]+(?:__(?:[a-z]+\-)*[a-z]+)?)_(?:[a-z]+_)*[a-z]+$/,
element: /^((?:[a-z]+\-)*[a-z]+)__(?:[a-z]+\-)*[a-z]+$/
}
}
function getMethodology() {
if (typeof config.methodology == "string") {
return methodologies[config.methodology]
}
return config.methodology
}
var config = {
methodology: "suit",
getBlockName: function(elementOrModifier) {
var block
, methodology = getMethodology()
if (methodology.modifier.test(elementOrModifier))
return block = RegExp.$1
if (methodology.element.test(elementOrModifier))
return block = RegExp.$1
return block || false
},
isElement: function(cls) {
return getMethodology().element.test(cls)
},
isModifier: function(cls) {
return getMethodology().modifier.test(cls)
}
}
module.exports = {
name: "bem-conventions",
config: config,
func: function(listener, reporter, config) {
var parents = require("dom-utils/src/parents")
, matches = require("dom-utils/src/matches")
listener.on('class', function(name) {
if (config.isElement(name)) {
// check the ancestors for the block class
var ancestorIsBlock = parents(this).some(function(el) {
return matches(el, "." + config.getBlockName(name))
})
if (!ancestorIsBlock) {
reporter.warn(
"bem-conventions",
"The BEM element '" + name
+ "' must be a descendent of '" + config.getBlockName(name)
+ "'.",
this
)
}
}
if (config.isModifier(name)) {
if (!matches(this, "." + config.getBlockName(name))) {
reporter.warn(
"bem-conventions",
"The BEM modifier class '" + name
+ "' was found without the unmodified class '" + config.getBlockName(name)
+ "'.",
this
)
}
}
})
}
}