@angular-wave/angular.ts 0.4.5 → 0.5.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.5",
5
+ "version": "0.5.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
 
@@ -1010,7 +1010,7 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
1010
1010
  name = name
1011
1011
  .replace(PREFIX_REGEXP, "")
1012
1012
  .toLowerCase()
1013
- .substr(4 + ngPrefixMatch[1].length)
1013
+ .substring(4 + ngPrefixMatch[1].length)
1014
1014
  .replace(/_(.)/g, (match, letter) => letter.toUpperCase());
1015
1015
 
1016
1016
  // Support *-start / *-end multi element directives
@@ -1019,8 +1019,8 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
1019
1019
  directiveIsMultiElement(multiElementMatch[1])
1020
1020
  ) {
1021
1021
  attrStartName = name;
1022
- attrEndName = `${name.substr(0, name.length - 5)}end`;
1023
- name = name.substr(0, name.length - 6);
1022
+ attrEndName = `${name.substring(0, name.length - 5)}end`;
1023
+ name = name.substring(0, name.length - 6);
1024
1024
  }
1025
1025
 
1026
1026
  if (isNgProp || isNgEvent) {
@@ -2100,7 +2100,7 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
2100
2100
  *
2101
2101
  * @param {string} name name of the directive to look up.
2102
2102
  * @param {string} location The directive must be found in specific format.
2103
- * String containing any of theses characters:
2103
+ * String containing any of these characters:
2104
2104
  *
2105
2105
  * * `E`: element name
2106
2106
  * * `A': attribute
@@ -2115,8 +2115,8 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
2115
2115
  startAttrName,
2116
2116
  endAttrName,
2117
2117
  ) {
2118
- if (name === ignoreDirective) return null;
2119
- let match = null;
2118
+ if (name === ignoreDirective) return false;
2119
+ let match = false;
2120
2120
  if (Object.prototype.hasOwnProperty.call(hasDirectives, name)) {
2121
2121
  for (
2122
2122
  let directive,
@@ -2394,7 +2394,7 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
2394
2394
  });
2395
2395
 
2396
2396
  return function delayedNodeLinkFn(
2397
- ignoreChildLinkFn,
2397
+ _ignoreChildLinkFn,
2398
2398
  scope,
2399
2399
  node,
2400
2400
  rootElement,
@@ -2453,19 +2453,16 @@ export function CompileProvider($provide, $$sanitizeUriProvider) {
2453
2453
  }
2454
2454
 
2455
2455
  function addTextInterpolateDirective(directives, text) {
2456
- const interpolateFn = $interpolate(text, true);
2456
+ const interpolateFn = $interpolate(text, true); // Create interpolation function
2457
2457
  if (interpolateFn) {
2458
2458
  directives.push({
2459
2459
  priority: 0,
2460
- compile: function textInterpolateCompileFn() {
2461
- // When transcluding a template that has bindings in the root
2462
- // we don't have a parent and thus need to add the class during linking fn.
2463
-
2464
- return function textInterpolateLinkFn(scope, node) {
2465
- scope.$watch(interpolateFn, (value) => {
2466
- node[0].nodeValue = value;
2467
- });
2468
- };
2460
+ // When transcluding a template that has bindings in the root
2461
+ // we don't have a parent and thus need to add the class during linking fn.
2462
+ compile: () => (scope, node) => {
2463
+ scope.$watch(interpolateFn, (value) => {
2464
+ node[0].nodeValue = value; // Update text node with new interpolated value
2465
+ });
2469
2466
  },
2470
2467
  });
2471
2468
  }
@@ -13,7 +13,7 @@ describe("$$cookieReader", () => {
13
13
  for (let i = 0; i < cookies.length; i++) {
14
14
  const cookie = cookies[i];
15
15
  const eqPos = cookie.indexOf("=");
16
- const name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;
16
+ const name = eqPos > -1 ? cookie.substring(0, eqPos) : cookie;
17
17
  const parts = path.split("/");
18
18
  while (parts.length) {
19
19
  document.cookie = `${name}=;path=${parts.join("/") || "/"};expires=Thu, 01 Jan 1970 00:00:00 GMT`;
@@ -353,19 +353,16 @@ export class InterpolateProvider {
353
353
  expressions,
354
354
  $$watchDelegate(scope, listener) {
355
355
  let lastValue;
356
- return scope.$watchGroup(
357
- parseFns,
358
- function interpolateFnWatcher(values, oldValues) {
359
- const currValue = compute(values);
360
- listener.call(
361
- this,
362
- currValue,
363
- values !== oldValues ? lastValue : currValue,
364
- scope,
365
- );
366
- lastValue = currValue;
367
- },
368
- );
356
+ return scope.$watchGroup(parseFns, (values, oldValues) => {
357
+ const currValue = compute(values);
358
+ listener.call(
359
+ this,
360
+ currValue,
361
+ values !== oldValues ? lastValue : currValue,
362
+ scope,
363
+ );
364
+ lastValue = currValue;
365
+ });
369
366
  },
370
367
  },
371
368
  );
@@ -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,
@@ -42,6 +43,8 @@ export class Location {
42
43
  * @param {string} appBaseNoFile application base URL stripped of any filename
43
44
  */
44
45
  constructor(appBase, appBaseNoFile) {
46
+ const parsedUrl = urlResolve(appBase);
47
+
45
48
  /** @type {string} */
46
49
  this.appBase = appBase;
47
50
 
@@ -67,16 +70,17 @@ export class Location {
67
70
  this.$$replace = false;
68
71
 
69
72
  /** @type {import('../url-utils/url-utils').HttpProtocol} */
70
- this.$$protocol = undefined;
73
+ this.$$protocol = parsedUrl.protocol;
71
74
 
72
75
  /** @type {string} */
73
- this.$$host = undefined;
76
+ this.$$host = parsedUrl.hostname;
74
77
 
75
78
  /**
76
79
  * The port, without ":"
77
80
  * @type {number}
78
81
  */
79
- this.$$port = undefined;
82
+ this.$$port =
83
+ toInt(parsedUrl.port) || DEFAULT_PORTS[parsedUrl.protocol] || null;
80
84
 
81
85
  /**
82
86
  * The pathname, beginning with "/"
@@ -359,7 +363,6 @@ export class LocationHtml5Url extends Location {
359
363
  super(appBase, appBaseNoFile);
360
364
  this.$$html5 = true;
361
365
  this.basePrefix = basePrefix || "";
362
- parseAbsoluteUrl(appBase, this);
363
366
  }
364
367
 
365
368
  /**
@@ -387,7 +390,7 @@ export class LocationHtml5Url extends Location {
387
390
  }
388
391
 
389
392
  $$normalizeUrl(url) {
390
- return this.appBaseNoFile + url.substr(1); // first char is always '/'
393
+ return this.appBaseNoFile + url.substring(1); // first char is always '/'
391
394
  }
392
395
 
393
396
  /**
@@ -442,10 +445,7 @@ export class LocationHtml5Url extends Location {
442
445
  export class LocationHashbangUrl extends Location {
443
446
  constructor(appBase, appBaseNoFile, hashPrefix) {
444
447
  super(appBase, appBaseNoFile);
445
- this.appBase = appBase;
446
- this.appBaseNoFile = appBaseNoFile;
447
448
  this.hashPrefix = hashPrefix;
448
- parseAbsoluteUrl(appBase, this);
449
449
  }
450
450
 
451
451
  /**
@@ -542,28 +542,26 @@ export class LocationHashbangUrl extends Location {
542
542
  }
543
543
  }
544
544
 
545
- export class LocationProvider {
546
- constructor() {
547
- this.hashPrefixValue = "!";
548
- this.html5ModeConfig = {
549
- enabled: false,
550
- requireBase: true,
551
- rewriteLinks: true,
552
- };
553
- }
545
+ export function LocationProvider() {
546
+ let hashPrefix = "!";
547
+ const html5Mode = {
548
+ enabled: false,
549
+ requireBase: true,
550
+ rewriteLinks: true,
551
+ };
554
552
 
555
553
  /**
556
554
  * The default value for the prefix is `'!'`.
557
- * @param {string=} prefix - Prefix for hash part (containing path and search)
558
- * @returns {string|LocationProvider} current value if used as getter or itself (chaining) if used as setter
555
+ * @param {string=} prefix Prefix for hash part (containing path and search)
556
+ * @returns {*} current value if used as getter or itself (chaining) if used as setter
559
557
  */
560
- hashPrefix(prefix) {
561
- if (typeof prefix !== "undefined") {
562
- this.hashPrefixValue = prefix;
558
+ this.hashPrefix = function (prefix) {
559
+ if (isDefined(prefix)) {
560
+ hashPrefix = prefix;
563
561
  return this;
564
562
  }
565
- return this.hashPrefixValue;
566
- }
563
+ return hashPrefix;
564
+ };
567
565
 
568
566
  /**
569
567
  * @param {(boolean|Object)=} mode If boolean, sets `html5Mode.enabled` to value.
@@ -585,29 +583,30 @@ export class LocationProvider {
585
583
  *
586
584
  * @returns {Object} html5Mode object if used as getter or itself (chaining) if used as setter
587
585
  */
588
- html5Mode(mode) {
589
- if (typeof mode === "boolean") {
590
- this.html5ModeConfig.enabled = mode;
586
+ this.html5Mode = function (mode) {
587
+ if (isBoolean(mode)) {
588
+ html5Mode.enabled = mode;
591
589
  return this;
592
590
  }
591
+ if (isObject(mode)) {
592
+ if (isBoolean(mode.enabled)) {
593
+ html5Mode.enabled = mode.enabled;
594
+ }
593
595
 
594
- if (typeof mode === "object") {
595
- if (typeof mode.enabled === "boolean")
596
- this.html5ModeConfig.enabled = mode.enabled;
597
- if (typeof mode.requireBase === "boolean")
598
- this.html5ModeConfig.requireBase = mode.requireBase;
599
- if (
600
- typeof mode.rewriteLinks === "boolean" ||
601
- typeof mode.rewriteLinks === "string"
602
- ) {
603
- this.html5ModeConfig.rewriteLinks = mode.rewriteLinks;
596
+ if (isBoolean(mode.requireBase)) {
597
+ html5Mode.requireBase = mode.requireBase;
604
598
  }
599
+
600
+ if (isBoolean(mode.rewriteLinks) || isString(mode.rewriteLinks)) {
601
+ html5Mode.rewriteLinks = mode.rewriteLinks;
602
+ }
603
+
605
604
  return this;
606
605
  }
607
- return this.html5ModeConfig;
608
- }
606
+ return html5Mode;
607
+ };
609
608
 
610
- $get = [
609
+ this.$get = [
611
610
  "$rootScope",
612
611
  "$browser",
613
612
  "$rootElement",
@@ -626,8 +625,8 @@ export class LocationProvider {
626
625
  const initialUrl = /** @type {string} */ ($browser.url());
627
626
  let appBase;
628
627
 
629
- if (this.html5Mode.enabled) {
630
- if (!baseHref && this.html5Mode.requireBase) {
628
+ if (html5Mode.enabled) {
629
+ if (!baseHref && html5Mode.requireBase) {
631
630
  throw $locationMinErr(
632
631
  "nobase",
633
632
  "$location in HTML5 mode requires a <base> tag to be present!",
@@ -641,11 +640,7 @@ export class LocationProvider {
641
640
  }
642
641
  const appBaseNoFile = stripFile(appBase);
643
642
 
644
- $location = new LocationMode(
645
- appBase,
646
- appBaseNoFile,
647
- `#${this.hashPrefix}`,
648
- );
643
+ $location = new LocationMode(appBase, appBaseNoFile, `#${hashPrefix}`);
649
644
  $location.$$parseLinkUrl(initialUrl, initialUrl);
