@angular-wave/angular.ts 0.0.1

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 (231) hide show
  1. package/.eslintignore +1 -0
  2. package/.eslintrc.cjs +29 -0
  3. package/.github/workflows/playwright.yml +27 -0
  4. package/CHANGELOG.md +17974 -0
  5. package/CODE_OF_CONDUCT.md +3 -0
  6. package/CONTRIBUTING.md +246 -0
  7. package/DEVELOPERS.md +488 -0
  8. package/LICENSE +22 -0
  9. package/Makefile +31 -0
  10. package/README.md +115 -0
  11. package/RELEASE.md +98 -0
  12. package/SECURITY.md +16 -0
  13. package/TRIAGING.md +135 -0
  14. package/css/angular.css +22 -0
  15. package/dist/angular-ts.cjs.js +36843 -0
  16. package/dist/angular-ts.esm.js +36841 -0
  17. package/dist/angular-ts.umd.js +36848 -0
  18. package/dist/build/angular-animate.js +4272 -0
  19. package/dist/build/angular-aria.js +426 -0
  20. package/dist/build/angular-message-format.js +1072 -0
  21. package/dist/build/angular-messages.js +829 -0
  22. package/dist/build/angular-mocks.js +3757 -0
  23. package/dist/build/angular-parse-ext.js +1275 -0
  24. package/dist/build/angular-resource.js +911 -0
  25. package/dist/build/angular-route.js +1266 -0
  26. package/dist/build/angular-sanitize.js +891 -0
  27. package/dist/build/angular-touch.js +368 -0
  28. package/dist/build/angular.js +36600 -0
  29. package/e2e/unit.spec.ts +15 -0
  30. package/images/android-chrome-192x192.png +0 -0
  31. package/images/android-chrome-512x512.png +0 -0
  32. package/images/apple-touch-icon.png +0 -0
  33. package/images/favicon-16x16.png +0 -0
  34. package/images/favicon-32x32.png +0 -0
  35. package/images/favicon.ico +0 -0
  36. package/images/site.webmanifest +1 -0
  37. package/index.html +104 -0
  38. package/package.json +47 -0
  39. package/playwright.config.ts +78 -0
  40. package/public/circle.html +1 -0
  41. package/public/my_child_directive.html +1 -0
  42. package/public/my_directive.html +1 -0
  43. package/public/my_other_directive.html +1 -0
  44. package/public/test.html +1 -0
  45. package/rollup.config.js +31 -0
  46. package/src/animations/animateCache.js +55 -0
  47. package/src/animations/animateChildrenDirective.js +105 -0
  48. package/src/animations/animateCss.js +1139 -0
  49. package/src/animations/animateCssDriver.js +291 -0
  50. package/src/animations/animateJs.js +367 -0
  51. package/src/animations/animateJsDriver.js +67 -0
  52. package/src/animations/animateQueue.js +851 -0
  53. package/src/animations/animation.js +506 -0
  54. package/src/animations/module.js +779 -0
  55. package/src/animations/ngAnimateSwap.js +119 -0
  56. package/src/animations/rafScheduler.js +50 -0
  57. package/src/animations/shared.js +378 -0
  58. package/src/constants.js +20 -0
  59. package/src/core/animate.js +845 -0
  60. package/src/core/animateCss.js +73 -0
  61. package/src/core/animateRunner.js +195 -0
  62. package/src/core/attributes.js +199 -0
  63. package/src/core/cache.js +45 -0
  64. package/src/core/compile.js +4727 -0
  65. package/src/core/controller.js +225 -0
  66. package/src/core/exceptionHandler.js +63 -0
  67. package/src/core/filter.js +146 -0
  68. package/src/core/interpolate.js +442 -0
  69. package/src/core/interval.js +188 -0
  70. package/src/core/intervalFactory.js +57 -0
  71. package/src/core/location.js +1086 -0
  72. package/src/core/parser/parse.js +2562 -0
  73. package/src/core/parser/parse.md +13 -0
  74. package/src/core/q.js +746 -0
  75. package/src/core/rootScope.js +1596 -0
  76. package/src/core/sanitizeUri.js +85 -0
  77. package/src/core/sce.js +1161 -0
  78. package/src/core/taskTrackerFactory.js +125 -0
  79. package/src/core/timeout.js +121 -0
  80. package/src/core/urlUtils.js +187 -0
  81. package/src/core/utils.js +1349 -0
  82. package/src/directive/a.js +37 -0
  83. package/src/directive/attrs.js +283 -0
  84. package/src/directive/bind.js +51 -0
  85. package/src/directive/bind.md +142 -0
  86. package/src/directive/change.js +12 -0
  87. package/src/directive/change.md +25 -0
  88. package/src/directive/cloak.js +12 -0
  89. package/src/directive/cloak.md +24 -0
  90. package/src/directive/events.js +75 -0
  91. package/src/directive/events.md +166 -0
  92. package/src/directive/form.js +725 -0
  93. package/src/directive/init.js +15 -0
  94. package/src/directive/init.md +41 -0
  95. package/src/directive/input.js +1783 -0
  96. package/src/directive/list.js +46 -0
  97. package/src/directive/list.md +22 -0
  98. package/src/directive/ngClass.js +249 -0
  99. package/src/directive/ngController.js +64 -0
  100. package/src/directive/ngCsp.js +82 -0
  101. package/src/directive/ngIf.js +134 -0
  102. package/src/directive/ngInclude.js +217 -0
  103. package/src/directive/ngModel.js +1356 -0
  104. package/src/directive/ngModelOptions.js +509 -0
  105. package/src/directive/ngOptions.js +670 -0
  106. package/src/directive/ngRef.js +90 -0
  107. package/src/directive/ngRepeat.js +650 -0
  108. package/src/directive/ngShowHide.js +255 -0
  109. package/src/directive/ngSwitch.js +178 -0
  110. package/src/directive/ngTransclude.js +98 -0
  111. package/src/directive/non-bindable.js +11 -0
  112. package/src/directive/non-bindable.md +17 -0
  113. package/src/directive/script.js +30 -0
  114. package/src/directive/select.js +624 -0
  115. package/src/directive/style.js +25 -0
  116. package/src/directive/style.md +23 -0
  117. package/src/directive/validators.js +329 -0
  118. package/src/exts/aria.js +544 -0
  119. package/src/exts/messages.js +852 -0
  120. package/src/filters/filter.js +207 -0
  121. package/src/filters/filter.md +69 -0
  122. package/src/filters/filters.js +239 -0
  123. package/src/filters/json.md +16 -0
  124. package/src/filters/limit-to.js +43 -0
  125. package/src/filters/limit-to.md +19 -0
  126. package/src/filters/order-by.js +183 -0
  127. package/src/filters/order-by.md +83 -0
  128. package/src/index.js +13 -0
  129. package/src/injector.js +1034 -0
  130. package/src/jqLite.js +1117 -0
  131. package/src/loader.js +1320 -0
  132. package/src/public.js +215 -0
  133. package/src/routeToRegExp.js +41 -0
  134. package/src/services/anchorScroll.js +135 -0
  135. package/src/services/browser.js +321 -0
  136. package/src/services/cacheFactory.js +398 -0
  137. package/src/services/cookieReader.js +72 -0
  138. package/src/services/document.js +64 -0
  139. package/src/services/http.js +1537 -0
  140. package/src/services/httpBackend.js +206 -0
  141. package/src/services/log.js +160 -0
  142. package/src/services/templateRequest.js +139 -0
  143. package/test/angular.spec.js +2153 -0
  144. package/test/aria/aria.spec.js +1245 -0
  145. package/test/binding.spec.js +504 -0
  146. package/test/build-test.html +14 -0
  147. package/test/injector.spec.js +2327 -0
  148. package/test/jasmine/jasmine-5.1.2/boot0.js +65 -0
  149. package/test/jasmine/jasmine-5.1.2/boot1.js +133 -0
  150. package/test/jasmine/jasmine-5.1.2/jasmine-html.js +963 -0
  151. package/test/jasmine/jasmine-5.1.2/jasmine.css +320 -0
  152. package/test/jasmine/jasmine-5.1.2/jasmine.js +10824 -0
  153. package/test/jasmine/jasmine-5.1.2/jasmine_favicon.png +0 -0
  154. package/test/jasmine/jasmine-browser.json +17 -0
  155. package/test/jasmine/jasmine.json +9 -0
  156. package/test/jqlite.spec.js +2133 -0
  157. package/test/loader.spec.js +219 -0
  158. package/test/messages/messages.spec.js +1146 -0
  159. package/test/min-err.spec.js +174 -0
  160. package/test/mock-test.html +13 -0
  161. package/test/module-test.html +15 -0
  162. package/test/ng/anomate.spec.js +606 -0
  163. package/test/ng/cache-factor.spec.js +334 -0
  164. package/test/ng/compile.spec.js +17956 -0
  165. package/test/ng/controller-provider.spec.js +227 -0
  166. package/test/ng/cookie-reader.spec.js +98 -0
  167. package/test/ng/directive/a.spec.js +192 -0
  168. package/test/ng/directive/bind.spec.js +334 -0
  169. package/test/ng/directive/boolean.spec.js +136 -0
  170. package/test/ng/directive/change.spec.js +71 -0
  171. package/test/ng/directive/class.spec.js +858 -0
  172. package/test/ng/directive/click.spec.js +38 -0
  173. package/test/ng/directive/cloak.spec.js +44 -0
  174. package/test/ng/directive/constoller.spec.js +194 -0
  175. package/test/ng/directive/element-style.spec.js +92 -0
  176. package/test/ng/directive/event.spec.js +282 -0
  177. package/test/ng/directive/form.spec.js +1518 -0
  178. package/test/ng/directive/href.spec.js +143 -0
  179. package/test/ng/directive/if.spec.js +402 -0
  180. package/test/ng/directive/include.spec.js +828 -0
  181. package/test/ng/directive/init.spec.js +68 -0
  182. package/test/ng/directive/input.spec.js +3810 -0
  183. package/test/ng/directive/list.spec.js +170 -0
  184. package/test/ng/directive/model-options.spec.js +1008 -0
  185. package/test/ng/directive/model.spec.js +1905 -0
  186. package/test/ng/directive/non-bindable.spec.js +55 -0
  187. package/test/ng/directive/options.spec.js +3583 -0
  188. package/test/ng/directive/ref.spec.js +575 -0
  189. package/test/ng/directive/repeat.spec.js +1675 -0
  190. package/test/ng/directive/script.spec.js +52 -0
  191. package/test/ng/directive/scrset.spec.js +67 -0
  192. package/test/ng/directive/select.spec.js +2541 -0
  193. package/test/ng/directive/show-hide.spec.js +253 -0
  194. package/test/ng/directive/src.spec.js +157 -0
  195. package/test/ng/directive/style.spec.js +178 -0
  196. package/test/ng/directive/switch.spec.js +647 -0
  197. package/test/ng/directive/validators.spec.js +717 -0
  198. package/test/ng/document.spec.js +52 -0
  199. package/test/ng/filter/filter.spec.js +714 -0
  200. package/test/ng/filter/filters.spec.js +35 -0
  201. package/test/ng/filter/limit-to.spec.js +251 -0
  202. package/test/ng/filter/order-by.spec.js +891 -0
  203. package/test/ng/filter.spec.js +149 -0
  204. package/test/ng/http-backend.spec.js +398 -0
  205. package/test/ng/http.spec.js +4071 -0
  206. package/test/ng/interpolate.spec.js +642 -0
  207. package/test/ng/interval.spec.js +343 -0
  208. package/test/ng/location.spec.js +3488 -0
  209. package/test/ng/on.spec.js +229 -0
  210. package/test/ng/parse.spec.js +4655 -0
  211. package/test/ng/prop.spec.js +805 -0
  212. package/test/ng/q.spec.js +2904 -0
  213. package/test/ng/root-element.spec.js +16 -0
  214. package/test/ng/sanitize-uri.spec.js +249 -0
  215. package/test/ng/sce.spec.js +660 -0
  216. package/test/ng/scope.spec.js +3442 -0
  217. package/test/ng/template-request.spec.js +236 -0
  218. package/test/ng/timeout.spec.js +351 -0
  219. package/test/ng/url-utils.spec.js +156 -0
  220. package/test/ng/utils.spec.js +144 -0
  221. package/test/original-test.html +21 -0
  222. package/test/public.spec.js +34 -0
  223. package/test/sanitize/bing-html.spec.js +36 -0
  224. package/test/server/express.js +158 -0
  225. package/test/test-utils.js +11 -0
  226. package/tsconfig.json +17 -0
  227. package/types/angular.d.ts +138 -0
  228. package/types/global.d.ts +9 -0
  229. package/types/index.d.ts +2357 -0
  230. package/types/jqlite.d.ts +558 -0
  231. package/vite.config.js +14 -0
