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