Skip to content

Commit d39d6e8

Browse files
committed
Updated jscore to f8ced57.
1 parent 5de343e commit d39d6e8

File tree

1 file changed

+217
-49
lines changed

1 file changed

+217
-49
lines changed

lib/blocks/core.js

Lines changed: 217 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,107 @@
120120
return target;
121121
};
122122

123+
// Adds a function to the pending array that sets the value if it's not created yet (for circular references)
124+
// e.g. var a = {}; var b = {parent: a}; a.b = b;
125+
// otherwise it looks if the value got already cloned it set's a reference to it
126+
// e.g. var a = {answer: 42}; var b = {first: a, second: a};
127+
// otherwise it clones the value
128+
function cloneIfNotExsists(clone, key, value, history) {
129+
var stack = history.stack;
130+
var processed = history.processed;
131+
var clones = history.clones;
132+
var pending = history.pending;
133+
134+
for (var stackIndex = 0; stackIndex < stack.length; stackIndex++) {
135+
if (value[key] === stack[stackIndex]) {
136+
pending[stackIndex].push(function (cloned) {
137+
clone[key] = cloned;
138+
});
139+
return;
140+
}
141+
}
142+
143+
for (var processedIndex = 0; processedIndex < processed.length; processedIndex++) {
144+
if (value[key] === processed[processedIndex]) {
145+
clone[key] = clones[processedIndex];
146+
return;
147+
}
148+
}
149+
clone[key] = internalClone(value[key], true, history);
150+
}
151+
152+
// internal clone helper function
153+
function internalClone(value, deepClone, history) {
154+
if (value == null) {
155+
return value;
156+
}
157+
158+
history.stack.push(value);
159+
history.pending.push([]);
160+
161+
var type = blocks.type(value);
162+
var clone;
163+
var key;
164+
var pending;
165+
166+
if (blocks.isFunction(value.clone)) {
167+
clone = value.clone(deepClone);
168+
}
169+
170+
if (type == 'object' || type == 'array') {
171+
if (value.constructor === Object) {
172+
clone = {};
173+
} else if (type == 'object'){
174+
clone = new value.constructor();
175+
} else {
176+
clone = [];
177+
}
178+
179+
for (key in value) {
180+
if (!deepClone) {
181+
clone[key] = value[key];
182+
} else {
183+
cloneIfNotExsists(clone, key, value, history);
184+
}
185+
}
186+
} else if (type == 'date') {
187+
clone = new Date(value.getFullYear(), value.getMonth(), value.getDate(),
188+
value.getHours(), value.getMinutes(), value.getSeconds(), value.getMilliseconds());
189+
} else if (type == 'string') {
190+
history.pending.pop();
191+
history.stack.pop();
192+
return value.toString();
193+
} else if (type == 'regexp') {
194+
var flags = '';
195+
if (value.global) {
196+
flags += 'g';
197+
}
198+
if (value.ignoreCase) {
199+
flags += 'i';
200+
}
201+
if (value.multiline) {
202+
flags += 'm';
203+
}
204+
clone = new RegExp(value.source, flags);
205+
clone.lastIndex = value.lastIndex;
206+
}
207+
208+
history.stack.pop();
209+
if (clone) {
210+
history.processed.push(value);
211+
history.clones.push(clone);
212+
pending = history.pending.pop();
213+
214+
for (var pendingIndex = 0; pendingIndex < pending.length; pendingIndex++) {
215+
pending[pendingIndex](clone || value);
216+
}
217+
} else {
218+
history.pending.pop();
219+
}
220+
221+
return clone || value;
222+
}
223+
123224
/**
124225
* @callback iterateCallback
125226
* @param {*} value - The value
@@ -277,6 +378,7 @@
277378
Class.prototype._super = _super;
278379
} else if (prototype) {
279380
Class.prototype = prototype;
381+
Class.prototype.constructor = Class;
280382
}
281383

282384
return Class;
@@ -556,9 +658,9 @@
556658
* Clones value. If deepClone is set to true the value will be cloned recursively
557659
*
558660
* @memberof blocks
559-
* @param {*} value -
560-
* @param {boolean} [deepClone] - Description
561-
* @returns {*} Description
661+
* @param {*} value - The value to clone.
662+
* @param {boolean} [deepClone] - If true it will be a deep clone.
663+
* @returns {*} - The cloned object.
562664
*
563665
* @example {javascript}
564666
* var array = [3, 1, 4];
@@ -567,54 +669,17 @@
567669
* var areEqual = array == cloned;
568670
* // -> false
569671
*/
570-
clone: function(value, deepClone) {
571-
if (value == null) {
572-
return value;
573-
}
574-
575-
var type = blocks.type(value);
576-
var clone;
577-
var key;
578-
579-
if (blocks.isFunction(value.clone)) {
580-
return value.clone(deepClone);
672+
clone: function (value, deepClone) {
673+
var rootClone = false;
674+
if (!blocks.core.currentClone) {
675+
blocks.core.currentClone = {stack: [], processed: [], clones: [], pending: []};
676+
rootClone = true;
581677
}
582-
583-
if (type == 'array') {
584-
return value.slice(0);
585-
} else if (type == 'object') {
586-
if (value.constructor === Object) {
587-
clone = {};
588-
} else {
589-
clone = new value.constructor();
590-
}
591-
592-
for (key in value) {
593-
clone[key] = deepClone ? blocks.clone(value[key], true) : value[key];
594-
}
595-
return clone;
596-
} else if (type == 'date') {
597-
return new Date(value.getFullYear(), value.getMonth(), value.getDate(),
598-
value.getHours(), value.getMinutes(), value.getSeconds(), value.getMilliseconds());
599-
} else if (type == 'string') {
600-
return value.toString();
601-
} else if (type == 'regexp') {
602-
var flags = '';
603-
if (value.global) {
604-
flags += 'g';
605-
}
606-
if (value.ignoreCase) {
607-
flags += 'i';
608-
}
609-
if (value.multiline) {
610-
flags += 'm';
611-
}
612-
clone = new RegExp(value.source, flags);
613-
clone.lastIndex = value.lastIndex;
614-
return clone;
678+
var clone = internalClone(value, deepClone, blocks.core.currentClone);
679+
if (rootClone) {
680+
blocks.core.currentClone = null;
615681
}
616-
617-
return value;
682+
return clone;
618683
},
619684

620685
/**
@@ -857,6 +922,96 @@
857922
return bound;
858923
},
859924

925+
/**
926+
* Converts an array of keys and an array of values to an object.
927+
* If no value array is specified the values will be set to true.
928+
* @param {String[]|Object[]} array - The array of keys or an array of
929+
* objects containing objects with key and value properties.
930+
* @param {*[]} [values] - The array of values.
931+
* @returns {Object} - The object with the combined keys and values.
932+
*
933+
* @example {javascript}
934+
*
935+
* var keys = ['a', 'b', 'c'];
936+
* var values = [1, 2, 3];
937+
* blocks.toObject(keys, values);
938+
* // -> {a: 1, b: 2, c: 3}
939+
*
940+
* blocks.toObject(keys);
941+
* // -> {a: true, b: true, c: true}
942+
*
943+
* blocks.toObject([{key: 'a', value: 1}, {key: 'b', value: 2}]);
944+
* // -> {a: 1, b: 2}
945+
*/
946+
toObject: function (array, values) {
947+
var result = {},
948+
useValuesArray = arguments.length > 1 && values,
949+
i = 0,
950+
length = array.length,
951+
value;
952+
953+
for (; i < length; i++) {
954+
value = array[i];
955+
if (blocks.isArray(value)) {
956+
result[value[0]] = value[1];
957+
} else if (blocks.isObject(value)) {
958+
result[value.key] = value.value;
959+
} else {
960+
result[value] = useValuesArray ? values[i] : true;
961+
}
962+
}
963+
return result;
964+
},
965+
966+
/**
967+
* Converts an given object into an array of objects with properties key and value.
968+
* Where key is the property name in the original object and value is the value of the property.
969+
* @param {Object} obj - The object to convert.
970+
* @returns {Object[]} - An array of objects with the key/value pairs.
971+
*
972+
* @example {javascript}
973+
* var myObject = {
974+
* a: 1,
975+
* b: "something"
976+
* };
977+
* blocks.pairs(myObject);
978+
* // -> [{key: a, value: 1}, {key: b, value: "someting"}]
979+
*/
980+
pairs: function (obj) {
981+
var pairs = [];
982+
for (var key in obj) {
983+
pairs.push({key: key, value: obj[key]});
984+
}
985+
return pairs;
986+
},
987+
988+
/**
989+
* Flattens an array of values.
990+
* @param {Array} collection - The array to flatten.
991+
* @param {boolean} [shallow=false] - If true makes the flatten shallow.
992+
* @returns {Array} - The flattend array.
993+
*
994+
* @example {javascript}
995+
* var unflattend = [1, 2, [3, [4, 5]]];
996+
* blocks.flatten(unflattend);
997+
* // -> [1, 2, 3, 4, 5]
998+
* blocks.flatten(unflattend, true);
999+
* // -> [1, 2, 3, [4, 5]]
1000+
*/
1001+
flatten: function (collection, shallow) {
1002+
var flatten = blocks.core.flatten;
1003+
var result = [];
1004+
var length = collection.length;
1005+
var value;
1006+
var index = -1;
1007+
1008+
while (++index < length) {
1009+
value = collection[index];
1010+
flatten(shallow, value, result);
1011+
}
1012+
return result;
1013+
},
1014+
8601015
/**
8611016
* Determines if two values are deeply equal.
8621017
* Set deepEqual to false to stop recusively equality checking
@@ -1066,6 +1221,19 @@
10661221
return callback;
10671222
}
10681223

1224+
core.flatten = function (shallow, value, result) {
1225+
if (blocks.isArray(value) || blocks.isArguments(value)) {
1226+
if (shallow) {
1227+
result.push.apply(result, value);
1228+
} else {
1229+
for (var i = 0; i < value.length; i++) {
1230+
core.flatten(shallow, value[i], result);
1231+
}
1232+
}
1233+
} else {
1234+
result.push(value);
1235+
}
1236+
};
10691237

10701238
// @debug-code
10711239

0 commit comments

Comments
 (0)