650
645
 
651
646
  $location.$$state = $browser.state();
@@ -672,7 +667,7 @@ export class LocationProvider {
672
667
  }
673
668
 
674
669
  $rootElement.on("click", (event) => {
675
- const { rewriteLinks } = this.html5Mode;
670
+ const { rewriteLinks } = html5Mode;
676
671
  // TODO(vojta): rewrite link when opening in new tab/window (in legacy browser)
677
672
  // currently we open nice url link and redirect then
678
673
 
@@ -775,7 +770,7 @@ export class LocationProvider {
775
770
  });
776
771
 
777
772
  // update browser
778
- function browserUpdate() {
773
+ $rootScope.$watch(() => {
779
774
  if (initializing || $location.$$urlUpdatedByLocation) {
780
775
  $location.$$urlUpdatedByLocation = false;
781
776
 
@@ -823,9 +818,7 @@ export class LocationProvider {
823
818
 
824
819
  // we don't need to return anything because $evalAsync will make the digest loop dirty when
825
820
  // there is a change
826
- }
827
-
828
- setTimeout(() => browserUpdate());
821
+ });
829
822
 
830
823
  return $location;
831
824
 
@@ -837,7 +830,6 @@ export class LocationProvider {
837
830
  $location.$$state,
838
831
  oldState,
839
832
  );
840
- browserUpdate();
841
833
  }
842
834
  },
843
835
  ];
