UNPKG

enb-bem-techs-2x

Version:
256 lines (246 loc) 8.44 kB
/** * A set of utilities for work with dependencies. * * @namespace deps */ module.exports = { /** * Merges DEPS declarations. * * @memberof deps * @param {Array} depsToMerge * @returns {Array} */ merge: function (depsToMerge) { depsToMerge = [].concat(depsToMerge); var startingDep = depsToMerge.shift(), index = buildDepsIndex(startingDep), result = [].concat(startingDep), currentDep, dep, key; while (!!(currentDep = depsToMerge.shift())) { for (var i = 0, l = currentDep.length; i < l; i++) { dep = currentDep[i]; key = depKey(dep); if (!index[key]) { result.push(dep); index[key] = true; } } } return result; }, /** * Subtracts DEPS declarations. * * @memberof deps * @param {Array} from * @param {Array} what * @returns {Array} */ subtract: function (from, what) { var whatIndex = buildDepsIndex(what); return from.filter(function (dep) { return !whatIndex[depKey(dep)]; }); }, /** * Translates declaration from BEMDECL format to DEPS format (not resolve). * * @memberof deps * @param {Object} bemdecl * @returns {Array} */ fromBemdecl: function (bemdecl) { if (bemdecl) { var res = []; bemdecl.forEach(function (block) { res.push({ block: block.name }); if (block.mods) { block.mods.forEach(function (mod) { if (mod.vals) { mod.vals.forEach(function (val) { res.push({ block: block.name, mod: mod.name, val: val.name }); }); } else { res.push({ block: block.name, mod: mod.name }); } }); } if (block.elems) { block.elems.forEach(function (elem) { res.push({ block: block.name, elem: elem.name }); if (elem.mods) { elem.mods.forEach(function (mod) { if (mod.vals) { mod.vals.forEach(function (val) { res.push({ block: block.name, elem: elem.name, mod: mod.name, val: val.name }); }); } else { res.push({ block: block.name, elem: elem.name, mod: mod.name }); } }); } }); } }); return res; } else { return []; } }, /** * Translates declaration from DEPS format to BEMDECL format (not resolve). * * @memberof deps * @param {Object} deps * @returns {Array} */ toBemdecl: function (deps) { if (deps) { var res = []; deps.forEach(function (dep) { var item = { name: dep.block }; if (dep.elem) { if (dep.mod) { if (dep.val) { item.elems = [{ name: dep.elem, mods: [{ name: dep.mod, vals: [{ name: dep.val }] }] }]; } else { item.elems = [{ name: dep.elem, mods: [{ name: dep.mod }] }]; } } else { item.elems = [{ name: dep.elem }]; } } else { if (dep.mod) { if (dep.val) { item.mods = [{ name: dep.mod, vals: [{ name: dep.val }] }]; } else { item.mods = [{ name: dep.mod }]; } } } res.push(item); }); return res; } else { return []; } }, /** * Converts shortcut to verbose array. * * @memberof deps * @param {Object} dep * @param {String} [blockName] * @returns {Array} */ flattenDep: function (dep, blockName) { if (typeof dep === 'string') { return [{ block: dep }]; } var res = []; if (!dep.block) { dep.block = blockName; } if (dep.elem) { if (dep.mods) { Object.keys(dep.mods).forEach(function (modName) { var modVals = dep.mods[modName]; if (!Array.isArray(modVals)) { modVals = [modVals]; } res = res.concat(modVals.map(function (modVal) { return { block: dep.block, elem: dep.elem, mod: modName, val: modVal }; })); }); } else if (dep.mod) { if (dep.val) { res.push({ block: dep.block, elem: dep.elem, mod: dep.mod, val: dep.val }); } else { res.push({ block: dep.block, elem: dep.elem, mod: dep.mod }); } } else { res.push({ block: dep.block, elem: dep.elem }); } } else if (dep.mods || dep.elems) { Object.keys(dep.mods || {}).forEach(function (modName) { var modVals = dep.mods[modName]; if (!Array.isArray(modVals)) { modVals = [modVals]; } res = res.concat(modVals.map(function (modVal) { return { block: dep.block, mod: modName, val: modVal }; })); }); if (dep.elems) { res.push({ block: dep.block }); var elems = dep.elems; if (!Array.isArray(elems)) { elems = [elems]; } elems.forEach(function (elem) { if (typeof elem === 'object') { res.push({ block: dep.block, elem: elem.elem }); Object.keys(elem.mods || {}).forEach(function (modName) { var modVals = elem.mods[modName]; if (!Array.isArray(modVals)) { modVals = [modVals]; } res = res.concat(modVals.map(function (modVal) { return { block: dep.block, elem: elem.elem, mod: modName, val: modVal }; })); }); } else { res.push({ block: dep.block, elem: elem }); } }); } } else if (dep.mod) { if (dep.val) { res.push({ block: dep.block, mod: dep.mod, val: dep.val }); } else { res.push({ block: dep.block, mod: dep.mod }); } } else { res = [{ block: dep.block }]; } if (dep.tech) { res.forEach(function (resDep) { resDep.tech = dep.tech; }); } return res; }, /** * Converts declaration with shortcuts to verbose array. * * @memberof deps * @param {Array|Object} deps * @returns {Array} */ flattenDeps: function (deps) { if (Array.isArray(deps)) { var result = []; for (var i = 0, l = deps.length; i < l; i++) { result = result.concat(this.flattenDep(deps[i])); } return result; } else { return this.flattenDep(deps); } } }; function depKey(dep) { return dep.block + (dep.elem ? '__' + dep.elem : '') + (dep.mod ? '_' + dep.mod + (dep.val ? '_' + dep.val : '') : ''); } function buildDepsIndex(deps) { var result = {}; for (var i = 0, l = deps.length; i < l; i++) { result[depKey(deps[i])] = true; } return result; }