| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 | var stringifyBody = require('../stringifier/one-time').body;var stringifySelectors = require('../stringifier/one-time').selectors;var cleanUpSelectors = require('./clean-up').selectors;var isSpecial = require('./is-special');function unsafeSelector(value) {  return /\.|\*| :/.test(value);}function isBemElement(token) {  var asString = stringifySelectors(token[1]);  return asString.indexOf('__') > -1 || asString.indexOf('--') > -1;}function withoutModifier(selector) {  return selector.replace(/--[^ ,>\+~:]+/g, '');}function removeAnyUnsafeElements(left, candidates) {  var leftSelector = withoutModifier(stringifySelectors(left[1]));  for (var body in candidates) {    var right = candidates[body];    var rightSelector = withoutModifier(stringifySelectors(right[1]));    if (rightSelector.indexOf(leftSelector) > -1 || leftSelector.indexOf(rightSelector) > -1)      delete candidates[body];  }}function mergeNonAdjacentByBody(tokens, options) {  var candidates = {};  var adjacentSpace = options.compatibility.selectors.adjacentSpace;  for (var i = tokens.length - 1; i >= 0; i--) {    var token = tokens[i];    if (token[0] != 'selector')      continue;    if (token[2].length > 0 && (!options.semanticMerging && unsafeSelector(stringifySelectors(token[1]))))      candidates = {};    if (token[2].length > 0 && options.semanticMerging && isBemElement(token))      removeAnyUnsafeElements(token, candidates);    var candidateBody = stringifyBody(token[2]);    var oldToken = candidates[candidateBody];    if (oldToken && !isSpecial(options, stringifySelectors(token[1])) && !isSpecial(options, stringifySelectors(oldToken[1]))) {      token[1] = token[2].length > 0 ?        cleanUpSelectors(oldToken[1].concat(token[1]), false, adjacentSpace) :        oldToken[1].concat(token[1]);      oldToken[2] = [];      candidates[candidateBody] = null;    }    candidates[stringifyBody(token[2])] = token;  }}module.exports = mergeNonAdjacentByBody;
 |