source: imaps-frontend/node_modules/css-tree/lib/syntax/config/mix.js@ d565449

main
Last change on this file since d565449 was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 3.7 KB
Line 
1const hasOwnProperty = Object.prototype.hasOwnProperty;
2const shape = {
3 generic: true,
4 types: appendOrAssign,
5 atrules: {
6 prelude: appendOrAssignOrNull,
7 descriptors: appendOrAssignOrNull
8 },
9 properties: appendOrAssign,
10 parseContext: assign,
11 scope: deepAssign,
12 atrule: ['parse'],
13 pseudo: ['parse'],
14 node: ['name', 'structure', 'parse', 'generate', 'walkContext']
15};
16
17function isObject(value) {
18 return value && value.constructor === Object;
19}
20
21function copy(value) {
22 return isObject(value)
23 ? Object.assign({}, value)
24 : value;
25}
26
27function assign(dest, src) {
28 return Object.assign(dest, src);
29}
30
31function deepAssign(dest, src) {
32 for (const key in src) {
33 if (hasOwnProperty.call(src, key)) {
34 if (isObject(dest[key])) {
35 deepAssign(dest[key], copy(src[key]));
36 } else {
37 dest[key] = copy(src[key]);
38 }
39 }
40 }
41
42 return dest;
43}
44
45function append(a, b) {
46 if (typeof b === 'string' && /^\s*\|/.test(b)) {
47 return typeof a === 'string'
48 ? a + b
49 : b.replace(/^\s*\|\s*/, '');
50 }
51
52 return b || null;
53}
54
55function appendOrAssign(a, b) {
56 if (typeof b === 'string') {
57 return append(a, b);
58 }
59
60 const result = Object.assign({}, a);
61 for (let key in b) {
62 if (hasOwnProperty.call(b, key)) {
63 result[key] = append(hasOwnProperty.call(a, key) ? a[key] : undefined, b[key]);
64 }
65 }
66
67 return result;
68}
69
70function appendOrAssignOrNull(a, b) {
71 const result = appendOrAssign(a, b);
72
73 return !isObject(result) || Object.keys(result).length
74 ? result
75 : null;
76}
77
78function mix(dest, src, shape) {
79 for (const key in shape) {
80 if (hasOwnProperty.call(shape, key) === false) {
81 continue;
82 }
83
84 if (shape[key] === true) {
85 if (key in src) {
86 if (hasOwnProperty.call(src, key)) {
87 dest[key] = copy(src[key]);
88 }
89 }
90 } else if (shape[key]) {
91 if (typeof shape[key] === 'function') {
92 const fn = shape[key];
93 dest[key] = fn({}, dest[key]);
94 dest[key] = fn(dest[key] || {}, src[key]);
95 } else if (isObject(shape[key])) {
96 const result = {};
97
98 for (let name in dest[key]) {
99 result[name] = mix({}, dest[key][name], shape[key]);
100 }
101
102 for (let name in src[key]) {
103 result[name] = mix(result[name] || {}, src[key][name], shape[key]);
104 }
105
106 dest[key] = result;
107 } else if (Array.isArray(shape[key])) {
108 const res = {};
109 const innerShape = shape[key].reduce(function(s, k) {
110 s[k] = true;
111 return s;
112 }, {});
113
114 for (const [name, value] of Object.entries(dest[key] || {})) {
115 res[name] = {};
116 if (value) {
117 mix(res[name], value, innerShape);
118 }
119 }
120
121 for (const name in src[key]) {
122 if (hasOwnProperty.call(src[key], name)) {
123 if (!res[name]) {
124 res[name] = {};
125 }
126
127 if (src[key] && src[key][name]) {
128 mix(res[name], src[key][name], innerShape);
129 }
130 }
131 }
132
133 dest[key] = res;
134 }
135 }
136 }
137 return dest;
138}
139
140module.exports = (dest, src) => mix(dest, src, shape);
Note: See TracBrowser for help on using the repository browser.