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;
|
---|