[6a3a178] | 1 | var decls = require('./decls.json');
|
---|
| 2 |
|
---|
| 3 | function template(string, data) {
|
---|
| 4 | return string.replace(/\$\{([\w\-\.]*)\}/g, function (_str, key) {
|
---|
| 5 | var v = data[key];
|
---|
| 6 | return typeof v !== 'undefined' && v !== null ? v : '';
|
---|
| 7 | });
|
---|
| 8 | }
|
---|
| 9 |
|
---|
| 10 | /*
|
---|
| 11 | Rules legend:
|
---|
| 12 | - combined - if rule is combined it will be rendered with template
|
---|
| 13 | - combined and basic rules are present in basic reset
|
---|
| 14 | - combined, basic and inherited rules are present in full reset
|
---|
| 15 | */
|
---|
| 16 |
|
---|
| 17 | function _getRulesMap(inputDecls) {
|
---|
| 18 | return inputDecls
|
---|
| 19 | .filter(function (decl) {
|
---|
| 20 | return !decl.combined;
|
---|
| 21 | })
|
---|
| 22 | .reduce(function (map, decl) {
|
---|
| 23 | map[decl.prop.replace(/\-/g, '')] = decl.initial;
|
---|
| 24 | return map;
|
---|
| 25 | }, {});
|
---|
| 26 | }
|
---|
| 27 |
|
---|
| 28 | function _compileDecls(inputDecls) {
|
---|
| 29 | var templateVars = _getRulesMap(inputDecls);
|
---|
| 30 | return inputDecls.map(function (decl) {
|
---|
| 31 | if (decl.combined && decl.initial) {
|
---|
| 32 | decl.initial = template(decl.initial.replace(/\-/g, ''), templateVars);
|
---|
| 33 | }
|
---|
| 34 | return decl;
|
---|
| 35 | });
|
---|
| 36 | }
|
---|
| 37 |
|
---|
| 38 | function _getRequirements(inputDecls) {
|
---|
| 39 | return inputDecls.reduce(function (map, decl) {
|
---|
| 40 | if (!decl.contains) return map;
|
---|
| 41 | return decl.contains.reduce(function (mapInner, dependency) {
|
---|
| 42 | mapInner[dependency] = decl;
|
---|
| 43 | return mapInner;
|
---|
| 44 | }, map);
|
---|
| 45 | }, {});
|
---|
| 46 | }
|
---|
| 47 |
|
---|
| 48 | function _expandContainments(inputDecls) {
|
---|
| 49 | var requiredMap = _getRequirements(inputDecls);
|
---|
| 50 | return inputDecls
|
---|
| 51 | .filter(function (decl) {
|
---|
| 52 | return !decl.contains;
|
---|
| 53 | }).map(function (decl) {
|
---|
| 54 | var dependency = requiredMap[decl.prop];
|
---|
| 55 | if (dependency) {
|
---|
| 56 | decl.requiredBy = dependency.prop;
|
---|
| 57 | decl.basic = decl.basic || dependency.basic;
|
---|
| 58 | decl.inherited = decl.inherited || dependency.inherited;
|
---|
| 59 | }
|
---|
| 60 | return decl;
|
---|
| 61 | });
|
---|
| 62 | }
|
---|
| 63 |
|
---|
| 64 | var compiledDecls = _expandContainments(_compileDecls(decls));
|
---|
| 65 |
|
---|
| 66 | function _clearDecls(rules, value) {
|
---|
| 67 | return rules.map(function (rule) {
|
---|
| 68 | return {
|
---|
| 69 | prop: rule.prop,
|
---|
| 70 | value: value.replace(/\binitial\b/g, rule.initial)
|
---|
| 71 | };
|
---|
| 72 | });
|
---|
| 73 | }
|
---|
| 74 |
|
---|
| 75 | function _allDecls(onlyInherited) {
|
---|
| 76 | return compiledDecls.filter(function (decl) {
|
---|
| 77 | var allowed = decl.combined || decl.basic;
|
---|
| 78 | if (onlyInherited) return allowed && decl.inherited;
|
---|
| 79 | return allowed;
|
---|
| 80 | });
|
---|
| 81 | }
|
---|
| 82 |
|
---|
| 83 | function _concreteDecl(declName) {
|
---|
| 84 | return compiledDecls.filter(function (decl) {
|
---|
| 85 | return declName === decl.prop || declName === decl.requiredBy;
|
---|
| 86 | });
|
---|
| 87 | }
|
---|
| 88 |
|
---|
| 89 | function makeFallbackFunction(onlyInherited) {
|
---|
| 90 | return function (declName, declValue) {
|
---|
| 91 | var result;
|
---|
| 92 | if (declName === 'all') {
|
---|
| 93 | result = _allDecls(onlyInherited);
|
---|
| 94 | } else {
|
---|
| 95 | result = _concreteDecl(declName);
|
---|
| 96 | }
|
---|
| 97 | return _clearDecls(result, declValue);
|
---|
| 98 | };
|
---|
| 99 | }
|
---|
| 100 |
|
---|
| 101 | module.exports = makeFallbackFunction;
|
---|