@angular-wave/angular.ts 0.4.4 → 0.4.6

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 (123) hide show
  1. package/Makefile +1 -0
  2. package/dist/angular-ts.esm.js +2 -2
  3. package/dist/angular-ts.umd.js +2 -12
  4. package/index.html +3 -74
  5. package/package.json +1 -1
  6. package/src/angular.spec.js +5 -0
  7. package/src/animations/animate-css.js +13 -5
  8. package/src/animations/animate-queue.js +21 -22
  9. package/src/animations/animate-runner.js +8 -4
  10. package/src/animations/animate.md +1 -1
  11. package/src/animations/animate.spec.js +21 -0
  12. package/src/animations/animation.js +1 -1
  13. package/src/binding.spec.js +1 -0
  14. package/src/core/compile/compile.js +25 -27
  15. package/src/core/compile/compile.spec.js +266 -17
  16. package/src/core/controller/controller.js +0 -2
  17. package/src/core/di/injector.md +1 -1
  18. package/src/core/di/injector.spec.js +2 -0
  19. package/src/core/di/internal-injector.js +1 -2
  20. package/src/core/interpolate/interpolate.js +12 -28
  21. package/src/core/interpolate/interpolate.spec.js +16 -70
  22. package/src/core/interval/interval-factory.js +50 -0
  23. package/src/core/interval/interval.html +18 -0
  24. package/src/core/interval/interval.js +77 -0
  25. package/src/core/interval/interval.md +123 -0
  26. package/src/core/interval/interval.spec.js +280 -0
  27. package/src/core/interval/interval.test.js +1 -1
  28. package/src/core/location/location.js +53 -59
  29. package/src/core/location/location.spec.js +27 -27
  30. package/src/core/on.spec.js +7 -0
  31. package/src/core/parse/interpreter.js +7 -10
  32. package/src/core/parse/parse.js +5 -26
  33. package/src/core/parse/parse.spec.js +91 -95
  34. package/src/core/prop.spec.js +60 -4
  35. package/src/core/q/q.html +18 -0
  36. package/src/core/q/q.js +472 -0
  37. package/src/core/q/q.md +211 -0
  38. package/src/core/q/q.spec.js +2748 -0
  39. package/src/core/q/q.test.js +12 -0
  40. package/src/core/sce/sce.spec.js +8 -0
  41. package/src/core/{model/model.html → scope/scope.html} +1 -1
  42. package/src/core/scope/scope.js +16 -15
  43. package/src/core/scope/scope.spec.js +1959 -24
  44. package/src/core/scope/scope.test.js +12 -0
  45. package/src/core/timeout/timeout.html +18 -0
  46. package/src/core/timeout/timeout.js +109 -0
  47. package/src/core/timeout/timeout.spec.js +354 -0
  48. package/src/core/timeout/timout.test.js +12 -0
  49. package/src/core/url-utils/url-utils.spec.js +1 -1
  50. package/src/directive/aria/aria.js +6 -3
  51. package/src/directive/aria/aria.spec.js +87 -0
  52. package/src/directive/attrs/attrs.spec.js +5 -0
  53. package/src/directive/attrs/boolean.spec.js +15 -0
  54. package/src/directive/attrs/element-style.spec.js +8 -0
  55. package/src/directive/attrs/src.spec.js +7 -0
  56. package/src/directive/bind/bind.spec.js +33 -0
  57. package/src/directive/bind/bing-html.spec.js +3 -0
  58. package/src/directive/class/class.js +3 -3
  59. package/src/directive/class/class.spec.js +75 -9
  60. package/src/directive/controller/controller.spec.js +13 -0
  61. package/src/directive/events/click.spec.js +3 -0
  62. package/src/directive/events/event.spec.js +6 -0
  63. package/src/directive/events/events.html +1 -0
  64. package/src/directive/form/form.js +3 -2
  65. package/src/directive/form/form.spec.js +65 -0
  66. package/src/directive/if/if.spec.js +4 -0
  67. package/src/directive/include/include.spec.js +59 -8
  68. package/src/directive/init/init.js +2 -6
  69. package/src/directive/init/init.spec.js +2 -0
  70. package/src/directive/input/input.spec.js +136 -0
  71. package/src/directive/messages/messages.spec.js +35 -4
  72. package/src/directive/model/model.js +25 -18
  73. package/src/directive/model/model.spec.js +49 -2
  74. package/src/directive/model-options/model-options.spec.js +6 -0
  75. package/src/directive/non-bindable/non-bindable.spec.js +1 -0
  76. package/src/directive/observe/observe.js +5 -1
  77. package/src/directive/observe/observe.spec.js +22 -0
  78. package/src/directive/observe/test.html +3 -11
  79. package/src/directive/options/options.spec.js +34 -0
  80. package/src/directive/ref/href.spec.js +15 -0
  81. package/src/directive/repeat/repeat.spec.js +135 -8
  82. package/src/directive/script/script.spec.js +2 -0
  83. package/src/directive/select/select.js +3 -3
  84. package/src/directive/select/select.spec.js +96 -0
  85. package/src/directive/show-hide/show-hide.js +2 -2
  86. package/src/directive/show-hide/show-hide.spec.js +19 -8
  87. package/src/directive/style/style.spec.js +7 -0
  88. package/src/directive/switch/switch.spec.js +5 -5
  89. package/src/directive/validators/validators.spec.js +1 -0
  90. package/src/loader.js +1 -0
  91. package/src/public.js +10 -2
  92. package/src/router/common/coreservices.js +2 -0
  93. package/src/router/directives/state-directives.js +14 -6
  94. package/src/router/directives/state-directives.spec.js +83 -0
  95. package/src/router/directives/view-directive.js +13 -4
  96. package/src/router/directives/view-directive.spec.js +71 -25
  97. package/src/router/hooks/lazy-load.js +2 -2
  98. package/src/router/hooks/views.js +5 -3
  99. package/src/router/resolve/resolvable.js +6 -3
  100. package/src/router/resolve/resolve-context.js +2 -2
  101. package/src/router/state/state-service.js +4 -4
  102. package/src/router/state/state.spec.js +5 -2
  103. package/src/router/state/state.test.js +1 -1
  104. package/src/router/state/views.js +10 -7
  105. package/src/router/template-factory.js +6 -3
  106. package/src/router/template-factory.spec.js +4 -0
  107. package/src/router/transition/transition-hook.js +1 -1
  108. package/src/router/transition/transition.js +1 -1
  109. package/src/router/view-hook.spec.js +2 -2
  110. package/src/router/view-scroll.js +6 -4
  111. package/src/services/browser.js +5 -8
  112. package/src/services/http/http.js +9 -6
  113. package/src/services/http/http.spec.js +31 -30
  114. package/src/services/http/template-request.spec.js +10 -0
  115. package/src/services/http-backend/http-backend.spec.js +3 -3
  116. package/src/services/template-request.js +4 -2
  117. package/src/shared/common.js +2 -1
  118. package/types/core/location/location.d.ts +37 -34
  119. package/types/core/parse/parse.d.ts +0 -26
  120. package/types/core/scope/scope.d.ts +11 -11
  121. package/src/core/model/model.js +0 -944
  122. package/src/core/model/model.spec.js +0 -3012
  123. package/types/core/model/model.d.ts +0 -204
