@angular-wave/angular.ts 0.0.46 → 0.0.48

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.
Files changed (60) hide show
  1. package/dist/angular-ts.esm.js +2 -2
  2. package/dist/angular-ts.umd.js +2 -2
  3. package/package.json +1 -1
  4. package/src/angular.spec.js +1 -2
  5. package/src/animations/animate-css-driver.js +1 -1
  6. package/src/animations/animate-queue.js +3 -4
  7. package/src/animations/animation.js +1 -1
  8. package/src/animations/raf-scheduler.js +0 -1
  9. package/src/animations/shared.js +1 -1
  10. package/src/core/animate/animate.js +0 -1
  11. package/src/core/compile/compile.spec.js +1 -1
  12. package/src/core/filter/filter.js +2 -2
  13. package/src/core/location/location.js +1 -1
  14. package/src/core/location/location.spec.js +1 -1
  15. package/src/core/parser/ast-type.js +22 -0
  16. package/src/core/parser/ast.js +422 -0
  17. package/src/core/parser/compiler.js +561 -0
  18. package/src/core/parser/interpreter.js +422 -0
  19. package/src/core/parser/lexer.js +257 -0
  20. package/src/core/parser/parse.js +9 -1930
  21. package/src/core/parser/parse.spec.js +2 -2
  22. package/src/core/parser/parser.js +39 -0
  23. package/src/core/parser/shared.js +228 -0
  24. package/src/core/q/q.spec.js +0 -1
  25. package/src/core/sce/sce.js +3 -6
  26. package/src/core/scope/scope.js +19 -11
  27. package/src/core/task-tracker-factory.js +0 -1
  28. package/src/directive/attrs/attrs.js +4 -185
  29. package/src/directive/attrs/attrs.md +224 -0
  30. package/src/directive/class/class.js +0 -2
  31. package/src/directive/form/form.js +0 -3
  32. package/src/directive/include/include.js +1 -1
  33. package/src/directive/include/include.spec.js +0 -1
  34. package/src/directive/input/input.js +1 -2
  35. package/src/directive/model/model.js +1 -3
  36. package/src/directive/model/model.spec.js +0 -1
  37. package/src/directive/repeat/repeat.spec.js +0 -2
  38. package/src/exts/aria/aria.js +0 -1
  39. package/src/filters/filter.spec.js +0 -1
  40. package/src/injector.js +1 -1
  41. package/src/injector.spec.js +0 -5
  42. package/src/loader.js +0 -5
  43. package/src/services/cookie-reader.js +0 -1
  44. package/src/services/http/http.spec.js +0 -2
  45. package/src/shared/jqlite/jqlite.js +219 -140
  46. package/src/shared/utils.js +18 -7
  47. package/src/types.js +10 -0
  48. package/types/core/parser/ast-type.d.ts +20 -0
  49. package/types/core/parser/ast.d.ts +78 -0
  50. package/types/core/parser/compiler.d.ts +49 -0
  51. package/types/core/parser/interpreter.d.ts +57 -0
  52. package/types/core/parser/parse.d.ts +79 -0
  53. package/types/core/parser/parser.d.ts +22 -0
  54. package/types/core/parser/shared.d.ts +29 -0
  55. package/types/core/scope/scope.d.ts +9 -2
  56. package/types/directive/attrs/attrs.d.ts +0 -174
  57. package/types/shared/jqlite/jqlite.d.ts +33 -4
  58. package/types/shared/utils.d.ts +18 -5
  59. package/types/types.d.ts +1 -0
  60. package/types-back/index.d.ts +0 -12
@@ -1,4 +1,5 @@
1
- import { AST, Lexer } from "./parse";
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,39 @@
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
+ constructor(lexer, $filter, options) {
11
+ this.ast = new AST(lexer, options);
12
+ this.astCompiler = options.csp
13
+ ? new ASTInterpreter($filter)
14
+ : new ASTCompiler($filter);
15
+ }
16
+
17
+ parse(text) {
18
+ const { ast, oneTime } = this.getAst(text);
19
+ const fn = this.astCompiler.compile(ast);
20
+ fn.literal = isLiteral(ast);
21
+ fn.constant = isConstant(ast);
22
+ fn.oneTime = oneTime;
23
+ return fn;
24
+ }
25
+
26
+ getAst(exp) {
27
+ let oneTime = false;
28
+ exp = exp.trim();
29
+
30
+ if (exp.startsWith("::")) {
31
+ oneTime = true;
32
+ exp = exp.substring(2);
33
+ }
34
+ return {
35
+ ast: this.ast.ast(exp),
36
+ oneTime,
37
+ };
38
+ }
39
+ }
@@ -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
+ }
@@ -811,7 +811,6 @@ describe("all", function () {
811
811
  });
812
812
 
