@angular-wave/angular.ts 0.4.2 → 0.4.4

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 (150) hide show
  1. package/dist/angular-ts.esm.js +2 -2
  2. package/dist/angular-ts.umd.js +12 -2
  3. package/index.html +74 -3
  4. package/package.json +7 -7
  5. package/src/angular.spec.js +1 -269
  6. package/src/animations/animate-css-driver.js +2 -2
  7. package/src/animations/animate-css.js +12 -21
  8. package/src/animations/animate-js-driver.js +1 -3
  9. package/src/animations/animate-js.js +4 -4
  10. package/src/animations/animate-queue.js +23 -23
  11. package/src/animations/animate-runner.js +4 -8
  12. package/src/animations/animate.md +1 -1
  13. package/src/animations/animate.spec.js +0 -21
  14. package/src/animations/animation.js +4 -4
  15. package/src/animations/shared.js +14 -12
  16. package/src/binding.spec.js +0 -1
  17. package/src/core/cache/cache.js +2 -29
  18. package/src/core/compile/attributes.js +2 -3
  19. package/src/core/compile/compile.js +260 -245
  20. package/src/core/compile/compile.spec.js +63 -317
  21. package/src/core/compile/compile.test.js +1 -1
  22. package/src/core/controller/controller.js +2 -0
  23. package/src/core/di/injector.md +1 -1
  24. package/src/core/di/injector.spec.js +0 -2
  25. package/src/core/di/internal-injector.js +2 -1
  26. package/src/core/interpolate/interpolate.js +16 -3
  27. package/src/core/interpolate/interpolate.spec.js +70 -16
  28. package/src/core/location/location.js +0 -2
  29. package/src/core/location/location.spec.js +27 -27
  30. package/src/core/{scope/scope.html → model/model.html} +1 -1
  31. package/src/core/model/model.js +944 -0
  32. package/src/core/model/model.spec.js +3012 -0
  33. package/src/core/on.spec.js +0 -7
  34. package/src/core/parse/interpreter.js +10 -7
  35. package/src/core/parse/parse.js +28 -7
  36. package/src/core/parse/parse.spec.js +95 -91
  37. package/src/core/prop.spec.js +4 -60
  38. package/src/core/sce/sce.js +1 -2
  39. package/src/core/sce/sce.spec.js +0 -8
  40. package/src/core/scope/scope.js +62 -32
  41. package/src/core/scope/scope.spec.js +25 -1960
  42. package/src/directive/aria/aria.js +3 -6
  43. package/src/directive/aria/aria.spec.js +0 -87
  44. package/src/directive/attrs/attrs.spec.js +0 -5
  45. package/src/directive/{list/list.test.js → attrs/attrs.test.js} +1 -1
  46. package/src/{core/q/q.html → directive/attrs/boolean.html} +1 -1
  47. package/src/directive/attrs/boolean.spec.js +0 -15
  48. package/src/{core/q/q.test.js → directive/attrs/boolean.test.js} +1 -2
  49. package/src/{core/timeout/timeout.html → directive/attrs/element-style.html} +4 -1
  50. package/src/directive/attrs/element-style.spec.js +0 -8
  51. package/src/{core/scope/scope.test.js → directive/attrs/element-style.test.js} +1 -2
  52. package/src/directive/attrs/src.spec.js +0 -7
  53. package/src/directive/bind/bind.spec.js +0 -33
  54. package/src/directive/bind/bing-html.spec.js +1 -4
  55. package/src/{core/interval/interval.html → directive/channel/channel.html} +1 -1
  56. package/src/directive/channel/channel.js +29 -0
  57. package/src/directive/channel/channel.spec.js +52 -0
  58. package/src/directive/channel/channel.test.js +9 -0
  59. package/src/directive/class/class.js +3 -3
  60. package/src/directive/class/class.spec.js +9 -75
  61. package/src/directive/controller/controller.spec.js +0 -13
  62. package/src/directive/events/click.spec.js +0 -3
  63. package/src/directive/events/event.spec.js +0 -6
  64. package/src/directive/form/form.js +14 -22
  65. package/src/directive/form/form.spec.js +0 -65
  66. package/src/directive/if/if.spec.js +2 -7
  67. package/src/directive/if/if.test.js +1 -2
  68. package/src/directive/include/include.js +2 -2
  69. package/src/directive/include/include.spec.js +8 -59
  70. package/src/directive/init/init.js +6 -2
  71. package/src/directive/init/init.spec.js +0 -2
  72. package/src/directive/input/input.js +1 -2
  73. package/src/directive/input/input.spec.js +191 -331
  74. package/src/directive/messages/messages.spec.js +4 -35
  75. package/src/directive/model/model.js +30 -42
  76. package/src/directive/model/model.spec.js +2 -49
  77. package/src/directive/model-options/model-options.js +22 -26
  78. package/src/directive/model-options/model-options.spec.js +0 -6
  79. package/src/directive/non-bindable/non-bindable.spec.js +0 -1
  80. package/src/directive/observe/observe.js +0 -1
  81. package/src/directive/observe/observe.spec.js +0 -1
  82. package/src/directive/options/options.js +1 -3
  83. package/src/directive/options/options.spec.js +3 -38
  84. package/src/directive/ref/href.spec.js +0 -15
  85. package/src/directive/repeat/repeat.js +2 -2
  86. package/src/directive/repeat/repeat.spec.js +56 -192
  87. package/src/directive/script/script.spec.js +0 -2
  88. package/src/directive/select/select.js +3 -3
  89. package/src/directive/select/select.spec.js +9 -106
  90. package/src/directive/show-hide/show-hide.js +2 -2
  91. package/src/directive/show-hide/show-hide.spec.js +8 -19
  92. package/src/directive/style/style.spec.js +0 -7
  93. package/src/directive/switch/switch.js +1 -2
  94. package/src/directive/switch/switch.spec.js +5 -5
  95. package/src/directive/validators/validators.spec.js +0 -1
  96. package/src/loader.js +0 -1
  97. package/src/public.js +75 -80
  98. package/src/router/common/coreservices.js +0 -2
  99. package/src/router/directives/state-directives.js +24 -30
  100. package/src/router/directives/state-directives.spec.js +0 -83
  101. package/src/router/directives/view-directive.js +6 -15
  102. package/src/router/directives/view-directive.spec.js +25 -71
  103. package/src/router/hooks/lazy-load.js +2 -2
  104. package/src/router/hooks/views.js +3 -5
  105. package/src/router/resolve/resolvable.js +3 -6
  106. package/src/router/resolve/resolve-context.js +2 -2
  107. package/src/router/state/state-service.js +4 -4
  108. package/src/router/state/state.spec.js +2 -5
  109. package/src/router/state/views.js +9 -12
  110. package/src/router/template-factory.js +3 -6
  111. package/src/router/template-factory.spec.js +0 -4
  112. package/src/router/transition/transition-hook.js +1 -1
  113. package/src/router/transition/transition.js +1 -1
  114. package/src/router/url/url-service.js +2 -8
  115. package/src/router/url/url-service.spec.js +3 -4
  116. package/src/router/view-hook.spec.js +2 -2
  117. package/src/router/view-scroll.js +4 -6
  118. package/src/services/http/http.js +11 -15
  119. package/src/services/http/http.spec.js +30 -31
  120. package/src/services/http/template-request.spec.js +0 -10
  121. package/src/services/http-backend/http-backend.js +19 -17
  122. package/src/services/http-backend/http-backend.spec.js +3 -3
  123. package/src/services/template-request.js +2 -4
  124. package/src/shared/common.js +6 -10
  125. package/src/shared/jqlite/jqlite.js +14 -15
  126. package/src/shared/jqlite/jqlite.spec.js +2 -2
  127. package/src/shared/utils.js +15 -92
  128. package/types/core/cache/cache.d.ts +1 -1
  129. package/types/core/model/model.d.ts +204 -0
  130. package/types/core/parse/parse.d.ts +26 -0
  131. package/types/core/scope/scope.d.ts +22 -21
  132. package/types/directive/channel/channel.d.ts +11 -0
  133. package/types/directive/form/form.d.ts +1 -0
  134. package/types/shared/common.d.ts +0 -1
  135. package/types/shared/utils.d.ts +0 -35
  136. package/src/core/interval/interval-factory.js +0 -50
  137. package/src/core/interval/interval.js +0 -77
  138. package/src/core/interval/interval.md +0 -123
  139. package/src/core/interval/interval.spec.js +0 -280
  140. package/src/core/q/q.js +0 -472
  141. package/src/core/q/q.md +0 -211
  142. package/src/core/q/q.spec.js +0 -2748
  143. package/src/core/timeout/timeout.js +0 -109
  144. package/src/core/timeout/timeout.spec.js +0 -354
  145. package/src/core/timeout/timout.test.js +0 -12
  146. package/src/directive/list/list.html +0 -18
  147. package/src/directive/list/list.js +0 -46
  148. package/src/directive/list/list.md +0 -22
  149. package/src/directive/list/list.spec.js +0 -172
  150. package/types/directive/list/list.d.ts +0 -4
