@angular-wave/angular.ts 0.4.6 → 0.6.0

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/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@angular-wave/angular.ts",
3
3
  "description": "A modern, optimized and typesafe version of AngularJS",
4
4
  "license": "MIT",
5
- "version": "0.4.6",
5
+ "version": "0.6.0",
6
6
  "type": "module",
7
7
  "main": "dist/angular-ts.esm.js",
8
8
  "browser": "dist/angular-ts.umd.js",
@@ -61,7 +61,7 @@ export function AnimateJsProvider($animateProvider) {
61
61
  beforeFn = "leave";
62
62
  afterFn = "afterLeave"; // TODO(matsko): get rid of this
63
63
  } else {
64
- beforeFn = `before${event.charAt(0).toUpperCase()}${event.substr(1)}`;
64
+ beforeFn = `before${event.charAt(0).toUpperCase()}${event.substring(1)}`;
65
65
  afterFn = event;
66
66
  }
67
67
 
@@ -118,7 +118,7 @@ export function AnimateProvider($provide) {
118
118
  }
119
119
 
120
120
  const key = `${name}-animation`;
121
- provider.$$registeredAnimations[name.substr(1)] = key;
121
+ provider.$$registeredAnimations[name.substring(1)] = key;
122
122
  $provide.factory(key, factory);
123
123
  };
124
124
 
@@ -37,6 +37,7 @@ import { PREFIX_REGEXP } from "../../shared/constants";
37
37
  import { createEventDirective } from "../../directive/events/events";
38
38
  import { CACHE, EXPANDO } from "../cache/cache";
39
39
  import { Attributes } from "./attributes";
40
+ import { ngObserveDirective } from "../../directive/observe/observe";
40
41
 
41
42
  let ttl = TTL;
42
43
 
@@ -586,7 +587,7 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
586
587
  ? (x) => x
587
588
  : (x) => x.replace(/\{\{/g, startSymbol).replace(/}}/g, endSymbol);
588
589
 
589
- const NG_PREFIX_BINDING = /^ng(Attr|Prop|On)([A-Z].*)$/;
590
+ const NG_PREFIX_BINDING = /^ng(Attr|Prop|On|Observe)([A-Z].*)$/;
590
591
  const MULTI_ELEMENT_DIR_RE = /^(.+)Start$/;
591
592
  return compile;
592
593
 
@@ -992,6 +993,7 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
992
993
  let isNgAttr = false;
993
994
  let isNgProp = false;
994
995
  let isNgEvent = false;
996
+ let isNgObserve = false;
995
997
  let multiElementMatch;
996
998
 
997
999
  attr = nAttrs[j];
@@ -1005,12 +1007,13 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
1005
1007
  isNgAttr = ngPrefixMatch[1] === "Attr";
1006
1008
  isNgProp = ngPrefixMatch[1] === "Prop";
1007
1009
  isNgEvent = ngPrefixMatch[1] === "On";
1010
+ isNgObserve = ngPrefixMatch[1] === "Observe";
1008
1011
 
1009
1012
  // Normalize the non-prefixed name
1010
1013
  name = name
1011
1014
  .replace(PREFIX_REGEXP, "")
1012
1015
  .toLowerCase()
1013
- .substr(4 + ngPrefixMatch[1].length)
1016
+ .substring(4 + ngPrefixMatch[1].length)
1014
1017
  .replace(/_(.)/g, (match, letter) => letter.toUpperCase());
1015
1018
 
1016
1019
  // Support *-start / *-end multi element directives
@@ -1019,8 +1022,8 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
1019
1022
  directiveIsMultiElement(multiElementMatch[1])
1020
1023
  ) {
1021
1024
  attrStartName = name;
1022
- attrEndName = `${name.substr(0, name.length - 5)}end`;
1023
- name = name.substr(0, name.length - 6);
1025
+ attrEndName = `${name.substring(0, name.length - 5)}end`;
1026
+ name = name.substring(0, name.length - 6);
1024
1027
  }
