1 |
|
2 | var object, _common,
|
3 | __hasProp = {}.hasOwnProperty;
|
4 |
|
5 | _common = require('./_common');
|
6 |
|
7 | module.exports = object = {
|
8 | isBareObject: _common.isBareObject.bind(_common),
|
9 | |
10 |
|
11 |
|
12 |
|
13 | isInstance: function(what) {
|
14 | return !this.isBareObject(what);
|
15 | },
|
16 | |
17 |
|
18 |
|
19 |
|
20 | typeOf: _common.typeOf.bind(_common),
|
21 | |
22 |
|
23 |
|
24 |
|
25 | clone: _common.clone.bind(_common),
|
26 | |
27 |
|
28 |
|
29 |
|
30 | empty: function(o) {
|
31 | var prop;
|
32 | for (prop in o) {
|
33 | if (o.hasOwnProperty(prop)) {
|
34 | delete o[prop];
|
35 | }
|
36 | }
|
37 | return o;
|
38 | },
|
39 | |
40 |
|
41 |
|
42 |
|
43 |
|
44 | fastEmpty: function(o) {
|
45 | var property;
|
46 | for (property in o) {
|
47 | delete o[property];
|
48 | }
|
49 | return o;
|
50 | },
|
51 | |
52 |
|
53 |
|
54 |
|
55 |
|
56 | overrideOnto: function(base, newValues) {
|
57 | var key, newVal, oldVal;
|
58 | if (!this.isBareObject(newValues) || !this.isBareObject(base)) {
|
59 | return base;
|
60 | }
|
61 | for (key in base) {
|
62 | oldVal = base[key];
|
63 | newVal = newValues[key];
|
64 | if (newVal === void 0) {
|
65 | continue;
|
66 | }
|
67 | if (typeof newVal !== 'object' || this.isInstance(newVal)) {
|
68 | base[key] = this.clone(newVal);
|
69 | } else {
|
70 | if (typeof oldVal !== 'object' || this.isInstance(oldVal)) {
|
71 | base[key] = this.clone(newVal);
|
72 | } else {
|
73 | this.overrideOnto(oldVal, newVal);
|
74 | }
|
75 | }
|
76 | }
|
77 | return base;
|
78 | },
|
79 | |
80 |
|
81 |
|
82 |
|
83 | override: function(base, newValues) {
|
84 | return this.overrideOnto(this.clone(base), newValues);
|
85 | },
|
86 | append: function(base, toAppend) {
|
87 | return this.appendOnto(this.clone(base), toAppend);
|
88 | },
|
89 | appendOnto: function(base, toAppend) {
|
90 | var key, newVal, oldVal;
|
91 | if (!this.isBareObject(toAppend) || !this.isBareObject(base)) {
|
92 | return base;
|
93 | }
|
94 | for (key in toAppend) {
|
95 | if (!__hasProp.call(toAppend, key)) continue;
|
96 | newVal = toAppend[key];
|
97 | if (newVal === void 0) {
|
98 | continue;
|
99 | }
|
100 | if (typeof newVal !== 'object' || this.isInstance(newVal)) {
|
101 | base[key] = newVal;
|
102 | } else {
|
103 | oldVal = base[key];
|
104 | if (typeof oldVal !== 'object' || this.isInstance(oldVal)) {
|
105 | base[key] = this.clone(newVal);
|
106 | } else {
|
107 | this.appendOnto(oldVal, newVal);
|
108 | }
|
109 | }
|
110 | }
|
111 | return base;
|
112 | },
|
113 | groupProps: function(obj, groups) {
|
114 | var def, defs, grouped, key, name, shouldAdd, val, _i, _len;
|
115 | grouped = {};
|
116 | for (name in groups) {
|
117 | defs = groups[name];
|
118 | grouped[name] = {};
|
119 | }
|
120 | grouped['rest'] = {};
|
121 | top:
|
122 | for (key in obj) {
|
123 | val = obj[key];
|
124 | shouldAdd = false;
|
125 | for (name in groups) {
|
126 | defs = groups[name];
|
127 | if (!Array.isArray(defs)) {
|
128 | defs = [defs];
|
129 | }
|
130 | for (_i = 0, _len = defs.length; _i < _len; _i++) {
|
131 | def = defs[_i];
|
132 | if (typeof def === 'string') {
|
133 | if (key === def) {
|
134 | shouldAdd = true;
|
135 | }
|
136 | } else if (def instanceof RegExp) {
|
137 | if (def.test(key)) {
|
138 | shouldAdd = true;
|
139 | }
|
140 | } else if (def instanceof Function) {
|
141 | if (def(key)) {
|
142 | shouldAdd = true;
|
143 | }
|
144 | } else {
|
145 | throw Error('Group definitions must either\
|
146 | be strings, regexes, or functions.');
|
147 | }
|
148 | if (shouldAdd) {
|
149 | grouped[name][key] = val;
|
150 | continue top;
|
151 | }
|
152 | }
|
153 | }
|
154 | grouped['rest'][key] = val;
|
155 | }
|
156 | return grouped;
|
157 | }
|
158 | };
|