mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-04-23 03:30:02 +08:00
fix(angular.copy): support circular references in the value being copied
Closes #7618
This commit is contained in:
@@ -757,7 +757,7 @@ function isLeafNode (node) {
|
||||
</file>
|
||||
</example>
|
||||
*/
|
||||
function copy(source, destination) {
|
||||
function copy(source, destination, stackSource, stackDest) {
|
||||
if (isWindow(source) || isScope(source)) {
|
||||
throw ngMinErr('cpws',
|
||||
"Can't copy! Making copies of Window or Scope instances is not supported.");
|
||||
@@ -767,22 +767,40 @@ function copy(source, destination) {
|
||||
destination = source;
|
||||
if (source) {
|
||||
if (isArray(source)) {
|
||||
destination = copy(source, []);
|
||||
destination = copy(source, [], stackSource, stackDest);
|
||||
} else if (isDate(source)) {
|
||||
destination = new Date(source.getTime());
|
||||
} else if (isRegExp(source)) {
|
||||
destination = new RegExp(source.source);
|
||||
} else if (isObject(source)) {
|
||||
destination = copy(source, {});
|
||||
destination = copy(source, {}, stackSource, stackDest);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (source === destination) throw ngMinErr('cpi',
|
||||
"Can't copy! Source and destination are identical.");
|
||||
|
||||
stackSource = stackSource || [];
|
||||
stackDest = stackDest || [];
|
||||
|
||||
if (isObject(source)) {
|
||||
var index = indexOf(stackSource, source);
|
||||
if (index !== -1) return stackDest[index];
|
||||
|
||||
stackSource.push(source);
|
||||
stackDest.push(destination);
|
||||
}
|
||||
|
||||
var result;
|
||||
if (isArray(source)) {
|
||||
destination.length = 0;
|
||||
for ( var i = 0; i < source.length; i++) {
|
||||
destination.push(copy(source[i]));
|
||||
result = copy(source[i], null, stackSource, stackDest);
|
||||
if (isObject(source[i])) {
|
||||
stackSource.push(source[i]);
|
||||
stackDest.push(result);
|
||||
}
|
||||
destination.push(result);
|
||||
}
|
||||
} else {
|
||||
var h = destination.$$hashKey;
|
||||
@@ -790,10 +808,16 @@ function copy(source, destination) {
|
||||
delete destination[key];
|
||||
});
|
||||
for ( var key in source) {
|
||||
destination[key] = copy(source[key]);
|
||||
result = copy(source[key], null, stackSource, stackDest);
|
||||
if (isObject(source[key])) {
|
||||
stackSource.push(source[key]);
|
||||
stackDest.push(result);
|
||||
}
|
||||
destination[key] = result;
|
||||
}
|
||||
setHashKey(destination,h);
|
||||
}
|
||||
|
||||
}
|
||||
return destination;
|
||||
}
|
||||
|
||||
@@ -1072,7 +1072,7 @@ function $ParseProvider() {
|
||||
self.$$postDigestQueue.push(function () {
|
||||
// create a copy if the value is defined and it is not a $sce value
|
||||
if ((stable = isDefined(lastValue)) && !lastValue.$$unwrapTrustedValue) {
|
||||
lastValue = copy(lastValue);
|
||||
lastValue = copy(lastValue, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -702,7 +702,7 @@ function $RootScopeProvider(){
|
||||
&& isNaN(value) && isNaN(last)))) {
|
||||
dirty = true;
|
||||
lastDirtyWatch = watch;
|
||||
watch.last = watch.eq ? copy(value) : value;
|
||||
watch.last = watch.eq ? copy(value, null) : value;
|
||||
watch.fn(value, ((last === initWatchVal) ? value : last), current);
|
||||
if (ttl < 5) {
|
||||
logIdx = 4 - ttl;
|
||||
|
||||
Reference in New Issue
Block a user