@@ -940,17 +932,17 @@ function startsWith(str, search) {
940
932
  */
941
933
  export function stripBaseUrl(base, url) {
942
934
  if (startsWith(url, base)) {
943
- return url.substr(base.length);
935
+ return url.substring(base.length);
944
936
  }
945
937
  }
946
938
 
947
939
  export function stripHash(url) {
948
940
  const index = url.indexOf("#");
949
- return index === -1 ? url : url.substr(0, index);
941
+ return index === -1 ? url : url.substring(0, index);
950
942
  }
951
943
 
952
944
  export function stripFile(url) {
953
- return url.substr(0, stripHash(url).lastIndexOf("/") + 1);
945
+ return url.substring(0, stripHash(url).lastIndexOf("/") + 1);
954
946
  }
955
947
 
956
948
  /* return the server only (scheme://host:port) */
@@ -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
  });
@@ -11,6 +11,7 @@
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
13
  <script type="module" src="/src/directive/events/event.spec.js"></script>
14
+ <script type="module" src="/src/directive/events/click.spec.js"></script>
14
15
  </head>
15
16
  <body>
16
17
  <div id="dummy"></div>
@@ -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
 
@@ -6,8 +6,11 @@ export function ngObserveDirective() {
6
6
  restrict: "A",
7
7
  link: (scope, element, attrs) => {
8
8
  const targetElement = element[0];
9
- const prop = targetElement.dataset["update"];
10
9
  const source = attrs["ngObserve"];
10
+ let prop = targetElement.dataset["update"];
11
+ if (!prop) {
12
+ prop = source;
13
+ }
11
14
 
12
15
  if (!scope[prop]) {
13
16
  scope[prop] = targetElement.getAttribute(source);
@@ -89,4 +89,25 @@ describe("observe", () => {
89
89
 
90
90
  expect(observerSpy.disconnect).toHaveBeenCalled();
91
91
  });
92
+
93
+ it("should observe attribute changes and update the same scope name if data-update attribute is absent", () => {
94
+ $scope.myProp = "";
95
+ const template = `<div ng-observe="test-attribute"></div>`;
96
+ element = $compile(template)($scope);
97
+ $scope.$digest();
98
+ spyOn($scope, "$digest").and.callThrough();
99
+
100
+ const mutationObserverCallback =
101
+ MutationObserver.calls.mostRecent().args[0];
102
+ const mutationRecord = {
103
+ target: element[0],
104
+ attributeName: "test-attribute",
105
+ };
106
+
107
+ element.attr("test-attribute", "newValue");
108
+ element[0].setAttribute("test-attribute", "newValue");
109
+
110
+ mutationObserverCallback([mutationRecord]);
111
+ expect($scope.$digest).toHaveBeenCalled();
112
+ });
92
113
  });
@@ -86,11 +86,7 @@
86
86
  <br />
87
87
 
88
88
  {{ activeid }}
89
- <fluent-tabs
90
- ng-observe="activeid"
91
- data-update="activeid"
92
- activeid="entrees"
93
- >
89
+ <fluent-tabs ng-observe="activeid" activeid="entrees">
94
90
  <fluent-tab id="apps">Appetizers</fluent-tab>
95
91
  <fluent-tab id="entrees">Entrees</fluent-tab>
96
92
  <fluent-tab id="desserts">Desserts</fluent-tab>
@@ -173,13 +169,9 @@
173
169
  </fluent-tab-panel>
174
170
  </fluent-tabs>
175
171
 
176
- {{ radio }}
172
+ {{ value }}
177
173
 
178
- <fluent-radio-group
179
- ng-observe="value"
180
- data-update="radio"
181
- orientation="vertical"
182
- >
174
+ <fluent-radio-group ng-observe="value" orientation="vertical">
183
175
  <fluent-radio value="1">18-24</fluent-radio>
184
176
  <fluent-radio value="2">25-33</fluent-radio>
185
177
  <fluent-radio value="3">34-44</fluent-radio>
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 {
@@ -51,7 +51,7 @@ export class ParamType {
51
51
  }
52
52
  $subPattern() {
53
53
  const sub = this.pattern.toString();
54
- return sub.substr(1, sub.length - 2);
54
+ return sub.substring(1, sub.length - 2);
55
55
  }
56
56
  toString() {
57
57
  return `{ParamType:${this.name}}`;
@@ -177,7 +177,7 @@ export class Ng1ViewConfig {
177
177
  ngViewName = relativeViewNameSugar[2]; // set view-name to "foo.bar"
178
178
  }
179
179
  if (ngViewName.charAt(0) === "!") {
180
- ngViewName = ngViewName.substr(1);
180
+ ngViewName = ngViewName.substring(1);
181
181
  ngViewContextAnchor = ""; // target absolutely from root
182
182
  }
183
183
  // handle parent relative targeting "^.^.^"
@@ -20,7 +20,7 @@ import { pattern, val } from "./hof";
20
20
  */
21
21
  export function maxLength(max, str) {
22
22
  if (str.length <= max) return str;
23
- return str.substr(0, max - 3) + "...";
23
+ return str.substring(0, max - 3) + "...";
24
24
  }
25
25
  /**
26
26
  * Returns a string, with spaces added to the end, up to a desired str length
@@ -46,7 +46,7 @@ export function functionToString(fn) {
46
46
  const toStr = namedFunctionMatch ? namedFunctionMatch[1] : fnStr;
47
47
  const fnName = fn["name"] || "";
48
48
  if (fnName && toStr.match(/function \(/)) {
49
- return "function " + fnName + toStr.substr(9);
49
+ return "function " + fnName + toStr.substring(9);
50
50
  }
51
51
  return toStr;
52
52
  }
@@ -97,7 +97,7 @@ export const beforeAfterSubstr = (char) => (str) => {
97
97
  if (!str) return ["", ""];
98
98
  const idx = str.indexOf(char);
99
99
  if (idx === -1) return [str, ""];
100
- return [str.substr(0, idx), str.substr(idx + 1)];
100
+ return [str.substring(0, idx), str.substring(idx + 1)];
101
101
  };
102
102
  export const hostRegex = new RegExp("^(?:[a-z]+:)?//[^/]+/");
103
103
  export const stripLastPathElement = (str) => str.replace(/\/[^/]*$/, "");
@@ -230,15 +230,13 @@ export class LocationHtml5Url extends Location {
230
230
  */
231
231
  export class LocationHashbangUrl extends Location {
232
232
  constructor(appBase: any, appBaseNoFile: any, hashPrefix: any);
233
- appBase: any;
234
- appBaseNoFile: any;
235
233
  hashPrefix: any;
236
234
  /**
237
235
  * Parse given hashbang URL into properties
238
236
  * @param {string} url Hashbang URL
239
237
  */
240
238
  $$parse(url: string): void;
241
- $$normalizeUrl(url: any): any;
239
+ $$normalizeUrl(url: any): string;
242
240
  /**
243
241
  * @param {string} url
244
242
  * @returns {boolean}