Skip to content
This repository was archived by the owner on Aug 19, 2019. It is now read-only.

Commit 3bcd20c

Browse files
committed
Merge from 'pobems v0.3.1'
1 parent 3ab5b0b commit 3bcd20c

File tree

2 files changed

+94
-19
lines changed

2 files changed

+94
-19
lines changed

lib/index.js

+45-19
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@ import postcss from 'postcss';
33
const modDelim = process.env.REBEM_MOD_DELIM || '_';
44
const elemDelim = process.env.REBEM_ELEM_DELIM || '__';
55

6-
function buildSelector (block) {
6+
function buildSelector (ctx, mod) {
77
let selector = '.';
88

9-
if (block.blockName) {
10-
selector += block.blockName;
9+
if (ctx.blockName) {
10+
selector += ctx.blockName;
1111
}
12-
if (block.elemName) {
13-
selector += elemDelim + block.elemName;
12+
if (ctx.elemName) {
13+
selector += elemDelim + ctx.elemName;
1414
}
15-
if (block.modName) {
16-
selector += modDelim + block.modName;
15+
if (mod) {
16+
selector += modDelim + mod;
1717
}
1818

1919
return selector;
@@ -25,10 +25,10 @@ export default postcss.plugin('rebem-css', () => (css) => {
2525
.replace(/(:block\(.+)/g, (match, rawSelector) => {
2626

2727
// ":block(b):mod(m v) div :block(b2)" -> [":block(b):mod(m v)", "div", "block(b2)"]
28-
const groups = rawSelector.split(/\s+(?!\w+\))/gi);
28+
const groups = rawSelector.split(/\s+(?![\w\s->'",]+\))/gi);
2929

30-
const re = /:(block|elem|mod)\(([\w-\s]+)\)(\s+)?/g;
31-
const blockDecl = { blockName: false, elemName: false, modName: false };
30+
const re = /(:+)([\w-]+)(\((['",\w->\s]+)\))?/g;
31+
const ctx = { blockName: false, elemName: false };
3232

3333
// Convert all groups to CSS selectors
3434
// :block(b):mod(m v) -> .b_m_v
@@ -43,25 +43,51 @@ export default postcss.plugin('rebem-css', () => (css) => {
4343

4444
let selector = '';
4545
let mathes = null;
46+
let requiredBuild = false;
4647

4748
while ((mathes = re.exec(group)) !== null) {
49+
const _spliter = 1;
50+
const _tag = 2;
51+
const _rawValue = 3;
52+
const _value = 4;
53+
const spliter = mathes[_spliter];
54+
const tag = mathes[_tag];
55+
const rawValue = mathes[_rawValue];
56+
const value = mathes[_value] ?
57+
mathes[_value].replace(/([\(\)'"])/g, '').trim() : false;
58+
59+
60+
if (tag === 'block') {
61+
requiredBuild = true;
62+
ctx.blockName = value;
63+
continue;
64+
}
4865

49-
if (mathes[1] === 'block') {
50-
blockDecl.blockName = mathes[2];
66+
if (tag === 'elem') {
67+
requiredBuild = true;
68+
ctx.elemName = value;
69+
continue;
5170
}
5271

53-
if (mathes[1] === 'elem') {
54-
blockDecl.elemName = mathes[2];
72+
if (tag === 'mod') {
73+
requiredBuild = false;
74+
const mod = value.replace(/(\s?->\s?|,\s?|\s+?)/g, modDelim);
75+
76+
selector += buildSelector(ctx, mod);
77+
continue;
5578
}
5679

57-
if (mathes[1] === 'mod') {
58-
blockDecl.modName = mathes[2].replace(' ', modDelim);
59-
selector += buildSelector(blockDecl);
80+
// For pseudo-classes
81+
selector += requiredBuild ? buildSelector(ctx) : '';
82+
selector += spliter + tag;
83+
if (rawValue) {
84+
selector += rawValue;
6085
}
6186

87+
requiredBuild = false;
6288
}
63-
if (!blockDecl.modName) {
64-
selector += buildSelector(blockDecl);
89+
if (requiredBuild) {
90+
selector += buildSelector(ctx);
6591
}
6692

6793
result.push(selector);

test/lib/index.js

+49
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,27 @@ describe('plugin', () => {
2727
);
2828
});
2929

30+
it('block name with double quotes', () => {
31+
test(
32+
':block("block1") :block("block2")',
33+
'.block1 .block2'
34+
);
35+
});
36+
37+
it('block name with single quotes', () => {
38+
test(
39+
':block(\'block1\') :block(\'block2\')',
40+
'.block1 .block2'
41+
);
42+
});
43+
44+
it('with pseudo classes', () => {
45+
test(
46+
':root :block(block1):mod(m v):hover::before :block(block1):nth-of-type(2)',
47+
':root .block1_m_v:hover::before .block1:nth-of-type(2)'
48+
);
49+
});
50+
3051
it('with other tags', () => {
3152
test(
3253
':block(block1) div :block(bl2) img',
@@ -81,19 +102,47 @@ describe('plugin', () => {
81102
);
82103
});
83104

105+
it('multiple blocks mods with delimeter "-" in value', () => {
106+
test(
107+
':block(block):mod(mod val-1) :block(block):elem(icon)',
108+
'.block_mod_val-1 .block__icon'
109+
);
110+
});
111+
84112
it('block mod', () => {
85113
test(
86114
':block(block):mod(mod val)',
87115
'.block_mod_val'
88116
);
89117
});
90118

119+
it('block mod with double quotes', () => {
120+
test(
121+
':block("block1"):mod("mod", "val")',
122+
'.block1_mod_val'
123+
);
124+
});
125+
126+
it('block mod with single quotes', () => {
127+
test(
128+
':block(\'block1\'):mod(\'mod\',\'val\')',
129+
'.block1_mod_val'
130+
);
131+
});
132+
91133
it('multiple blocks mods', () => {
92134
test(
93135
':block(block1):mod(mod1 val1) :block(block2):mod(mod2 val2)',
94136
'.block1_mod1_val1 .block2_mod2_val2'
95137
);
96138
});
139+
140+
it('mod val with delimeter "->"', () => {
141+
test(
142+
':block(block1):mod(mod1 -> val1) :block(block2):mod("mod2" -> "val2")',
143+
'.block1_mod1_val1 .block2_mod2_val2'
144+
);
145+
});
97146
});
98147

99148
describe('elem', () => {

0 commit comments

Comments
 (0)