@angular-wave/angular.ts 0.0.47 → 0.0.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Makefile +3 -0
- package/README.md +1 -1
- package/css/angular.css +0 -6
- package/dist/angular-ts.esm.js +2 -2
- package/dist/angular-ts.umd.js +2 -2
- package/jsdoc.json +24 -0
- package/package.json +6 -2
- package/src/angular.spec.js +1 -2
- package/src/animations/animate-queue.js +0 -1
- package/src/animations/animation.js +1 -1
- package/src/animations/raf-scheduler.js +0 -1
- package/src/animations/shared.js +1 -1
- package/src/core/animate/animate.js +0 -1
- package/src/core/compile/compile.md +1 -1
- package/src/core/compile/compile.spec.js +49 -47
- package/src/core/location/location.spec.js +1 -1
- package/src/core/on.spec.js +7 -12
- package/src/core/parser/ast-type.js +22 -0
- package/src/core/parser/ast.js +426 -0
- package/src/core/parser/compiler.js +561 -0
- package/src/core/parser/interpreter.js +422 -0
- package/src/core/parser/lexer.js +345 -0
- package/src/core/parser/parse.js +23 -1984
- package/src/core/parser/parse.md +57 -0
- package/src/core/parser/parse.spec.js +2 -2
- package/src/core/parser/parser.js +45 -0
- package/src/core/parser/shared.js +228 -0
- package/src/core/prop.spec.js +4 -4
- package/src/core/q/q.spec.js +0 -1
- package/src/core/sce/sce.js +3 -6
- package/src/core/scope/scope.js +33 -21
- package/src/core/task-tracker-factory.js +0 -1
- package/src/directive/class/class.js +0 -2
- package/src/directive/form/form.js +0 -3
- package/src/directive/form/form.spec.js +18 -18
- package/src/directive/include/include.js +1 -1
- package/src/directive/include/include.spec.js +18 -19
- package/src/directive/input/input.js +1 -2
- package/src/directive/model/model.js +1 -3
- package/src/directive/model/model.spec.js +0 -1
- package/src/directive/repeat/repeat.spec.js +0 -2
- package/src/directive/switch/switch.spec.js +4 -4
- package/src/exts/aria/aria.js +0 -1
- package/src/filters/filter.spec.js +0 -1
- package/src/injector.js +1 -1
- package/src/injector.spec.js +0 -5
- package/src/loader.js +0 -5
- package/src/services/cookie-reader.js +0 -1
- package/src/services/http/http.spec.js +0 -2
- package/src/shared/constants.js +3 -2
- package/src/shared/utils.js +18 -7
- package/src/types.js +10 -0
- package/types/core/parser/ast-type.d.ts +20 -0
- package/types/core/parser/ast.d.ts +86 -0
- package/types/core/parser/compiler.d.ts +49 -0
- package/types/core/parser/interpreter.d.ts +57 -0
- package/types/core/parser/lexer.d.ts +153 -0
- package/types/core/parser/parse.d.ts +68 -0
- package/types/core/parser/parser.d.ts +28 -0
- package/types/core/parser/shared.d.ts +29 -0
- package/types/core/scope/scope.d.ts +19 -12
- package/types/shared/utils.d.ts +18 -5
- package/types/types.d.ts +1 -0
- package/types-back/index.d.ts +0 -12
package/src/core/parser/parse.md
CHANGED
|
@@ -11,3 +11,60 @@
|
|
|
11
11
|
// content then it is possible that your application contains a security vulnerability to an XSS style attack.
|
|
12
12
|
//
|
|
13
13
|
// See https://docs.angularjs.org/guide/security
|
|
14
|
+
|
|
15
|
+
/\*\*
|
|
16
|
+
|
|
17
|
+
- @ngdoc service
|
|
18
|
+
- @name $parse
|
|
19
|
+
- @kind function
|
|
20
|
+
-
|
|
21
|
+
- @description
|
|
22
|
+
-
|
|
23
|
+
- Converts AngularJS {@link guide/expression expression} into a function.
|
|
24
|
+
-
|
|
25
|
+
- ```js
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
- let getter = $parse('user.name');
|
|
30
|
+
- let setter = getter.assign;
|
|
31
|
+
- let context = {user:{name:'AngularJS'}};
|
|
32
|
+
- let locals = {user:{name:'local'}};
|
|
33
|
+
-
|
|
34
|
+
- expect(getter(context)).toEqual('AngularJS');
|
|
35
|
+
- setter(context, 'newValue');
|
|
36
|
+
- expect(context.user.name).toEqual('newValue');
|
|
37
|
+
- expect(getter(context, locals)).toEqual('local');
|
|
38
|
+
- ```
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
-
|
|
43
|
+
-
|
|
44
|
+
- @param {string} expression String expression to compile.
|
|
45
|
+
- @returns {function(context, locals)} a function which represents the compiled expression:
|
|
46
|
+
-
|
|
47
|
+
- - `context` – `{object}` – an object against which any expressions embedded in the strings
|
|
48
|
+
- are evaluated against (typically a scope object).
|
|
49
|
+
- - `locals` – `{object=}` – local variables context object, useful for overriding values in
|
|
50
|
+
- `context`.
|
|
51
|
+
-
|
|
52
|
+
- The returned function also has the following properties:
|
|
53
|
+
- * `literal` – `{boolean}` – whether the expression's top-level node is a JavaScript
|
|
54
|
+
- literal.
|
|
55
|
+
- * `constant` – `{boolean}` – whether the expression is made entirely of JavaScript
|
|
56
|
+
- constant literals.
|
|
57
|
+
- * `assign` – `{?function(context, value)}` – if the expression is assignable, this will be
|
|
58
|
+
- set to a function to change its value on the given context.
|
|
59
|
+
- \*/
|
|
60
|
+
|
|
61
|
+
/\*\*
|
|
62
|
+
|
|
63
|
+
- @ngdoc provider
|
|
64
|
+
- @name $parseProvider
|
|
65
|
+
-
|
|
66
|
+
-
|
|
67
|
+
- @description
|
|
68
|
+
- `$parseProvider` can be used for configuring the default behavior of the {@link ng.$parse $parse}
|
|
69
|
+
- service.
|
|
70
|
+
\*/
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { AST
|
|
1
|
+
import { AST } from "./ast";
|
|
2
|
+
import { Lexer } from "./lexer";
|
|
2
3
|
import {
|
|
3
4
|
forEach,
|
|
4
5
|
isFunction,
|
|
@@ -2366,7 +2367,6 @@ describe("parser", () => {
|
|
|
2366
2367
|
|
|
2367
2368
|
it("should evaluate negation", () => {
|
|
2368
2369
|
expect(scope.$eval("!false || true")).toEqual(!false || true);
|
|
2369
|
-
// eslint-disable-next-line eqeqeq
|
|
2370
2370
|
expect(scope.$eval("!11 == 10")).toEqual(!11 == 10);
|
|
2371
2371
|
expect(scope.$eval("12/6/2")).toEqual(12 / 6 / 2);
|
|
2372
2372
|
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { AST } from "./ast";
|
|
2
|
+
import { isLiteral, isConstant } from "./shared";
|
|
3
|
+
import { ASTInterpreter } from "./interpreter";
|
|
4
|
+
import { ASTCompiler } from "./compiler";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @constructor
|
|
8
|
+
*/
|
|
9
|
+
export class Parser {
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* @param {import('./lexer').Lexer} lexer
|
|
13
|
+
* @param {*} $filter
|
|
14
|
+
* @param {*} options
|
|
15
|
+
*/
|
|
16
|
+
constructor(lexer, $filter, options) {
|
|
17
|
+
this.ast = new AST(lexer, options);
|
|
18
|
+
this.astCompiler = options.csp
|
|
19
|
+
? new ASTInterpreter($filter)
|
|
20
|
+
: new ASTCompiler($filter);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
parse(text) {
|
|
24
|
+
const { ast, oneTime } = this.getAst(text);
|
|
25
|
+
const fn = this.astCompiler.compile(ast);
|
|
26
|
+
fn.literal = isLiteral(ast);
|
|
27
|
+
fn.constant = isConstant(ast);
|
|
28
|
+
fn.oneTime = oneTime;
|
|
29
|
+
return fn;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
getAst(exp) {
|
|
33
|
+
let oneTime = false;
|
|
34
|
+
exp = exp.trim();
|
|
35
|
+
|
|
36
|
+
if (exp.startsWith("::")) {
|
|
37
|
+
oneTime = true;
|
|
38
|
+
exp = exp.substring(2);
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
ast: this.ast.ast(exp),
|
|
42
|
+
oneTime,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { ASTType } from "./ast-type";
|
|
2
|
+
import { forEach, isFunction } from "../../shared/utils";
|
|
3
|
+
|
|
4
|
+
const objectValueOf = {}.constructor.prototype.valueOf;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Converts parameter to strings property name for use as keys in an object.
|
|
8
|
+
* Any non-string object, including a number, is typecasted into a string via the toString method.
|
|
9
|
+
* {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Property_accessors#Property_names}
|
|
10
|
+
*
|
|
11
|
+
* @param {!any} name
|
|
12
|
+
* @returns {string}
|
|
13
|
+
*/
|
|
14
|
+
export function getStringValue(name) {
|
|
15
|
+
return `${name}`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/// //////////////////////////////////////
|
|
19
|
+
|
|
20
|
+
export function ifDefined(v, d) {
|
|
21
|
+
return typeof v !== "undefined" ? v : d;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function plusFn(l, r) {
|
|
25
|
+
if (typeof l === "undefined") return r;
|
|
26
|
+
if (typeof r === "undefined") return l;
|
|
27
|
+
return l + r;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function isStateless($filter, filterName) {
|
|
31
|
+
const fn = $filter(filterName);
|
|
32
|
+
return !fn.$stateful;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const PURITY_ABSOLUTE = 1;
|
|
36
|
+
export const PURITY_RELATIVE = 2;
|
|
37
|
+
|
|
38
|
+
// Detect nodes which could depend on non-shallow state of objects
|
|
39
|
+
export function isPure(node, parentIsPure) {
|
|
40
|
+
switch (node.type) {
|
|
41
|
+
// Computed members might invoke a stateful toString()
|
|
42
|
+
case ASTType.MemberExpression:
|
|
43
|
+
if (node.computed) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
break;
|
|
47
|
+
|
|
48
|
+
// Unary always convert to primative
|
|
49
|
+
case ASTType.UnaryExpression:
|
|
50
|
+
return PURITY_ABSOLUTE;
|
|
51
|
+
|
|
52
|
+
// The binary + operator can invoke a stateful toString().
|
|
53
|
+
case ASTType.BinaryExpression:
|
|
54
|
+
return node.operator !== "+" ? PURITY_ABSOLUTE : false;
|
|
55
|
+
|
|
56
|
+
// Functions / filters probably read state from within objects
|
|
57
|
+
case ASTType.CallExpression:
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return undefined === parentIsPure ? PURITY_RELATIVE : parentIsPure;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function findConstantAndWatchExpressions(ast, $filter, parentIsPure) {
|
|
65
|
+
let allConstants;
|
|
66
|
+
let argsToWatch;
|
|
67
|
+
let isStatelessFilter;
|
|
68
|
+
|
|
69
|
+
const astIsPure = (ast.isPure = isPure(ast, parentIsPure));
|
|
70
|
+
|
|
71
|
+
switch (ast.type) {
|
|
72
|
+
case ASTType.Program:
|
|
73
|
+
allConstants = true;
|
|
74
|
+
/** @type {[any]} */ (ast.body).forEach((expr) => {
|
|
75
|
+
findConstantAndWatchExpressions(expr.expression, $filter, astIsPure);
|
|
76
|
+
allConstants = allConstants && expr.expression.constant;
|
|
77
|
+
});
|
|
78
|
+
ast.constant = allConstants;
|
|
79
|
+
break;
|
|
80
|
+
case ASTType.Literal:
|
|
81
|
+
ast.constant = true;
|
|
82
|
+
ast.toWatch = [];
|
|
83
|
+
break;
|
|
84
|
+
case ASTType.UnaryExpression:
|
|
85
|
+
findConstantAndWatchExpressions(ast.argument, $filter, astIsPure);
|
|
86
|
+
ast.constant = ast.argument.constant;
|
|
87
|
+
ast.toWatch = ast.argument.toWatch;
|
|
88
|
+
break;
|
|
89
|
+
case ASTType.BinaryExpression:
|
|
90
|
+
findConstantAndWatchExpressions(ast.left, $filter, astIsPure);
|
|
91
|
+
findConstantAndWatchExpressions(ast.right, $filter, astIsPure);
|
|
92
|
+
ast.constant = ast.left.constant && ast.right.constant;
|
|
93
|
+
ast.toWatch = ast.left.toWatch.concat(ast.right.toWatch);
|
|
94
|
+
break;
|
|
95
|
+
case ASTType.LogicalExpression:
|
|
96
|
+
findConstantAndWatchExpressions(ast.left, $filter, astIsPure);
|
|
97
|
+
findConstantAndWatchExpressions(ast.right, $filter, astIsPure);
|
|
98
|
+
ast.constant = ast.left.constant && ast.right.constant;
|
|
99
|
+
ast.toWatch = ast.constant ? [] : [ast];
|
|
100
|
+
break;
|
|
101
|
+
case ASTType.ConditionalExpression:
|
|
102
|
+
findConstantAndWatchExpressions(ast.test, $filter, astIsPure);
|
|
103
|
+
findConstantAndWatchExpressions(ast.alternate, $filter, astIsPure);
|
|
104
|
+
findConstantAndWatchExpressions(ast.consequent, $filter, astIsPure);
|
|
105
|
+
ast.constant =
|
|
106
|
+
ast.test.constant && ast.alternate.constant && ast.consequent.constant;
|
|
107
|
+
ast.toWatch = ast.constant ? [] : [ast];
|
|
108
|
+
break;
|
|
109
|
+
case ASTType.Identifier:
|
|
110
|
+
ast.constant = false;
|
|
111
|
+
ast.toWatch = [ast];
|
|
112
|
+
break;
|
|
113
|
+
case ASTType.MemberExpression:
|
|
114
|
+
findConstantAndWatchExpressions(ast.object, $filter, astIsPure);
|
|
115
|
+
if (ast.computed) {
|
|
116
|
+
findConstantAndWatchExpressions(ast.property, $filter, astIsPure);
|
|
117
|
+
}
|
|
118
|
+
ast.constant =
|
|
119
|
+
ast.object.constant && (!ast.computed || ast.property.constant);
|
|
120
|
+
ast.toWatch = ast.constant ? [] : [ast];
|
|
121
|
+
break;
|
|
122
|
+
case ASTType.CallExpression:
|
|
123
|
+
isStatelessFilter = ast.filter
|
|
124
|
+
? isStateless($filter, ast.callee.name)
|
|
125
|
+
: false;
|
|
126
|
+
allConstants = isStatelessFilter;
|
|
127
|
+
argsToWatch = [];
|
|
128
|
+
forEach(ast.arguments, (expr) => {
|
|
129
|
+
findConstantAndWatchExpressions(expr, $filter, astIsPure);
|
|
130
|
+
allConstants = allConstants && expr.constant;
|
|
131
|
+
argsToWatch.push.apply(argsToWatch, expr.toWatch);
|
|
132
|
+
});
|
|
133
|
+
ast.constant = allConstants;
|
|
134
|
+
ast.toWatch = isStatelessFilter ? argsToWatch : [ast];
|
|
135
|
+
break;
|
|
136
|
+
case ASTType.AssignmentExpression:
|
|
137
|
+
findConstantAndWatchExpressions(ast.left, $filter, astIsPure);
|
|
138
|
+
findConstantAndWatchExpressions(ast.right, $filter, astIsPure);
|
|
139
|
+
ast.constant = ast.left.constant && ast.right.constant;
|
|
140
|
+
ast.toWatch = [ast];
|
|
141
|
+
break;
|
|
142
|
+
case ASTType.ArrayExpression:
|
|
143
|
+
allConstants = true;
|
|
144
|
+
argsToWatch = [];
|
|
145
|
+
forEach(ast.elements, (expr) => {
|
|
146
|
+
findConstantAndWatchExpressions(expr, $filter, astIsPure);
|
|
147
|
+
allConstants = allConstants && expr.constant;
|
|
148
|
+
argsToWatch.push.apply(argsToWatch, expr.toWatch);
|
|
149
|
+
});
|
|
150
|
+
ast.constant = allConstants;
|
|
151
|
+
ast.toWatch = argsToWatch;
|
|
152
|
+
break;
|
|
153
|
+
case ASTType.ObjectExpression:
|
|
154
|
+
allConstants = true;
|
|
155
|
+
argsToWatch = [];
|
|
156
|
+
forEach(ast.properties, (property) => {
|
|
157
|
+
findConstantAndWatchExpressions(property.value, $filter, astIsPure);
|
|
158
|
+
allConstants = allConstants && property.value.constant;
|
|
159
|
+
argsToWatch.push.apply(argsToWatch, property.value.toWatch);
|
|
160
|
+
if (property.computed) {
|
|
161
|
+
// `{[key]: value}` implicitly does `key.toString()` which may be non-pure
|
|
162
|
+
findConstantAndWatchExpressions(
|
|
163
|
+
property.key,
|
|
164
|
+
$filter,
|
|
165
|
+
/* parentIsPure= */ false,
|
|
166
|
+
);
|
|
167
|
+
allConstants = allConstants && property.key.constant;
|
|
168
|
+
argsToWatch.push.apply(argsToWatch, property.key.toWatch);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
ast.constant = allConstants;
|
|
172
|
+
ast.toWatch = argsToWatch;
|
|
173
|
+
break;
|
|
174
|
+
case ASTType.ThisExpression:
|
|
175
|
+
ast.constant = false;
|
|
176
|
+
ast.toWatch = [];
|
|
177
|
+
break;
|
|
178
|
+
case ASTType.LocalsExpression:
|
|
179
|
+
ast.constant = false;
|
|
180
|
+
ast.toWatch = [];
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export function getInputs(body) {
|
|
186
|
+
if (body.length !== 1) return;
|
|
187
|
+
const lastExpression = body[0].expression;
|
|
188
|
+
const candidate = lastExpression.toWatch;
|
|
189
|
+
if (candidate.length !== 1) return candidate;
|
|
190
|
+
return candidate[0] !== lastExpression ? candidate : undefined;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export function isAssignable(ast) {
|
|
194
|
+
return (
|
|
195
|
+
ast.type === ASTType.Identifier || ast.type === ASTType.MemberExpression
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export function assignableAST(ast) {
|
|
200
|
+
if (ast.body.length === 1 && isAssignable(ast.body[0].expression)) {
|
|
201
|
+
return {
|
|
202
|
+
type: ASTType.AssignmentExpression,
|
|
203
|
+
left: ast.body[0].expression,
|
|
204
|
+
right: { type: ASTType.NGValueParameter },
|
|
205
|
+
operator: "=",
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export function isLiteral(ast) {
|
|
211
|
+
return (
|
|
212
|
+
ast.body.length === 0 ||
|
|
213
|
+
(ast.body.length === 1 &&
|
|
214
|
+
(ast.body[0].expression.type === ASTType.Literal ||
|
|
215
|
+
ast.body[0].expression.type === ASTType.ArrayExpression ||
|
|
216
|
+
ast.body[0].expression.type === ASTType.ObjectExpression))
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export function isConstant(ast) {
|
|
221
|
+
return ast.constant;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export function getValueOf(value) {
|
|
225
|
+
return isFunction(value.valueOf)
|
|
226
|
+
? value.valueOf()
|
|
227
|
+
: objectValueOf.call(value);
|
|
228
|
+
}
|
package/src/core/prop.spec.js
CHANGED
|
@@ -119,7 +119,7 @@ describe("ngProp*", () => {
|
|
|
119
119
|
it("should work with different prefixes", () => {
|
|
120
120
|
$rootScope.name = "Misko";
|
|
121
121
|
const element = $compile(
|
|
122
|
-
'<span ng
|
|
122
|
+
'<span ng-prop-test="name" ng-Prop-test2="name" ng-Prop-test3="name"></span>',
|
|
123
123
|
)($rootScope);
|
|
124
124
|
expect(element[0].test).toBe("Misko");
|
|
125
125
|
expect(element[0].test2).toBe("Misko");
|
|
@@ -138,7 +138,7 @@ describe("ngProp*", () => {
|
|
|
138
138
|
it("should work if they are prefixed with x- or data- and different prefixes", () => {
|
|
139
139
|
$rootScope.name = "Misko";
|
|
140
140
|
const element = $compile(
|
|
141
|
-
'<span data-ng-prop-test2="name" ng-prop-test3="name" data-ng
|
|
141
|
+
'<span data-ng-prop-test2="name" ng-prop-test3="name" data-ng-prop-test4="name" ' +
|
|
142
142
|
'ng-prop-test5="name" ng-prop-test6="name"></span>',
|
|
143
143
|
)($rootScope);
|
|
144
144
|
expect(element[0].test2).toBe("Misko");
|
|
@@ -179,7 +179,7 @@ describe("ngProp*", () => {
|
|
|
179
179
|
}),
|
|
180
180
|
);
|
|
181
181
|
$compile(
|
|
182
|
-
'<div attr-exposer ng-prop-title="12" ng-prop-super-title="34" ng-prop-my-
|
|
182
|
+
'<div attr-exposer ng-prop-title="12" ng-prop-super-title="34" ng-prop-my-camel-title="56">',
|
|
183
183
|
)($rootScope);
|
|
184
184
|
|
|
185
185
|
expect(attrs.title).toBeUndefined();
|
|
@@ -195,7 +195,7 @@ describe("ngProp*", () => {
|
|
|
195
195
|
expect(attrs.myCamelTitle).toBeUndefined();
|
|
196
196
|
expect(attrs.$attr.myCamelTitle).toBeUndefined();
|
|
197
197
|
expect(attrs.ngPropMyCamelTitle).toBe("56");
|
|
198
|
-
expect(attrs.$attr.ngPropMyCamelTitle).toBe("ng-prop-my-
|
|
198
|
+
expect(attrs.$attr.ngPropMyCamelTitle).toBe("ng-prop-my-camel-title");
|
|
199
199
|
});
|
|
200
200
|
|
|
201
201
|
it("should not conflict with (ng-attr-)attribute mappings of the same name", () => {
|
package/src/core/q/q.spec.js
CHANGED
package/src/core/sce/sce.js
CHANGED
|
@@ -46,12 +46,9 @@ export const SCE_CONTEXTS = {
|
|
|
46
46
|
// http://docs.closure-library.googlecode.com/git/local_closure_goog_string_string.js.source.html#line1021
|
|
47
47
|
// Prereq: s is a string.
|
|
48
48
|
export function escapeForRegexp(s) {
|
|
49
|
-
return
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
// eslint-disable-next-line no-control-regex
|
|
53
|
-
.replace(/\x08/g, "\\x08")
|
|
54
|
-
);
|
|
49
|
+
return s
|
|
50
|
+
.replace(/([-()[\]{}+?*.$^|,:#<!\\])/g, "\\$1")
|
|
51
|
+
.replace(/\x08/g, "\\x08");
|
|
55
52
|
}
|
|
56
53
|
|
|
57
54
|
export function adjustMatcher(matcher) {
|
package/src/core/scope/scope.js
CHANGED
|
@@ -45,13 +45,17 @@ const $rootScopeMinErr = minErr("$rootScope");
|
|
|
45
45
|
/** @type {AsyncQueueTask[]} */
|
|
46
46
|
export const $$asyncQueue = [];
|
|
47
47
|
export const $$postDigestQueue = [];
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @type {Function[]}
|
|
51
|
+
*/
|
|
48
52
|
export const $$applyAsyncQueue = [];
|
|
49
53
|
let postDigestQueuePosition = 0;
|
|
50
54
|
let lastDirtyWatch = null;
|
|
51
55
|
let applyAsyncId = null;
|
|
52
56
|
|
|
53
57
|
/** Services required by each scope instance */
|
|
54
|
-
/** @type {
|
|
58
|
+
/** @type {import('../parser/parse').ParseService} */
|
|
55
59
|
let $parse;
|
|
56
60
|
/** @type {import('../../services/browser').Browser} */
|
|
57
61
|
let $browser;
|
|
@@ -84,9 +88,9 @@ export class $RootScopeProvider {
|
|
|
84
88
|
"$parse",
|
|
85
89
|
"$browser",
|
|
86
90
|
/**
|
|
87
|
-
* @param {
|
|
88
|
-
* @param {import('../
|
|
89
|
-
* @param {
|
|
91
|
+
* @param {import('../exception-handler').ErrorHandler} exceptionHandler
|
|
92
|
+
* @param {import('../parser/parse').ParseService} parse
|
|
93
|
+
* @param {import('../../services/browser').Browser} browser
|
|
90
94
|
* @returns {Scope} root scope
|
|
91
95
|
*/
|
|
92
96
|
function (exceptionHandler, parse, browser) {
|
|
@@ -144,7 +148,7 @@ export class Scope {
|
|
|
144
148
|
this.$root = this;
|
|
145
149
|
|
|
146
150
|
/**
|
|
147
|
-
* @type {
|
|
151
|
+
* @type {Array<any>}
|
|
148
152
|
*/
|
|
149
153
|
this.$$watchers = [];
|
|
150
154
|
|
|
@@ -259,7 +263,7 @@ export class Scope {
|
|
|
259
263
|
if (isolate || parent !== this) {
|
|
260
264
|
child.$on(
|
|
261
265
|
"$destroy",
|
|
262
|
-
/** @param {
|
|
266
|
+
/** @param {any} $event */ //angular.IAngularEvent
|
|
263
267
|
($event) => {
|
|
264
268
|
$event.currentScope.$$destroyed = true;
|
|
265
269
|
},
|
|
@@ -436,10 +440,10 @@ export class Scope {
|
|
|
436
440
|
* values are examined for changes on every call to `$digest`.
|
|
437
441
|
* - The `listener` is called whenever any expression in the `watchExpressions` array changes.
|
|
438
442
|
*
|
|
439
|
-
* @param {Array.<string|
|
|
443
|
+
* @param {Array.<string|((Scope)=>any)>} watchExpressions Array of expressions that will be individually
|
|
440
444
|
* watched using {@link ng.$rootScope.Scope#$watch $watch()}
|
|
441
445
|
*
|
|
442
|
-
* @param {function(
|
|
446
|
+
* @param {function(any, any, Scope): any} listener Callback called whenever the return value of any
|
|
443
447
|
* expression in `watchExpressions` changes
|
|
444
448
|
* The `newValues` array contains the current values of the `watchExpressions`, with the indexes matching
|
|
445
449
|
* those of `watchExpression`
|
|
@@ -529,12 +533,12 @@ export class Scope {
|
|
|
529
533
|
*
|
|
530
534
|
*
|
|
531
535
|
*
|
|
532
|
-
* @param {string|function(
|
|
536
|
+
* @param {string|function(Scope):any} obj Evaluated as {@link guide/expression expression}. The
|
|
533
537
|
* expression value should evaluate to an object or an array which is observed on each
|
|
534
538
|
* {@link ng.$rootScope.Scope#$digest $digest} cycle. Any shallow change within the
|
|
535
539
|
* collection will trigger a call to the `listener`.
|
|
536
540
|
*
|
|
537
|
-
* @param {function(
|
|
541
|
+
* @param {function(any[], any[], Scope):any} listener a callback function called
|
|
538
542
|
* when a change is detected.
|
|
539
543
|
* - The `newCollection` object is the newly modified data obtained from the `obj` expression
|
|
540
544
|
* - The `oldCollection` object is a copy of the former collection data.
|
|
@@ -606,7 +610,6 @@ export class Scope {
|
|
|
606
610
|
oldItem = oldValue[i];
|
|
607
611
|
newItem = newValue[i];
|
|
608
612
|
|
|
609
|
-
// eslint-disable-next-line no-self-compare
|
|
610
613
|
bothNaN = oldItem !== oldItem && newItem !== newItem;
|
|
611
614
|
if (!bothNaN && oldItem !== newItem) {
|
|
612
615
|
changeDetected++;
|
|
@@ -629,7 +632,6 @@ export class Scope {
|
|
|
629
632
|
oldItem = oldValue[key];
|
|
630
633
|
|
|
631
634
|
if (key in oldValue) {
|
|
632
|
-
// eslint-disable-next-line no-self-compare
|
|
633
635
|
bothNaN = oldItem !== oldItem && newItem !== newItem;
|
|
634
636
|
if (!bothNaN && oldItem !== newItem) {
|
|
635
637
|
changeDetected++;
|
|
@@ -1238,13 +1240,19 @@ export class Scope {
|
|
|
1238
1240
|
} catch (e) {
|
|
1239
1241
|
$exceptionHandler(e);
|
|
1240
1242
|
} finally {
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1243
|
+
this.retry();
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
/**
|
|
1248
|
+
* @private
|
|
1249
|
+
*/
|
|
1250
|
+
retry() {
|
|
1251
|
+
try {
|
|
1252
|
+
this.$root.$digest();
|
|
1253
|
+
} catch (e) {
|
|
1254
|
+
$exceptionHandler(e);
|
|
1255
|
+
throw e;
|
|
1248
1256
|
}
|
|
1249
1257
|
}
|
|
1250
1258
|
|
|
@@ -1301,7 +1309,7 @@ export class Scope {
|
|
|
1301
1309
|
* - `defaultPrevented` - `{boolean}`: true if `preventDefault` was called.
|
|
1302
1310
|
*
|
|
1303
1311
|
* @param {string} name Event name to listen on.
|
|
1304
|
-
* @param {function(
|
|
1312
|
+
* @param {function(any): any} listener Function to call when the event is emitted witn angular.IAngularEvent
|
|
1305
1313
|
* @returns {function()} Returns a deregistration function for this listener.
|
|
1306
1314
|
*/
|
|
1307
1315
|
$on(name, listener) {
|
|
@@ -1311,6 +1319,7 @@ export class Scope {
|
|
|
1311
1319
|
}
|
|
1312
1320
|
namedListeners.push(listener);
|
|
1313
1321
|
|
|
1322
|
+
/** @type {Scope} */
|
|
1314
1323
|
let current = this;
|
|
1315
1324
|
do {
|
|
1316
1325
|
current.$$listenerCount[name] = (current.$$listenerCount[name] ?? 0) + 1;
|
|
@@ -1381,6 +1390,7 @@ export class Scope {
|
|
|
1381
1390
|
$emit(name, ...args) {
|
|
1382
1391
|
const empty = [];
|
|
1383
1392
|
let namedListeners;
|
|
1393
|
+
/** @type {Scope} */
|
|
1384
1394
|
let scope = this;
|
|
1385
1395
|
let stopPropagation = false;
|
|
1386
1396
|
const event = {
|
|
@@ -1421,7 +1431,7 @@ export class Scope {
|
|
|
1421
1431
|
break;
|
|
1422
1432
|
}
|
|
1423
1433
|
// traverse upwards
|
|
1424
|
-
scope = scope.$parent;
|
|
1434
|
+
scope = /** @type {Scope} */ scope.$parent;
|
|
1425
1435
|
} while (scope);
|
|
1426
1436
|
|
|
1427
1437
|
event.currentScope = null;
|
|
@@ -1452,8 +1462,10 @@ export class Scope {
|
|
|
1452
1462
|
*/
|
|
1453
1463
|
$broadcast(name, ...args) {
|
|
1454
1464
|
const target = this;
|
|
1465
|
+
/** @type {Scope} */
|
|
1455
1466
|
let current = target;
|
|
1456
1467
|
|
|
1468
|
+
/** @type {Scope} */
|
|
1457
1469
|
let next = target;
|
|
1458
1470
|
const event = {
|
|
1459
1471
|
name,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { forEach, isObject, isString } from "../../shared/utils";
|
|
2
2
|
|
|
3
3
|
function classDirective(name, selector) {
|
|
4
|
-
// eslint-disable-next-line no-param-reassign
|
|
5
4
|
name = `ngClass${name}`;
|
|
6
5
|
var indexWatchExpression;
|
|
7
6
|
|
|
@@ -24,7 +23,6 @@ function classDirective(name, selector) {
|
|
|
24
23
|
if (name !== "ngClass") {
|
|
25
24
|
if (!indexWatchExpression) {
|
|
26
25
|
indexWatchExpression = $parse("$index", function moduloTwo($index) {
|
|
27
|
-
// eslint-disable-next-line no-bitwise
|
|
28
26
|
return $index & 1;
|
|
29
27
|
});
|
|
30
28
|
}
|
|
@@ -244,7 +244,6 @@ FormController.prototype = {
|
|
|
244
244
|
forEach(
|
|
245
245
|
this.$pending,
|
|
246
246
|
function (value, name) {
|
|
247
|
-
// eslint-disable-next-line no-invalid-this
|
|
248
247
|
this.$setValidity(name, null, control);
|
|
249
248
|
},
|
|
250
249
|
this,
|
|
@@ -252,7 +251,6 @@ FormController.prototype = {
|
|
|
252
251
|
forEach(
|
|
253
252
|
this.$error,
|
|
254
253
|
function (value, name) {
|
|
255
|
-
// eslint-disable-next-line no-invalid-this
|
|
256
254
|
this.$setValidity(name, null, control);
|
|
257
255
|
},
|
|
258
256
|
this,
|
|
@@ -260,7 +258,6 @@ FormController.prototype = {
|
|
|
260
258
|
forEach(
|
|
261
259
|
this.$$success,
|
|
262
260
|
function (value, name) {
|
|
263
|
-
// eslint-disable-next-line no-invalid-this
|
|
264
261
|
this.$setValidity(name, null, control);
|
|
265
262
|
},
|
|
266
263
|
this,
|