95 lines
2.6 KiB
JavaScript
95 lines
2.6 KiB
JavaScript
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
var shape = {
|
|
generic: true,
|
|
types: {},
|
|
properties: {},
|
|
parseContext: {},
|
|
scope: {},
|
|
atrule: ['parse'],
|
|
pseudo: ['parse'],
|
|
node: ['name', 'structure', 'parse', 'generate', 'walkContext']
|
|
};
|
|
|
|
function isObject(value) {
|
|
return value && value.constructor === Object;
|
|
}
|
|
|
|
function copy(value) {
|
|
if (isObject(value)) {
|
|
var res = {};
|
|
for (var key in value) {
|
|
if (hasOwnProperty.call(value, key)) {
|
|
res[key] = value[key];
|
|
}
|
|
}
|
|
return res;
|
|
} else {
|
|
return value;
|
|
}
|
|
}
|
|
|
|
function extend(dest, src) {
|
|
for (var key in src) {
|
|
if (hasOwnProperty.call(src, key)) {
|
|
if (isObject(dest[key])) {
|
|
extend(dest[key], copy(src[key]));
|
|
} else {
|
|
dest[key] = copy(src[key]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function mix(dest, src, shape) {
|
|
for (var key in shape) {
|
|
if (hasOwnProperty.call(shape, key) === false) {
|
|
continue;
|
|
}
|
|
|
|
if (shape[key] === true) {
|
|
if (key in src) {
|
|
if (hasOwnProperty.call(src, key)) {
|
|
dest[key] = copy(src[key]);
|
|
}
|
|
}
|
|
} else if (shape[key]) {
|
|
if (isObject(shape[key])) {
|
|
var res = {};
|
|
extend(res, dest[key]);
|
|
extend(res, src[key]);
|
|
dest[key] = res;
|
|
} else if (Array.isArray(shape[key])) {
|
|
var res = {};
|
|
var innerShape = shape[key].reduce(function(s, k) {
|
|
s[k] = true;
|
|
return s;
|
|
}, {});
|
|
for (var name in dest[key]) {
|
|
if (hasOwnProperty.call(dest[key], name)) {
|
|
res[name] = {};
|
|
if (dest[key] && dest[key][name]) {
|
|
mix(res[name], dest[key][name], innerShape);
|
|
}
|
|
}
|
|
}
|
|
for (var name in src[key]) {
|
|
if (hasOwnProperty.call(src[key], name)) {
|
|
if (!res[name]) {
|
|
res[name] = {};
|
|
}
|
|
if (src[key] && src[key][name]) {
|
|
mix(res[name], src[key][name], innerShape);
|
|
}
|
|
}
|
|
}
|
|
dest[key] = res;
|
|
}
|
|
}
|
|
}
|
|
return dest;
|
|
}
|
|
|
|
module.exports = function(dest, src) {
|
|
return mix(dest, src, shape);
|
|
};
|