1025
1028
 
1026
1029
  if (isNgProp || isNgEvent) {
@@ -1032,6 +1035,8 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
1032
1035
  } else {
1033
1036
  addEventDirective(directives, nName, name);
1034
1037
  }
1038
+ } else if (isNgObserve) {
1039
+ addObserveDirective(directives, name, value);
1035
1040
  } else {
1036
1041
  // Update nName for cases where a prefix was removed
1037
1042
  // NOTE: the .toLowerCase() is unnecessary and causes https://github.com/angular/angular.js/issues/16624 for ng-attr-*
@@ -2100,7 +2105,7 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
2100
2105
  *
2101
2106
  * @param {string} name name of the directive to look up.
2102
2107
  * @param {string} location The directive must be found in specific format.
2103
- * String containing any of theses characters:
2108
+ * String containing any of these characters:
2104
2109
  *
2105
2110
  * * `E`: element name
2106
2111
  * * `A': attribute
@@ -2115,8 +2120,8 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
2115
2120
  startAttrName,
2116
2121
  endAttrName,
2117
2122
  ) {
2118
- if (name === ignoreDirective) return null;
2119
- let match = null;
2123
+ if (name === ignoreDirective) return false;
2124
+ let match = false;
2120
2125
  if (Object.prototype.hasOwnProperty.call(hasDirectives, name)) {
2121
2126
  for (
2122
2127
  let directive,
@@ -2651,6 +2656,10 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
2651
2656
  );
2652
2657
  }
2653
2658
 
2659
+ function addObserveDirective(directives, source, prop) {
2660
+ directives.push(ngObserveDirective(source, prop));
2661
+ }
2662
+
2654
2663
  function addAttrInterpolateDirective(
2655
2664
  node,
2656
2665
  directives,
@@ -10,7 +10,6 @@
10
10
  <script src="/jasmine/jasmine-5.1.2/jasmine-html.js"></script>
11
11
  <script src="/jasmine/jasmine-5.1.2/boot0.js"></script>
12
12
  <script src="/jasmine/jasmine-5.1.2/boot1.js"></script>
13
- <script type="module" src="/src/core/cookie-reader.spec.js"></script>
14
13
  <script type="module" src="/src/core/on.spec.js"></script>
15
14
  <script type="module" src="/src/core/prop.spec.js"></script>
16
15
  <script type="module" src="/src/core/root-element.spec.js"></script>
@@ -2,6 +2,7 @@ import { JQLite } from "../../shared/jqlite/jqlite";
2
2
  import { urlResolve } from "../url-utils/url-utils";
3
3
  import {
4
4
  encodeUriSegment,
5
+ isBoolean,
5
6
  isDefined,
6
7
  isNumber,
7
8
  isObject,
@@ -22,10 +23,21 @@ import { ScopePhase } from "../scope/scope";
22
23
  */
23
24
 
24
25
  /**
26
+ * Represents the configuration options for HTML5 mode.
27
+ *
25
28
  * @typedef {Object} Html5Mode
26
- * @property {boolean} enabled
27
- * @property {boolean} requireBase
28
- * @property {boolean|string} rewriteLinks
29
+ * @property {boolean} enabled - (default: false) If true, will rely on `history.pushState` to
30
+ * change URLs where supported. Falls back to hash-prefixed paths in browsers that do not
31
+ * support `pushState`.
32
+ * @property {boolean} requireBase - (default: `true`) When html5Mode is enabled, specifies
33
+ * whether or not a `<base>` tag is required to be present. If both `enabled` and `requireBase`
34
+ * are true, and a `<base>` tag is not present, an error will be thrown when `$location` is injected.
35
+ * See the {@link guide/$location $location guide} for more information.
36
+ * @property {boolean|string} rewriteLinks - (default: `true`) When html5Mode is enabled, enables or
37
+ * disables URL rewriting for relative links. If set to a string, URL rewriting will only apply to links
38
+ * with an attribute that matches the given string. For example, if set to `'internal-link'`, URL rewriting
39
+ * will only occur for `<a internal-link>` links. Note that [attribute name normalization](guide/directive#normalization)
40
+ * does not apply here, so `'internalLink'` will **not** match `'internal-link'`.
29
41
  */
30
42
 
31
43
  /** @type {DefaultPorts} */
@@ -389,7 +401,7 @@ export class LocationHtml5Url extends Location {
389
401
  }
390
402
 
391
403
  $$normalizeUrl(url) {
392
- return this.appBaseNoFile + url.substr(1); // first char is always '/'
404
+ return this.appBaseNoFile + url.substring(1); // first char is always '/'
393
405
  }
394
406
 
395
407
  /**
@@ -543,8 +555,11 @@ export class LocationHashbangUrl extends Location {
543
555
 
544
556
  export class LocationProvider {
545
557
  constructor() {
546
- this.hashPrefixValue = "!";
547
- this.html5ModeConfig = {
558
+ /** @type {string} */
559
+ this.hashPrefixConf = "!";
560
+
561
+ /** @type {Html5Mode} */
562
+ this.html5ModeConf = {
548
563
  enabled: false,
549
564
  requireBase: true,
550
565
  rewriteLinks: true,
@@ -553,57 +568,59 @@ export class LocationProvider {
553
568
 
554
569
  /**
555
570
  * The default value for the prefix is `'!'`.
556
- * @param {string=} prefix - Prefix for hash part (containing path and search)
557
- * @returns {string|LocationProvider} current value if used as getter or itself (chaining) if used as setter
571
+ * @param {string=} prefix Prefix for hash part (containing path and search)
572
+ * @returns {void}
558
573
  */
559
- hashPrefix(prefix) {
560
- if (typeof prefix !== "undefined") {
561
- this.hashPrefixValue = prefix;
562
- return this;
563
- }
564
- return this.hashPrefixValue;
574
+ setHashPrefix(prefix) {
575
+ this.hashPrefixConf = prefix;
576
+ }
577
+
578
+ /**
579
+ * Current hash prefix
580
+ * @returns {string}
581
+ */
582
+ getHashPrefix() {
583
+ return this.hashPrefixConf;
565
584
  }
566
585
 
567
586
  /**
568
- * @param {(boolean|Object)=} mode If boolean, sets `html5Mode.enabled` to value.
569
- * If object, sets `enabled`, `requireBase` and `rewriteLinks` to respective values. Supported
570
- * properties:
571
- * - **enabled** – `{boolean}` – (default: false) If true, will rely on `history.pushState` to
572
- * change urls where supported. Will fall back to hash-prefixed paths in browsers that do not
573
- * support `pushState`.
574
- * - **requireBase** - `{boolean}` - (default: `true`) When html5Mode is enabled, specifies
575
- * whether or not a <base> tag is required to be present. If `enabled` and `requireBase` are
576
- * true, and a base tag is not present, an error will be thrown when `$location` is injected.
577
- * See the {@link guide/$location $location guide for more information}
578
- * - **rewriteLinks** - `{boolean|string}` - (default: `true`) When html5Mode is enabled,
579
- * enables/disables URL rewriting for relative links. If set to a string, URL rewriting will
580
- * only happen on links with an attribute that matches the given string. For example, if set
581
- * to `'internal-link'`, then the URL will only be rewritten for `<a internal-link>` links.
582
- * Note that [attribute name normalization](guide/directive#normalization) does not apply
583
- * here, so `'internalLink'` will **not** match `'internal-link'`.
587
+ * Configures html5 mode
588
+ * @param {(boolean|Html5Mode)=} mode If boolean, sets `html5Mode.enabled` to value. Otherwise, accepts html5Mode object
584
589
  *
585
- * @returns {Object} html5Mode object if used as getter or itself (chaining) if used as setter
590
+ * @returns {void}
586
591
  */
587
- html5Mode(mode) {
588
- if (typeof mode === "boolean") {
589
- this.html5ModeConfig.enabled = mode;
590
- return this;
592
+ setHtml5Mode(mode) {
593
+ if (isBoolean(mode)) {
594
+ this.html5ModeConf.enabled = /** @type {boolean} */ (mode);
591
595
  }
596
+ if (isObject(mode)) {
597
+ const html5Mode = /** @type {Html5Mode} */ (mode);
598
+ if (isDefined(html5Mode.enabled) && isBoolean(html5Mode.enabled)) {
599
+ this.html5ModeConf.enabled = html5Mode.enabled;
600
+ }
592
601
 
593
- if (typeof mode === "object") {
594
- if (typeof mode.enabled === "boolean")
595
- this.html5ModeConfig.enabled = mode.enabled;
596
- if (typeof mode.requireBase === "boolean")
597
- this.html5ModeConfig.requireBase = mode.requireBase;
598
602
  if (
599
- typeof mode.rewriteLinks === "boolean" ||
600
- typeof mode.rewriteLinks === "string"
603
+ isDefined(html5Mode.requireBase) &&
604
+ isBoolean(html5Mode.requireBase)
601
605
  ) {
602
- this.html5ModeConfig.rewriteLinks = mode.rewriteLinks;
606
+ this.html5ModeConf.requireBase = html5Mode.requireBase;
607
+ }
608
+
609
+ if (
610
+ isDefined(html5Mode.rewriteLinks) &&
611
+ (isBoolean(html5Mode.rewriteLinks) || isString(html5Mode.rewriteLinks))
612
+ ) {
613
+ this.html5ModeConf.rewriteLinks = html5Mode.rewriteLinks;
603
614
  }
604
- return this;
605
615
  }
606
- return this.html5ModeConfig;
616
+ }
617
+
618
+ /**
619
+ * Returns html5 mode cofiguration
620
+ * @returns {Html5Mode}
621
+ */
622
+ getHtml5Mode() {
623
+ return this.html5ModeConf;
607
624
  }
608
625
 
609
626
  $get = [
@@ -617,7 +634,7 @@ export class LocationProvider {
617
634
  * @param {JQLite} $rootElement
618
635
  * @returns
619
636
  */
620
- function ($rootScope, $browser, $rootElement) {
637
+ ($rootScope, $browser, $rootElement) => {
621
638
  /** @type {Location} */
622
639
  let $location;
623
640
  let LocationMode;
@@ -625,8 +642,8 @@ export class LocationProvider {
625
642
  const initialUrl = /** @type {string} */ ($browser.url());
626
643
  let appBase;
627
644
 
628
- if (this.html5Mode.enabled) {
629
- if (!baseHref && this.html5Mode.requireBase) {
645
+ if (this.getHtml5Mode().enabled) {
646
+ if (!baseHref && this.getHtml5Mode().requireBase) {
630
647
  throw $locationMinErr(
631
648
  "nobase",
632
649
  "$location in HTML5 mode requires a <base> tag to be present!",
@@ -643,7 +660,7 @@ export class LocationProvider {
643
660
  $location = new LocationMode(
644
661
  appBase,
645
662
  appBaseNoFile,
646
- `#${this.hashPrefix}`,
663
+ `#${this.getHashPrefix()}`,
647
664
  );
