Skip to content

Commit 4c0c834

Browse files
committed
fix(angular-loader): do not depend on "closure" globals that may not be available
Code that is distributed as part of both `angular.js` and `angular-loader.js` should not depend on "closure" globals that may not be available in `angular-loader`. Fixes angular#15880
1 parent f90b48d commit 4c0c834

File tree

6 files changed

+207
-174
lines changed

6 files changed

+207
-174
lines changed

src/Angular.js

-44
Original file line numberDiff line numberDiff line change
@@ -129,50 +129,6 @@ var VALIDITY_STATE_PROPERTY = 'validity';
129129

130130
var hasOwnProperty = Object.prototype.hasOwnProperty;
131131

132-
var minErrConfig = {
133-
objectMaxDepth: 5
134-
};
135-
136-
/**
137-
* @ngdoc function
138-
* @name angular.errorHandlingConfig
139-
* @module ng
140-
* @kind function
141-
*
142-
* @description
143-
* Configure several aspects of error handling in AngularJS if used as a setter or return the
144-
* current configuration if used as a getter. The following options are supported:
145-
*
146-
* - **objectMaxDepth**: The maximum depth to which objects are traversed when stringified for error messages.
147-
*
148-
* Omitted or undefined options will leave the corresponding configuration values unchanged.
149-
*
150-
* @param {Object=} config - The configuration object. May only contain the options that need to be
151-
* updated. Supported keys:
152-
*
153-
* * `objectMaxDepth` **{Number}** - The max depth for stringifying objects. Setting to a
154-
* non-positive or non-numeric value, removes the max depth limit.
155-
* Default: 5
156-
*/
157-
function errorHandlingConfig(config) {
158-
if (isObject(config)) {
159-
if (isDefined(config.objectMaxDepth)) {
160-
minErrConfig.objectMaxDepth = isValidObjectMaxDepth(config.objectMaxDepth) ? config.objectMaxDepth : NaN;
161-
}
162-
} else {
163-
return minErrConfig;
164-
}
165-
}
166-
167-
/**
168-
* @private
169-
* @param {Number} maxDepth
170-
* @return {boolean}
171-
*/
172-
function isValidObjectMaxDepth(maxDepth) {
173-
return isNumber(maxDepth) && maxDepth > 0;
174-
}
175-
176132
/**
177133
* @private
178134
*

src/loader.prefix

+19
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,24 @@
77
(function() {
88
function isFunction(value) {return typeof value === 'function';}
99
function isDefined(value) {return typeof value !== 'undefined';}
10+
function isNumber(value) {return typeof value === 'number';}
1011
function isObject(value) {return value !== null && typeof value === 'object';}
12+
function isScope(obj) {return obj && obj.$evalAsync && obj.$watch;}
13+
function isWindow(obj) {return obj && obj.window === obj;}
14+
function sliceArgs(args, startIndex) {return Array.prototype.slice.call(args, startIndex || 0);}
15+
function toJsonReplacer(key, value) {
16+
var val = value;
17+
18+
if (typeof key === 'string' && key.charAt(0) === '$' && key.charAt(1) === '$') {
19+
val = undefined;
20+
} else if (isWindow(value)) {
21+
val = '$WINDOW';
22+
} else if (value && window.document === value) {
23+
val = '$DOCUMENT';
24+
} else if (isScope(value)) {
25+
val = '$SCOPE';
26+
}
27+
28+
return val;
29+
}
1130

src/minErr.js

+50
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,55 @@
11
'use strict';
22

3+
/* exported
4+
minErrConfig,
5+
errorHandlingConfig,
6+
isValidObjectMaxDepth
7+
*/
8+
9+
var minErrConfig = {
10+
objectMaxDepth: 5
11+
};
12+
13+
/**
14+
* @ngdoc function
15+
* @name angular.errorHandlingConfig
16+
* @module ng
17+
* @kind function
18+
*
19+
* @description
20+
* Configure several aspects of error handling in AngularJS if used as a setter or return the
21+
* current configuration if used as a getter. The following options are supported:
22+
*
23+
* - **objectMaxDepth**: The maximum depth to which objects are traversed when stringified for error messages.
24+
*
25+
* Omitted or undefined options will leave the corresponding configuration values unchanged.
26+
*
27+
* @param {Object=} config - The configuration object. May only contain the options that need to be
28+
* updated. Supported keys:
29+
*
30+
* * `objectMaxDepth` **{Number}** - The max depth for stringifying objects. Setting to a
31+
* non-positive or non-numeric value, removes the max depth limit.
32+
* Default: 5
33+
*/
34+
function errorHandlingConfig(config) {
35+
if (isObject(config)) {
36+
if (isDefined(config.objectMaxDepth)) {
37+
minErrConfig.objectMaxDepth = isValidObjectMaxDepth(config.objectMaxDepth) ? config.objectMaxDepth : NaN;
38+
}
39+
} else {
40+
return minErrConfig;
41+
}
42+
}
43+
44+
/**
45+
* @private
46+
* @param {Number} maxDepth
47+
* @return {boolean}
48+
*/
49+
function isValidObjectMaxDepth(maxDepth) {
50+
return isNumber(maxDepth) && maxDepth > 0;
51+
}
52+
353
/**
454
* @description
555
*

src/stringify.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
'use strict';
22

3-
/* global toDebugString: true */
3+
/* exported toDebugString */
4+
5+
// This file is also included in `angular-loader`, so `copy()` might not always be available in the
6+
// closure. In such cases, it is lazily retrieved as `angular.copy()` when needed.
7+
var copyFn;
48