@@ -0,0 +1,280 @@
1
+ import { Angular } from "../../loader";
2
+ import { createInjector } from "../di/injector";
3
+ import { wait } from "../../shared/test-utils";
4
+
5
+ describe("$interval", () => {
6
+ let injector;
7
+ let $interval;
8
+ let $rootScope;
9
+ let errors;
10
+
11
+ beforeEach(() => {
12
+ errors = [];
13
+ window.angular = new Angular();
14
+ window.angular
15
+ .module("myModule", ["ng"])
16
+ .decorator("$exceptionHandler", () => {
17
+ return (exception) => {
18
+ errors.push(exception);
19
+ };
20
+ });
21
+ injector = createInjector(["myModule"]);
22
+
23
+ $interval = injector.get("$interval");
24
+ $rootScope = injector.get("$rootScope");
25
+ });
26
+
27
+ it("should run tasks repeatedly", async () => {
28
+ let counter = 0;
29
+ $interval(() => {
30
+ counter++;
31
+ }, 1);
32
+ expect(counter).toBe(0);
33
+ await wait(15);
34
+ expect(counter).toBeGreaterThanOrEqual(1);
35
+ });
36
+
37
+ it("should call $apply after each task is executed", (done) => {
38
+ const applySpy = spyOn($rootScope, "$apply").and.callThrough();
39
+
40
+ $interval(() => {}, 1);
41
+ expect(applySpy).not.toHaveBeenCalled();
42
+
43
+ setTimeout(() => {
44
+ expect(applySpy).toHaveBeenCalled();
45
+ }, 3);
46
+
47
+ applySpy.calls.reset();
48
+
49
+ $interval(() => {}, 1);
50
+ $interval(() => {}, 1);
51
+
52
+ setTimeout(() => {
53
+ expect(applySpy).toHaveBeenCalledTimes(3);
54
+ done();
55
+ }, 1);
56
+ });
57
+
58
+ it("should allow you to specify a number of iterations", async () => {
59
+ let counter = 0;
60
+ $interval(
61
+ () => {
62
+ counter++;
63
+ },
64
+ 1,
65
+ 2,
66
+ );
67
+
68
+ await wait(15);
69
+ expect(counter).toBe(2);
70
+ });
71
+
72
+ it("should allow you to specify a number of arguments", (done) => {
73
+ const task1 = jasmine.createSpy("task1");
74
+ const task2 = jasmine.createSpy("task2");
75
+ const task3 = jasmine.createSpy("task3");
76
+ $interval(task1, 1, 2, true, "Task1");
77
+ $interval(task2, 1, 2, true, "Task2");
78
+ $interval(task3, 1, 2, true, "I", "am", "a", "Task3", "spy");
79
+
80
+ setTimeout(() => {
81
+ expect(task1).toHaveBeenCalledWith("Task1");
82
+ expect(task2).toHaveBeenCalledWith("Task2");
83
+ expect(task3).toHaveBeenCalledWith("I", "am", "a", "Task3", "spy");
84
+ }, 1);
85
+
86
+ task1.calls.reset();
87
+ task2.calls.reset();
88
+ task3.calls.reset();
89
+
90
+ setTimeout(() => {
91
+ expect(task1).toHaveBeenCalledWith("Task1");
92
+ expect(task2).toHaveBeenCalledWith("Task2");
93
+ expect(task3).toHaveBeenCalledWith("I", "am", "a", "Task3", "spy");
94
+ done();
95
+ }, 1);
96
+ });
97
+
98
+ it("should return a promise which will be updated with the count on each iteration", async () => {
99
+ const log = [];
100
+ const promise = $interval(() => {
101
+ log.push("tick");
102
+ }, 1);
103
+
104
+ promise.then(
105
+ (value) => {
106
+ log.push(`promise success: ${value}`);
107
+ },
108
+ (err) => {
109
+ log.push(`promise error: ${err}`);
110
+ },
111
+ (note) => {
112
+ log.push(`promise update: ${note}`);
113
+ },
114
+ );
115
+ expect(log).toEqual([]);
116
+
117
+ await wait(5);
118
+ expect(log[0]).toEqual("tick");
119
+ expect(log[1]).toEqual("tick");
120
+ });
121
+
122
+ it("should return a promise which will be resolved after the specified number of iterations", async () => {
123
+ const log = [];
124
+ const promise = $interval(
125
+ () => {
126
+ log.push("tick");
127
+ },
128
+ 1,
129
+ 2,
130
+ );
131
+
132
+ promise.then(
133
+ (value) => {
134
+ log.push(`promise success: ${value}`);
135
+ },
136
+ (err) => {
137
+ log.push(`promise error: ${err}`);
138
+ },
139
+ );
140
+ expect(log).toEqual([]);
141
+ await wait(15);
142
+ expect(log).toEqual(["tick", "tick", "promise success: 2"]);
143
+ });
144
+
145
+ describe("exception handling", () => {
146
+ it("should delegate exception to the $exceptionHandler service", (done) => {
147
+ errors = [];
148
+ $interval(() => {
149
+ throw "Test Error";
150
+ }, 10);
151
+
152
+ setTimeout(() => {
153
+ expect(errors).toContain("Test Error");
154
+ done();
155
+ }, 20);
156
+ });
157
+
158
+ it("should call $apply even if an exception is thrown in callback", (done) => {
159
+ const applySpy = spyOn($rootScope, "$apply").and.callThrough();
160
+
161
+ $interval(() => {
162
+ throw "Test Error2";
163
+ }, 10);
164
+ expect(applySpy).not.toHaveBeenCalled();
165
+
166
+ setTimeout(() => {
167
+ expect(applySpy).toHaveBeenCalled();
168
+ done();
169
+ }, 11);
170
+ });
171
+ });
172
+
173
+ describe("cancel", () => {
174
+ it("should cancel tasks", (done) => {
175
+ const task1 = jasmine.createSpy("task1", 1);
176
+ const task2 = jasmine.createSpy("task2", 1);
177
+ const task3 = jasmine.createSpy("task3", 1);
178
+ let promise1;
179
+ let promise3;
180
+
181
+ promise1 = $interval(task1, 2);
182
+ $interval(task2, 1);
183
+ promise3 = $interval(task3, 3);
184
+
185
+ $interval.cancel(promise3);
186
+ $interval.cancel(promise1);
187
+ setTimeout(() => {
188
+ expect(task1).not.toHaveBeenCalled();
189
+ expect(task2).toHaveBeenCalled();
190
+ expect(task3).not.toHaveBeenCalled();
191
+ done();
192
+ }, 1);
193
+ });
194
+
195
+ it("should cancel the promise", (done) => {
196
+ const promise = $interval(() => {}, 1);
197
+ const log = [];
198
+ promise.then(
199
+ (value) => {
200
+ log.push(`promise success: ${value}`);
201
+ },
202
+ (err) => {
203
+ log.push(`promise error: ${err}`);
204
+ },
205
+ );
206
+ expect(log).toEqual([]);
207
+
208
+ setTimeout(() => {
209
+ $interval.cancel(promise);
210
+ }, 1);
211
+
212
+ setTimeout(() => {
213
+ $rootScope.$apply(); // For resolving the promise -
214
+ // necessary since q uses $rootScope.evalAsync.
215
+
216
+ expect(log).toEqual(["promise error: canceled"]);
217
+ done();
218
+ }, 2);
219
+ });
220
+
221
+ it("should return true if a task was successfully canceled", (done) => {
222
+ const task1 = jasmine.createSpy("task1");
223
+ const task2 = jasmine.createSpy("task2");
224
+ let promise1;
225
+ let promise2;
226
+
227
+ promise1 = $interval(task1, 1, 1);
228
+ setTimeout(() => {
229
+ promise2 = $interval(task2, 1, 1);
230
+
231
+ expect($interval.cancel(promise1)).toBe(false);
232
+ expect($interval.cancel(promise2)).toBe(true);
233
+ done();
234
+ }, 1);
235
+ });
236
+
237
+ it("should not throw an error when given an undefined promise", () => {
238
+ expect($interval.cancel()).toBe(false);
239
+ });
240
+
241
+ it("should throw an error when given a non-$interval promise", () => {
242
+ const promise = $interval(() => {}).then(() => {});
243
+ expect(() => {
244
+ $interval.cancel(promise);
245
+ }).toThrowError(/badprom/);
246
+ });
247
+
248
+ it("should not trigger digest when cancelled", () => {
249
+ const watchSpy = jasmine.createSpy("watchSpy");
250
+ $rootScope.$watch(watchSpy);
251
+
252
+ const t = $interval();
253
+ $interval.cancel(t);
254
+ expect(watchSpy).not.toHaveBeenCalled();
255
+ });
256
+ });
257
+
258
+ describe("$window delegation", () => {
259
+ it("should use $window.setInterval instead of the global function", () => {
260
+ const setIntervalSpy = spyOn(window, "setInterval");
261
+
262
+ $interval(() => {}, 1);
263
+ expect(setIntervalSpy).toHaveBeenCalled();
264
+ });
265
+
266
+ it("should use $window.clearInterval instead of the global function", (done) => {
267
+ const clearIntervalSpy = spyOn(window, "clearInterval");
268
+
269
+ $interval(() => {}, 1, 1);
270
+ setTimeout(() => {
271
+ expect(clearIntervalSpy).toHaveBeenCalled();
272
+
273
+ clearIntervalSpy.calls.reset();
274
+ $interval.cancel($interval(() => {}, 1));
275
+ expect(clearIntervalSpy).toHaveBeenCalled();
276
+ done();
277
+ }, 1);
278
+ });
279
+ });
280
+ });
@@ -5,7 +5,7 @@ const TEST_URL = "src/core/interval/interval.html";
5
5
  test("unit tests contain no errors", async ({ page }) => {
6
6
  await page.goto(TEST_URL);
7
7
  await page.content();
8
- await page.waitForTimeout(100);
8
+ await page.waitForTimeout(500);
9
9
  await expect(page.locator(".jasmine-overall-result")).toHaveText(
10
10
  /0 failures/,
11
11
  );
@@ -2,7 +2,6 @@ import { JQLite } from "../../shared/jqlite/jqlite";
2
2
  import { urlResolve } from "../url-utils/url-utils";
3
3
  import {
4
4
  encodeUriSegment,
5
- isBoolean,
6
5
  isDefined,
7
6
  isNumber,
8
7
  isObject,
@@ -13,6 +12,7 @@ import {
13
12
  toInt,
14
13
  toKeyValue,
15
14
  } from "../../shared/utils";
15
+ import { ScopePhase } from "../scope/scope";
16
16
 
17
17
  /**
18
18
  * @typedef {Object} DefaultPorts
@@ -42,6 +42,8 @@ export class Location {
42
42
  * @param {string} appBaseNoFile application base URL stripped of any filename
43
43
  */
44
44
  constructor(appBase, appBaseNoFile) {
45
+ const parsedUrl = urlResolve(appBase);
46
+
45
47
  /** @type {string} */
46
48
  this.appBase = appBase;
47
49
 
@@ -67,16 +69,17 @@ export class Location {
67
69
  this.$$replace = false;
68
70
 
69
71
  /** @type {import('../url-utils/url-utils').HttpProtocol} */
70
- this.$$protocol = undefined;
72
+ this.$$protocol = parsedUrl.protocol;
71
73
 
72
74
  /** @type {string} */
73
- this.$$host = undefined;
75
+ this.$$host = parsedUrl.hostname;
74
76
 
75
77
  /**
76
78
  * The port, without ":"
77
79
  * @type {number}
78
80
  */
79
- this.$$port = undefined;
81
+ this.$$port =
82
+ toInt(parsedUrl.port) || DEFAULT_PORTS[parsedUrl.protocol] || null;
80
83
 
81
84
  /**
82
85
  * The pathname, beginning with "/"
@@ -329,7 +332,6 @@ export class Location {
329
332
  // so the modification window is narrow.
330
333
  this.$$state = isUndefined(state) ? null : state;
331
334
  this.$$urlUpdatedByLocation = true;
332
-
333
335
  return this;
334
336
  }
335
337
 
@@ -360,7 +362,6 @@ export class LocationHtml5Url extends Location {
360
362
  super(appBase, appBaseNoFile);
361
363
  this.$$html5 = true;
362
364
  this.basePrefix = basePrefix || "";
363
- parseAbsoluteUrl(appBase, this);
364
365
  }
365
366
 
366
367
  /**
@@ -443,10 +444,7 @@ export class LocationHtml5Url extends Location {
443
444
  export class LocationHashbangUrl extends Location {
444
445
  constructor(appBase, appBaseNoFile, hashPrefix) {
445
446
  super(appBase, appBaseNoFile);
446
- this.appBase = appBase;
447
- this.appBaseNoFile = appBaseNoFile;
448
447
  this.hashPrefix = hashPrefix;
449
- parseAbsoluteUrl(appBase, this);
450
448
  }
451
449
 
452
450
  /**
@@ -543,26 +541,28 @@ export class LocationHashbangUrl extends Location {
543
541
  }
544
542
  }
545
543
 
546
- export function LocationProvider() {
547
- let hashPrefix = "!";
548
- const html5Mode = {
549
- enabled: false,
550
- requireBase: true,
551
- rewriteLinks: true,
552
- };
544
+ export class LocationProvider {
545
+ constructor() {
546
+ this.hashPrefixValue = "!";
547
+ this.html5ModeConfig = {
548
+ enabled: false,
549
+ requireBase: true,
550
+ rewriteLinks: true,
551
+ };
552
+ }
553
553
 
554
554
  /**
555
555
  * The default value for the prefix is `'!'`.
556
- * @param {string=} prefix Prefix for hash part (containing path and search)
557
- * @returns {*} current value if used as getter or itself (chaining) if used as setter
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
558
558
  */
559
- this.hashPrefix = function (prefix) {
560
- if (isDefined(prefix)) {
561
- hashPrefix = prefix;
559
+ hashPrefix(prefix) {
560
+ if (typeof prefix !== "undefined") {
561
+ this.hashPrefixValue = prefix;
562
562
  return this;
563
563
  }
564
- return hashPrefix;
565
- };
564
+ return this.hashPrefixValue;
565
+ }
566
566
 
567
567
  /**
568
568
  * @param {(boolean|Object)=} mode If boolean, sets `html5Mode.enabled` to value.
@@ -584,30 +584,29 @@ export function LocationProvider() {
584
584
  *
585
585
  * @returns {Object} html5Mode object if used as getter or itself (chaining) if used as setter
586
586
  */
587
- this.html5Mode = function (mode) {
588
- if (isBoolean(mode)) {
589
- html5Mode.enabled = mode;
587
+ html5Mode(mode) {
588
+ if (typeof mode === "boolean") {
589
+ this.html5ModeConfig.enabled = mode;
590
590
  return this;
591
591
  }
592
- if (isObject(mode)) {
593
- if (isBoolean(mode.enabled)) {
594
- html5Mode.enabled = mode.enabled;
595
- }
596
-
597
- if (isBoolean(mode.requireBase)) {
598
- html5Mode.requireBase = mode.requireBase;
599
- }
600
592
 
601
- if (isBoolean(mode.rewriteLinks) || isString(mode.rewriteLinks)) {
602
- html5Mode.rewriteLinks = mode.rewriteLinks;
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
+ if (
599
+ typeof mode.rewriteLinks === "boolean" ||
600
+ typeof mode.rewriteLinks === "string"
601
+ ) {
602
+ this.html5ModeConfig.rewriteLinks = mode.rewriteLinks;
603
603
  }
604
-
605
604
  return this;
606
605
  }
607
- return html5Mode;
608
- };
606
+ return this.html5ModeConfig;
607
+ }
609
608
 
610
- this.$get = [
609
+ $get = [
611
610
  "$rootScope",
612
611
  "$browser",
613
612
  "$rootElement",
@@ -626,8 +625,8 @@ export function LocationProvider() {
626
625
  const initialUrl = /** @type {string} */ ($browser.url());
627
626
  let appBase;
628
627
 
629
- if (html5Mode.enabled) {
630
- if (!baseHref && html5Mode.requireBase) {
628
+ if (this.html5Mode.enabled) {
629
+ if (!baseHref && this.html5Mode.requireBase) {
631
630
  throw $locationMinErr(
632
631
  "nobase",
633
632
  "$location in HTML5 mode requires a <base> tag to be present!",
@@ -641,7 +640,11 @@ export function LocationProvider() {
641
640
  }
642
641
  const appBaseNoFile = stripFile(appBase);
643
642
 
644
- $location = new LocationMode(appBase, appBaseNoFile, `#${hashPrefix}`);
643
+ $location = new LocationMode(
644
+ appBase,
645
+ appBaseNoFile,
646
+ `#${this.hashPrefix}`,
647
+ );
645
648
  $location.$$parseLinkUrl(initialUrl, initialUrl);
646
649
 
647
650
  $location.$$state = $browser.state();
@@ -668,7 +671,7 @@ export function LocationProvider() {
668
671
  }
669
672
 
670
673
  $rootElement.on("click", (event) => {
671
- const { rewriteLinks } = html5Mode;
674
+ const { rewriteLinks } = this.html5Mode;
672
675
  // TODO(vojta): rewrite link when opening in new tab/window (in legacy browser)
673
676
  // currently we open nice url link and redirect then
674
677
 
@@ -767,10 +770,11 @@ export function LocationProvider() {
767
770
  afterLocationChange(oldUrl, oldState);
768
771
  }
769
772
  });
773
+ if ($rootScope.$$phase === ScopePhase.NONE) $rootScope.$digest();
770
774
  });
771
775
 
772
776
  // update browser
773
- $rootScope.$watch(() => {
777
+ function browserUpdate() {
774
778
  if (initializing || $location.$$urlUpdatedByLocation) {
775
779
  $location.$$urlUpdatedByLocation = false;
776
780
 
@@ -818,7 +822,9 @@ export function LocationProvider() {
818
822
 
819
823
  // we don't need to return anything because $evalAsync will make the digest loop dirty when
820
824
  // there is a change
821
- });
825
+ }
826
+
827
+ setTimeout(() => browserUpdate());
822
828
 
823
829
  return $location;
824
830
 
@@ -830,6 +836,7 @@ export function LocationProvider() {
830
836
  $location.$$state,
831
837
  oldState,
832
838
  );
839
+ browserUpdate();
833
840
  }
834
841
  },
835
842
  ];
@@ -882,19 +889,6 @@ function normalizePath(pathValue, searchValue, hashValue) {
882
889
  return path + (search ? `?${search}` : "") + hash;
883
890
  }
884
891
 
885
- /**
886
- * @param {string} absoluteUrl
887
- * @param {Location} locationObj
888
- */
889
- function parseAbsoluteUrl(absoluteUrl, locationObj) {
890
- const parsedUrl = urlResolve(absoluteUrl);
891
-
892
- locationObj.$$protocol = parsedUrl.protocol;
893
- locationObj.$$host = parsedUrl.hostname;
894
- locationObj.$$port =
895
- toInt(parsedUrl.port) || DEFAULT_PORTS[parsedUrl.protocol] || null;
896
- }
897
-
898
892
  function parseAppUrl(url, locationObj, html5Mode) {
899
893
  if (/^\s*[\\/]{2,}/.test(url)) {
900
894
  throw $locationMinErr("badpath", 'Invalid url "{0}".', url);