648
665
  $location.$$parseLinkUrl(initialUrl, initialUrl);
649
666
 
@@ -671,7 +688,7 @@ export class LocationProvider {
671
688
  }
672
689
 
673
690
  $rootElement.on("click", (event) => {
674
- const { rewriteLinks } = this.html5Mode;
691
+ const rewriteLinks = this.getHtml5Mode().rewriteLinks;
675
692
  // TODO(vojta): rewrite link when opening in new tab/window (in legacy browser)
676
693
  // currently we open nice url link and redirect then
677
694
 
@@ -774,7 +791,7 @@ export class LocationProvider {
774
791
  });
775
792
 
776
793
  // update browser
777
- function browserUpdate() {
794
+ $rootScope.$watch(() => {
778
795
  if (initializing || $location.$$urlUpdatedByLocation) {
779
796
  $location.$$urlUpdatedByLocation = false;
780
797
 
@@ -822,9 +839,7 @@ export class LocationProvider {
822
839
 
823
840
  // we don't need to return anything because $evalAsync will make the digest loop dirty when
824
841
  // there is a change
825
- }
826
-
827
- setTimeout(() => browserUpdate());
842
+ });
828
843
 
829
844
  return $location;
830
845
 
@@ -836,7 +851,6 @@ export class LocationProvider {
836
851
  $location.$$state,
837
852
  oldState,
838
853
  );
839
- browserUpdate();
840
854
  }
841
855
  },
842
856
  ];
