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