@@ -783,98 +783,121 @@ function arrayRemove(array, value) {
783
783
</file>
784
784
</example>
785
785
*/
786
- function copy ( source , destination , stackSource , stackDest ) {
787
- if ( isWindow ( source ) || isScope ( source ) ) {
788
- throw ngMinErr ( 'cpws' ,
789
- "Can't copy! Making copies of Window or Scope instances is not supported." ) ;
790
- }
791
- if ( isTypedArray ( destination ) ) {
792
- throw ngMinErr ( 'cpta' ,
793
- "Can't copy! TypedArray destination cannot be mutated." ) ;
794
- }
795
-
796
- if ( ! destination ) {
797
- destination = source ;
798
- if ( isObject ( source ) ) {
799
- var index ;
800
- if ( stackSource && ( index = stackSource . indexOf ( source ) ) !== - 1 ) {
801
- return stackDest [ index ] ;
802
- }
803
-
804
- // TypedArray, Date and RegExp have specific copy functionality and must be
805
- // pushed onto the stack before returning.
806
- // Array and other objects create the base object and recurse to copy child
807
- // objects. The array/object will be pushed onto the stack when recursed.
808
- if ( isArray ( source ) ) {
809
- return copy ( source , [ ] , stackSource , stackDest ) ;
810
- } else if ( isTypedArray ( source ) ) {
811
- destination = new source . constructor ( source ) ;
812
- } else if ( isDate ( source ) ) {
813
- destination = new Date ( source . getTime ( ) ) ;
814
- } else if ( isRegExp ( source ) ) {
815
- destination = new RegExp ( source . source , source . toString ( ) . match ( / [ ^ \/ ] * $ / ) [ 0 ] ) ;
816
- destination . lastIndex = source . lastIndex ;
817
- } else {
818
- var emptyObject = Object . create ( getPrototypeOf ( source ) ) ;
819
- return copy ( source , emptyObject , stackSource , stackDest ) ;
820
- }
821
-
822
- if ( stackDest ) {
823
- stackSource . push ( source ) ;
824
- stackDest . push ( destination ) ;
825
- }
786
+ function copy ( source , destination ) {
787
+ var stackSource_obj = [ ] ;
788
+ var stackDest_obj = [ ] ;
789
+ var stackSource_arr = [ ] ;
790
+ var stackDest_arr = [ ] ;
791
+ var stackSource_ta = [ ] ;
792
+ var stackDest_ta = [ ] ;
793
+ var stackSource_date = [ ] ;
794
+ var stackDest_date = [ ] ;
795
+ var stackSource_regex = [ ] ;
796
+ var stackDest_regex = [ ] ;
797
+ return copy_ ( source , destination ) ;
798
+
799
+ function copy_ ( source , destination ) {
800
+ if ( isWindow ( source ) || isScope ( source ) ) {
801
+ throw ngMinErr ( 'cpws' ,
802
+ "Can't copy! Making copies of Window or Scope instances is not supported." ) ;
826
803
}
827
- } else {
828
- if ( source === destination ) throw ngMinErr ( 'cpi' ,
829
- "Can't copy! Source and destination are identical." ) ;
830
-
831
- stackSource = stackSource || [ ] ;
832
- stackDest = stackDest || [ ] ;
833
-
834
- if ( isObject ( source ) ) {
835
- stackSource . push ( source ) ;
836
- stackDest . push ( destination ) ;
804
+ if ( isTypedArray ( destination ) ) {
805
+ throw ngMinErr ( 'cpta' ,
806
+ "Can't copy! TypedArray destination cannot be mutated." ) ;
837
807
}
838
808
839
- var result , key ;
840
- if ( isArray ( source ) ) {
841
- destination . length = 0 ;
842
- for ( var i = 0 ; i < source . length ; i ++ ) {
843
- destination . push ( copy ( source [ i ] , null , stackSource , stackDest ) ) ;
809
+ if ( ! destination ) {
810
+ destination = source ;
811
+ if ( isObject ( source ) ) {
812
+ var index ;
813
+
814
+ // TypedArray, Date and RegExp have specific copy functionality and must be
815
+ // pushed onto the stack before returning.
816
+ // Array and other objects create the base object and recurse to copy child
817
+ // objects. The array/object will be pushed onto the stack when recursed.
818
+ if ( isArray ( source ) ) {
819
+ if ( ( index = stackSource_arr . indexOf ( source ) ) !== - 1 ) {
820
+ return stackDest_arr [ index ] ;
821
+ }
822
+ return copy_ ( source , [ ] ) ;
823
+ } else if ( isTypedArray ( source ) ) {
824
+ if ( ( index = stackSource_ta . indexOf ( source ) ) !== - 1 ) {
825
+ return stackDest_ta [ index ] ;
826
+ }
827
+ destination = new source . constructor ( source ) ;
828
+ stackSource_ta . push ( source ) ;
829
+ stackDest_ta . push ( destination ) ;
830
+ } else if ( isDate ( source ) ) {
831
+ if ( ( index = stackSource_date . indexOf ( source ) ) !== - 1 ) {
832
+ return stackDest_date [ index ] ;
833
+ }
834
+ destination = new Date ( source . getTime ( ) ) ;
835
+ stackSource_date . push ( source ) ;
836
+ stackDest_date . push ( destination ) ;
837
+ } else if ( isRegExp ( source ) ) {
838
+ if ( ( index = stackSource_regex . indexOf ( source ) ) !== - 1 ) {
839
+ return stackDest_regex [ index ] ;
840
+ }
841
+ destination = new RegExp ( source . source , source . toString ( ) . match ( / [ ^ \/ ] * $ / ) [ 0 ] ) ;
842
+ destination . lastIndex = source . lastIndex ;
843
+ stackSource_regex . push ( source ) ;
844
+ stackDest_regex . push ( destination ) ;
845
+ } else {
846
+ if ( ( index = stackSource_obj . indexOf ( source ) ) !== - 1 ) {
847
+ return stackDest_obj [ index ] ;
848
+ }
849
+ var emptyObject = Object . create ( getPrototypeOf ( source ) ) ;
850
+ return copy_ ( source , emptyObject ) ;
851
+ }
844
852
}
845
853
} else {
846
- var h = destination . $$hashKey ;
847
- if ( isArray ( destination ) ) {
854
+ if ( source === destination ) throw ngMinErr ( 'cpi' ,
855
+ "Can't copy! Source and destination are identical." ) ;
856
+
857
+ var result , key ;
858
+ if ( isArray ( source ) ) {
859
+ stackSource_arr . push ( source ) ;
860
+ stackDest_arr . push ( destination ) ;
848
861
destination . length = 0 ;
849
- } else {
850
- forEach ( destination , function ( value , key ) {
851
- delete destination [ key ] ;
852
- } ) ;
853
- }
854
- if ( isBlankObject ( source ) ) {
855
- // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
856
- for ( key in source ) {
857
- destination [ key ] = copy ( source [ key ] , null , stackSource , stackDest ) ;
862
+ for ( var i = 0 ; i < source . length ; i ++ ) {
863
+ destination . push ( copy_ ( source [ i ] , null ) ) ;
858
864
}
859
- } else if ( source && typeof source . hasOwnProperty === 'function' ) {
860
- // Slow path, which must rely on hasOwnProperty
861
- for ( key in source ) {
862
- if ( source . hasOwnProperty ( key ) ) {
863
- destination [ key ] = copy ( source [ key ] , null , stackSource , stackDest ) ;
865
+ } else {
866
+ stackSource_obj . push ( source ) ;
867
+ stackDest_obj . push ( destination ) ;
868
+ var h = destination . $$hashKey ;
869
+ if ( isArray ( destination ) ) {
870
+ destination . length = 0 ;
871
+ } else {
872
+ for ( key in destination ) {
873
+ delete destination [ key ] ;
864
874
}
865
875
}
866
- } else {
867
- // Slowest path --- hasOwnProperty can't be called as a method
868
- for ( key in source ) {
869
- if ( hasOwnProperty . call ( source , key ) ) {
870
- destination [ key ] = copy ( source [ key ] , null , stackSource , stackDest ) ;
876
+ if ( isBlankObject ( source ) ) {
877
+ // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
878
+ for ( key in source ) {
879
+ destination [ key ] = copy_ ( source [ key ] , null ) ;
880
+ }
881
+ } else if ( source && typeof source . hasOwnProperty === 'function' ) {
882
+ // Slow path, which must rely on hasOwnProperty
883
+ for ( key in source ) {
884
+ if ( source . hasOwnProperty ( key ) ) {
885
+ destination [ key ] = copy_ ( source [ key ] , null ) ;
886
+ }
887
+ }
888
+ } else {
889
+ // Slowest path --- hasOwnProperty can't be called as a method
890
+ for ( key in source ) {
891
+ if ( hasOwnProperty . call ( source , key ) ) {
892
+ destination [ key ] = copy_ ( source [ key ] , null ) ;
893
+ }
871
894
}
872
895
}
896
+ setHashKey ( destination , h ) ;
873
897
}
874
- setHashKey ( destination , h ) ;
875
898
}
899
+ return destination ;
876
900
}
877
- return destination ;
878
901
}
879
902
880
903
/**
0 commit comments