@@ -0,0 +1,660 @@
1
+ import { createInjector } from "../../src/injector";
2
+
3
+ import { publishExternalAPI } from "../../src/public";
4
+ import { adjustMatcher } from "../../src/core/sce";
5
+
6
+ describe("SCE", () => {
7
+ let $sce, $rootScope;
8
+ let sceDelegateProvider;
9
+ let logs = [];
10
+
11
+ describe("when disabled", () => {
12
+ beforeEach(function () {
13
+ publishExternalAPI();
14
+ createInjector([
15
+ "ng",
16
+ function ($sceProvider) {
17
+ $sceProvider.enabled(false);
18
+ },
19
+ ]).invoke((_$sce_) => {
20
+ $sce = _$sce_;
21
+ });
22
+ });
23
+
24
+ it("should provide the getter for enabled", () => {
25
+ expect($sce.isEnabled()).toBe(false);
26
+ });
27
+
28
+ it("should not wrap/unwrap any value or throw exception on non-string values", () => {
29
+ const originalValue = { foo: "bar" };
30
+ expect($sce.trustAs($sce.JS, originalValue)).toBe(originalValue);
31
+ expect($sce.getTrusted($sce.JS, originalValue)).toBe(originalValue);
32
+ });
33
+ });
34
+
35
+ describe("when enabled", () => {
36
+ beforeEach(function () {
37
+ publishExternalAPI();
38
+ createInjector([
39
+ "ng",
40
+ function ($sceProvider) {
41
+ $sceProvider.enabled(true);
42
+ },
43
+ ]).invoke((_$sce_) => {
44
+ $sce = _$sce_;
45
+ });
46
+ });
47
+
48
+ it("should wrap string values with TrustedValueHolder", () => {
49
+ const originalValue = "original_value";
50
+ let wrappedValue = $sce.trustAs($sce.HTML, originalValue);
51
+ expect(typeof wrappedValue).toBe("object");
52
+ expect($sce.getTrusted($sce.HTML, wrappedValue)).toBe("original_value");
53
+ expect(() => {
54
+ $sce.getTrusted($sce.CSS, wrappedValue);
55
+ }).toThrowError(/unsafe/);
56
+ wrappedValue = $sce.trustAs($sce.CSS, originalValue);
57
+ expect(typeof wrappedValue).toBe("object");
58
+ expect($sce.getTrusted($sce.CSS, wrappedValue)).toBe("original_value");
59
+ expect(() => {
60
+ $sce.getTrusted($sce.HTML, wrappedValue);
61
+ }).toThrowError(/unsafe/);
62
+ wrappedValue = $sce.trustAs($sce.URL, originalValue);
63
+ expect(typeof wrappedValue).toBe("object");
64
+ expect($sce.getTrusted($sce.URL, wrappedValue)).toBe("original_value");
65
+ wrappedValue = $sce.trustAs($sce.JS, originalValue);
66
+ expect(typeof wrappedValue).toBe("object");
67
+ expect($sce.getTrusted($sce.JS, wrappedValue)).toBe("original_value");
68
+ });
69
+
70
+ it("should NOT wrap non-string values", () => {
71
+ expect(() => {
72
+ $sce.trustAsCss(123);
73
+ }).toThrowError(/itype/);
74
+ });
75
+
76
+ it("should NOT wrap unknown contexts", () => {
77
+ expect(() => {
78
+ $sce.trustAs("unknown1", "123");
79
+ }).toThrowError(/icontext/);
80
+ });
81
+
82
+ it("should NOT wrap undefined context", () => {
83
+ expect(() => {
84
+ $sce.trustAs(undefined, "123");
85
+ }).toThrowError(/icontext/);
86
+ });
87
+
88
+ it("should wrap undefined into undefined", () => {
89
+ expect($sce.trustAsHtml(undefined)).toBeUndefined();
90
+ });
91
+
92
+ it("should unwrap undefined into undefined", () => {
93
+ expect($sce.getTrusted($sce.HTML, undefined)).toBeUndefined();
94
+ });
95
+
96
+ it("should wrap null into null", () => {
97
+ expect($sce.trustAsHtml(null)).toBe(null);
98
+ });
99
+
100
+ it("should unwrap null into null", () => {
101
+ expect($sce.getTrusted($sce.HTML, null)).toBe(null);
102
+ });
103
+
104
+ it('should wrap "" into ""', () => {
105
+ expect($sce.trustAsHtml("")).toBe("");
106
+ });
107
+
108
+ it('should unwrap "" into ""', () => {
109
+ expect($sce.getTrusted($sce.HTML, "")).toBe("");
110
+ });
111
+
112
+ it("should unwrap values and return the original", () => {
113
+ const originalValue = "originalValue";
114
+ const wrappedValue = $sce.trustAs($sce.HTML, originalValue);
115
+ expect($sce.getTrusted($sce.HTML, wrappedValue)).toBe(originalValue);
116
+ });
117
+
118
+ it("should NOT unwrap values when the type is different", () => {
119
+ const originalValue = "originalValue";
120
+ const wrappedValue = $sce.trustAs($sce.HTML, originalValue);
121
+ expect(() => {
122
+ $sce.getTrusted($sce.CSS, wrappedValue);
123
+ }).toThrowError(/unsafe/);
124
+ });
125
+
126
+ it("should NOT unwrap values that had not been wrapped", () => {
127
+ function TrustedValueHolder(trustedValue) {
128
+ this.$unwrapTrustedValue = function () {
129
+ return trustedValue;
130
+ };
131
+ }
132
+ const wrappedValue = new TrustedValueHolder("originalValue");
133
+ expect(() => $sce.getTrusted($sce.HTML, wrappedValue)).toThrowError(
134
+ /unsafe/,
135
+ );
136
+ });
137
+
138
+ it("should implement toString on trusted values", () => {
139
+ const originalValue = "123";
140
+ const wrappedValue = $sce.trustAsHtml(originalValue);
141
+ expect($sce.getTrustedHtml(wrappedValue)).toBe(originalValue);
142
+ expect(wrappedValue.toString()).toBe(originalValue.toString());
143
+ });
144
+ });
145
+
146
+ describe("replace $sceDelegate", () => {
147
+ it("should override the default $sce.trustAs/valueOf/etc.", () => {
148
+ publishExternalAPI();
149
+ createInjector([
150
+ "ng",
151
+ function ($provide) {
152
+ $provide.value("$sceDelegate", {
153
+ trustAs(type, value) {
154
+ return `wrapped:${value}`;
155
+ },
156
+ getTrusted(type, value) {
157
+ return `unwrapped:${value}`;
158
+ },
159
+ valueOf(value) {
160
+ return `valueOf:${value}`;
161
+ },
162
+ });
163
+ },
164
+ ]).invoke((_$sce_) => {
165
+ $sce = _$sce_;
166
+ });
167
+
168
+ expect($sce.trustAsJs("value")).toBe("wrapped:value");
169
+ expect($sce.valueOf("value")).toBe("valueOf:value");
170
+ expect($sce.getTrustedJs("value")).toBe("unwrapped:value");
171
+ expect($sce.parseAsJs("name")({ name: "chirayu" })).toBe(
172
+ "unwrapped:chirayu",
173
+ );
174
+ });
175
+ });
176
+
177
+ describe("$sce.parseAs", () => {
178
+ beforeEach(function () {
179
+ createInjector(["ng"]).invoke((_$sce_, _$rootScope_) => {
180
+ $sce = _$sce_;
181
+ $rootScope = _$rootScope_;
182
+ });
183
+ logs = [];
184
+ });
185
+
186
+ it("should parse constant literals as trusted", () => {
187
+ expect($sce.parseAsJs("1")()).toBe(1);
188
+ expect($sce.parseAsJs("1", $sce.ANY)()).toBe(1);
189
+ expect($sce.parseAsJs("1", $sce.HTML)()).toBe(1);
190
+ expect($sce.parseAsJs("1", "UNDEFINED")()).toBe(1);
191
+ expect($sce.parseAsJs("true")()).toBe(true);
192
+ expect($sce.parseAsJs("false")()).toBe(false);
193
+ expect($sce.parseAsJs("null")()).toBe(null);
194
+ expect($sce.parseAsJs("undefined")()).toBeUndefined();
195
+ expect($sce.parseAsJs('"string"')()).toBe("string");
196
+ });
197
+
198
+ it("should be possible to do one-time binding on a non-concatenable context", () => {
199
+ $rootScope.$watch($sce.parseAsHtml("::foo"), (value) => {
200
+ logs.push(`${value}`);
201
+ });
202
+
203
+ $rootScope.$digest();
204
+ expect(logs[0]).toEqual("undefined"); // initial listener call
205
+
206
+ $rootScope.foo = $sce.trustAs($sce.HTML, "trustedValue");
207
+ expect($rootScope.$$watchers.length).toBe(1);
208
+ $rootScope.$digest();
209
+
210
+ expect($rootScope.$$watchers.length).toBe(0);
211
+ expect(logs[1]).toEqual("trustedValue");
212
+
213
+ $rootScope.foo = $sce.trustAs($sce.HTML, "anotherTrustedValue");
214
+ $rootScope.$digest();
215
+ expect(logs[2]).toBeUndefined(); // watcher no longer active
216
+ });
217
+
218
+ it("should be possible to do one-time binding on a concatenable context", () => {
219
+ $rootScope.$watch($sce.parseAsUrl("::foo"), (value) => {
220
+ logs.push(`${value}`);
221
+ });
222
+
223
+ $rootScope.$digest();
224
+ expect(logs[0]).toEqual("undefined"); // initial listener call
225
+
226
+ $rootScope.foo = $sce.trustAs($sce.URL, "trustedValue");
227
+ expect($rootScope.$$watchers.length).toBe(1);
228
+ $rootScope.$digest();
229
+
230
+ expect($rootScope.$$watchers.length).toBe(0);
231
+ expect(logs[1]).toEqual("trustedValue");
232
+
233
+ $rootScope.foo = $sce.trustAs($sce.URL, "anotherTrustedValue");
234
+ $rootScope.$digest();
235
+ expect(logs[2]).toBeUndefined(); // watcher no longer active
236
+ });
237
+
238
+ it("should NOT parse constant non-literals", () => {
239
+ // Until there's a real world use case for this, we're disallowing
240
+ // constant non-literals. See $SceParseProvider.
241
+ const exprFn = $sce.parseAsJs("1+1");
242
+ expect(exprFn).toThrow();
243
+ });
244
+
245
+ it("should NOT return untrusted values from expression function", () => {
246
+ const exprFn = $sce.parseAs($sce.HTML, "foo");
247
+ expect(() => exprFn({}, { foo: true })).toThrowError(/unsafe/);
248
+ });
249
+
250
+ it("should NOT return trusted values of the wrong type from expression function", () => {
251
+ const exprFn = $sce.parseAs($sce.HTML, "foo");
252
+ expect(() =>
253
+ exprFn({}, { foo: $sce.trustAs($sce.JS, "123") }),
254
+ ).toThrowError(/unsafe/);
255
+ });
256
+
257
+ it("should return trusted values from expression function", () => {
258
+ const exprFn = $sce.parseAs($sce.HTML, "foo");
259
+ expect(exprFn({}, { foo: $sce.trustAs($sce.HTML, "trustedValue") })).toBe(
260
+ "trustedValue",
261
+ );
262
+ });
263
+
264
+ it("should support shorthand methods", () => {
265
+ // Test shorthand parse methods.
266
+ expect($sce.parseAsHtml("1")()).toBe(1);
267
+ // Test short trustAs methods.
268
+ expect($sce.trustAsAny).toBeUndefined();
269
+ expect(() => {
270
+ // mismatched types.
271
+ $sce.parseAsCss("foo")({}, { foo: $sce.trustAsHtml("1") });
272
+ }).toThrowError(/unsafe/);
273
+ });
274
+ });
275
+
276
+ describe("$sceDelegate resource url policies", () => {
277
+ beforeEach(() => {
278
+ createInjector([
279
+ "ng",
280
+ ($sceDelegateProvider) => {
281
+ sceDelegateProvider = $sceDelegateProvider;
282
+ },
283
+ ]).invoke((_$sce_) => {
284
+ $sce = _$sce_;
285
+ });
286
+ });
287
+
288
+ it('should default to "self" which allows relative urls', () => {
289
+ expect($sce.getTrustedResourceUrl("foo/bar")).toEqual("foo/bar");
290
+ });
291
+
292
+ it("should reject everything when trusted resource URL list is empty", () => {
293
+ sceDelegateProvider.trustedResourceUrlList([]);
294
+ sceDelegateProvider.bannedResourceUrlList([]);
295
+ expect(() => {
296
+ $sce.getTrustedResourceUrl("#");
297
+ }).toThrowError(/insecurl/);
298
+ });
299
+
300
+ it("should match against normalized urls", () => {
301
+ sceDelegateProvider.trustedResourceUrlList([/^foo$/]);
302
+ sceDelegateProvider.bannedResourceUrlList([]);
303
+ expect(() => {
304
+ $sce.getTrustedResourceUrl("foo");
305
+ }).toThrowError(/insecurl/);
306
+ });
307
+
308
+ it("should not accept unknown matcher type", () => {
309
+ expect(() => {
310
+ sceDelegateProvider.trustedResourceUrlList([{}]);
311
+ }).toThrowError(/imatcher/);
312
+ });
313
+
314
+ describe("adjustMatcher", () => {
315
+ /* global adjustMatcher: false */
316
+ it("should rewrite regex into regex and add ^ & $ on either end", () => {
317
+ expect(adjustMatcher(/a.*b/).exec("a.b")).not.toBeNull();
318
+ expect(adjustMatcher(/a.*b/).exec("-a.b-")).toBeNull();
319
+ // Adding ^ & $ onto a regex that already had them should also work.
320
+ expect(adjustMatcher(/^a.*b$/).exec("a.b")).not.toBeNull();
321
+ expect(adjustMatcher(/^a.*b$/).exec("-a.b-")).toBeNull();
322
+ });
323
+
324
+ it("should should match * and **", () => {
325
+ expect(
326
+ adjustMatcher("*://*.example.com/**").exec(
327
+ "http://www.example.com/path",
328
+ ),
329
+ ).not.toBeNull();
330
+ });
331
+ });
332
+
333
+ describe("regex matcher", () => {
334
+ beforeEach(() => {
335
+ createInjector([
336
+ "ng",
337
+ ($sceDelegateProvider) => {
338
+ sceDelegateProvider = $sceDelegateProvider;
339
+ },
340
+ ]).invoke((_$sce_) => {
341
+ $sce = _$sce_;
342
+ });
343
+ });
344
+
345
+ it("should support custom regex", () => {
346
+ sceDelegateProvider.trustedResourceUrlList([
347
+ /^http:\/\/example\.com\/.*/,
348
+ ]);
349
+ sceDelegateProvider.bannedResourceUrlList([]);
350
+ expect($sce.getTrustedResourceUrl("http://example.com/foo")).toEqual(
351
+ "http://example.com/foo",
352
+ );
353
+ // must match entire regex
354
+ expect(() => {
355
+ $sce.getTrustedResourceUrl("https://example.com/foo");
356
+ }).toThrowError(/insecurl/);
357
+ // https doesn't match (mismatched protocol.)
358
+ expect(() => {
359
+ $sce.getTrustedResourceUrl("https://example.com/foo");
360
+ }).toThrowError(/insecurl/);
361
+ });
362
+
363
+ it("should match entire regex", () => {
364
+ sceDelegateProvider.trustedResourceUrlList([
365
+ /https?:\/\/example\.com\/foo/,
366
+ ]);
367
+ sceDelegateProvider.bannedResourceUrlList([]);
368
+ expect($sce.getTrustedResourceUrl("http://example.com/foo")).toEqual(
369
+ "http://example.com/foo",
370
+ );
371
+ expect($sce.getTrustedResourceUrl("https://example.com/foo")).toEqual(
372
+ "https://example.com/foo",
373
+ );
374
+ expect(() => {
375
+ $sce.getTrustedResourceUrl("http://example.com/fo");
376
+ }).toThrowError(/insecurl/);
377
+ // Suffix not allowed even though original regex does not contain an ending $.
378
+ expect(() => {
379
+ $sce.getTrustedResourceUrl("http://example.com/foo2");
380
+ }).toThrowError(/insecurl/);
381
+ // Prefix not allowed even though original regex does not contain a leading ^.
382
+ expect(() => {
383
+ $sce.getTrustedResourceUrl("xhttp://example.com/foo");
384
+ }).toThrowError(/insecurl/);
385
+ });
386
+ });
387
+
388
+ describe("string matchers", () => {
389
+ beforeEach(() => {
390
+ createInjector([
391
+ "ng",
392
+ ($sceDelegateProvider) => {
393
+ sceDelegateProvider = $sceDelegateProvider;
394
+ },
395
+ ]).invoke((_$sce_) => {
396
+ $sce = _$sce_;
397
+ });
398
+ });
399
+
400
+ it("should support strings as matchers", () => {
401
+ sceDelegateProvider.trustedResourceUrlList(["http://example.com/foo"]);
402
+ sceDelegateProvider.bannedResourceUrlList([]);
403
+ expect($sce.getTrustedResourceUrl("http://example.com/foo")).toEqual(
404
+ "http://example.com/foo",
405
+ );
406
+ // "." is not a special character like in a regex.
407
+ expect(() => {
408
+ $sce.getTrustedResourceUrl("http://example-com/foo");
409
+ }).toThrowError(/insecurl/);
410
+ // You can match a prefix.
411
+ expect(() => {
412
+ $sce.getTrustedResourceUrl("http://example.com/foo2");
413
+ }).toThrowError(/insecurl/);
414
+ // You can match a suffix.
415
+ expect(() => {
416
+ $sce.getTrustedResourceUrl("xhttp://example.com/foo");
417
+ }).toThrowError(/insecurl/);
418
+ });
419
+
420
+ it("should support the * wildcard", () => {
421
+ sceDelegateProvider.trustedResourceUrlList(["http://example.com/foo*"]);
422
+ sceDelegateProvider.bannedResourceUrlList([]);
423
+ expect($sce.getTrustedResourceUrl("http://example.com/foo")).toEqual(
424
+ "http://example.com/foo",
425
+ );
426
+ // The * wildcard should match extra characters.
427
+ expect(
428
+ $sce.getTrustedResourceUrl("http://example.com/foo-bar"),
429
+ ).toEqual("http://example.com/foo-bar");
430
+ // The * wildcard does not match ':'
431
+ expect(() => {
432
+ $sce.getTrustedResourceUrl("http://example-com/foo:bar");
433
+ }).toThrowError(/insecurl/);
434
+ // The * wildcard does not match '/'
435
+ expect(() => {
436
+ $sce.getTrustedResourceUrl("http://example-com/foo/bar");
437
+ }).toThrowError(/insecurl/);
438
+ // The * wildcard does not match '.'
439
+ expect(() => {
440
+ $sce.getTrustedResourceUrl("http://example-com/foo.bar");
441
+ }).toThrowError(/insecurl/);
442
+ // The * wildcard does not match '?'
443
+ expect(() => {
444
+ $sce.getTrustedResourceUrl("http://example-com/foo?bar");
445
+ }).toThrowError(/insecurl/);
446
+ // The * wildcard does not match '&'
447
+ expect(() => {
448
+ $sce.getTrustedResourceUrl("http://example-com/foo&bar");
449
+ }).toThrowError(/insecurl/);
450
+ // The * wildcard does not match ';'
451
+ expect(() => {
452
+ $sce.getTrustedResourceUrl("http://example-com/foo;bar");
453
+ }).toThrowError(/insecurl/);
454
+ });
455
+
456
+ it("should support the ** wildcard", () => {
457
+ sceDelegateProvider.trustedResourceUrlList([
458
+ "http://example.com/foo**",
459
+ ]);
460
+ sceDelegateProvider.bannedResourceUrlList([]);
461
+ expect($sce.getTrustedResourceUrl("http://example.com/foo")).toEqual(
462
+ "http://example.com/foo",
463
+ );
464
+ // The ** wildcard should match extra characters.
465
+ expect(
466
+ $sce.getTrustedResourceUrl("http://example.com/foo-bar"),
467
+ ).toEqual("http://example.com/foo-bar");
468
+ // The ** wildcard accepts the ':/.?&' characters.
469
+ expect(
470
+ $sce.getTrustedResourceUrl("http://example.com/foo:1/2.3?4&5-6"),
471
+ ).toEqual("http://example.com/foo:1/2.3?4&5-6");
472
+ });
473
+
474
+ it("should not accept *** in the string", () => {
475
+ expect(() => {
476
+ sceDelegateProvider.trustedResourceUrlList(["http://***"]);
477
+ }).toThrowError(/iwcard/);
478
+ });
479
+ });
480
+
481
+ describe('"self" matcher', () => {
482
+ beforeEach(() => {
483
+ createInjector([
484
+ "ng",
485
+ ($sceDelegateProvider) => {
486
+ sceDelegateProvider = $sceDelegateProvider;
487
+ },
488
+ ]).invoke((_$sce_) => {
489
+ $sce = _$sce_;
490
+ });
491
+ });
492
+
493
+ it('should support the special string "self" in trusted resource URL list', () => {
494
+ sceDelegateProvider.trustedResourceUrlList(["self"]);
495
+ sceDelegateProvider.bannedResourceUrlList([]);
496
+ expect($sce.getTrustedResourceUrl("foo")).toEqual("foo");
497
+ });
498
+
499
+ it('should support the special string "self" in baneed resource URL list', () => {
500
+ sceDelegateProvider.trustedResourceUrlList([/.*/]);
501
+ sceDelegateProvider.bannedResourceUrlList(["self"]);
502
+ expect(() => {
503
+ $sce.getTrustedResourceUrl("foo");
504
+ }).toThrowError(/insecurl/);
505
+ });
506
+
507
+ describe("when the document base URL has changed", () => {
508
+ beforeEach(() => {
509
+ createInjector([
510
+ "ng",
511
+ ($sceDelegateProvider) => {
512
+ sceDelegateProvider = $sceDelegateProvider;
513
+ sceDelegateProvider.trustedResourceUrlList(["self"]);
514
+ sceDelegateProvider.bannedResourceUrlList([]);
515
+ },
516
+ ]).invoke((_$sce_) => {
517
+ $sce = _$sce_;
518
+ });
519
+ });
520
+
521
+ let baseElem;
522
+ beforeEach(() => {
523
+ baseElem = window.document.createElement("BASE");
524
+ baseElem.setAttribute(
525
+ "href",
526
+ `${window.location.protocol}//foo.example.com/path/`,
527
+ );
528
+ window.document.head.appendChild(baseElem);
529
+ });
530
+
531
+ afterEach(() => {
532
+ window.document.head.removeChild(baseElem);
533
+ });
534
+
535
+ it("should allow relative URLs", () => {
536
+ expect($sce.getTrustedResourceUrl("foo")).toEqual("foo");
537
+ });
538
+
539
+ it("should allow absolute URLs", () => {
540
+ expect($sce.getTrustedResourceUrl("//foo.example.com/bar")).toEqual(
541
+ "//foo.example.com/bar",
542
+ );
543
+ });
544
+
545
+ it("should still block some URLs", () => {
546
+ expect(() => {
547
+ $sce.getTrustedResourceUrl("//bad.example.com");
548
+ }).toThrowError(/insecurl/);
549
+ });
550
+ });
551
+ it("should have the banned resource URL list override the trusted resource URL list", () => {
552
+ sceDelegateProvider.trustedResourceUrlList(["self"]);
553
+ sceDelegateProvider.bannedResourceUrlList(["self"]);
554
+ expect(() => {
555
+ $sce.getTrustedResourceUrl("foo");
556
+ }).toThrowError(/insecurl/);
557
+ });
558
+
559
+ it("should support multiple items in both lists", () => {
560
+ sceDelegateProvider.trustedResourceUrlList([
561
+ /^http:\/\/example.com\/1$/,
562
+ /^http:\/\/example.com\/2$/,
563
+ /^http:\/\/example.com\/3$/,
564
+ "self",
565
+ ]);
566
+ sceDelegateProvider.bannedResourceUrlList([
567
+ /^http:\/\/example.com\/3$/,
568
+ /.*\/open_redirect/,
569
+ ]);
570
+ expect($sce.getTrustedResourceUrl("same_domain")).toEqual(
571
+ "same_domain",
572
+ );
573
+ expect($sce.getTrustedResourceUrl("http://example.com/1")).toEqual(
574
+ "http://example.com/1",
575
+ );
576
+ expect($sce.getTrustedResourceUrl("http://example.com/2")).toEqual(
577
+ "http://example.com/2",
578
+ );
579
+ expect(() => {
580
+ $sce.getTrustedResourceUrl("http://example.com/3");
581
+ }).toThrowError(/insecurl/);
582
+ expect(() => {
583
+ $sce.getTrustedResourceUrl("open_redirect");
584
+ }).toThrowError(/insecurl/);
585
+ });
586
+ });
587
+
588
+ describe("URL-context sanitization", () => {
589
+ it("should sanitize values that are not found in the trusted resource URL list", () => {
590
+ expect($sce.getTrustedMediaUrl("javascript:foo")).toEqual(
591
+ "unsafe:javascript:foo",
592
+ );
593
+ expect($sce.getTrustedUrl("javascript:foo")).toEqual(
594
+ "unsafe:javascript:foo",
595
+ );
596
+ });
597
+
598
+ it("should not sanitize values that are found in the trusted resource URL list", () => {
599
+ expect($sce.getTrustedMediaUrl("http://example.com")).toEqual(
600
+ "http://example.com",
601
+ );
602
+ expect($sce.getTrustedUrl("http://example.com")).toEqual(
603
+ "http://example.com",
604
+ );
605
+ });
606
+
607
+ it("should not sanitize trusted values", () => {
608
+ expect(
609
+ $sce.getTrustedMediaUrl($sce.trustAsMediaUrl("javascript:foo")),
610
+ ).toEqual("javascript:foo");
611
+ expect(
612
+ $sce.getTrustedMediaUrl($sce.trustAsUrl("javascript:foo")),
613
+ ).toEqual("javascript:foo");
614
+ expect(
615
+ $sce.getTrustedMediaUrl($sce.trustAsResourceUrl("javascript:foo")),
616
+ ).toEqual("javascript:foo");
617
+
618
+ expect(
619
+ $sce.getTrustedUrl($sce.trustAsMediaUrl("javascript:foo")),
620
+ ).toEqual("unsafe:javascript:foo");
621
+ expect($sce.getTrustedUrl($sce.trustAsUrl("javascript:foo"))).toEqual(
622
+ "javascript:foo",
623
+ );
624
+ expect(
625
+ $sce.getTrustedUrl($sce.trustAsResourceUrl("javascript:foo")),
626
+ ).toEqual("javascript:foo");
627
+ });
628
+
629
+ it("should use the $$sanitizeUri", () => {
630
+ const $$sanitizeUri = jasmine
631
+ .createSpy("$$sanitizeUri")
632
+ .and.returnValue("someSanitizedUrl");
633
+ // module(($provide) => {
634
+ // $provide.value("$$sanitizeUri", $$sanitizeUri);
635
+ // });
636
+ () => {
637
+ expect($sce.getTrustedMediaUrl("someUrl")).toEqual(
638
+ "someSanitizedUrl",
639
+ );
640
+ expect($$sanitizeUri).toHaveBeenCalledOnceWith("someUrl", true);
641
+
642
+ $$sanitizeUri.calls.reset();
643
+
644
+ expect($sce.getTrustedUrl("someUrl")).toEqual("someSanitizedUrl");
645
+ expect($$sanitizeUri).toHaveBeenCalledOnceWith("someUrl", false);
646
+ };
647
+ });
648
+ });
649
+
650
+ describe("sanitizing html", () => {
651
+ describe("when $sanitize is NOT available", () => {
652
+ it("should throw an exception for getTrusted(string) values", () => {
653
+ expect(() => {
654
+ $sce.getTrustedHtml("<b></b>");
655
+ }).toThrowError(/unsafe/);
656
+ });
657
+ });
658
+ });
659
+ });
660
+ });