59
function serializeObject(obj, maxDepth) {
610
var seen = [];
@@ -9,7 +13,10 @@ function serializeObject(obj, maxDepth) {
913
// and a very deep object can cause a performance issue, so we copy the object
1014
// based on this specific depth and then stringify it.
1115
if (isValidObjectMaxDepth(maxDepth)) {
12-
obj = copy(obj, null, maxDepth);
16+
if (!copyFn) {
17+
copyFn = copy || angular.copy;
18+
}
19+
obj = copyFn(obj, null, maxDepth);
1320
}
1421
return JSON.stringify(obj, function(key, val) {
1522
val = toJsonReplacer(key, val);

test/AngularSpec.js

-25
Original file line numberDiff line numberDiff line change
@@ -7,38 +7,13 @@ Float32Array, Float64Array, */
77

88
describe('angular', function() {
99
var element, document;
10-
var originalObjectMaxDepthInErrorMessage = minErrConfig.objectMaxDepth;
1110

1211
beforeEach(function() {
1312
document = window.document;
1413
});
1514

1615
afterEach(function() {
1716
dealoc(element);
18-
minErrConfig.objectMaxDepth = originalObjectMaxDepthInErrorMessage;
19-
});
20-
21-
describe('errorHandlingConfig', function() {
22-
it('should get default objectMaxDepth', function() {
23-
expect(errorHandlingConfig().objectMaxDepth).toBe(5);
24-
});
25-
26-
it('should set objectMaxDepth', function() {
27-
errorHandlingConfig({objectMaxDepth: 3});
28-
expect(errorHandlingConfig().objectMaxDepth).toBe(3);
29-
});
30-
31-
it('should not change objectMaxDepth when undefined is supplied', function() {
32-
errorHandlingConfig({objectMaxDepth: undefined});
33-
expect(errorHandlingConfig().objectMaxDepth).toBe(originalObjectMaxDepthInErrorMessage);
34-
});
35-
36-
they('should set objectMaxDepth to NaN when $prop is supplied',
37-
[NaN, null, true, false, -1, 0], function(maxDepth) {
38-
errorHandlingConfig({objectMaxDepth: maxDepth});
39-
expect(errorHandlingConfig().objectMaxDepth).toBeNaN();
40-
}
41-
);
4217
});
4318

4419
describe('case', function() {

0 commit comments

Comments
 (0)