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

Commit

Permalink
Merge from 'pobems v0.3.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
belozer committed Jul 12, 2016
1 parent 3ab5b0b commit 7f36cfa
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 20 deletions.
66 changes: 46 additions & 20 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,32 @@ import postcss from 'postcss';
const modDelim = process.env.REBEM_MOD_DELIM || '_';
const elemDelim = process.env.REBEM_ELEM_DELIM || '__';

function buildSelector (block) {
function buildSelector (ctx, mod) {
let selector = '.';

if (block.blockName) {
selector += block.blockName;
if (ctx.blockName) {
selector += ctx.blockName;
}
if (block.elemName) {
selector += elemDelim + block.elemName;
if (ctx.elemName) {
selector += elemDelim + ctx.elemName;
}
if (block.modName) {
selector += modDelim + block.modName;
if (mod) {
selector += modDelim + mod;
}

return selector;
}

export default postcss.plugin('rebem-css', () => (css) => {
export default postcss.plugin('pobems', () => (css) => {
css.walkRules((rule) => {
rule.selector = rule.selector
.replace(/(:block\(.+)/g, (match, rawSelector) => {

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

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

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

let selector = '';
let mathes = null;
let requiredBuild = false;

while ((mathes = re.exec(group)) !== null) {
const _spliter = 1;
const _tag = 2;
const _rawValue = 3;
const _value = 4;
const spliter = mathes[_spliter];
const tag = mathes[_tag];
const rawValue = mathes[_rawValue];
const value = mathes[_value] ?
mathes[_value].replace(/([\(\)'"])/g, '').trim() : false;


if (tag === 'block') {
requiredBuild = true;
ctx.blockName = value;
continue;
}

if (mathes[1] === 'block') {
blockDecl.blockName = mathes[2];
if (tag === 'elem') {
requiredBuild = true;
ctx.elemName = value;
continue;
}

if (mathes[1] === 'elem') {
blockDecl.elemName = mathes[2];
if (tag === 'mod') {
requiredBuild = false;
const mod = value.replace(/(\s?->\s?|,\s?|\s+?)/g, modDelim);

selector += buildSelector(ctx, mod);
continue;
}

if (mathes[1] === 'mod') {
blockDecl.modName = mathes[2].replace(' ', modDelim);
selector += buildSelector(blockDecl);
// For pseudo-classes
selector += requiredBuild ? buildSelector(ctx) : '';
selector += spliter + tag;
if (rawValue) {
selector += rawValue;
}

requiredBuild = false;
}
if (!blockDecl.modName) {
selector += buildSelector(blockDecl);
if (requiredBuild) {
selector += buildSelector(ctx);
}

result.push(selector);
Expand Down
49 changes: 49 additions & 0 deletions test/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,27 @@ describe('plugin', () => {
);
});

it('block name with double quotes', () => {
test(
':block("block1") :block("block2")',
'.block1 .block2'
);
});

it('block name with single quotes', () => {
test(
':block(\'block1\') :block(\'block2\')',
'.block1 .block2'
);
});

it('with pseudo classes', () => {
test(
':root :block(block1):mod(m v):hover::before :block(block1):nth-of-type(2)',
':root .block1_m_v:hover::before .block1:nth-of-type(2)'
);
});

it('with other tags', () => {
test(
':block(block1) div :block(bl2) img',
Expand Down Expand Up @@ -81,19 +102,47 @@ describe('plugin', () => {
);
});

it('multiple blocks mods with delimeter "-" in value', () => {
test(
':block(block):mod(mod val-1) :block(block):elem(icon)',
'.block_mod_val-1 .block__icon'
);
});

it('block mod', () => {
test(
':block(block):mod(mod val)',
'.block_mod_val'
);
});

it('block mod with double quotes', () => {
test(
':block("block1"):mod("mod", "val")',
'.block1_mod_val'
);
});

it('block mod with single quotes', () => {
test(
':block(\'block1\'):mod(\'mod\',\'val\')',
'.block1_mod_val'
);
});

it('multiple blocks mods', () => {
test(
':block(block1):mod(mod1 val1) :block(block2):mod(mod2 val2)',
'.block1_mod1_val1 .block2_mod2_val2'
);
});

it('mod val with delimeter "->"', () => {
test(
':block(block1):mod(mod1 -> val1) :block(block2):mod("mod2" -> "val2")',
'.block1_mod1_val1 .block2_mod2_val2'
);
});
});

describe('elem', () => {
Expand Down

0 comments on commit 7f36cfa

Please sign in to comment.