-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.js
89 lines (67 loc) · 2.45 KB
/
index.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
'use strict';
const stringifyObj = require('stringify-object');
const normalize = require('bem-decl').normalize;
const BemEntity = require('@bem/entity-name');
function getEntities(bemjson, ctx) {
const visited = {};
const collectDeps = (ent, deps, ctx_) => deps.concat(_getEntities(ent, ctx_));
function _getEntities(bemjson_, ctx_) {
ctx_ = Object.assign({}, ctx_);
let deps = [];
let contentDeps;
if (Array.isArray(bemjson_)) {
bemjson_.forEach(function(item) {
contentDeps = _getEntities(item, ctx_);
contentDeps && (deps = deps.concat(contentDeps));
});
return deps;
}
if (typeof bemjson_ !== 'object') {
return;
}
bemjson_.block && (ctx_.block = bemjson_.block);
const declItem = {
block: ctx_.block
};
bemjson_.elem && (declItem.elem = bemjson_.elem);
bemjson_.elem ?
bemjson_.elemMods && (declItem.mods = bemjson_.elemMods) :
bemjson_.mods && (declItem.mods = bemjson_.mods);
const decl = normalize(declItem, { harmony: true });
decl.forEach(declItem_ => {
const entity = new BemEntity(declItem_.entity);
_pushTo(entity, deps, visited);
if (entity.isSimpleMod() === false) {
_pushTo(BemEntity.create(Object.assign({}, declItem, { modVal: true })), deps, visited);
}
});
['js', 'attrs'].forEach(k => {
bemjson_[k] && Object.keys(bemjson_[k]).forEach(function(kk) {
deps = collectDeps(bemjson_[k][kk], deps, ctx_);
});
});
Object.keys(bemjson_).forEach(key => {
if (~['js', 'attrs', 'mods', 'elemMods', 'block', 'elem'].indexOf(key)) { return; }
[].concat(bemjson_[key]).forEach(ent => {
deps = collectDeps(ent, deps, ctx_);
});
});
return deps.filter(Boolean);
}
return _getEntities(bemjson, ctx);
}
function _pushTo(declItem, deps, visited) {
if (!visited[declItem.id]) {
visited[declItem.id] = true;
deps.push(declItem);
}
}
function stringify(bemjson, ctx, opts) {
opts || (opts = {});
opts.indent || (opts.indent = ' ');
return stringifyObj(getEntities(bemjson, ctx).map(entity => entity.toJSON()), opts);
}
module.exports = {
convert: getEntities,
stringify: stringify
};