10
10
splice,
11
11
push,
12
12
toString,
13
+ objectMaxDepthInErrorMessage,
14
+ configureErrorHandling,
15
+ isValidObjectMaxDepth,
13
16
ngMinErr,
14
17
angularModule,
15
18
uid,
@@ -125,6 +128,39 @@ var VALIDITY_STATE_PROPERTY = 'validity';
125
128
126
129
var hasOwnProperty = Object . prototype . hasOwnProperty ;
127
130
131
+ var objectMaxDepthInErrorMessage = 5 ;
132
+
133
+ /**
134
+ * @ngdoc function
135
+ * @name angular.configureErrorHandling
136
+ * @module ng
137
+ * @kind function
138
+ *
139
+ * @description Use this function to configure error handling.
140
+ *
141
+ * @param {Object= } config An object for defining configuration for error handling. The
142
+ * following keys are supported:
143
+ *
144
+ * * `objectMaxDepth` - used to stringify objects in error messages until reaching the max depth.
145
+ * if it is not supplied the default max depth which is 5 will be used instead, or if it is invalid
146
+ * (less than `1` or not a `Number`) no max depth will be used.
147
+ *
148
+ */
149
+ function configureErrorHandling ( config ) {
150
+ if ( isObject ( config ) ) {
151
+ objectMaxDepthInErrorMessage = isValidObjectMaxDepth ( config . objectMaxDepth ) ? config . objectMaxDepth : NaN ;
152
+ }
153
+ }
154
+
155
+ /**
156
+ * @private
157
+ * @param {Number } maxDepth
158
+ * @return {boolean }
159
+ */
160
+ function isValidObjectMaxDepth ( maxDepth ) {
161
+ return isNumber ( maxDepth ) && maxDepth > 0 ;
162
+ }
163
+
128
164
/**
129
165
* @ngdoc function
130
166
* @name angular.lowercase
@@ -796,6 +832,7 @@ function arrayRemove(array, value) {
796
832
* are deleted and then all elements/properties from the source are copied to it.
797
833
* * If `source` is not an object or array (inc. `null` and `undefined`), `source` is returned.
798
834
* * If `source` is identical to `destination` an exception will be thrown.
835
+ * * If `maxDepth` is supplied, all properties of the source will be copied until reaching the max depth.
799
836
*
800
837
* <br />
801
838
* <div class="alert alert-warning">
@@ -807,6 +844,7 @@ function arrayRemove(array, value) {
807
844
* Can be any type, including primitives, `null`, and `undefined`.
808
845
* @param {(Object|Array)= } destination Destination into which the source is copied. If
809
846
* provided, must be of the same type as `source`.
847
+ * @param {Number= } maxDepth All properties of the source will be copied until reaching the max depth.
810
848
* @returns {* } The copy or updated `destination`, if `destination` was specified.
811
849
*
812
850
* @example
@@ -847,9 +885,10 @@ function arrayRemove(array, value) {
847
885
</file>
848
886
</example>
849
887
*/
850
- function copy ( source , destination ) {
888
+ function copy ( source , destination , maxDepth ) {
851
889
var stackSource = [ ] ;
852
890
var stackDest = [ ] ;
891
+ maxDepth = isValidObjectMaxDepth ( maxDepth ) ? maxDepth : NaN ;
853
892
854
893
if ( destination ) {
855
894
if ( isTypedArray ( destination ) || isArrayBuffer ( destination ) ) {
@@ -872,43 +911,47 @@ function copy(source, destination) {
872
911
873
912
stackSource . push ( source ) ;
874
913
stackDest . push ( destination ) ;
875
- return copyRecurse ( source , destination ) ;
914
+ return copyRecurse ( source , destination , maxDepth ) ;
876
915
}
877
916
878
- return copyElement ( source ) ;
917
+ return copyElement ( source , maxDepth ) ;
879
918
880
- function copyRecurse ( source , destination ) {
919
+ function copyRecurse ( source , destination , maxDepth ) {
920
+ maxDepth -- ;
921
+ if ( maxDepth < 0 ) {
922
+ return '...' ;
923
+ }
881
924
var h = destination . $$hashKey ;
882
925
var key ;
883
926
if ( isArray ( source ) ) {
884
927
for ( var i = 0 , ii = source . length ; i < ii ; i ++ ) {
885
- destination . push ( copyElement ( source [ i ] ) ) ;
928
+ destination . push ( copyElement ( source [ i ] , maxDepth ) ) ;
886
929
}
887
930
} else if ( isBlankObject ( source ) ) {
888
931
// createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
889
932
for ( key in source ) {
890
- destination [ key ] = copyElement ( source [ key ] ) ;
933
+ destination [ key ] = copyElement ( source [ key ] , maxDepth ) ;
891
934
}
892
935
} else if ( source && typeof source . hasOwnProperty === 'function' ) {
893
936
// Slow path, which must rely on hasOwnProperty
894
937
for ( key in source ) {
895
938
if ( source . hasOwnProperty ( key ) ) {
896
- destination [ key ] = copyElement ( source [ key ] ) ;
939
+ destination [ key ] = copyElement ( source [ key ] , maxDepth ) ;
897
940
}
898
941
}
899
942
} else {
900
943
// Slowest path --- hasOwnProperty can't be called as a method
901
944
for ( key in source ) {
902
945
if ( hasOwnProperty . call ( source , key ) ) {
903
- destination [ key ] = copyElement ( source [ key ] ) ;
946
+ destination [ key ] = copyElement ( source [ key ] , maxDepth ) ;
904
947
}
905
948
}
906
949
}
907
950
setHashKey ( destination , h ) ;
908
951
return destination ;
909
952
}
910
953
911
- function copyElement ( source ) {
954
+ function copyElement ( source , maxDepth ) {
912
955
// Simple values
913
956
if ( ! isObject ( source ) ) {
914
957
return source ;
@@ -937,7 +980,7 @@ function copy(source, destination) {
937
980
stackDest . push ( destination ) ;
938
981
939
982
return needsRecurse
940
- ? copyRecurse ( source , destination )
983
+ ? copyRecurse ( source , destination , maxDepth )
941
984
: destination ;
942
985
}
943
986
0 commit comments