@@ -926,17 +940,17 @@ function startsWith(str, search) {
926
940
  */
927
941
  export function stripBaseUrl(base, url) {
928
942
  if (startsWith(url, base)) {
929
- return url.substr(base.length);
943
+ return url.substring(base.length);
930
944
  }
931
945
  }
932
946
 
933
947
  export function stripHash(url) {
934
948
  const index = url.indexOf("#");
935
- return index === -1 ? url : url.substr(0, index);
949
+ return index === -1 ? url : url.substring(0, index);
936
950
  }
937
951
 
938
952
  export function stripFile(url) {
939
- return url.substr(0, stripHash(url).lastIndexOf("/") + 1);
953
+ return url.substring(0, stripHash(url).lastIndexOf("/") + 1);
940
954
  }
941
955
 
942
956
  /* return the server only (scheme://host:port) */
@@ -15,7 +15,7 @@ describe("$location", () => {
15
15
 
16
16
  // function initService(options) {
17
17
  // module.config(($provide, $locationProvider) => {
18
- // $locationProvider.html5Mode(options.html5Mode);
18
+ // $locationProvider.setHtml5Mode(options.html5Mode);
19
19
  // $locationProvider.hashPrefix(options.hashPrefix);
20
20
  // $provide.value("$sniffer", { history: options.supportHistory });
21
21
  // });
@@ -24,12 +24,12 @@ describe("$location", () => {
24
24
  describe("defaults", () => {
25
25
  it('should have hashPrefix of "!"', () => {
26
26
  let provider = new LocationProvider();
27
- expect(provider.hashPrefix()).toBe("!");
27
+ expect(provider.getHashPrefix()).toBe("!");
28
28
  });
29
29
 
30
30
  it("should not be html5 mode", () => {
31
31
  let provider = new LocationProvider();
32
- expect(provider.html5Mode().enabled).toBeFalse();
32
+ expect(provider.getHtml5Mode().enabled).toBeFalse();
33
33
  });
34
34
  });
35
35
 
@@ -2947,7 +2947,7 @@ describe("$location", () => {
2947
2947
 
2948
2948
  // it("should listen on click events on href and prevent browser default in html5 mode", () => {
2949
2949
  // module(($locationProvider, $provide) => {
2950
- // $locationProvider.html5Mode(true);
2950
+ // $locationProvider.setHtml5Mode(true);
2951
2951
  // return function ($rootElement, $compile, $rootScope) {
2952
2952
  // $rootElement.html('<a href="http://server/somePath">link</a>');
2953
2953
  // $compile($rootElement)($rootScope);
@@ -3011,12 +3011,12 @@ describe("$location", () => {
3011
3011
  describe("html5Mode", () => {
3012
3012
  it("should set enabled, requireBase and rewriteLinks when called with object", () => {
3013
3013
  module.config(($locationProvider) => {
3014
- $locationProvider.html5Mode({
3014
+ $locationProvider.setHtml5Mode({
3015
3015
  enabled: true,
3016
3016
  requireBase: false,
3017
3017
  rewriteLinks: false,
3018
3018
  });
3019
- expect($locationProvider.html5Mode()).toEqual({
3019
+ expect($locationProvider.getHtml5Mode()).toEqual({
3020
3020
  enabled: true,
3021
3021
  requireBase: false,
3022
3022
  rewriteLinks: false,
@@ -3027,13 +3027,13 @@ describe("$location", () => {
3027
3027
 
3028
3028
  it("should only overwrite existing properties if values are of the correct type", () => {
3029
3029
  module.config(($locationProvider) => {
3030
- $locationProvider.html5Mode({
3030
+ $locationProvider.setHtml5Mode({
3031
3031
  enabled: "duh",
3032
3032
  requireBase: "probably",
3033
3033
  rewriteLinks: 0,
3034
3034
  });
3035
3035
 
3036
- expect($locationProvider.html5Mode()).toEqual({
3036
+ expect($locationProvider.getHtml5Mode()).toEqual({
3037
3037
  enabled: false,
3038
3038
  requireBase: true,
3039
3039
  rewriteLinks: true,
@@ -3045,11 +3045,11 @@ describe("$location", () => {
3045
3045
 
3046
3046
  it("should support setting rewriteLinks to a string", () => {
3047
3047
  module.config(($locationProvider) => {
3048
- $locationProvider.html5Mode({
3048
+ $locationProvider.setHtml5Mode({
3049
3049
  rewriteLinks: "yes-rewrite",
3050
3050
  });
3051
3051
 
3052
- expect($locationProvider.html5Mode().rewriteLinks).toEqual(
3052
+ expect($locationProvider.getHtml5Mode().rewriteLinks).toEqual(
3053
3053
  "yes-rewrite",
3054
3054
  );
3055
3055
  });
@@ -3059,11 +3059,11 @@ describe("$location", () => {
3059
3059
 
3060
3060
  it("should not set unknown input properties to html5Mode object", () => {
3061
3061
  module.config(($locationProvider) => {
3062
- $locationProvider.html5Mode({
3062
+ $locationProvider.setHtml5Mode({
3063
3063
  someProp: "foo",
3064
3064
  });
3065
3065
 
3066
- expect($locationProvider.html5Mode()).toEqual({
3066
+ expect($locationProvider.getHtml5Mode()).toEqual({
3067
3067
  enabled: false,
3068
3068
  requireBase: true,
3069
3069
  rewriteLinks: true,
@@ -3075,7 +3075,7 @@ describe("$location", () => {
3075
3075
 
3076
3076
  it("should default to enabled:false, requireBase:true and rewriteLinks:true", () => {
3077
3077
  module.config(($locationProvider) => {
3078
- expect($locationProvider.html5Mode()).toEqual({
3078
+ expect($locationProvider.getHtml5Mode()).toEqual({
3079
3079
  enabled: false,
3080
3080
  requireBase: true,
3081
3081
  rewriteLinks: true,
@@ -3178,7 +3178,7 @@ describe("$location", () => {
3178
3178
  // it("should complain if no base tag present", () => {
3179
3179
  // let module = window.angular.module("test1", ["ng"]);
3180
3180
  // module.config((_$locationProvider_) => {
3181
- // $locationProvider.html5Mode(true);
3181
+ // $locationProvider.setHtml5Mode(true);
3182
3182
  // });
3183
3183
 
3184
3184
  // createInjector(["test1"]).invoke(($browser, $injector) => {
@@ -3191,7 +3191,7 @@ describe("$location", () => {
3191
3191
 
3192
3192
  // it("should not complain if baseOptOut set to true in html5Mode", () => {
3193
3193
  // module.config(($locationProvider) => {
3194
- // $locationProvider.html5Mode({
3194
+ // $locationProvider.setHtml5Mode({
3195
3195
  // enabled: true,
3196
3196
  // requireBase: false,
3197
3197
  // });
@@ -688,7 +688,7 @@ describe("parser", () => {
688
688
  scope.zero = 0;
689
689
  scope.bool = false;
690
690
 
691
- expect(scope.$eval("empty.substr(0)")).toBe("");
691
+ expect(scope.$eval("empty.substring(0)")).toBe("");
692
692
  expect(scope.$eval("zero.toString()")).toBe("0");
693
693
  expect(scope.$eval("bool.toString()")).toBe("false");
694
694
  });
@@ -3,7 +3,7 @@ import { createInjector } from "./di/injector";
3
3
  import { valueFn } from "../shared/utils";
4
4
  import { dealoc } from "../shared/jqlite/jqlite";
5
5
 
6
- fdescribe("ngProp*", () => {
6
+ describe("ngProp*", () => {
7
7
  let $compile, $rootScope, compileProvider, $sce;
8
8
  let logs = [];
9
9
 
@@ -1265,7 +1265,7 @@ describe("ngModel", () => {
1265
1265
 
1266
1266
  it("should always use the most recent $viewValue for validation", () => {
1267
1267
  ctrl.$parsers.push((value) => {
1268
- if (value && value.substr(-1) === "b") {
1268
+ if (value && value.slice(-1) === "b") {
1269
1269
  value = "a";
1270
1270
  ctrl.$setViewValue(value);
1271
1271
  ctrl.$render();
@@ -1288,14 +1288,14 @@ describe("ngModel", () => {
1288
1288
 
1289
1289
  it("should validate even if the modelValue did not change", () => {
1290
1290
  ctrl.$parsers.push((value) => {
1291
- if (value && value.substr(-1) === "b") {
1291
+ if (value && value.slice(-1) === "b") {
1292
1292
  value = "a";
1293
1293
  }
1294
1294
 
1295
1295
  return value;
1296
1296
  });
1297
1297
 
1298
- ctrl.$validators.mock = function (modelValue) {
1298
+ ctrl.$validators.mock = function () {
1299
1299
  return true;
1300
1300
  };
1301
1301
 
@@ -1,17 +1,18 @@
1
+ import { isUndefined } from "../../shared/utils.js";
2
+
1
3
  /**
2
- * @returns {import("../../types").Directive}
4
+ * @param {string} source - the name of the attribute to be observed
5
+ * @param {string} prop - the scope property to be updated with attribute value
6
+ * @returns {import("../../types.js").Directive}
3
7
  */
4
- export function ngObserveDirective() {
8
+ export function ngObserveDirective(source, prop) {
5
9
  return {
6
10
  restrict: "A",
7
- link: (scope, element, attrs) => {
11
+ compile: () => (scope, element) => {
8
12
  const targetElement = element[0];
9
- const source = attrs["ngObserve"];
10
- let prop = targetElement.dataset["update"];
11
- if (!prop) {
13
+ if (isUndefined(prop) || prop == "") {
12
14
  prop = source;
13
15
  }
14
-
15
16
  if (!scope[prop]) {
16
17
  scope[prop] = targetElement.getAttribute(source);
17
18
  }
@@ -23,16 +23,14 @@ describe("observe", () => {
23
23
  });
24
24
 
25
25
  function createDirective(attributeValue, updateProp) {
26
- const template = `<div ng-observe="${attributeValue}" data-update="${updateProp}"></div>`;
26
+ const template = `<div ng-observe-${attributeValue}="${updateProp}"></div>`;
27
27
  element = $compile(template)($scope);
28
28
  $scope.$digest();
29
29
  }
30
30
 
31
31
  it("should set the scope property to the attribute value before any changes", () => {
32
32
  const scope = $rootScope.$new();
33
- const element = JQLite(
34
- '<div data-update="testProp" ng-observe="sourceAttr"></div>',
35
- );
33
+ const element = JQLite('<div ng-observe-sourceAttr="testProp"></div>');
36
34
  element.attr("sourceAttr", "initialValue");
37
35
  $compile(element)(scope);
38
36
 
@@ -92,7 +90,7 @@ describe("observe", () => {
92
90
 
93
91
  it("should observe attribute changes and update the same scope name if data-update attribute is absent", () => {
94
92
  $scope.myProp = "";
95
- const template = `<div ng-observe="test-attribute"></div>`;
93
+ const template = `<div ng-observe-test-attribute></div>`;
96
94
  element = $compile(template)($scope);
97
95
  $scope.$digest();
98
96
  spyOn($scope, "$digest").and.callThrough();
@@ -74,11 +74,7 @@
74
74
  <test-component greeting="{{ greeting }}"></test-component>
75
75
  <div>{{ greeting }}</div>
76
76
 
77
- <fluent-select
78
- ng-observe="current-value"
79
- data-update="greeting"
80
- title="Select a section"
81
- >
77
+ <fluent-select ng-observe-current-value="greeting" title="Select a section">
82
78
  <fluent-option value="Beginning">Beginning</fluent-option>
83
79
  <fluent-option value="Middle">Middle</fluent-option>
84
80
  <fluent-option value="End">End</fluent-option>
@@ -86,7 +82,7 @@
86
82
  <br />
87
83
 
88
84
  {{ activeid }}
89
- <fluent-tabs ng-observe="activeid" activeid="entrees">
85
+ <fluent-tabs ng-observe-activeid activeid="entrees">
90
86
  <fluent-tab id="apps">Appetizers</fluent-tab>
91
87
  <fluent-tab id="entrees">Entrees</fluent-tab>
92
88
  <fluent-tab id="desserts">Desserts</fluent-tab>
@@ -171,7 +167,7 @@
171
167
 
172
168
  {{ value }}
173
169
 
174
- <fluent-radio-group ng-observe="value" orientation="vertical">
170
+ <fluent-radio-group ng-observe-value orientation="vertical">
175
171
  <fluent-radio value="1">18-24</fluent-radio>
176
172
  <fluent-radio value="2">25-33</fluent-radio>
177
173
  <fluent-radio value="3">34-44</fluent-radio>
@@ -180,7 +176,7 @@
180
176
 
181
177
  {{ checked }}
182
178
 
183
- <fluent-switch ng-observe="aria-checked" data-update="checked">
179
+ <fluent-switch ng-observe-aria-checked="checked">
184
180
  <span slot="checked-message">On</span>
185
181
  <span slot="unchecked-message">Off</span>
186
182
  <label for="cap-switch">Captions:</label>
package/src/loader.js CHANGED
@@ -146,13 +146,14 @@ export class Angular {
146
146
  * @param {import("./core/di/internal-injector").InjectorService} $injector
147
147
  */
148
148
  function (scope, el, compile, $injector) {
149
+ // ng-route deps
150
+ services.$injector = $injector;
151
+ services.$q = $injector.get("$q");
149
152
  scope.$apply(() => {
150
153
  el.data("$injector", $injector);
151
154
  compile(el)(scope);
152
155
  });
153
- // ng-route deps
154
- services.$injector = $injector;
155
- services.$q = $injector.get("$q");
156
+
156
157
  // https://github.com/angular-ui/ui-router/issues/3678
157
158
  if (!Object.prototype.hasOwnProperty.call($injector, "strictDi")) {
158
159
  try {
package/src/public.js CHANGED
@@ -130,7 +130,6 @@ import {
130
130
  $ViewDirectiveFill,
131
131
  ngView,
132
132
  } from "./router/directives/view-directive.js";
133
- import { ngObserveDirective } from "./directive/observe/observe.js";
134
133
  import { ngChannelDirective } from "./directive/channel/channel.js";
135
134
 
136
135
  /**
@@ -191,7 +190,6 @@ export function publishExternalAPI(angular) {
191
190
  ngSwitch: ngSwitchDirective,
192
191
  ngSwitchWhen: ngSwitchWhenDirective,
193
192
  ngSwitchDefault: ngSwitchDefaultDirective,
194
- ngObserve: ngObserveDirective,
195
193
  ngOptions: ngOptionsDirective,
196
194
  ngTransclude: ngTranscludeDirective,
197
195
  ngModel: ngModelDirective,