813
813
  it("should support the instanceof operator", () => {
814
- // eslint-disable-next-line new-cap
815
814
  let promise = $q(() => {});
816
815
  expect(promise instanceof $q).toBe(true);
817
816
  promise = new $q(() => {});
@@ -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
- s
51
- .replace(/([-()[\]{}+?*.$^|,:#<!\\])/g, "\\$1")
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) {
@@ -45,6 +45,10 @@ 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;
@@ -84,9 +88,9 @@ export class $RootScopeProvider {
84
88
  "$parse",
85
89
  "$browser",
86
90
  /**
91
+ * @param {import('../exception-handler').ErrorHandler} exceptionHandler
87
92
  * @param {angular.IParseService} parse
88
- * @param {import('../services/browser').Browser} browser
89
- * @param {angular.IExceptionHandlerService} exceptionHandler
93
+ * @param {import('../../services/browser').Browser} browser
90
94
  * @returns {Scope} root scope
91
95
  */
92
96
  function (exceptionHandler, parse, browser) {
@@ -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
- try {
1242
- this.$root.$digest();
1243
- } catch (e) {
1244
- $exceptionHandler(e);
1245
- // eslint-disable-next-line no-unsafe-finally
1246
- throw e;
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
 
@@ -1,5 +1,4 @@
1
1
  export function $$TaskTrackerFactoryProvider() {
2
- // eslint-disable-next-line no-use-before-define
3
2
  this.$get = [
4
3
  "$log",
5
4
  /** @param {import('../services/log').LogService} log */
@@ -1,194 +1,13 @@
1
1
  import { BOOLEAN_ATTR } from "../../shared/jqlite/jqlite";
2
- import { forEach, directiveNormalize } from "../../shared/utils";
2
+ import { directiveNormalize } from "../../shared/utils";
3
3
  import { ALIASED_ATTR } from "../../shared/constants";
4
4
 
5
- /**
6
- * @ngdoc directive
7
- * @name ngHref
8
- * @restrict A
9
- * @priority 99
10
- *
11
- * @description
12
- * Using AngularJS markup like `{{hash}}` in an href attribute will
13
- * make the link go to the wrong URL if the user clicks it before
14
- * AngularJS has a chance to replace the `{{hash}}` markup with its
15
- * value. Until AngularJS replaces the markup the link will be broken
16
- * and will most likely return a 404 error. The `ngHref` directive
17
- * solves this problem.
18
- *
19
- * The wrong way to write it:
20
- * ```html
21
- * <a href="http://www.gravatar.com/avatar/{{hash}}">link1</a>
22
- * ```
23
- *
24
- * The correct way to write it:
25
- * ```html
26
- * <a ng-href="http://www.gravatar.com/avatar/{{hash}}">link1</a>
27
- * ```
28
- *
29
- * @element A
30
- * @param {template} ngHref any string which can contain `{{}}` markup.
31
- *
32
- */
33
-
34
5
  export const REGEX_STRING_REGEXP = /^\/(.+)\/([a-z]*)$/;
35
- /**
36
- * @ngdoc directive
37
- * @name ngSrc
38
- * @restrict A
39
- * @priority 99
40
- *
41
- * @description
42
- * Using AngularJS markup like `{{hash}}` in a `src` attribute doesn't
43
- * work right: The browser will fetch from the URL with the literal
44
- * text `{{hash}}` until AngularJS replaces the expression inside
45
- * `{{hash}}`. The `ngSrc` directive solves this problem.
46
- *
47
- * The buggy way to write it:
48
- * ```html
49
- * <img src="http://www.gravatar.com/avatar/{{hash}}" alt="Description"/>
50
- * ```
51
- *
52
- * The correct way to write it:
53
- * ```html
54
- * <img ng-src="http://www.gravatar.com/avatar/{{hash}}" alt="Description" />
55
- * ```
56
- *
57
- * @element IMG
58
- * @param {template} ngSrc any string which can contain `{{}}` markup.
59
- */
60
-
61
- /**
62
- * @ngdoc directive
63
- * @name ngSrcset
64
- * @restrict A
65
- * @priority 99
66
- *
67
- * @description
68
- * Using AngularJS markup like `{{hash}}` in a `srcset` attribute doesn't
69
- * work right: The browser will fetch from the URL with the literal
70
- * text `{{hash}}` until AngularJS replaces the expression inside
71
- * `{{hash}}`. The `ngSrcset` directive solves this problem.
72
- *
73
- * The buggy way to write it:
74
- * ```html
75
- * <img srcset="http://www.gravatar.com/avatar/{{hash}} 2x" alt="Description"/>
76
- * ```
77
- *
78
- * The correct way to write it:
79
- * ```html
80
- * <img ng-srcset="http://www.gravatar.com/avatar/{{hash}} 2x" alt="Description" />
81
- * ```
82
- *
83
- * @element IMG
84
- * @param {template} ngSrcset any string which can contain `{{}}` markup.
85
- */
86
-
87
- /**
88
- * @ngdoc directive
89
- * @name ngDisabled
90
- * @restrict A
91
- * @priority 100
92
- *
93
- * @description
94
- *
95
- * This directive sets the `disabled` attribute on the element (typically a form control,
96
- * e.g. `input`, `button`, `select` etc.) if the
97
- * {@link guide/expression expression} inside `ngDisabled` evaluates to truthy.
98
- *
99
- * A special directive is necessary because we cannot use interpolation inside the `disabled`
100
- * attribute. See the {@link guide/interpolation interpolation guide} for more info.
101
- *
102
- * @param {string} ngDisabled If the {@link guide/expression expression} is truthy,
103
- * then the `disabled` attribute will be set on the element
104
- */
105
-
106
- /**
107
- * @ngdoc directive
108
- * @name ngChecked
109
- * @restrict A
110
- * @priority 100
111
- *
112
- * @description
113
- * Sets the `checked` attribute on the element, if the expression inside `ngChecked` is truthy.
114
- *
115
- * Note that this directive should not be used together with {@link ngModel `ngModel`},
116
- * as this can lead to unexpected behavior.
117
- *
118
- * A special directive is necessary because we cannot use interpolation inside the `checked`
119
- * attribute. See the {@link guide/interpolation interpolation guide} for more info.
120
- *
121
- * @element INPUT
122
- * @param {string} ngChecked If the {@link guide/expression expression} is truthy,
123
- * then the `checked` attribute will be set on the element
124
- */
125
-
126
- /**
127
- *
128
- * @description
129
- *
130
- * Sets the `readonly` attribute on the element, if the expression inside `ngReadonly` is truthy.
131
- * Note that `readonly` applies only to `input` elements with specific types. [See the input docs on
132
- * MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-readonly) for more information.
133
- *
134
- * A special directive is necessary because we cannot use interpolation inside the `readonly`
135
- * attribute. See the {@link guide/interpolation interpolation guide} for more info.
136
- * @element INPUT
137
- * @param {string} ngReadonly If the {@link guide/expression expression} is truthy,
138
- * then special attribute "readonly" will be set on the element
139
- */
140
-
141
- /**
142
- * @ngdoc directive
143
- * @name ngSelected
144
- * @restrict A
145
- * @priority 100
146
- *
147
- * @description
148
- *
149
- * Sets the `selected` attribute on the element, if the expression inside `ngSelected` is truthy.
150
- *
151
- * A special directive is necessary because we cannot use interpolation inside the `selected`
152
- * attribute. See the {@link guide/interpolation interpolation guide} for more info.
153
- *
154
- * <div class="alert alert-warning">
155
- * **Note:** `ngSelected` does not interact with the `select` and `ngModel` directives, it only
156
- * sets the `selected` attribute on the element. If you are using `ngModel` on the select, you
157
- * should not use `ngSelected` on the options, as `ngModel` will set the select value and
158
- * selected options.
159
- * </div>
160
- * @element OPTION
161
- * @param {string} ngSelected If the {@link guide/expression expression} is truthy,
162
- * then special attribute "selected" will be set on the element
163
- */
164
-
165
- /**
166
- * @ngdoc directive
167
- * @name ngOpen
168
- * @restrict A
169
- * @priority 100
170
- *
171
- * @description
172
- *
173
- * Sets the `open` attribute on the element, if the expression inside `ngOpen` is truthy.
174
- *
175
- * A special directive is necessary because we cannot use interpolation inside the `open`
176
- * attribute. See the {@link guide/interpolation interpolation guide} for more info.
177
- *
178
- * ## A note about browser compatibility
179
- *
180
- * Internet Explorer and Edge do not support the `details` element, it is
181
- * recommended to use {@link ng.ngShow} and {@link ng.ngHide} instead.
182
- *
183
- * @element DETAILS
184
- * @param {string} ngOpen If the {@link guide/expression expression} is truthy,
185
- * then special attribute "open" will be set on the element
186
- */
187
6
 
188
7
  export const ngAttributeAliasDirectives = {};
189
8
 
190
9
  // boolean attrs are evaluated
191
- forEach(BOOLEAN_ATTR, (propName, attrName) => {
10
+ Object.entries(BOOLEAN_ATTR).forEach(([attrName, propName]) => {
192
11
  // binding to multiple is not supported
193
12
  if (propName === "multiple") return;
194
13
 
@@ -220,7 +39,7 @@ forEach(BOOLEAN_ATTR, (propName, attrName) => {
220
39
  });
221
40
 
222
41
  // aliased input attrs are evaluated
223
- forEach(ALIASED_ATTR, (htmlAttr, ngAttr) => {
42
+ Object.entries(ALIASED_ATTR).forEach(([ngAttr]) => {
224
43
  ngAttributeAliasDirectives[ngAttr] = function () {
225
44
  return {
226
45
  priority: 100,
@@ -244,7 +63,7 @@ forEach(ALIASED_ATTR, (htmlAttr, ngAttr) => {
244
63
  });
245
64
 
246
65
  // ng-src, ng-srcset, ng-href are interpolated
247
- forEach(["src", "srcset", "href"], (attrName) => {
66
+ ["src", "srcset", "href"].forEach((attrName) => {
248
67
  const normalized = directiveNormalize(`ng-${attrName}`);
249
68
  ngAttributeAliasDirectives[normalized] = [
250
69
  "$sce",