@@ -12,7 +12,6 @@ import {
12
12
  minErr,
13
13
  assertArg,
14
14
  assertNotHasOwnProperty,
15
- forEach,
16
15
  isDefined,
17
16
  isFunction,
18
17
  isObject,
@@ -74,7 +73,7 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
74
73
 
75
74
  const bindings = Object.create(null);
76
75
 
77
- forEach(scope, (definition, scopeName) => {
76
+ Object.entries(scope).forEach(([scopeName, definition]) => {
78
77
  definition = definition.trim();
79
78
 
80
79
  if (definition in bindingCache) {
@@ -337,7 +336,7 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
337
336
 
338
337
  // Copy any annotation properties (starting with $) over to the factory and controller constructor functions
339
338
  // These could be used by libraries such as the new component router
340
- forEach(options, (val, key) => {
339
+ Object.entries(options).forEach(([key, val]) => {
341
340
  if (key.charAt(0) === "$") {
342
341
  factory[key] = val;
343
342
  // Don't try to copy over annotations to named controller
@@ -550,7 +549,7 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
550
549
  // When changes occur, the call to trigger their hooks will be added to this queue
551
550
  let onChangesQueue;
552
551
 
553
- // This function is called in a $$postDigest to trigger all the onChanges hooks in a single digest
552
+ // This function is called in a $postUpdate to trigger all the onChanges hooks in a single digest
554
553
  function flushOnChangesQueue() {
555
554
  try {
556
555
  if (!--ttl) {
@@ -562,7 +561,7 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
562
561
  ttl,
563
562
  );
564
563
  }
565
- // We must run this hook in an apply since the $$postDigest runs outside apply
564
+ // We must run this hook in an apply since the $postUpdate runs outside apply
566
565
  $rootScope.$apply(() => {
567
566
  for (let i = 0, ii = onChangesQueue.length; i < ii; ++i) {
568
567
  try {
@@ -907,7 +906,7 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
907
906
  containingScope,
908
907
  ) {
909
908
  if (!transcludedScope) {
910
- transcludedScope = scope.$new(false, containingScope);
909
+ transcludedScope = scope.$transcluded(containingScope);
911
910
  transcludedScope.$$transcluded = true;
912
911
  }
913
912
 
@@ -1337,7 +1336,7 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
1337
1336
  const controller = elementControllers[name];
1338
1337
  const bindings = controllerDirective.$$bindings.bindToController;
1339
1338
 
1340
- controller.instance = controller();
1339
+ controller.instance = controllerScope.$new(controller());
1341
1340
  $element.data(
1342
1341
  `$${controllerDirective.name}Controller`,
1343
1342
  controller.instance,
@@ -1352,51 +1351,57 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
1352
1351
  }
1353
1352
 
1354
1353
  // Bind the required controllers to the controller, if `require` is an object and `bindToController` is truthy
1355
- forEach(controllerDirectives, (controllerDirective, name) => {
1356
- const { require } = controllerDirective;
1357
- if (
1358
- controllerDirective.bindToController &&
1359
- !Array.isArray(require) &&
1360
- isObject(require)
1361
- ) {
1362
- extend(
1363
- elementControllers[name].instance,
1364
- getControllers(name, require, $element, elementControllers),
1365
- );
1366
- }
1367
- });
1354
+ if (controllerDirectives) {
1355
+ Object.entries(controllerDirectives).forEach(
1356
+ ([name, controllerDirective]) => {
1357
+ const { require } = controllerDirective;
1358
+ if (
1359
+ controllerDirective.bindToController &&
1360
+ !Array.isArray(require) &&
1361
+ isObject(require)
1362
+ ) {
1363
+ extend(
1364
+ elementControllers[name].instance,
1365
+ getControllers(name, require, $element, elementControllers),
1366
+ );
1367
+ }
1368
+ },
1369
+ );
1370
+ }
1368
1371
 
1369
1372
  // Handle the init and destroy lifecycle hooks on all controllers that have them
1370
- forEach(elementControllers, (controller) => {
1371
- const controllerInstance = controller.instance;
1372
- if (isFunction(controllerInstance.$onChanges)) {
1373
- try {
1374
- controllerInstance.$onChanges(
1375
- controller.bindingInfo.initialChanges,
1376
- );
1377
- } catch (e) {
1378
- $exceptionHandler(e);
1373
+ if (elementControllers) {
1374
+ Object.values(elementControllers).forEach((controller) => {
1375
+ const controllerInstance = controller.instance;
1376
+ if (isFunction(controllerInstance.$onChanges)) {
1377
+ try {
1378
+ controllerInstance.$onChanges(
1379
+ controller.bindingInfo.initialChanges,
1380
+ );
1381
+ } catch (e) {
1382
+ $exceptionHandler(e);
1383
+ }
1379
1384
  }
1380
- }
1381
- if (isFunction(controllerInstance.$onInit)) {
1382
- try {
1383
- controllerInstance.$onInit();
1384
- } catch (e) {
1385
- $exceptionHandler(e);
1385
+ if (isFunction(controllerInstance.$onInit)) {
1386
+ try {
1387
+ controllerInstance.$onInit();
1388
+ } catch (e) {
1389
+ $exceptionHandler(e);
1390
+ }
1386
1391
  }
1387
- }
1388
- if (isFunction(controllerInstance.$doCheck)) {
1389
- controllerScope.$watch(() => {
1392
+ if (isFunction(controllerInstance.$doCheck)) {
1393
+ controllerScope.$watch(() => {
1394
+ controllerInstance.$doCheck();
1395
+ });
1390
1396
  controllerInstance.$doCheck();
1391
- });
1392
- controllerInstance.$doCheck();
1393
- }
1394
- if (isFunction(controllerInstance.$onDestroy)) {
1395
- controllerScope.$on("$destroy", () => {
1396
- controllerInstance.$onDestroy();
1397
- });
1398
- }
1399
- });
1397
+ }
1398
+ if (isFunction(controllerInstance.$onDestroy)) {
1399
+ controllerScope.$on("$destroy", () => {
1400
+ controllerInstance.$onDestroy();
1401
+ });
1402
+ }
1403
+ });
1404
+ }
1400
1405
 
1401
1406
  // PRELINKING
1402
1407
  for (i = 0, ii = preLinkFns.length; i < ii; i++) {
@@ -1456,13 +1461,15 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
1456
1461
  );
1457
1462
  }
1458
1463
 
1459
- // Trigger $postLink lifecycle hooks
1460
- forEach(elementControllers, (controller) => {
1461
- const controllerInstance = controller.instance;
1462
- if (isFunction(controllerInstance.$postLink)) {
1463
- controllerInstance.$postLink();
1464
- }
1465
- });
1464
+ if (elementControllers) {
1465
+ // Trigger $postLink lifecycle hooks
1466
+ Object.values(elementControllers).forEach((controller) => {
1467
+ const controllerInstance = controller.instance;
1468
+ if (isFunction(controllerInstance.$postLink)) {
1469
+ controllerInstance.$postLink();
1470
+ }
1471
+ });
1472
+ }
1466
1473
 
1467
1474
  // This is the function that is injected as `$transclude`.
1468
1475
  // Note: all arguments are optional!
@@ -1683,42 +1690,45 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
1683
1690
  const filledSlots = Object.create(null);
1684
1691
 
1685
1692
  // Parse the element selectors
1686
- forEach(directiveValue, (elementSelector, slotName) => {
1687
- // If an element selector starts with a ? then it is optional
1688
- const optional = elementSelector.charAt(0) === "?";
1689
- elementSelector = optional
1690
- ? elementSelector.substring(1)
1691
- : elementSelector;
1692
-
1693
- slotMap[elementSelector] = slotName;
1694
-
1695
- // We explicitly assign `null` since this implies that a slot was defined but not filled.
1696
- // Later when calling boundTransclusion functions with a slot name we only error if the
1697
- // slot is `undefined`
1698
- slots[slotName] = null;
1699
-
1700
- // filledSlots contains `true` for all slots that are either optional or have been
1701
- // filled. This is used to check that we have not missed any required slots
1702
- filledSlots[slotName] = optional;
1703
- });
1693
+ Object.entries(directiveValue).forEach(
1694
+ ([slotName, elementSelector]) => {
1695
+ // If an element selector starts with a ? then it is optional
1696
+ const optional = elementSelector.charAt(0) === "?";
1697
+ elementSelector = optional
1698
+ ? elementSelector.substring(1)
1699
+ : elementSelector;
1700
+
1701
+ slotMap[elementSelector] = slotName;
1702
+
1703
+ // We explicitly assign `null` since this implies that a slot was defined but not filled.
1704
+ // Later when calling boundTransclusion functions with a slot name we only error if the
1705
+ // slot is `undefined`
1706
+ slots[slotName] = null;
1707
+
1708
+ // filledSlots contains `true` for all slots that are either optional or have been
1709
+ // filled. This is used to check that we have not missed any required slots
1710
+ filledSlots[slotName] = optional;
1711
+ },
1712
+ );
1704
1713
 
1705
1714
  // Add the matching elements into their slot
1706
-
1707
- forEach(JQLite($compileNode[0].childNodes), (node) => {
1708
- const slotName =
1709
- slotMap[directiveNormalize(getNodeName(node))];
1710
- if (slotName) {
1711
- filledSlots[slotName] = true;
1712
- slots[slotName] =
1713
- slots[slotName] || document.createDocumentFragment();
1714
- slots[slotName].appendChild(node);
1715
- } else {
1716
- $template.appendChild(node);
1717
- }
1718
- });
1715
+ JQLite($compileNode[0].childNodes)
1716
+ .elements()
1717
+ .forEach((node) => {
1718
+ const slotName =
1719
+ slotMap[directiveNormalize(getNodeName(node))];
1720
+ if (slotName) {
1721
+ filledSlots[slotName] = true;
1722
+ slots[slotName] =
1723
+ slots[slotName] || document.createDocumentFragment();
1724
+ slots[slotName].appendChild(node);
1725
+ } else {
1726
+ $template.appendChild(node);
1727
+ }
1728
+ });
1719
1729
 
1720
1730
  // Check for required slots that were not filled
1721
- forEach(filledSlots, (filled, slotName) => {
1731
+ Object.entries(filledSlots).forEach(([slotName, filled]) => {
1722
1732
  if (!filled) {
1723
1733
  throw $compileMinErr(
1724
1734
  "reqslot",
@@ -2009,7 +2019,7 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
2009
2019
  }
2010
2020
  } else if (isObject(require)) {
2011
2021
  value = {};
2012
- forEach(require, (controller, property) => {
2022
+ Object.entries(require).forEach(([property, controller]) => {
2013
2023
  value[property] = getControllers(
2014
2024
  directiveName,
2015
2025
  controller,
@@ -2184,7 +2194,7 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
2184
2194
  const dstAttr = dst.$attr;
2185
2195
 
2186
2196
  // reapply the old attributes to the new element
2187
- forEach(dst, (value, key) => {
2197
+ Object.entries(dst).forEach(([key, value]) => {
2188
2198
  if (key.charAt(0) !== "$") {
2189
2199
  if (src[key] && src[key] !== value) {
2190
2200
  if (value.length) {
@@ -2198,7 +2208,7 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
2198
2208
  });
2199
2209
 
2200
2210
  // copy the new attributes on the old attrs object
2201
- forEach(src, (value, key) => {
2211
+ Object.entries(src).forEach(([key, value]) => {
2202
2212
  // Check if we already set this attribute in the loop above.
2203
2213
  // `dst` will never contain hasOwnProperty as DOM parser won't let it.
2204
2214
  // You will get an "InvalidCharacterError: DOM Exception 5" error if you
@@ -2309,11 +2319,13 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
2309
2319
  postLinkFns,
2310
2320
  previousCompileContext,
2311
2321
  );
2312
- forEach($rootElement, (node, i) => {
2313
- if (node === compileNode) {
2314
- $rootElement[i] = $compileNode[0];
2315
- }
2316
- });
2322
+ if ($rootElement) {
2323
+ Object.entries($rootElement).forEach(([i, node]) => {
2324
+ if (node === compileNode) {
2325
+ $rootElement[i] = $compileNode[0];
2326
+ }
2327
+ });
2328
+ }
2317
2329
  afterTemplateChildLinkFn = compileNodes(
2318
2330
  $compileNode[0].childNodes,
2319
2331
  childTranscludeFn,
@@ -2445,15 +2457,12 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
2445
2457
  if (interpolateFn) {
2446
2458
  directives.push({
2447
2459
  priority: 0,
2448
- compile: function textInterpolateCompileFn() {
2449
- // When transcluding a template that has bindings in the root
2450
- // we don't have a parent and thus need to add the class during linking fn.
2460
+ compile: () => (scope, node, arg1, arg3) => {
2461
+ let current = JQLite(node).controller();
2451
2462
 
2452
- return function textInterpolateLinkFn(scope, node) {
2453
- scope.$watch(interpolateFn, (value) => {
2454
- node[0].nodeValue = value;
2455
- });
2456
- };
2463
+ node[0].nodeValue = interpolateFn(current || scope, (val) => {
2464
+ node[0].nodeValue = val;
2465
+ });
2457
2466
  },
2458
2467
  });
2459
2468
  }
@@ -2856,161 +2865,167 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
2856
2865
  const initialChanges = {};
2857
2866
  let changes;
2858
2867
 
2859
- forEach(bindings, (definition, scopeName) => {
2860
- const { attrName } = definition;
2861
- const { optional } = definition;
2862
- const { mode } = definition; // @, =, <, or &
2863
- let lastValue;
2864
- let parentGet;
2865
- let parentSet;
2866
- let compare;
2867
- let removeWatch;
2868
-
2869
- switch (mode) {
2870
- case "@":
2871
- if (!optional && !Object.hasOwnProperty.call(attrs, attrName)) {
2872
- strictBindingsCheck(attrName, directive.name);
2873
- destination[scopeName] = attrs[attrName] = undefined;
2874
- }
2875
- removeWatch = attrs.$observe(attrName, (value) => {
2876
- if (isString(value) || isBoolean(value)) {
2877
- const oldValue = destination[scopeName];
2878
- recordChanges(scopeName, value, oldValue);
2879
- destination[scopeName] = value;
2868
+ if (bindings) {
2869
+ Object.entries(bindings).forEach(([scopeName, definition]) => {
2870
+ const { attrName } = definition;
2871
+ const { optional } = definition;
2872
+ const { mode } = definition; // @, =, <, or &
2873
+ let lastValue;
2874
+ let parentGet;
2875
+ let parentSet;
2876
+ let compare;
2877
+ let removeWatch;
2878
+
2879
+ switch (mode) {
2880
+ case "@":
2881
+ if (!optional && !Object.hasOwnProperty.call(attrs, attrName)) {
2882
+ strictBindingsCheck(attrName, directive.name);
2883
+ destination[scopeName] = attrs[attrName] = undefined;
2880
2884
  }
2881
- });
2882
- attrs.$$observers[attrName].$$scope = scope;
2883
- lastValue = attrs[attrName];
2884
- if (isString(lastValue)) {
2885
- // If the attribute has been provided then we trigger an interpolation to ensure
2886
- // the value is there for use in the link fn
2887
- destination[scopeName] = $interpolate(lastValue)(scope);
2888
- } else if (isBoolean(lastValue)) {
2889
- // If the attributes is one of the BOOLEAN_ATTR then AngularJS will have converted
2890
- // the value to boolean rather than a string, so we special case this situation
2891
- destination[scopeName] = lastValue;
2892
- }
2893
- initialChanges[scopeName] = new SimpleChange(
2894
- UNINITALIZED_VALIED,
2895
- destination[scopeName],
2896
- );
2897
- removeWatchCollection.push(removeWatch);
2898
- break;
2899
-
2900
- case "=":
2901
- if (!Object.hasOwnProperty.call(attrs, attrName)) {
2902
- if (optional) break;
2903
- strictBindingsCheck(attrName, directive.name);
2904
- attrs[attrName] = undefined;
2905
- }
2906
- if (optional && !attrs[attrName]) break;
2907
-
2908
- parentGet = $parse(attrs[attrName]);
2909
- if (parentGet.literal) {
2910
- compare = equals;
2911
- } else {
2912
- compare = simpleCompare;
2913
- }
2914
- parentSet =
2915
- parentGet.assign ||
2916
- function () {
2917
- // reset the change, or we will throw this exception on every $digest
2918
- lastValue = destination[scopeName] = parentGet(scope);
2919
- throw $compileMinErr(
2920
- "nonassign",
2921
- "Expression '{0}' in attribute '{1}' used with directive '{2}' is non-assignable!",
2922
- attrs[attrName],
2923
- attrName,
2924
- directive.name,
2925
- );
2926
- };
2927
- lastValue = destination[scopeName] = parentGet(scope);
2928
- var parentValueWatch = function parentValueWatch(parentValue) {
2929
- if (!compare(parentValue, destination[scopeName])) {
2930
- // we are out of sync and need to copy
2931
- if (!compare(parentValue, lastValue)) {
2932
- // parent changed and it has precedence
2933
- destination[scopeName] = parentValue;
2934
- } else {
2935
- // if the parent can be assigned then do so
2936
- parentSet(scope, (parentValue = destination[scopeName]));
2885
+ removeWatch = attrs.$observe(attrName, (value) => {
2886
+ if (isString(value) || isBoolean(value)) {
2887
+ const oldValue = destination[scopeName];
2888
+ recordChanges(scopeName, value, oldValue);
2889
+ destination[scopeName] = value;
2937
2890
  }
2891
+ });
2892
+ attrs.$$observers[attrName].$$scope = scope;
2893
+ lastValue = attrs[attrName];
2894
+ if (isString(lastValue)) {
2895
+ // If the attribute has been provided then we trigger an interpolation to ensure
2896
+ // the value is there for use in the link fn
2897
+ destination[scopeName] = $interpolate(lastValue)(scope);
2898
+ } else if (isBoolean(lastValue)) {
2899
+ // If the attributes is one of the BOOLEAN_ATTR then AngularJS will have converted
2900
+ // the value to boolean rather than a string, so we special case this situation
2901
+ destination[scopeName] = lastValue;
2938
2902
  }
2939
- lastValue = parentValue;
2940
- return lastValue;
2941
- };
2942
- parentValueWatch.$stateful = true;
2943
- if (definition.collection) {
2944
- removeWatch = scope.$watchCollection(
2945
- attrs[attrName],
2946
- parentValueWatch,
2903
+ initialChanges[scopeName] = new SimpleChange(
2904
+ UNINITALIZED_VALIED,
2905
+ destination[scopeName],
2947
2906
  );
2948
- } else {
2949
- removeWatch = scope.$watch(
2950
- $parse(attrs[attrName], parentValueWatch),
2951
- null,
2952
- parentGet.literal,
2953
- );
2954
- }
2955
- removeWatchCollection.push(removeWatch);
2956
- break;
2957
-
2958
- case "<":
2959
- if (!Object.hasOwnProperty.call(attrs, attrName)) {
2960
- if (optional) break;
2961
- strictBindingsCheck(attrName, directive.name);
2962
- attrs[attrName] = undefined;
2963
- }
2964
- if (optional && !attrs[attrName]) break;
2965
-
2966
- parentGet = $parse(attrs[attrName]);
2967
- var isLiteral = parentGet.literal;
2907
+ removeWatchCollection.push(removeWatch);
2908
+ break;
2968
2909
 
2969
- var initialValue = (destination[scopeName] = parentGet(scope));
2970
- initialChanges[scopeName] = new SimpleChange(
2971
- UNINITALIZED_VALIED,
2972
- destination[scopeName],
2973
- );
2910
+ case "=":
2911
+ if (!Object.hasOwnProperty.call(attrs, attrName)) {
2912
+ if (optional) break;
2913
+ strictBindingsCheck(attrName, directive.name);
2914
+ attrs[attrName] = undefined;
2915
+ }
2916
+ if (optional && !attrs[attrName]) break;
2974
2917
 
2975
- removeWatch = scope[
2976
- definition.collection ? "$watchCollection" : "$watch"
2977
- ](parentGet, (newValue, oldValue) => {
2978
- if (oldValue === newValue) {
2979
- if (
2980
- oldValue === initialValue ||
2981
- (isLiteral && equals(oldValue, initialValue))
2982
- ) {
2983
- return;
2918
+ parentGet = $parse(attrs[attrName]);
2919
+ if (parentGet.literal) {
2920
+ compare = equals;
2921
+ } else {
2922
+ compare = simpleCompare;
2923
+ }
2924
+ parentSet =
2925
+ parentGet.assign ||
2926
+ function () {
2927
+ // reset the change, or we will throw this exception on every $digest
2928
+ lastValue = destination[scopeName] = parentGet(scope);
2929
+ throw $compileMinErr(
2930
+ "nonassign",
2931
+ "Expression '{0}' in attribute '{1}' used with directive '{2}' is non-assignable!",
2932
+ attrs[attrName],
2933
+ attrName,
2934
+ directive.name,
2935
+ );
2936
+ };
2937
+ lastValue = destination[scopeName] = parentGet(scope);
2938
+ var parentValueWatch = function parentValueWatch(parentValue) {
2939
+ if (!compare(parentValue, destination[scopeName])) {
2940
+ // we are out of sync and need to copy
2941
+ if (!compare(parentValue, lastValue)) {
2942
+ // parent changed and it has precedence
2943
+ destination[scopeName] = parentValue;
2944
+ } else {
2945
+ // if the parent can be assigned then do so
2946
+ parentSet(scope, (parentValue = destination[scopeName]));
2947
+ }
2984
2948
  }
2985
- oldValue = initialValue;
2949
+ lastValue = parentValue;
2950
+ return lastValue;
2951
+ };
2952
+ parentValueWatch.$stateful = true;
2953
+ if (definition.collection) {
2954
+ removeWatch = scope.$watchCollection(
2955
+ attrs[attrName],
2956
+ parentValueWatch,
2957
+ );
2958
+ } else {
2959
+ removeWatch = scope.$watch(
2960
+ $parse(attrs[attrName], parentValueWatch),
2961
+ null,
2962
+ parentGet.literal,
2963
+ );
2986
2964
  }
2987
- recordChanges(scopeName, newValue, oldValue);
2988
- destination[scopeName] = newValue;
2989
- });
2965
+ removeWatchCollection.push(removeWatch);
2966
+ break;
2990
2967
 
2991
- removeWatchCollection.push(removeWatch);
2992
- break;
2968
+ case "<":
2969
+ if (!Object.hasOwnProperty.call(attrs, attrName)) {
2970
+ if (optional) break;
2971
+ strictBindingsCheck(attrName, directive.name);
2972
+ attrs[attrName] = undefined;
2973
+ }
2974
+ if (optional && !attrs[attrName]) break;
2993
2975
 
2994
- case "&":
2995
- if (!optional && !Object.hasOwnProperty.call(attrs, attrName)) {
2996
- strictBindingsCheck(attrName, directive.name);
2997
- }
2998
- // Don't assign Object.prototype method to scope
2999
- parentGet = Object.prototype.hasOwnProperty.call(attrs, attrName)
3000
- ? $parse(attrs[attrName])
3001
- : () => {};
2976
+ parentGet = $parse(attrs[attrName]);
2977
+ var isLiteral = parentGet.literal;
3002
2978
 
3003
- // Don't assign noop to destination if expression is not valid
3004
- if (parentGet.toString() === (() => {}).toString() && optional)
3005
- break;
2979
+ var initialValue = (destination[scopeName] = parentGet(scope));
2980
+ initialChanges[scopeName] = new SimpleChange(
2981
+ UNINITALIZED_VALIED,
2982
+ destination[scopeName],
2983
+ );
3006
2984
 
3007
- destination[scopeName] = function (locals) {
3008
- return parentGet(scope, locals);
3009
- };
3010
- break;
3011
- }
3012
- });
2985
+ scope.attrs = attrs;
2986
+ removeWatch = scope.$watch(
2987
+ `attrs.${attrName}`,
2988
+ (newValue, oldValue) => {
2989
+ if (oldValue === newValue) {
2990
+ if (
2991
+ oldValue === initialValue ||
2992
+ (isLiteral && equals(oldValue, initialValue))
2993
+ ) {
2994
+ return;
2995
+ }
2996
+ oldValue = initialValue;
2997
+ }
2998
+ recordChanges(scopeName, newValue, oldValue);
2999
+ destination[scopeName] = newValue;
3000
+ },
3001
+ );
3002
+
3003
+ removeWatchCollection.push(removeWatch);
3004
+ break;
3013
3005
 
3006
+ case "&":
3007
+ if (!optional && !Object.hasOwnProperty.call(attrs, attrName)) {
3008
+ strictBindingsCheck(attrName, directive.name);
3009
+ }
3010
+ // Don't assign Object.prototype method to scope
3011
+ parentGet = Object.prototype.hasOwnProperty.call(
3012
+ attrs,
3013
+ attrName,
3014
+ )
3015
+ ? $parse(attrs[attrName])
3016
+ : () => {};
3017
+
3018
+ // Don't assign noop to destination if expression is not valid
3019
+ if (parentGet.toString() === (() => {}).toString() && optional)
3020
+ break;
3021
+
3022
+ destination[scopeName] = function (locals) {
3023
+ return parentGet(scope, locals);
3024
+ };
3025
+ break;
3026
+ }
3027
+ });
3028
+ }
3014
3029
  function recordChanges(key, currentValue, previousValue) {
3015
3030
  if (
3016
3031
  isFunction(destination.$onChanges) &&
@@ -3018,7 +3033,7 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
3018
3033
  ) {
3019
3034
  // If we have not already scheduled the top level onChangesQueue handler then do so now
3020
3035
  if (!onChangesQueue) {
3021
- scope.$$postDigest(flushOnChangesQueue);
3036
+ scope.$postUpdate(flushOnChangesQueue);
3022
3037
  onChangesQueue = [];
3023
3038
  }
3024
3039
  // If we have not already queued a trigger of onChanges for this controller then do so now