@angular-wave/angular.ts 0.9.4 → 0.9.5

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 (645) hide show
  1. package/@types/index.d.ts +1 -84
  2. package/{src/index.ts → @types/namespace.d.ts} +4 -24
  3. package/@types/router/template-factory.d.ts +2 -2
  4. package/dist/angular-ts.esm.js +3 -3
  5. package/dist/angular-ts.umd.js +3 -3
  6. package/dist/angular-ts.umd.min.js +1 -1
  7. package/package.json +8 -1
  8. package/.github/workflows/ci.yml +0 -104
  9. package/.github/workflows/gh-pages.yml +0 -75
  10. package/.husky/pre-commit +0 -5
  11. package/.prettierignore +0 -9
  12. package/CHANGELOG.md +0 -17667
  13. package/CODE_OF_CONDUCT.md +0 -3
  14. package/CONTRIBUTING.md +0 -247
  15. package/DEVELOPERS.md +0 -499
  16. package/Makefile +0 -60
  17. package/RELEASE.md +0 -86
  18. package/TRIAGING.md +0 -127
  19. package/docs/.cspell.yml +0 -8
  20. package/docs/.github/dependabot.yml +0 -14
  21. package/docs/.nvmrc +0 -1
  22. package/docs/CONTRIBUTING.md +0 -28
  23. package/docs/Dockerfile +0 -4
  24. package/docs/LICENSE +0 -201
  25. package/docs/README.md +0 -217
  26. package/docs/assets/icons/logo.svg +0 -1
  27. package/docs/assets/scss/_variables_project.scss +0 -12
  28. package/docs/assets/scss/_variables_project_after_bs.scss +0 -8
  29. package/docs/assets/scss/index.scss +0 -48
  30. package/docs/config.yaml +0 -15
  31. package/docs/content/_index.md +0 -28
  32. package/docs/content/docs/_index.md +0 -61
  33. package/docs/content/docs/directive/_index.md +0 -4
  34. package/docs/content/docs/directive/app.md +0 -11
  35. package/docs/content/docs/directive/aria.md +0 -0
  36. package/docs/content/docs/directive/bind.md +0 -72
  37. package/docs/content/docs/directive/blur.md +0 -38
  38. package/docs/content/docs/directive/channel.md +0 -37
  39. package/docs/content/docs/directive/class-even.md +0 -47
  40. package/docs/content/docs/directive/class-odd.md +0 -48
  41. package/docs/content/docs/directive/class.md +0 -64
  42. package/docs/content/docs/directive/click.md +0 -41
  43. package/docs/content/docs/directive/cloak.md +0 -74
  44. package/docs/content/docs/directive/copy.md +0 -38
  45. package/docs/content/docs/directive/cut.md +0 -40
  46. package/docs/content/docs/directive/dblclick.md +0 -41
  47. package/docs/content/docs/directive/focus.md +0 -38
  48. package/docs/content/docs/directive/get.md +0 -203
  49. package/docs/content/docs/directive/include.md +0 -7
  50. package/docs/content/docs/directive/keydown.md +0 -38
  51. package/docs/content/docs/directive/keyup.md +0 -38
  52. package/docs/content/docs/directive/load.md +0 -43
  53. package/docs/content/docs/directive/mousedown.md +0 -38
  54. package/docs/content/docs/directive/mouseenter.md +0 -38
  55. package/docs/content/docs/directive/mouseleave.md +0 -38
  56. package/docs/content/docs/directive/mousemove.md +0 -38
  57. package/docs/content/docs/directive/mouseout.md +0 -38
  58. package/docs/content/docs/directive/mouseover.md +0 -38
  59. package/docs/content/docs/directive/mouseup.md +0 -38
  60. package/docs/content/docs/directive/non-bindable.md +0 -28
  61. package/docs/content/docs/filter/_index.md +0 -4
  62. package/docs/content/docs/filter/filter.md +0 -78
  63. package/docs/content/docs/filter/json.md +0 -19
  64. package/docs/content/docs/filter/limit-to.md +0 -30
  65. package/docs/content/docs/filter/order-by.md +0 -123
  66. package/docs/content/docs/provider/_index.md +0 -4
  67. package/docs/content/docs/provider/eventBusProvider.md +0 -35
  68. package/docs/content/docs/provider/locationProvider.md +0 -26
  69. package/docs/content/docs/provider/logProvider.md +0 -59
  70. package/docs/content/docs/provider/sceProvider.md +0 -194
  71. package/docs/content/docs/provider/templateCacheProvider.md +0 -100
  72. package/docs/content/docs/provider/templateRequestProvider.md +0 -5
  73. package/docs/content/docs/service/_index.md +0 -4
  74. package/docs/content/docs/service/compile.md +0 -5
  75. package/docs/content/docs/service/controller.md +0 -5
  76. package/docs/content/docs/service/eventBus.md +0 -56
  77. package/docs/content/docs/service/http.md +0 -161
  78. package/docs/content/docs/service/interpolation.md +0 -5
  79. package/docs/content/docs/service/location.md +0 -57
  80. package/docs/content/docs/service/log.md +0 -113
  81. package/docs/content/docs/service/parse.md +0 -5
  82. package/docs/content/docs/service/rootElement.md +0 -5
  83. package/docs/content/docs/service/rootScope.md +0 -5
  84. package/docs/content/docs/service/sce.md +0 -194
  85. package/docs/content/docs/service/templateCache.md +0 -64
  86. package/docs/content/docs/service/templateRequest.md +0 -5
  87. package/docs/content/docs/service/url.md +0 -5
  88. package/docs/content/docs/values/_index.md +0 -4
  89. package/docs/content/docs/values/document.md +0 -29
  90. package/docs/content/docs/values/window.md +0 -29
  91. package/docs/docker-compose.yaml +0 -12
  92. package/docs/docsy.work +0 -5
  93. package/docs/docsy.work.sum +0 -0
  94. package/docs/go.mod +0 -5
  95. package/docs/go.sum +0 -6
  96. package/docs/hugo-disabled.toml +0 -220
  97. package/docs/hugo.yaml +0 -200
  98. package/docs/layouts/404.html +0 -13
  99. package/docs/layouts/_markup/render-heading.html +0 -1
  100. package/docs/layouts/partials/hooks/head-end.html +0 -3
  101. package/docs/layouts/shortcodes/showcss.html +0 -2
  102. package/docs/layouts/shortcodes/showhtml.html +0 -2
  103. package/docs/layouts/shortcodes/showjs.html +0 -2
  104. package/docs/layouts/shortcodes/showraw.html +0 -1
  105. package/docs/layouts/shortcodes/version.html +0 -1
  106. package/docs/package-lock.json +0 -2293
  107. package/docs/package.json +0 -53
  108. package/docs/static/examples/counter/counter-test.html +0 -13
  109. package/docs/static/examples/counter/counter.html +0 -5
  110. package/docs/static/examples/counter/counter.test.js +0 -28
  111. package/docs/static/examples/document/document.html +0 -3
  112. package/docs/static/examples/eventbus/eventbus-test.html +0 -15
  113. package/docs/static/examples/eventbus/eventbus.html +0 -13
  114. package/docs/static/examples/eventbus/eventbus.js +0 -15
  115. package/docs/static/examples/eventbus/eventbus.test.js +0 -19
  116. package/docs/static/examples/i18n/i18n.html +0 -77
  117. package/docs/static/examples/ng-bind/ng-bind.html +0 -9
  118. package/docs/static/examples/ng-blur/ng-blur.html +0 -9
  119. package/docs/static/examples/ng-channel/ng-channel-test.html +0 -17
  120. package/docs/static/examples/ng-channel/ng-channel.html +0 -24
  121. package/docs/static/examples/ng-channel/ng-channel.test.js +0 -31
  122. package/docs/static/examples/ng-class/ng-class.html +0 -71
  123. package/docs/static/examples/ng-class-even/ng-class-even.html +0 -8
  124. package/docs/static/examples/ng-class-odd/ng-class-odd.html +0 -8
  125. package/docs/static/examples/ng-click/ng-click.html +0 -6
  126. package/docs/static/examples/ng-copy/ng-copy.html +0 -6
  127. package/docs/static/examples/ng-cut/ng-cut.html +0 -6
  128. package/docs/static/examples/ng-dblclick/ng-dblclick.html +0 -10
  129. package/docs/static/examples/ng-focus/ng-focus.html +0 -9
  130. package/docs/static/examples/ng-keydown/ng-keydown.html +0 -9
  131. package/docs/static/examples/ng-keyup/ng-keyup.html +0 -9
  132. package/docs/static/examples/ng-load/ng-load.html +0 -8
  133. package/docs/static/examples/ng-mousedown/ng-mousedown.html +0 -6
  134. package/docs/static/examples/ng-mouseenter/ng-mouseenter.html +0 -4
  135. package/docs/static/examples/ng-mouseleave/ng-mouseleave.html +0 -4
  136. package/docs/static/examples/ng-mousemove/ng-mousemove.html +0 -4
  137. package/docs/static/examples/ng-mouseout/ng-mouseout.html +0 -4
  138. package/docs/static/examples/ng-mouseover/ng-mouseover.html +0 -4
  139. package/docs/static/examples/ng-mouseup/ng-mouseup.html +0 -4
  140. package/docs/static/examples/ng-non-bindable/ng-non-bindable-test.html +0 -13
  141. package/docs/static/examples/ng-non-bindable/ng-non-bindable.html +0 -3
  142. package/docs/static/examples/ng-non-bindable/ng-non-bindable.test.js +0 -11
  143. package/docs/static/examples/window/window.html +0 -4
  144. package/docs/static/typedoc/.nojekyll +0 -1
  145. package/docs/static/typedoc/assets/hierarchy.js +0 -1
  146. package/docs/static/typedoc/assets/highlight.css +0 -29
  147. package/docs/static/typedoc/assets/icons.js +0 -18
  148. package/docs/static/typedoc/assets/icons.svg +0 -1
  149. package/docs/static/typedoc/assets/main.js +0 -60
  150. package/docs/static/typedoc/assets/navigation.js +0 -1
  151. package/docs/static/typedoc/assets/search.js +0 -1
  152. package/docs/static/typedoc/assets/style.css +0 -1633
  153. package/docs/static/typedoc/classes/Location.html +0 -55
  154. package/docs/static/typedoc/classes/LocationProvider.html +0 -20
  155. package/docs/static/typedoc/classes/LogProvider.html +0 -6
  156. package/docs/static/typedoc/classes/PubSub.html +0 -71
  157. package/docs/static/typedoc/classes/PubSubProvider.html +0 -4
  158. package/docs/static/typedoc/classes/TemplateCacheProvider.html +0 -5
  159. package/docs/static/typedoc/hierarchy.html +0 -1
  160. package/docs/static/typedoc/index.html +0 -1
  161. package/docs/static/typedoc/interfaces/DefaultPorts.html +0 -5
  162. package/docs/static/typedoc/interfaces/Html5Mode.html +0 -23
  163. package/docs/static/typedoc/interfaces/HttpHeadersGetter.html +0 -1
  164. package/docs/static/typedoc/interfaces/HttpProviderDefaults.html +0 -31
  165. package/docs/static/typedoc/interfaces/HttpRequestConfigHeaders.html +0 -6
  166. package/docs/static/typedoc/interfaces/HttpRequestTransformer.html +0 -1
  167. package/docs/static/typedoc/interfaces/HttpResponse.html +0 -7
  168. package/docs/static/typedoc/interfaces/HttpResponseTransformer.html +0 -1
  169. package/docs/static/typedoc/interfaces/HttpService.html +0 -38
  170. package/docs/static/typedoc/interfaces/LogService.html +0 -12
  171. package/docs/static/typedoc/interfaces/RequestConfig.html +0 -48
  172. package/docs/static/typedoc/interfaces/RequestShortcutConfig.html +0 -38
  173. package/docs/static/typedoc/interfaces/ServiceProvider.html +0 -5
  174. package/docs/static/typedoc/interfaces/UrlParts.html +0 -9
  175. package/docs/static/typedoc/types/HttpParamSerializer.html +0 -2
  176. package/docs/static/typedoc/types/HttpParams.html +0 -2
  177. package/docs/static/typedoc/types/HttpPromise.html +0 -1
  178. package/docs/static/typedoc/types/HttpResponseStatus.html +0 -1
  179. package/docs/static/typedoc/types/LogCall.html +0 -2
  180. package/docs/static/typedoc/types/LogServiceFactory.html +0 -2
  181. package/docs/static/typedoc/types/UrlChangeListener.html +0 -5
  182. package/docs/static/typedoc/variables/EventBus.html +0 -1
  183. package/docs/static/version.js +0 -13
  184. package/docs/test-results/.last-run.json +0 -4
  185. package/docs/test-results/static-examples-counter-counter-counter-example/error-context.md +0 -50
  186. package/eslint.config.js +0 -26
  187. package/images/android-chrome-192x192.png +0 -0
  188. package/images/android-chrome-512x512.png +0 -0
  189. package/images/apple-touch-icon.png +0 -0
  190. package/images/favicon-16x16.png +0 -0
  191. package/images/favicon-32x32.png +0 -0
  192. package/images/favicon.ico +0 -0
  193. package/images/site.webmanifest +0 -19
  194. package/index.html +0 -86
  195. package/legacy.d.ts +0 -1678
  196. package/playwright.config.ts +0 -81
  197. package/public/jasmine/boot0.js +0 -66
  198. package/public/jasmine/boot1.js +0 -134
  199. package/public/jasmine/jasmine-html.js +0 -970
  200. package/public/jasmine/jasmine.css +0 -323
  201. package/public/jasmine/jasmine.js +0 -11406
  202. package/public/public/README.md +0 -1
  203. package/public/public/circle.html +0 -1
  204. package/public/public/jasmine-helper.css +0 -9
  205. package/public/public/my_child_directive.html +0 -1
  206. package/public/public/my_directive.html +0 -1
  207. package/public/public/my_other_directive.html +0 -1
  208. package/public/public/test.html +0 -1
  209. package/rollup.config.js +0 -51
  210. package/src/angular.js +0 -286
  211. package/src/angular.spec.js +0 -1191
  212. package/src/animations/animate-cache.js +0 -80
  213. package/src/animations/animate-children-directive.js +0 -32
  214. package/src/animations/animate-children-directive.md +0 -80
  215. package/src/animations/animate-css-driver.js +0 -284
  216. package/src/animations/animate-css.html +0 -58
  217. package/src/animations/animate-css.js +0 -915
  218. package/src/animations/animate-css.md +0 -263
  219. package/src/animations/animate-js-driver.js +0 -60
  220. package/src/animations/animate-js.html +0 -47
  221. package/src/animations/animate-js.js +0 -371
  222. package/src/animations/animate-queue.js +0 -859
  223. package/src/animations/animate-runner.js +0 -193
  224. package/src/animations/animate-swap.js +0 -33
  225. package/src/animations/animate-swap.md +0 -88
  226. package/src/animations/animate.html +0 -19
  227. package/src/animations/animate.js +0 -546
  228. package/src/animations/animate.md +0 -933
  229. package/src/animations/animate.spec.js +0 -490
  230. package/src/animations/animation.js +0 -519
  231. package/src/animations/animations.test.js +0 -10
  232. package/src/animations/interface.ts +0 -19
  233. package/src/animations/raf-scheduler.html +0 -19
  234. package/src/animations/raf-scheduler.js +0 -92
  235. package/src/animations/raf-scheduler.spec.js +0 -98
  236. package/src/animations/shared.js +0 -341
  237. package/src/binding.html +0 -19
  238. package/src/binding.spec.js +0 -474
  239. package/src/binding.test.js +0 -10
  240. package/src/core/compile/attributes.js +0 -337
  241. package/src/core/compile/compile.html +0 -19
  242. package/src/core/compile/compile.js +0 -3271
  243. package/src/core/compile/compile.md +0 -1128
  244. package/src/core/compile/compile.spec.js +0 -15574
  245. package/src/core/compile/compile.test.js +0 -12
  246. package/src/core/controller/controller.html +0 -22
  247. package/src/core/controller/controller.js +0 -193
  248. package/src/core/controller/controller.spec.js +0 -334
  249. package/src/core/controller/controller.test.js +0 -12
  250. package/src/core/controller/interface.ts +0 -6
  251. package/src/core/core.html +0 -20
  252. package/src/core/core.test.js +0 -12
  253. package/src/core/di/injector.html +0 -19
  254. package/src/core/di/injector.js +0 -307
  255. package/src/core/di/injector.md +0 -740
  256. package/src/core/di/injector.spec.js +0 -2310
  257. package/src/core/di/injector.test.js +0 -12
  258. package/src/core/di/internal-injector.js +0 -286
  259. package/src/core/di/ng-module.html +0 -19
  260. package/src/core/di/ng-module.js +0 -229
  261. package/src/core/di/ng-module.spec.js +0 -263
  262. package/src/core/di/ng-module.test.js +0 -12
  263. package/src/core/filter/filter.html +0 -19
  264. package/src/core/filter/filter.js +0 -55
  265. package/src/core/filter/filter.md +0 -132
  266. package/src/core/filter/filter.spec.js +0 -149
  267. package/src/core/filter/filter.test.js +0 -12
  268. package/src/core/interpolate/interface.ts +0 -14
  269. package/src/core/interpolate/interpolate.html +0 -22
  270. package/src/core/interpolate/interpolate.js +0 -410
  271. package/src/core/interpolate/interpolate.spec.js +0 -601
  272. package/src/core/interpolate/interpolate.test.js +0 -12
  273. package/src/core/parse/ast/ast-node.ts +0 -81
  274. package/src/core/parse/ast/ast.html +0 -19
  275. package/src/core/parse/ast/ast.js +0 -574
  276. package/src/core/parse/ast/ast.spec.js +0 -1453
  277. package/src/core/parse/ast/ast.test.js +0 -10
  278. package/src/core/parse/ast-type.js +0 -23
  279. package/src/core/parse/interface.ts +0 -84
  280. package/src/core/parse/interpreter.js +0 -915
  281. package/src/core/parse/lexer/lexer.html +0 -19
  282. package/src/core/parse/lexer/lexer.js +0 -338
  283. package/src/core/parse/lexer/lexer.spec.js +0 -303
  284. package/src/core/parse/lexer/lexer.test.js +0 -10
  285. package/src/core/parse/lexer/token.ts +0 -22
  286. package/src/core/parse/parse.html +0 -19
  287. package/src/core/parse/parse.js +0 -337
  288. package/src/core/parse/parse.md +0 -57
  289. package/src/core/parse/parse.spec.js +0 -2107
  290. package/src/core/parse/parse.test.js +0 -10
  291. package/src/core/parse/parser/parser.html +0 -19
  292. package/src/core/parse/parser/parser.js +0 -64
  293. package/src/core/parse/parser/parser.spec.js +0 -8
  294. package/src/core/parse/parser/parser.test.js +0 -10
  295. package/src/core/prop.spec.js +0 -775
  296. package/src/core/root-element.spec.js +0 -14
  297. package/src/core/sanitize/interface.ts +0 -10
  298. package/src/core/sanitize/sanitize-uri.js +0 -75
  299. package/src/core/sanitize/sanitize-uri.spec.js +0 -249
  300. package/src/core/sanitize/sanitize-uri.test.js +0 -12
  301. package/src/core/sanitize/sanitize.html +0 -22
  302. package/src/core/scope/scope.html +0 -19
  303. package/src/core/scope/scope.js +0 -1252
  304. package/src/core/scope/scope.spec.js +0 -3000
  305. package/src/core/scope/scope.test.js +0 -12
  306. package/src/directive/aria/aria.html +0 -19
  307. package/src/directive/aria/aria.js +0 -382
  308. package/src/directive/aria/aria.md +0 -145
  309. package/src/directive/aria/aria.spec.js +0 -1241
  310. package/src/directive/aria/aria.test.js +0 -12
  311. package/src/directive/attrs/attrs.html +0 -19
  312. package/src/directive/attrs/attrs.js +0 -106
  313. package/src/directive/attrs/attrs.md +0 -224
  314. package/src/directive/attrs/attrs.spec.js +0 -71
  315. package/src/directive/attrs/attrs.test.js +0 -12
  316. package/src/directive/attrs/boolean.html +0 -19
  317. package/src/directive/attrs/boolean.spec.js +0 -137
  318. package/src/directive/attrs/boolean.test.js +0 -12
  319. package/src/directive/attrs/element-style.html +0 -22
  320. package/src/directive/attrs/element-style.spec.js +0 -85
  321. package/src/directive/attrs/element-style.test.js +0 -12
  322. package/src/directive/attrs/src.html +0 -19
  323. package/src/directive/attrs/src.spec.js +0 -163
  324. package/src/directive/attrs/src.test.js +0 -12
  325. package/src/directive/bind/bind-html.spec.js +0 -36
  326. package/src/directive/bind/bind.html +0 -20
  327. package/src/directive/bind/bind.js +0 -78
  328. package/src/directive/bind/bind.md +0 -142
  329. package/src/directive/bind/bind.spec.js +0 -314
  330. package/src/directive/bind/bind.test.js +0 -12
  331. package/src/directive/channel/channel.html +0 -19
  332. package/src/directive/channel/channel.js +0 -30
  333. package/src/directive/channel/channel.spec.js +0 -67
  334. package/src/directive/channel/channel.test.js +0 -10
  335. package/src/directive/class/class-test.html +0 -23
  336. package/src/directive/class/class.html +0 -19
  337. package/src/directive/class/class.js +0 -184
  338. package/src/directive/class/class.spec.js +0 -704
  339. package/src/directive/class/class.test.js +0 -12
  340. package/src/directive/cloak/cloak.html +0 -19
  341. package/src/directive/cloak/cloak.js +0 -11
  342. package/src/directive/cloak/cloak.spec.js +0 -44
  343. package/src/directive/cloak/cloak.test.js +0 -12
  344. package/src/directive/controller/controller.html +0 -22
  345. package/src/directive/controller/controller.js +0 -11
  346. package/src/directive/controller/controller.md +0 -46
  347. package/src/directive/controller/controller.spec.js +0 -175
  348. package/src/directive/controller/controller.test.js +0 -12
  349. package/src/directive/events/click.spec.js +0 -35
  350. package/src/directive/events/event.spec.js +0 -267
  351. package/src/directive/events/events-test.html +0 -36
  352. package/src/directive/events/events.html +0 -20
  353. package/src/directive/events/events.js +0 -65
  354. package/src/directive/events/events.md +0 -125
  355. package/src/directive/events/events.test.js +0 -12
  356. package/src/directive/form/form.html +0 -19
  357. package/src/directive/form/form.js +0 -669
  358. package/src/directive/form/form.spec.js +0 -1515
  359. package/src/directive/form/form.test.js +0 -12
  360. package/src/directive/http/delete.spec.js +0 -23
  361. package/src/directive/http/form-router-test.html +0 -44
  362. package/src/directive/http/form-test.html +0 -18
  363. package/src/directive/http/get.spec.js +0 -488
  364. package/src/directive/http/http.html +0 -22
  365. package/src/directive/http/http.js +0 -342
  366. package/src/directive/http/http.test.js +0 -12
  367. package/src/directive/http/interface.ts +0 -36
  368. package/src/directive/http/post-example.html +0 -30
  369. package/src/directive/http/post.spec.js +0 -521
  370. package/src/directive/http/put.spec.js +0 -23
  371. package/src/directive/if/if-animate-css.html +0 -57
  372. package/src/directive/if/if-animate-svg.html +0 -25
  373. package/src/directive/if/if.html +0 -19
  374. package/src/directive/if/if.js +0 -72
  375. package/src/directive/if/if.md +0 -76
  376. package/src/directive/if/if.spec.js +0 -293
  377. package/src/directive/if/if.test.js +0 -114
  378. package/src/directive/include/include.html +0 -19
  379. package/src/directive/include/include.js +0 -151
  380. package/src/directive/include/include.md +0 -87
  381. package/src/directive/include/include.spec.js +0 -734
  382. package/src/directive/include/include.test.js +0 -12
  383. package/src/directive/init/init.html +0 -19
  384. package/src/directive/init/init.js +0 -22
  385. package/src/directive/init/init.md +0 -41
  386. package/src/directive/init/init.spec.js +0 -68
  387. package/src/directive/init/init.test.js +0 -12
  388. package/src/directive/inject/inject.html +0 -19
  389. package/src/directive/inject/inject.js +0 -35
  390. package/src/directive/inject/inject.spec.js +0 -108
  391. package/src/directive/inject/inject.test.js +0 -12
  392. package/src/directive/input/input-example.html +0 -15
  393. package/src/directive/input/input.html +0 -19
  394. package/src/directive/input/input.js +0 -1078
  395. package/src/directive/input/input.md +0 -706
  396. package/src/directive/input/input.spec.js +0 -3700
  397. package/src/directive/input/input.test.js +0 -12
  398. package/src/directive/messages/messages.html +0 -22
  399. package/src/directive/messages/messages.js +0 -349
  400. package/src/directive/messages/messages.md +0 -543
  401. package/src/directive/messages/messages.spec.js +0 -1083
  402. package/src/directive/messages/messages.test.js +0 -12
  403. package/src/directive/model/change.md +0 -25
  404. package/src/directive/model/model.html +0 -19
  405. package/src/directive/model/model.js +0 -1170
  406. package/src/directive/model/model.spec.js +0 -1976
  407. package/src/directive/model/model.test.js +0 -12
  408. package/src/directive/model-options/model-option.test.js +0 -12
  409. package/src/directive/model-options/model-options.html +0 -22
  410. package/src/directive/model-options/model-options.js +0 -142
  411. package/src/directive/model-options/model-options.md +0 -407
  412. package/src/directive/model-options/model-options.spec.js +0 -1022
  413. package/src/directive/non-bindable/non-bindable.html +0 -22
  414. package/src/directive/non-bindable/non-bindable.js +0 -9
  415. package/src/directive/non-bindable/non-bindable.spec.js +0 -59
  416. package/src/directive/non-bindable/non-bindable.test.js +0 -12
  417. package/src/directive/observe/observe-demo.html +0 -184
  418. package/src/directive/observe/observe.html +0 -19
  419. package/src/directive/observe/observe.js +0 -41
  420. package/src/directive/observe/observe.spec.js +0 -106
  421. package/src/directive/observe/observe.test.js +0 -10
  422. package/src/directive/on/on.html +0 -19
  423. package/src/directive/on/on.spec.js +0 -215
  424. package/src/directive/on/on.test.js +0 -12
  425. package/src/directive/options/options-example.html +0 -17
  426. package/src/directive/options/options.html +0 -22
  427. package/src/directive/options/options.js +0 -542
  428. package/src/directive/options/options.md +0 -179
  429. package/src/directive/options/options.spec.js +0 -3554
  430. package/src/directive/options/options.test.js +0 -12
  431. package/src/directive/ref/href.html +0 -19
  432. package/src/directive/ref/href.spec.js +0 -141
  433. package/src/directive/ref/href.test.js +0 -19
  434. package/src/directive/ref/ref.html +0 -19
  435. package/src/directive/ref/ref.js +0 -89
  436. package/src/directive/ref/ref.spec.js +0 -546
  437. package/src/directive/repeat/repeat.html +0 -19
  438. package/src/directive/repeat/repeat.js +0 -333
  439. package/src/directive/repeat/repeat.md +0 -330
  440. package/src/directive/repeat/repeat.spec.js +0 -1209
  441. package/src/directive/repeat/repeat.test.js +0 -12
  442. package/src/directive/script/script.html +0 -19
  443. package/src/directive/script/script.js +0 -17
  444. package/src/directive/script/script.md +0 -11
  445. package/src/directive/script/script.spec.js +0 -47
  446. package/src/directive/script/script.test.js +0 -12
  447. package/src/directive/select/select.html +0 -19
  448. package/src/directive/select/select.js +0 -594
  449. package/src/directive/select/select.md +0 -74
  450. package/src/directive/select/select.spec.js +0 -2566
  451. package/src/directive/select/select.test.js +0 -12
  452. package/src/directive/setter/setter.html +0 -19
  453. package/src/directive/setter/setter.js +0 -59
  454. package/src/directive/setter/setter.spec.js +0 -100
  455. package/src/directive/setter/setter.test.js +0 -12
  456. package/src/directive/show-hide/show-hide.html +0 -22
  457. package/src/directive/show-hide/show-hide.js +0 -65
  458. package/src/directive/show-hide/show-hide.md +0 -255
  459. package/src/directive/show-hide/show-hide.spec.js +0 -268
  460. package/src/directive/show-hide/show-hide.test.js +0 -12
  461. package/src/directive/style/style.html +0 -19
  462. package/src/directive/style/style.js +0 -27
  463. package/src/directive/style/style.md +0 -23
  464. package/src/directive/style/style.spec.js +0 -183
  465. package/src/directive/style/style.test.js +0 -12
  466. package/src/directive/switch/switch.html +0 -19
  467. package/src/directive/switch/switch.js +0 -133
  468. package/src/directive/switch/switch.md +0 -66
  469. package/src/directive/switch/switch.spec.js +0 -509
  470. package/src/directive/switch/switch.test.js +0 -12
  471. package/src/directive/transclude/transclude.js +0 -122
  472. package/src/directive/validators/validators.html +0 -22
  473. package/src/directive/validators/validators.js +0 -346
  474. package/src/directive/validators/validators.spec.js +0 -740
  475. package/src/directive/validators/validators.test.js +0 -12
  476. package/src/filters/filter.js +0 -213
  477. package/src/filters/filter.spec.js +0 -719
  478. package/src/filters/filters.html +0 -22
  479. package/src/filters/filters.js +0 -239
  480. package/src/filters/filters.spec.js +0 -36
  481. package/src/filters/filters.test.js +0 -12
  482. package/src/filters/interface.ts +0 -9
  483. package/src/filters/limit-to.js +0 -55
  484. package/src/filters/limit-to.spec.js +0 -252
  485. package/src/filters/order-by.js +0 -181
  486. package/src/filters/order-by.spec.js +0 -883
  487. package/src/index.js +0 -6
  488. package/src/index.spec.js +0 -11
  489. package/src/injection-tokens.js +0 -81
  490. package/src/interface.ts +0 -430
  491. package/src/ng.js +0 -291
  492. package/src/ng.spec.js +0 -45
  493. package/src/router/common/trace.js +0 -240
  494. package/src/router/directives/component-example.html +0 -37
  495. package/src/router/directives/state-directives.html +0 -22
  496. package/src/router/directives/state-directives.js +0 -393
  497. package/src/router/directives/state-directives.md +0 -435
  498. package/src/router/directives/state-directives.spec.js +0 -1091
  499. package/src/router/directives/state-directives.test.js +0 -10
  500. package/src/router/directives/view-directive.js +0 -489
  501. package/src/router/directives/view-directive.spec.js +0 -1921
  502. package/src/router/directives/view-directive.test.js +0 -10
  503. package/src/router/directives/view-directives.html +0 -22
  504. package/src/router/glob/glob.html +0 -19
  505. package/src/router/glob/glob.js +0 -102
  506. package/src/router/glob/glob.spec.js +0 -108
  507. package/src/router/glob/glob.test.js +0 -12
  508. package/src/router/hooks/core-resolvables.js +0 -38
  509. package/src/router/hooks/ignored-transition.js +0 -25
  510. package/src/router/hooks/invalid-transition.js +0 -14
  511. package/src/router/hooks/lazy-load.js +0 -104
  512. package/src/router/hooks/on-enter-exit-retain.js +0 -55
  513. package/src/router/hooks/redirect-to.js +0 -38
  514. package/src/router/hooks/resolve.js +0 -57
  515. package/src/router/hooks/update-globals.js +0 -34
  516. package/src/router/hooks/url.js +0 -34
  517. package/src/router/hooks/views.js +0 -41
  518. package/src/router/params/interface.ts +0 -626
  519. package/src/router/params/param-factory.js +0 -23
  520. package/src/router/params/param-type.js +0 -133
  521. package/src/router/params/param-types.js +0 -153
  522. package/src/router/params/param.js +0 -243
  523. package/src/router/params/state-params.js +0 -36
  524. package/src/router/path/path-node.js +0 -78
  525. package/src/router/path/path-utils.js +0 -207
  526. package/src/router/resolve/interface.ts +0 -208
  527. package/src/router/resolve/resolvable.js +0 -123
  528. package/src/router/resolve/resolve-context.js +0 -190
  529. package/src/router/router-test-hashbang.html +0 -45
  530. package/src/router/router-test.html +0 -41
  531. package/src/router/router.html +0 -22
  532. package/src/router/router.js +0 -54
  533. package/src/router/router.test.js +0 -12
  534. package/src/router/services.spec.js +0 -52
  535. package/src/router/state/interface.ts +0 -1007
  536. package/src/router/state/state-builder.js +0 -376
  537. package/src/router/state/state-builder.spec.js +0 -86
  538. package/src/router/state/state-matcher.js +0 -64
  539. package/src/router/state/state-object.js +0 -118
  540. package/src/router/state/state-queue-manager.js +0 -95
  541. package/src/router/state/state-registry.js +0 -262
  542. package/src/router/state/state-service.js +0 -687
  543. package/src/router/state/state.html +0 -23
  544. package/src/router/state/state.spec.js +0 -1002
  545. package/src/router/state/state.test.js +0 -12
  546. package/src/router/state/target-state.js +0 -162
  547. package/src/router/state/views.js +0 -195
  548. package/src/router/state-filter.spec.js +0 -139
  549. package/src/router/state-filters.js +0 -46
  550. package/src/router/template-factory.html +0 -19
  551. package/src/router/template-factory.js +0 -249
  552. package/src/router/template-factory.spec.js +0 -146
  553. package/src/router/template-factory.test.js +0 -12
  554. package/src/router/transition/hook-builder.js +0 -137
  555. package/src/router/transition/hook-registry.js +0 -181
  556. package/src/router/transition/interface.js +0 -18
  557. package/src/router/transition/interface.ts +0 -922
  558. package/src/router/transition/reject-factory.js +0 -122
  559. package/src/router/transition/transition-event-type.js +0 -26
  560. package/src/router/transition/transition-hook.js +0 -199
  561. package/src/router/transition/transition-service.js +0 -297
  562. package/src/router/transition/transition.js +0 -653
  563. package/src/router/url/url-config.js +0 -155
  564. package/src/router/url/url-matcher.js +0 -532
  565. package/src/router/url/url-rule.js +0 -231
  566. package/src/router/url/url-rules.js +0 -350
  567. package/src/router/url/url-service.js +0 -446
  568. package/src/router/url/url-service.spec.js +0 -1288
  569. package/src/router/url/url.html +0 -19
  570. package/src/router/url/url.test.js +0 -12
  571. package/src/router/view/interface.ts +0 -51
  572. package/src/router/view/view.html +0 -19
  573. package/src/router/view/view.js +0 -262
  574. package/src/router/view/view.spec.js +0 -100
  575. package/src/router/view/view.test.js +0 -12
  576. package/src/router/view-hook.spec.js +0 -215
  577. package/src/router/view-scroll.js +0 -33
  578. package/src/router/view-scroll.spec.js +0 -72
  579. package/src/services/anchor-scroll/anchor-scroll.html +0 -76
  580. package/src/services/anchor-scroll/anchor-scroll.js +0 -147
  581. package/src/services/exception/exception-handler.js +0 -75
  582. package/src/services/exception/interface.ts +0 -7
  583. package/src/services/http/http.html +0 -23
  584. package/src/services/http/http.js +0 -1109
  585. package/src/services/http/http.spec.js +0 -4320
  586. package/src/services/http/http.test.js +0 -11
  587. package/src/services/http/interface.ts +0 -256
  588. package/src/services/http/template-request.spec.js +0 -220
  589. package/src/services/location/interface.ts +0 -70
  590. package/src/services/location/location.html +0 -22
  591. package/src/services/location/location.js +0 -1006
  592. package/src/services/location/location.spec.js +0 -3792
  593. package/src/services/location/location.test.js +0 -12
  594. package/src/services/log/interface.ts +0 -39
  595. package/src/services/log/log.html +0 -19
  596. package/src/services/log/log.js +0 -74
  597. package/src/services/log/log.spec.js +0 -64
  598. package/src/services/log/log.test.js +0 -12
  599. package/src/services/pubsub/pubsub.html +0 -19
  600. package/src/services/pubsub/pubsub.js +0 -349
  601. package/src/services/pubsub/pubsub.spec.js +0 -400
  602. package/src/services/pubsub/pubsub.test.js +0 -12
  603. package/src/services/sce/sce.html +0 -19
  604. package/src/services/sce/sce.js +0 -852
  605. package/src/services/sce/sce.spec.js +0 -617
  606. package/src/services/sce/sce.test.js +0 -12
  607. package/src/services/template-cache/template-cache.html +0 -22
  608. package/src/services/template-cache/template-cache.js +0 -15
  609. package/src/services/template-cache/template-cache.spec.js +0 -134
  610. package/src/services/template-cache/template-cache.test.js +0 -12
  611. package/src/services/template-request/interface.ts +0 -23
  612. package/src/services/template-request/template-request.js +0 -142
  613. package/src/shared/cache.js +0 -7
  614. package/src/shared/common.js +0 -365
  615. package/src/shared/common.spec.js +0 -294
  616. package/src/shared/constants.js +0 -21
  617. package/src/shared/dom.js +0 -716
  618. package/src/shared/hof.js +0 -157
  619. package/src/shared/hof.spec.js +0 -60
  620. package/src/shared/interface.ts +0 -21
  621. package/src/shared/min-err.spec.js +0 -178
  622. package/src/shared/noderef.js +0 -225
  623. package/src/shared/predicates.js +0 -34
  624. package/src/shared/queue.js +0 -105
  625. package/src/shared/queue.spec.js +0 -80
  626. package/src/shared/shared.html +0 -24
  627. package/src/shared/shared.test.js +0 -12
  628. package/src/shared/strings.js +0 -142
  629. package/src/shared/strings.spec.js +0 -40
  630. package/src/shared/test-utils.js +0 -47
  631. package/src/shared/url-utils/interface.ts +0 -54
  632. package/src/shared/url-utils/url-utils.html +0 -22
  633. package/src/shared/url-utils/url-utils.js +0 -122
  634. package/src/shared/url-utils/url-utils.spec.js +0 -148
  635. package/src/shared/url-utils/url-utils.test.js +0 -12
  636. package/src/shared/utils.js +0 -1255
  637. package/src/shared/utils.spec.js +0 -178
  638. package/src/src.html +0 -21
  639. package/src/src.test.js +0 -10
  640. package/tsconfig.json +0 -19
  641. package/tsconfig.types.json +0 -14
  642. package/typedoc.json +0 -8
  643. package/utils/express.js +0 -203
  644. package/utils/version.cjs +0 -23
  645. package/vite.config.js +0 -14
@@ -1,3000 +0,0 @@
1
- import { wait } from "../../shared/test-utils.js";
2
- import { $postUpdateQueue, createScope } from "./scope.js";
3
- import { Angular } from "../../angular.js";
4
- import { createInjector } from "../di/injector.js";
5
- import { isDefined, isProxy, sliceArgs } from "../../shared/utils.js";
6
-
7
- describe("Scope", () => {
8
- let scope;
9
- let $parse;
10
- let logs;
11
- let $rootScope;
12
- let injector;
13
- let count;
14
-
15
- beforeEach(() => {
16
- logs = [];
17
- count = 0;
18
- delete window.angular;
19
- window.angular = new Angular();
20
- window.angular
21
- .module("myModule", ["ng"])
22
- .decorator("$exceptionHandler", function () {
23
- return (exception, cause) => {
24
- logs.push(exception);
25
- console.error(exception, cause);
26
- };
27
- });
28
-
29
- injector = createInjector(["myModule"]);
30
- $parse = injector.get("$parse");
31
- $rootScope = injector.get("$rootScope");
32
- scope = $rootScope;
33
- });
34
-
35
- it("can be instantiated without parameters", () => {
36
- scope = createScope();
37
- expect(scope).toBeDefined();
38
-
39
- scope.a = 1;
40
- expect(scope.a).toEqual(1);
41
- });
42
-
43
- it("can be instantiated with plain object", () => {
44
- scope = createScope({ a: 1, b: { c: 2 } });
45
- expect(scope).toBeDefined();
46
- expect(scope.a).toEqual(1);
47
- expect(scope.b.c).toEqual(2);
48
- scope.a = 2;
49
- expect(scope.a).toEqual(2);
50
- scope.d = 3;
51
- expect(scope.d).toEqual(3);
52
- });
53
-
54
- class Demo {
55
- a = "test";
56
-
57
- check() {
58
- return this.a + "!";
59
- }
60
- }
61
-
62
- it("can be instantiated from a class instance", () => {
63
- scope = createScope(new Demo());
64
- expect(scope.a).toEqual("test");
65
- expect(scope.check()).toEqual("test!");
66
- });
67
-
68
- it("can be instantiated from a class instance as a property", () => {
69
- scope.test = createScope(new Demo());
70
- expect(scope.test.a).toEqual("test");
71
- expect(scope.test.check()).toEqual("test!");
72
- });
73
-
74
- describe("$id", () => {
75
- it("should have a unique id", () => {
76
- expect(scope.$id < scope.$new().$id).toBeTruthy();
77
-
78
- const res = createScope(new Demo());
79
- expect(res.$id).toBeDefined();
80
- });
81
- });
82
-
83
- describe("$target", () => {
84
- it("should have a $target property", () => {
85
- scope = createScope({ a: 1 });
86
- expect(scope.$target).toBeDefined();
87
- });
88
-
89
- it("should make its properties available for getters", () => {
90
- scope = createScope({ a: 1, b: { test: "test" } });
91
- expect(scope.$target).toBeDefined();
92
- expect(scope.a).toEqual(1);
93
- expect(scope.$target.a).toEqual(1);
94
- expect(scope.a).toBe(scope.$target.a);
95
- expect(scope.b).toBe(scope.$target.b);
96
- });
97
-
98
- it("should make its properties available for setters", () => {
99
- scope = createScope({ a: 1, b: { test: "test" } });
100
- expect(scope.$target).toBeDefined();
101
- expect(scope.a).toEqual(1);
102
- scope.a = 2;
103
- expect(scope.$target.a).toEqual(2);
104
- scope.b = 2;
105
- expect(scope.$target.b).toEqual(2);
106
- });
107
- });
108
-
109
- describe("$nonscope", () => {
110
- it("should ignore objects with $nonscope property", () => {
111
- const res = createScope({ $nonscope: true });
112
- expect(res.$id).toBeUndefined();
113
- });
114
-
115
- it("should ignore instances from classes with $nonscope property", () => {
116
- Demo.$nonscope = true;
117
- const res = createScope(new Demo());
118
- expect(res.$id).toBeUndefined();
119
-
120
- Demo.$nonscope = undefined;
121
- });
122
-
123
- it("should ignore classes with static $nonscope property", () => {
124
- class NonScope {
125
- static $nonscope = true;
126
- }
127
- const res = createScope(new NonScope());
128
- expect(res.$id).toBeUndefined();
129
- });
130
-
131
- it("should ignore properties marked as $nonscope array", () => {
132
- class ExcludePropertyScope {
133
- constructor() {
134
- this.a = {};
135
- this.b = [];
136
- }
137
- }
138
- let res = createScope(new ExcludePropertyScope());
139
- expect(res.$id).toBeDefined();
140
- expect(res.a.$id).toBeDefined();
141
- expect(isProxy(res.a)).toBeTrue();
142
-
143
- ExcludePropertyScope.$nonscope = ["a"];
144
- res = createScope(new ExcludePropertyScope());
145
- expect(res.$id).toBeDefined();
146
- expect(res.a.$id).toBeUndefined();
147
- expect(isProxy(res.a)).toBeFalse();
148
- expect(isProxy(res.b)).toBeTrue();
149
-
150
- ExcludePropertyScope.$nonscope = ["a", "b"];
151
- res = createScope(new ExcludePropertyScope());
152
- expect(res.$id).toBeDefined();
153
- expect(res.a.$id).toBeUndefined();
154
- expect(isProxy(res.a)).toBeFalse();
155
- expect(isProxy(res.b)).toBeFalse();
156
-
157
- res = createScope({
158
- a: {},
159
- b: [],
160
- });
161
- expect(res.$id).toBeDefined();
162
- expect(res.a.$id).toBeDefined();
163
- expect(res.b.$id).toBeDefined();
164
- expect(isProxy(res.a)).toBeTrue();
165
- expect(isProxy(res.b)).toBeTrue();
166
-
167
- res = createScope({
168
- a: {},
169
- b: [],
170
- $nonscope: ["a", "b"],
171
- });
172
- expect(res.$id).toBeDefined();
173
- expect(res.a.$id).toBeUndefined();
174
- expect(res.b.$id).toBeUndefined();
175
- expect(isProxy(res.a)).toBeFalse();
176
- expect(isProxy(res.b)).toBeFalse();
177
- });
178
- });
179
-
180
- describe("inheritance", () => {
181
- it("can be constructed and used as an object", () => {
182
- const scope = createScope();
183
- scope.aProperty = 1;
184
-
185
- expect(scope.aProperty).toBe(1);
186
- });
187
-
188
- it("constructs a root scope by default while all children non-root", () => {
189
- const scope = createScope();
190
- expect(scope.$isRoot()).toBe(true);
191
-
192
- const child = scope.$new();
193
- expect(child.$isRoot()).toBe(false);
194
- });
195
-
196
- it("inherits the parents properties", () => {
197
- scope.aValue = [1, 2, 3];
198
-
199
- const child = scope.$new();
200
- expect(child.aValue).toEqual([1, 2, 3]);
201
-
202
- scope.bValue = 2;
203
- expect(child.bValue).toEqual(2);
204
- });
205
-
206
- it("does not cause a parent to inherit its properties", () => {
207
- const child = scope.$new();
208
- child.aValue = [1, 2, 3];
209
-
210
- expect(scope.aValue).toBeUndefined();
211
- });
212
-
213
- it("inherits the parents properties whenever they are defined", () => {
214
- const child = scope.$new();
215
-
216
- scope.aValue = [1, 2, 3];
217
-
218
- expect(child.aValue).toEqual([1, 2, 3]);
219
- });
220
-
221
- it("can create a scope from an existing object", () => {
222
- let instance = { bValue: "child" };
223
- const child = scope.$new(instance);
224
-
225
- scope.aValue = [1, 2, 3];
226
-
227
- expect(child.aValue).toEqual([1, 2, 3]);
228
- expect(child.bValue).toEqual("child");
229
- });
230
-
231
- it("can be nested at any depth", () => {
232
- const a = scope;
233
- const aa = a.$new();
234
- const aaa = aa.$new();
235
- const aab = aa.$new();
236
- const ab = a.$new();
237
- const abb = ab.$new();
238
-
239
- a.value = 1;
240
-
241
- expect(aa.value).toBe(1);
242
- expect(aaa.value).toBe(1);
243
- expect(aab.value).toBe(1);
244
- expect(ab.value).toBe(1);
245
- expect(abb.value).toBe(1);
246
-
247
- ab.anotherValue = 2;
248
-
249
- expect(abb.anotherValue).toBe(2);
250
- expect(aa.anotherValue).toBeUndefined();
251
- expect(aaa.anotherValue).toBeUndefined();
252
- });
253
-
254
- it("can manipulate a parent scopes property", () => {
255
- const child = scope.$new();
256
-
257
- scope.aValue = [1, 2, 3];
258
- child.aValue.push(4);
259
-
260
- expect(child.aValue).toEqual([1, 2, 3, 4]);
261
- expect(scope.aValue).toEqual([1, 2, 3, 4]);
262
- expect(child.aValue).toEqual(scope.aValue);
263
- });
264
-
265
- it("can manipulate a parent scopes property with functions", () => {
266
- class Demo {
267
- test() {
268
- return "Test";
269
- }
270
- increase() {
271
- this.counter++;
272
- }
273
- }
274
-
275
- let instance = new Demo();
276
- expect(instance.test()).toEqual("Test");
277
- const child = scope.$new(instance);
278
-
279
- scope.counter = 0;
280
-
281
- expect(child.counter).toEqual(0);
282
- expect(child.test()).toEqual("Test");
283
-
284
- child.increase();
285
- expect(child.counter).toEqual(1);
286
-
287
- child.increase();
288
- expect(child.counter).toEqual(2);
289
- });
290
-
291
- it("cannot override a parent scopes property", () => {
292
- const child = scope.$new();
293
- scope.aValue = [1, 2, 3];
294
- child.aValue = [1, 2, 3, 4];
295
- scope.bValue = { a: 1 };
296
- child.bValue = { b: 2 };
297
- scope.cValue = 1;
298
- child.cValue = 2;
299
- expect(scope.aValue).toEqual([1, 2, 3]);
300
- expect(child.aValue).toEqual([1, 2, 3, 4]);
301
- expect(scope.bValue).toEqual({ a: 1 });
302
- expect(child.bValue).toEqual({ b: 2 });
303
- expect(scope.cValue).toEqual(1);
304
- expect(child.cValue).toEqual(2);
305
- });
306
-
307
- it("inherits the parents listeners", () => {
308
- const child = scope.$new();
309
-
310
- expect(child.$$listeners).toBe(scope.$$listeners);
311
- });
312
- });
313
-
314
- describe("$new()", () => {
315
- it("should create a child scope", () => {
316
- const child = scope.$new();
317
- scope.a = 123;
318
- expect(child.a).toEqual(123);
319
- });
320
-
321
- it("should create a non prototypically inherited child scope", () => {
322
- const child = scope.$newIsolate();
323
- scope.a = 123;
324
- expect(child.a).toBeUndefined();
325
- expect(child.$parent).toBe(scope.$root);
326
- expect(child.$new).toBeDefined();
327
- expect(child.$root).toEqual(scope.$root);
328
- });
329
-
330
- it("should attach the child scope to a specified parent", () => {
331
- const isolated = scope.$newIsolate();
332
- const trans = scope.$transcluded(isolated);
333
- scope.a = 123;
334
- expect(isolated.a).toBeUndefined();
335
- expect(trans.a).toEqual(123);
336
- expect(trans.$root.$id).toBeDefined();
337
- expect(trans.$root.$id).toEqual(scope.$root.$id);
338
- expect(trans.$parent.$id).toEqual(isolated.$id);
339
- });
340
- });
341
-
342
- describe("$root", () => {
343
- it("should point to itself", () => {
344
- expect(scope.$root.$id).toEqual(scope.$id);
345
- expect(scope.$root).toEqual(scope.$root.$root);
346
- });
347
-
348
- it("should expose the constructor", () => {
349
- expect(Object.getPrototypeOf(scope)).toBe(scope.constructor.prototype);
350
- });
351
-
352
- it("should not have $root on children, but should inherit", () => {
353
- const child = scope.$new();
354
- expect(child.$root).toEqual(scope.$root);
355
- });
356
- });
357
-
358
- describe("$parent", () => {
359
- it("should point to parent", () => {
360
- const child = scope.$new();
361
-
362
- expect(scope.$parent).toEqual(null);
363
- expect(child.$parent.$id).toEqual(scope.$id);
364
- expect(child.$parent).toEqual(scope.$handler);
365
- expect(child.$new().$parent).toEqual(child.$handler);
366
- });
367
-
368
- it("should keep track of its children", () => {
369
- const child = scope.$new();
370
- expect(scope.$children).toEqual([child]);
371
-
372
- const child2 = scope.$new();
373
- expect(scope.$children).toEqual([child, child2]);
374
-
375
- const child3 = child2.$new();
376
- expect(scope.$children).toEqual([child, child2]);
377
- expect(child2.$children).toEqual([child3]);
378
- });
379
-
380
- it("should can get children by id", () => {
381
- const child = scope.$new();
382
- const child2 = scope.$new();
383
- const child3 = child2.$new();
384
- const child4 = child3.$transcluded();
385
-
386
- expect(scope.$getById(child.$id).$id).toEqual(child.$id);
387
- expect(scope.$getById(child2.$id).$id).toEqual(child2.$id);
388
- expect(scope.$getById(child3.$id).$id).toEqual(child3.$id);
389
- expect(scope.$getById(child4.$id).$id).toEqual(child4.$id);
390
- });
391
- });
392
-
393
- describe("this", () => {
394
- it("should evaluate 'this' to be the scope", () => {
395
- const child = scope.$new();
396
- expect(scope.$eval("this")).toEqual(scope.$target);
397
- expect(child.$eval("this")).toEqual(child.$target);
398
- });
399
-
400
- it("'this' should not be recursive", () => {
401
- expect(scope.$eval("this.this")).toBeUndefined();
402
- expect(scope.$eval("$parent.this")).toBeUndefined();
403
- });
404
-
405
- it("should not be able to overwrite the 'this' keyword", () => {
406
- scope.this = 123;
407
- expect(scope.$eval("this")).toEqual(scope);
408
- });
409
-
410
- it("should be able to access a constant variable named 'this'", () => {
411
- scope.this = 42;
412
- expect(scope.$eval("this['this']")).toBe(42);
413
- });
414
- });
415
-
416
- describe("$watch", () => {
417
- it("needs an expression to designate a watched property", async () => {
418
- expect(() => scope.$watch()).toThrowError();
419
- });
420
-
421
- it("does not need a listener function", async () => {
422
- expect(() => scope.$watch("1")).not.toThrowError();
423
- });
424
-
425
- it("can register listeners via watch", async () => {
426
- const listenerFn = jasmine.createSpy();
427
- scope.$watch("a", listenerFn);
428
- scope.a = 1;
429
- await wait();
430
- expect(listenerFn).toHaveBeenCalled();
431
- });
432
-
433
- it("can calls a listener upon registration", async () => {
434
- const listenerFn = jasmine.createSpy();
435
- scope.$watch("a", listenerFn);
436
- await wait();
437
- expect(listenerFn).toHaveBeenCalled();
438
- });
439
-
440
- it("should return a deregistration function watch", () => {
441
- let fn = scope.$watch("a", () => {});
442
- expect(fn).toBeDefined();
443
- expect(typeof fn).toEqual("function");
444
- });
445
-
446
- it("should manipulate the $watcher count", () => {
447
- let fn = scope.$watch("a", () => {});
448
- expect(scope.$$watchersCount).toBeDefined();
449
- expect(scope.$$watchersCount).toEqual(1);
450
-
451
- fn();
452
- expect(scope.$$watchersCount).toEqual(0);
453
- });
454
-
455
- it("should not expose the `inner working of watch", async () => {
456
- let get, listen;
457
- function Listener() {
458
- listen = this;
459
- }
460
- scope.$watch("foo", Listener);
461
-
462
- scope.a = 1;
463
- await wait();
464
-
465
- expect(get).toBeUndefined();
466
- expect(listen).toBeUndefined();
467
- });
468
-
469
- it("can trigger watch from a class", async () => {
470
- let called = false;
471
- class Demo {
472
- constructor() {
473
- this.counter = 0;
474
- }
475
- test() {
476
- this.counter++;
477
- }
478
- }
479
-
480
- scope = createScope(new Demo());
481
-
482
- scope.$watch("counter", () => {
483
- called = true;
484
- });
485
-
486
- expect(scope.counter).toEqual(0);
487
- expect(called).toBeFalse();
488
-
489
- scope.test();
490
- await wait();
491
-
492
- expect(scope.counter).toEqual(1);
493
- expect(called).toBeTrue();
494
- });
495
-
496
- it("can trigger watch from a constuctor function", async () => {
497
- let called = false;
498
- function Demo() {
499
- this.counter = 0;
500
- this.test = function () {
501
- this.counter++;
502
- };
503
- }
504
-
505
- scope = createScope(new Demo());
506
-
507
- scope.$watch("counter", () => {
508
- called = true;
509
- });
510
-
511
- expect(scope.counter).toEqual(0);
512
- expect(called).toBeFalse();
513
-
514
- scope.test();
515
- await wait();
516
-
517
- expect(scope.counter).toEqual(1);
518
- expect(called).toBeTrue();
519
- });
520
-
521
- it("can trigger watch from an POJO object ", async () => {
522
- let called = false;
523
- const demo = {
524
- counter: 0,
525
- test: function () {
526
- this.counter++;
527
- },
528
- };
529
-
530
- scope = createScope(demo);
531
-
532
- scope.$watch("counter", () => {
533
- called = true;
534
- });
535
-
536
- expect(scope.counter).toEqual(0);
537
- expect(called).toBeFalse();
538
-
539
- scope.test();
540
- await wait();
541
-
542
- expect(scope.counter).toEqual(1);
543
- expect(called).toBeTrue();
544
- });
545
-
546
- it("calls the listener function when the watched value is initialized", async () => {
547
- scope.counter = 0;
548
- scope.someValue = "b";
549
- scope.$watch("someValue", () => scope.counter++);
550
- expect(scope.counter).toBe(0);
551
-
552
- await wait();
553
- expect(scope.counter).toBe(1);
554
-
555
- scope.someValue = "b";
556
- await wait();
557
- expect(scope.counter).toBe(1);
558
-
559
- scope.someValue = "c";
560
- await wait();
561
- expect(scope.counter).toBe(2);
562
- });
563
-
564
- it("calls the listener function when the watched value is destroyed", async () => {
565
- scope.counter = 0;
566
- scope.someValue = "b";
567
- expect(scope.counter).toBe(0);
568
-
569
- scope.$watch("someValue", () => scope.counter++);
570
- await wait();
571
- expect(scope.counter).toBe(1);
572
-
573
- delete scope.someValue;
574
- await wait();
575
- expect(scope.counter).toBe(2);
576
- });
577
-
578
- it("can call multiple the listener functions when the watched value changes", async () => {
579
- scope.someValue = "a";
580
- scope.counter = 0;
581
-
582
- scope.$watch("someValue", () => {
583
- scope.counter++;
584
- });
585
-
586
- scope.$watch("someValue", () => scope.counter++);
587
- await wait();
588
- expect(scope.counter).toBe(2);
589
-
590
- scope.someValue = "b";
591
- await wait();
592
- expect(scope.counter).toBe(4);
593
- });
594
-
595
- it("calls only the listeners registerred at the moment the watched value changes", async () => {
596
- scope.someValue = "a";
597
- scope.counter = 0;
598
-
599
- scope.$watch("someValue", () => scope.counter++);
600
- await wait();
601
- expect(scope.counter).toBe(1);
602
-
603
- scope.someValue = "b";
604
- await wait();
605
- expect(scope.counter).toBe(2);
606
-
607
- scope.$watch("someValue", () => {
608
- scope.counter++;
609
- });
610
- await wait();
611
- expect(scope.counter).toBe(3);
612
-
613
- scope.someValue = "b";
614
- await wait();
615
- expect(scope.counter).toBe(3);
616
-
617
- scope.someValue = "c";
618
- await wait();
619
- expect(scope.counter).toBe(5);
620
- });
621
-
622
- it("correctly handles NaNs", async () => {
623
- scope.counter = 0;
624
- scope.$watch("number", function (newValue, scope) {
625
- scope.counter++;
626
- });
627
- scope.number = 0 / 0;
628
- await wait();
629
- expect(scope.number).toBeNaN();
630
- expect(scope.counter).toBe(2);
631
-
632
- scope.number = NaN;
633
- await wait();
634
- expect(scope.number).toBeNaN();
635
- expect(scope.counter).toBe(2);
636
- });
637
-
638
- it("calls listener with undefined old value the first time", async () => {
639
- let newValueGiven;
640
- scope.$watch("someValue", function (newValue, scope) {
641
- newValueGiven = newValue;
642
- });
643
- scope.someValue = 123;
644
- await wait();
645
- expect(newValueGiven).toBe(123);
646
- });
647
-
648
- it("calls listener with new value and old value the first time if defined", async () => {
649
- let newValueGiven;
650
- scope.someValue = 123;
651
-
652
- scope.$watch("someValue", function (newValue) {
653
- newValueGiven = newValue;
654
- });
655
- scope.someValue = 321;
656
- await wait();
657
-
658
- expect(newValueGiven).toBe(321);
659
- });
660
-
661
- it("calls listener with with the instance of a scope as 2nd argument", async () => {
662
- let scopeInstance;
663
- scope.someValue = 123;
664
-
665
- scope.$watch("someValue", function (_1, m) {
666
- scopeInstance = m;
667
- });
668
- scope.someValue = 321;
669
- await wait();
670
-
671
- expect(scopeInstance).toBeDefined();
672
- expect(scopeInstance).toEqual(scope);
673
- });
674
-
675
- it("triggers chained watchers in the same scope change", async () => {
676
- scope.$watch("nameUpper", function (newValue) {
677
- if (newValue) {
678
- scope.initial = newValue.substring(0, 1) + ".";
679
- }
680
- });
681
- scope.$watch("name", function (newValue) {
682
- if (newValue) {
683
- scope.nameUpper = newValue.toUpperCase();
684
- }
685
- });
686
- scope.name = "Jane";
687
- await wait();
688
- expect(scope.initial).toBe("J.");
689
-
690
- scope.name = "Bob";
691
- await wait();
692
- expect(scope.initial).toBe("B.");
693
- });
694
-
695
- it("can register nested watches", async () => {
696
- scope.counter = 0;
697
- scope.aValue = "abc";
698
- scope.$watch("aValue", () => {
699
- scope.$watch("bValue", () => {
700
- scope.counter++;
701
- });
702
- });
703
- scope.aValue = "2";
704
- await wait();
705
- expect(scope.counter).toBe(2);
706
-
707
- scope.bValue = "3";
708
- await wait();
709
- expect(scope.counter).toBe(4);
710
-
711
- scope.aValue = "6";
712
- await wait();
713
- expect(scope.counter).toBe(5);
714
- });
715
-
716
- it("should delegate exceptions", async () => {
717
- scope.$watch("a", () => {
718
- throw new Error("abc");
719
- });
720
- scope.a = 1;
721
- await wait();
722
- expect(logs[0]).toMatch(/abc/);
723
- });
724
-
725
- it("should fire watches in order of addition", async () => {
726
- // this is not an external guarantee, just our own sanity
727
- logs = "";
728
- scope.$watch("a", () => {
729
- logs += "a";
730
- });
731
- scope.$watch("b", () => {
732
- logs += "b";
733
- });
734
- // constant expressions have slightly different handling as they are executed in priority
735
- scope.$watch("1", () => {
736
- logs += "1";
737
- });
738
- scope.$watch("c", () => {
739
- logs += "c";
740
- });
741
- scope.$watch("2", () => {
742
- logs += "2";
743
- });
744
- scope.a = 1;
745
- scope.b = 1;
746
- scope.c = 1;
747
- await wait();
748
- expect(logs).toEqual("ab1c2abc");
749
- });
750
-
751
- it("should repeat watch cycle while scope changes are identified", async () => {
752
- logs = "";
753
- scope.$watch("c", (v) => {
754
- scope.d = v;
755
- logs += "c";
756
- });
757
- scope.$watch("b", (v) => {
758
- scope.c = v;
759
- logs += "b";
760
- });
761
- scope.$watch("a", (v) => {
762
- scope.b = v;
763
- logs += "a";
764
- });
765
- await wait();
766
- expect(logs).toEqual("cba");
767
- logs = "";
768
- scope.a = 1;
769
- await wait();
770
- expect(scope.a).toEqual(1);
771
- expect(scope.b).toEqual(1);
772
- expect(scope.c).toEqual(1);
773
- expect(scope.d).toEqual(1);
774
- expect(logs).toEqual("abc");
775
- });
776
-
777
- describe("constants", () => {
778
- it("does not watch constants", async () => {
779
- scope.$watch("1", () => {});
780
- expect(scope.$$watchersCount).toBe(0);
781
- await wait();
782
- expect(scope.$$watchersCount).toBe(0);
783
- });
784
-
785
- const cases = [
786
- { expression: "1", expected: 1 },
787
- { expression: "'a'", expected: "a" },
788
- { expression: "[1,2,3]", expected: [1, 2, 3] },
789
- { expression: "false", expected: false },
790
- { expression: "null", expected: null },
791
- { expression: '{x: 1}["x"]', expected: 1 },
792
- { expression: "2 + 2", expected: 4 },
793
- { expression: "2 / 0", expected: Infinity },
794
- { expression: "false || 2", expected: 2 },
795
- { expression: "false && 2", expected: false },
796
- ];
797
-
798
- for (const { expression, expected } of cases) {
799
- it("passes constants to listener cb " + expression, async () => {
800
- let res;
801
- scope.$watch(expression, (val) => {
802
- res = val;
803
- });
804
-
805
- await wait();
806
- expect(res).toEqual(expected);
807
- });
808
- }
809
- });
810
-
811
- describe("expressions", () => {
812
- it("its should increase the count of watchers", async () => {
813
- logs = "";
814
- scope.a = 1;
815
- scope.$watch("a", () => {
816
- logs += "a";
817
- });
818
- scope.$watch("b", () => {
819
- logs += "b";
820
- });
821
-
822
- expect(scope.$handler.watchers.size).toEqual(2);
823
- expect(scope.$$watchersCount).toEqual(scope.$handler.watchers.size);
824
- });
825
-
826
- it("should fire upon $watch registration on initial registeration", async () => {
827
- logs = "";
828
- scope.a = 1;
829
- scope.$watch("a", () => {
830
- logs += "a";
831
- });
832
- scope.$watch("b", () => {
833
- logs += "b";
834
- });
835
- await wait();
836
- expect(logs).toEqual("ab");
837
- });
838
-
839
- it("invokes a callback on property change", async () => {
840
- let newV, target;
841
- scope.$watch("foo", (a, b) => {
842
- newV = a;
843
- target = b;
844
- });
845
-
846
- scope.foo = 1;
847
- await wait();
848
- expect(newV).toEqual(1);
849
- expect(target).toEqual(scope.$target);
850
-
851
- scope.foo = 2;
852
- await wait();
853
- expect(newV).toEqual(2);
854
- expect(target).toEqual(scope.$target);
855
-
856
- scope.foo = [];
857
- await wait();
858
- expect(newV).toEqual([]);
859
- expect(target).toEqual(scope.$target);
860
- });
861
-
862
- it("calls the listener function when the watched value changes", async () => {
863
- scope.counter = 0;
864
- scope.$watch("someValue", function (newValue, scope) {
865
- scope.counter++;
866
- });
867
- await wait();
868
- expect(scope.counter).toBe(1);
869
-
870
- scope.someValue = "1";
871
- await wait();
872
- expect(scope.counter).toBe(2);
873
-
874
- scope.someValue = "2";
875
- await wait();
876
- expect(scope.counter).toBe(3);
877
- });
878
-
879
- it("should watch and fire on simple property change", async () => {
880
- const spy = jasmine.createSpy();
881
- scope.$watch("name", spy);
882
-
883
- spy.calls.reset();
884
-
885
- expect(spy).not.toHaveBeenCalled();
886
- scope.name = "misko";
887
- await wait();
888
- expect(spy).toHaveBeenCalledWith("misko", scope);
889
- });
890
-
891
- it("should watch and fire on correct expression change", async () => {
892
- const spy = jasmine.createSpy();
893
- scope.$watch("name.first", spy);
894
- await wait();
895
- expect(spy).toHaveBeenCalled();
896
-
897
- spy.calls.reset();
898
- scope.name = {};
899
- await wait();
900
- expect(spy).not.toHaveBeenCalled();
901
-
902
- spy.calls.reset();
903
- scope.first = "bruno";
904
- await wait();
905
- expect(spy).not.toHaveBeenCalled();
906
-
907
- spy.calls.reset();
908
- scope.name.first = "misko";
909
- await wait();
910
- expect(spy).toHaveBeenCalled();
911
-
912
- spy.calls.reset();
913
- scope.first = "misko";
914
- await wait();
915
- expect(spy).not.toHaveBeenCalled();
916
- });
917
- });
918
-
919
- describe("array expressions", () => {
920
- it("adds watches for array expressions", async () => {
921
- expect(scope.$$watchersCount).toBe(0);
922
- scope.$watch("foo[0]", () => {});
923
-
924
- await wait();
925
- expect(scope.$$watchersCount).toBe(1);
926
- });
927
-
928
- it("adds watches for array expressions", async () => {
929
- expect(scope.$$watchersCount).toBe(0);
930
- let res;
931
-
932
- scope.$watch("foo[0]", (val) => {
933
- res = val;
934
- });
935
-
936
- scope.foo = [];
937
- await wait();
938
- expect(scope.$$watchersCount).toBe(1);
939
-
940
- scope.foo = [1];
941
- await wait();
942
- expect(res).toEqual(1);
943
-
944
- scope.foo = [2];
945
- await wait();
946
- expect(res).toEqual(2);
947
- });
948
- });
949
-
950
- describe("apply expression", () => {
951
- it("adds watches for expressions", async () => {
952
- expect(scope.$$watchersCount).toBe(0);
953
- scope.$watch("foo = 1", () => {});
954
-
955
- await wait();
956
- expect(scope.$$watchersCount).toBe(1);
957
- });
958
-
959
- it("applies a property change and continues watching the scopes", async () => {
960
- expect(scope.$$watchersCount).toBe(0);
961
- scope.$watch("foo = 2", () => {});
962
-
963
- await wait();
964
- expect(scope.$$watchersCount).toBe(1);
965
- expect(scope.$handler.watchers.has("foo")).toBeTrue();
966
- expect(scope.foo).toBe(2);
967
-
968
- scope.$watch("boo = 3", () => {});
969
-
970
- await wait();
971
- expect(scope.$$watchersCount).toBe(2);
972
- expect(scope.boo).toBe(3);
973
- });
974
-
975
- it("should apply a change and not increase watchers if no listener function", async () => {
976
- expect(scope.$$watchersCount).toBe(0);
977
- scope.$watch("foo = 2");
978
-
979
- await wait();
980
- expect(scope.$$watchersCount).toBe(0);
981
- expect(scope.foo).toBe(2);
982
-
983
- scope.$watch("foo = 3");
984
-
985
- await wait();
986
- expect(scope.$$watchersCount).toBe(0);
987
- expect(scope.foo).toBe(3);
988
- });
989
- });
990
-
991
- describe("filters", () => {
992
- it("applies filters to constants", async () => {
993
- expect(scope.$$watchersCount).toBe(0);
994
- let res;
995
- scope.$watch("'abcd'|limitTo:3", (val) => {
996
- res = val;
997
- });
998
- await wait();
999
- expect(res).toEqual("abc");
1000
-
1001
- scope.$watch("'abcd'|limitTo:3|limitTo:2", (val) => {
1002
- res = val;
1003
- });
1004
-
1005
- await wait();
1006
- expect(res).toEqual("ab");
1007
-
1008
- scope.$watch("'abcd'|limitTo:3|limitTo:2|limitTo:1", (val) => {
1009
- res = val;
1010
- });
1011
-
1012
- await wait();
1013
- expect(res).toEqual("a");
1014
- });
1015
- });
1016
-
1017
- describe("$watch on constants", () => {
1018
- beforeEach(() => (logs = []));
1019
- it("should not $watch constant literals ", () => {
1020
- scope.$watch("[]", () => {});
1021
- scope.$watch("{}", () => {});
1022
- scope.$watch("1", () => {});
1023
- scope.$watch('"foo"', () => {});
1024
- expect(scope.$$watchersCount).toEqual(0);
1025
- });
1026
-
1027
- it("should not $watch filtered literals", () => {
1028
- scope.$watch('[1] | filter:"x"', () => {});
1029
- scope.$watch("1 | limitTo:2", () => {});
1030
- expect(scope.$$watchersCount).toEqual(0);
1031
- });
1032
-
1033
- it("should ignore $watch of constant expressions", () => {
1034
- scope.$watch("1 + 1", () => {});
1035
- scope.$watch('"a" + "b"', () => {});
1036
- scope.$watch('"ab".length', () => {});
1037
- scope.$watch("[].length", () => {});
1038
- scope.$watch("(1 + 1) | limitTo:2", () => {});
1039
- expect(scope.$$watchersCount).toEqual(0);
1040
- });
1041
- });
1042
-
1043
- describe("watching objects", () => {
1044
- it("should watch objects", async () => {
1045
- scope.a = { c: 2 };
1046
- scope.$watch("a", (value) => {
1047
- logs += "success";
1048
- expect(value).toEqual(scope.a);
1049
- });
1050
- await wait();
1051
- logs = "";
1052
- scope.a.c = "1";
1053
-
1054
- await wait();
1055
- expect(logs).toEqual("success");
1056
- });
1057
-
1058
- it("calls the listener function registered via function when a value is created as an object", async () => {
1059
- scope.counter = 0;
1060
-
1061
- scope.$watch("someValue", () => {
1062
- scope.counter++;
1063
- });
1064
- await wait();
1065
-
1066
- expect(scope.counter).toBe(1);
1067
-
1068
- scope.someValue = {};
1069
- await wait();
1070
-
1071
- expect(scope.counter).toBe(2);
1072
-
1073
- scope.someValue = { a: 3 };
1074
- await wait();
1075
-
1076
- expect(scope.counter).toBe(3);
1077
-
1078
- // Should not trigger as we are updating the inner object and we are not listening on its property
1079
- scope.someValue.a = 4;
1080
- await wait();
1081
-
1082
- expect(scope.counter).toBe(3);
1083
- });
1084
-
1085
- it("calls the listener function registered via expression when a value is created as an object", async () => {
1086
- scope.counter = 0;
1087
-
1088
- scope.$watch("someValue", () => {
1089
- scope.counter++;
1090
- });
1091
- await wait();
1092
-
1093
- expect(scope.counter).toBe(1);
1094
-
1095
- scope.someValue = {};
1096
- await wait();
1097
-
1098
- expect(scope.counter).toBe(2);
1099
- });
1100
-
1101
- it("calls the listener function registered via function when a value is created on a nested object", async () => {
1102
- scope.counter = 0;
1103
- scope.a = { someValue: 1 };
1104
- scope.$watch("a.someValue", () => {
1105
- scope.counter++;
1106
- });
1107
- await wait();
1108
- expect(scope.counter).toBe(1);
1109
-
1110
- scope.a.someValue = 2;
1111
-
1112
- await wait();
1113
- expect(scope.counter).toBe(2);
1114
-
1115
- scope.a.someValue = 3;
1116
- await wait();
1117
- expect(scope.counter).toBe(3);
1118
- });
1119
-
1120
- it("calls the listener function registered via expression when a value is created on a nested object", async () => {
1121
- scope.counter = 0;
1122
- scope.a = { someValue: 1 };
1123
-
1124
- scope.$watch("a.someValue", () => {
1125
- scope.counter++;
1126
- });
1127
-
1128
- await wait();
1129
- expect(scope.counter).toBe(1);
1130
-
1131
- scope.a.someValue = 2;
1132
-
1133
- await wait();
1134
- expect(scope.counter).toBe(2);
1135
-
1136
- scope.a.someValue = 3;
1137
- await wait();
1138
- expect(scope.counter).toBe(3);
1139
- });
1140
-
1141
- it("calls the listener function when a nested value is created on an empty wrapper object", async () => {
1142
- scope.counter = 0;
1143
- scope.someValue = {};
1144
-
1145
- scope.$watch("someValue.b", () => {
1146
- scope.counter++;
1147
- });
1148
- await wait();
1149
-
1150
- expect(scope.counter).toBe(1);
1151
- scope.someValue = { b: 2 };
1152
- await wait();
1153
-
1154
- expect(scope.counter).toBe(2);
1155
- });
1156
-
1157
- it("calls the listener function when a nested value is created on an undefined wrapper object", async () => {
1158
- scope.counter = 0;
1159
- scope.someValue = undefined;
1160
-
1161
- scope.$watch("someValue.b", async () => {
1162
- scope.counter++;
1163
- });
1164
- await wait();
1165
-
1166
- expect(scope.counter).toBe(1);
1167
-
1168
- scope.someValue = { b: 2 };
1169
- await wait();
1170
-
1171
- expect(scope.counter).toBe(2);
1172
-
1173
- scope.someValue.b = 3;
1174
- await wait();
1175
-
1176
- expect(scope.counter).toBe(3);
1177
- });
1178
-
1179
- it("calls the listener function when a nested value is created from a wrapper object", async () => {
1180
- scope.someValue = { b: 1 };
1181
- scope.counter = 0;
1182
-
1183
- scope.$watch("someValue.b", () => scope.counter++);
1184
- await wait();
1185
- expect(scope.counter).toBe(1);
1186
-
1187
- scope.someValue = { b: 2 };
1188
- await wait();
1189
- expect(scope.counter).toBe(2);
1190
-
1191
- scope.someValue = { c: 2 };
1192
- await wait();
1193
- expect(scope.counter).toBe(3);
1194
-
1195
- scope.someValue = { b: 2 };
1196
- await wait();
1197
- expect(scope.counter).toBe(4);
1198
-
1199
- scope.someValue = undefined;
1200
- await wait();
1201
- expect(scope.counter).toBe(5);
1202
- });
1203
-
1204
- it("call the listener function when a nested value is created from an instance", async () => {
1205
- let ctrl = createScope({ scope: { name: "John" } });
1206
- let count = 0;
1207
- expect(ctrl.scope.name).toEqual("John");
1208
-
1209
- ctrl.$watch("scope.name", () => {
1210
- count++;
1211
- });
1212
- await wait();
1213
- expect(count).toEqual(1);
1214
-
1215
- ctrl.scope.name = "Bob";
1216
- await wait();
1217
- expect(count).toEqual(2);
1218
-
1219
- ctrl.scope.name = "John";
1220
- await wait();
1221
- expect(count).toEqual(3);
1222
-
1223
- ctrl.scope.lastName = "NaN";
1224
- await wait();
1225
-
1226
- expect(count).toEqual(3);
1227
- });
1228
-
1229
- it("calls the listener function when a deeply nested watched value changes", async () => {
1230
- scope.counter = 0;
1231
- scope.someValue = { b: { c: { d: 1 } } };
1232
-
1233
- scope.$watch("someValue.b.c.d", function (newValue, scope) {
1234
- scope.counter++;
1235
- });
1236
- await wait();
1237
- expect(scope.counter).toBe(1);
1238
-
1239
- scope.someValue.b.c.d = 2;
1240
- await wait();
1241
- expect(scope.counter).toBe(2);
1242
-
1243
- scope.someValue = { b: { c: { d: 3 } } };
1244
- await wait();
1245
-
1246
- expect(scope.counter).toBe(3);
1247
- });
1248
-
1249
- it("call the listener function on correct listener", async () => {
1250
- scope.counter = 0;
1251
- scope.someValue = { b: { c: 1 } };
1252
-
1253
- scope.$watch("someValue.b.c", function (newValue, scope) {
1254
- scope.counter++;
1255
- });
1256
- await wait();
1257
- expect(scope.counter).toBe(1);
1258
-
1259
- scope.c = 5;
1260
- await wait();
1261
- expect(scope.counter).toBe(1);
1262
- });
1263
-
1264
- it("calls the listener function when a deeply nested watched value is initially undefined", async () => {
1265
- scope.counter = 0;
1266
- scope.someValue = { b: { c: undefined } };
1267
-
1268
- scope.$watch("someValue.b.c.d", function (newValue, scope) {
1269
- scope.counter++;
1270
- });
1271
- await wait();
1272
- expect(scope.counter).toBe(1);
1273
-
1274
- scope.someValue = { b: { c: { d: 2 } } };
1275
- await wait();
1276
- expect(scope.counter).toBe(2);
1277
-
1278
- scope.someValue.b.c.d = 3;
1279
- await wait();
1280
- expect(scope.counter).toBe(3);
1281
- });
1282
- });
1283
-
1284
- describe("inherited $watch", () => {
1285
- it("should decrement the watcherCount when destroying a child scope", () => {
1286
- const child1 = scope.$new();
1287
- const child2 = scope.$new();
1288
-
1289
- expect(scope.$$watchersCount).toBe(0);
1290
- expect(child1.$$watchersCount).toBe(0);
1291
- expect(child1.$$watchersCount).toBe(0);
1292
-
1293
- const grandChild1 = child1.$new();
1294
- const grandChild2 = child2.$new();
1295
- child1.$watch("a", () => {});
1296
- expect(scope.$$watchersCount).toBe(1);
1297
- expect(child1.$$watchersCount).toBe(1);
1298
-
1299
- child2.$watch("a", () => {});
1300
- expect(scope.$$watchersCount).toBe(2);
1301
- expect(child2.$$watchersCount).toBe(1);
1302
-
1303
- grandChild1.$watch("a", () => {});
1304
- expect(grandChild1.$$watchersCount).toBe(1);
1305
- expect(child1.$$watchersCount).toBe(2);
1306
-
1307
- grandChild2.$watch("a", () => {});
1308
- expect(grandChild2.$$watchersCount).toBe(1);
1309
- expect(child2.$$watchersCount).toBe(2);
1310
-
1311
- // a watcher is shared by all
1312
- expect(scope.$$watchersCount).toBe(4);
1313
- expect(child1.$$watchersCount).toBe(2);
1314
- expect(grandChild1.$$watchersCount).toBe(1);
1315
- expect(child2.$$watchersCount).toBe(2);
1316
- expect(grandChild1.$$watchersCount).toBe(1);
1317
- expect(grandChild2.$$watchersCount).toBe(1);
1318
- grandChild2.$destroy();
1319
-
1320
- expect(child2.$$watchersCount).toBe(1);
1321
- expect(scope.$$watchersCount).toBe(3);
1322
-
1323
- child1.$destroy();
1324
- expect(child1.$$watchersCount).toBe(1);
1325
- expect(scope.$$watchersCount).toBe(1);
1326
- });
1327
-
1328
- it("should decrement the watcherCount when calling the remove function", () => {
1329
- const child1 = scope.$new();
1330
- const child2 = scope.$new();
1331
- const grandChild1 = child1.$new();
1332
- const grandChild2 = child2.$new();
1333
- let remove1 = child1.$watch("a", () => {});
1334
- child2.$watch("a", () => {});
1335
- grandChild1.$watch("a", () => {});
1336
- let remove2 = grandChild2.$watch("a", () => {});
1337
-
1338
- expect(grandChild2.$$watchersCount).toBe(1);
1339
- expect(child2.$$watchersCount).toBe(2);
1340
- expect(scope.$$watchersCount).toBe(4);
1341
-
1342
- expect(remove2()).toBeTrue();
1343
- expect(grandChild2.$$watchersCount).toBe(0);
1344
- expect(child2.$$watchersCount).toBe(1);
1345
- expect(scope.$$watchersCount).toBe(3);
1346
-
1347
- expect(grandChild1.$$watchersCount).toBe(1);
1348
- expect(child1.$$watchersCount).toBe(2);
1349
-
1350
- expect(remove1()).toBeTrue();
1351
- expect(grandChild1.$$watchersCount).toBe(1);
1352
- expect(child1.$$watchersCount).toBe(1);
1353
- expect(scope.$$watchersCount).toBe(2);
1354
-
1355
- // Execute everything a second time to be sure that calling the remove function
1356
- // several times, it only decrements the counter once
1357
- remove2();
1358
- expect(child2.$$watchersCount).toBe(1);
1359
- expect(scope.$$watchersCount).toBe(2);
1360
- remove1();
1361
- expect(child1.$$watchersCount).toBe(1);
1362
- expect(scope.$$watchersCount).toBe(2);
1363
- });
1364
-
1365
- it("should call child $watchers in addition order", async () => {
1366
- logs = "";
1367
- const childA = scope.$new();
1368
- childA.$watch("a", () => {
1369
- logs += "a";
1370
- });
1371
- childA.$watch("a", () => {
1372
- logs += "b";
1373
- });
1374
- childA.$watch("a", () => {
1375
- logs += "c";
1376
- });
1377
- await wait();
1378
- logs = "";
1379
- childA.a = 1;
1380
- await wait();
1381
- expect(logs).toEqual("abc");
1382
- });
1383
-
1384
- it("should share listeners with parent", async () => {
1385
- logs = "";
1386
- const childA = scope.$new();
1387
- const childB = scope.$new();
1388
-
1389
- scope.$watch("a", () => {
1390
- logs += "r";
1391
- });
1392
-
1393
- childA.$watch("a", () => {
1394
- logs += "a";
1395
- });
1396
- childB.$watch("a", () => {
1397
- logs += "b";
1398
- });
1399
- await wait();
1400
- logs = "";
1401
-
1402
- // init
1403
- scope.a = 1;
1404
- await wait();
1405
- expect(logs).toBe("rab");
1406
-
1407
- logs = "";
1408
- childA.a = 3;
1409
- await wait();
1410
- expect(logs).toBe("rab");
1411
-
1412
- logs = "";
1413
- childA.a = 4;
1414
- await wait();
1415
- expect(logs).toBe("rab");
1416
- });
1417
-
1418
- it("should repeat watch cycle from the root element", async () => {
1419
- logs = "";
1420
- const child = scope.$new();
1421
- scope.$watch("c", () => {
1422
- logs += "a";
1423
- });
1424
- child.$watch("c", () => {
1425
- logs += "b";
1426
- });
1427
- await wait();
1428
- logs = "";
1429
- scope.c = 1;
1430
- child.c = 2;
1431
- await wait();
1432
- expect(logs).toEqual("abab");
1433
- });
1434
- });
1435
-
1436
- it("should watch functions", async () => {
1437
- scope.$watch("fn", (fn) => {
1438
- logs.push(fn);
1439
- });
1440
- await wait();
1441
- logs = [];
1442
- scope.fn = function () {
1443
- return "a";
1444
- };
1445
- await wait();
1446
- expect(logs).toEqual(["a"]);
1447
- scope.fn = function () {
1448
- return "b";
1449
- };
1450
- await wait();
1451
- expect(logs).toEqual(["a", "b"]);
1452
- });
1453
-
1454
- it("should allow a watch to be added while in a digest", async () => {
1455
- const watch1 = jasmine.createSpy("watch1");
1456
- const watch2 = jasmine.createSpy("watch2");
1457
- scope.$watch("foo", () => {
1458
- scope.$watch("foo", watch1);
1459
- scope.$watch("foo", watch2);
1460
- });
1461
-
1462
- scope.$apply("foo = true");
1463
- await wait();
1464
- expect(watch1).toHaveBeenCalled();
1465
- expect(watch2).toHaveBeenCalled();
1466
- });
1467
-
1468
- it("should not skip watchers when adding new watchers during digest", async () => {
1469
- const watch1 = jasmine.createSpy("watch1");
1470
- const watch2 = jasmine.createSpy("watch2");
1471
- scope.$watch("foo", () => {
1472
- scope.$watch("foo", watch1);
1473
- scope.$watch("foo", watch2);
1474
- });
1475
- scope.foo = "a";
1476
- await wait();
1477
- expect(watch1).toHaveBeenCalled();
1478
- expect(watch2).toHaveBeenCalled();
1479
- });
1480
-
1481
- it("should not skip watchers when adding new watchers during property update", async () => {
1482
- const watch1 = jasmine.createSpy("watch1");
1483
- const watch2 = jasmine.createSpy("watch2");
1484
- scope.$watch("foo", () => {
1485
- scope.$watch("foo", watch1);
1486
- scope.$watch("foo", watch2);
1487
- });
1488
- scope.foo = 2;
1489
- await wait();
1490
- expect(watch1).toHaveBeenCalled();
1491
- expect(watch2).toHaveBeenCalled();
1492
- });
1493
-
1494
- describe("$watch deregistration", () => {
1495
- beforeEach(() => (logs = []));
1496
- it("should return a function that allows listeners to be deregistered", async () => {
1497
- const listener = jasmine.createSpy("watch listener");
1498
- let listenerRemove;
1499
-
1500
- listenerRemove = scope.$watch("foo", listener);
1501
-
1502
- expect(listener).not.toHaveBeenCalled();
1503
- expect(listenerRemove).toBeDefined();
1504
-
1505
- scope.foo = "bar";
1506
- await wait();
1507
- expect(listener).toHaveBeenCalled();
1508
-
1509
- listener.calls.reset();
1510
- listenerRemove();
1511
- scope.foo = "baz";
1512
- await wait();
1513
- expect(listener).not.toHaveBeenCalled();
1514
- });
1515
-
1516
- it("should allow a watch to be deregistered while in a digest", async () => {
1517
- let remove1;
1518
- let remove2;
1519
- scope.$watch("remove", () => {
1520
- remove1();
1521
- remove2();
1522
- });
1523
- remove1 = scope.$watch("thing", () => {});
1524
- remove2 = scope.$watch("thing", () => {});
1525
- expect(async () => {
1526
- scope.$apply("remove = true");
1527
- await wait();
1528
- }).not.toThrow();
1529
- });
1530
- });
1531
-
1532
- describe("watching arrays", () => {
1533
- it("can watch arrays", async () => {
1534
- scope.aValue = [1, 2, 3];
1535
- scope.counter = 0;
1536
- scope.$watch("aValue", function (newValue, m) {
1537
- m.counter++;
1538
- });
1539
- await wait();
1540
- expect(scope.counter).toBe(1);
1541
-
1542
- scope.aValue.push(4);
1543
- await wait();
1544
- expect(scope.counter).toBe(2);
1545
-
1546
- scope.aValue.pop();
1547
- await wait();
1548
- expect(scope.counter).toBe(3);
1549
-
1550
- scope.aValue.unshift(4);
1551
- await wait();
1552
- expect(scope.counter).toBe(4);
1553
- });
1554
-
1555
- it("can pass the new value of the array as well as the previous value of the dropped item", async () => {
1556
- scope.aValue = [];
1557
- let newValueGiven;
1558
- scope.$watch("aValue", function (newValue) {
1559
- newValueGiven = newValue;
1560
- });
1561
-
1562
- scope.aValue.push(4);
1563
- await wait();
1564
- expect(newValueGiven).toEqual(scope.aValue);
1565
-
1566
- scope.aValue.push(5);
1567
- await wait();
1568
- expect(newValueGiven).toEqual([4, 5]);
1569
-
1570
- scope.aValue[1] = 2;
1571
- await wait();
1572
- expect(newValueGiven).toEqual([4, 2]);
1573
-
1574
- scope.aValue[0] = 2;
1575
- await wait();
1576
- expect(newValueGiven).toEqual([2, 2]);
1577
- });
1578
-
1579
- it("can detect removal of items", async () => {
1580
- scope.aValue = [2, 3];
1581
- let newValueGiven;
1582
- scope.$watch("aValue", function (newValue) {
1583
- newValueGiven = newValue;
1584
- });
1585
-
1586
- scope.aValue.pop();
1587
- await wait();
1588
- expect(newValueGiven).toEqual([2]);
1589
- });
1590
-
1591
- it("should return oldCollection === newCollection only on the first listener call", async () => {
1592
- // first time should be identical
1593
- scope.aValue = ["a", "b"];
1594
- scope.counter = 0;
1595
- let newValueGiven;
1596
- scope.$watch("aValue", function (newValue, m) {
1597
- newValueGiven = newValue;
1598
- m.counter++;
1599
- });
1600
- await wait();
1601
- expect(scope.counter).toBe(1);
1602
-
1603
- scope.aValue[1] = "c";
1604
- await wait();
1605
- expect(newValueGiven).toEqual(["a", "c"]);
1606
- expect(scope.counter).toBe(2);
1607
- });
1608
-
1609
- it("should trigger when property changes into array", async () => {
1610
- scope.aValue = "test";
1611
- scope.counter = 0;
1612
- let newValue;
1613
- scope.$watch("aValue", function (newV, m) {
1614
- m.counter++;
1615
- newValue = newV;
1616
- });
1617
-
1618
- scope.aValue = [];
1619
- await wait();
1620
- expect(scope.counter).toBe(2);
1621
- expect(newValue).toEqual([]);
1622
-
1623
- scope.aValue = {};
1624
- await wait();
1625
- expect(scope.counter).toBe(3);
1626
- expect(newValue).toEqual({});
1627
-
1628
- scope.aValue = [];
1629
- await wait();
1630
- expect(scope.counter).toBe(4);
1631
- expect(newValue).toEqual([]);
1632
-
1633
- scope.aValue = {};
1634
- await wait();
1635
- expect(scope.counter).toBe(5);
1636
-
1637
- scope.aValue = undefined;
1638
- await wait();
1639
- expect(scope.counter).toBe(6);
1640
- expect(newValue).toEqual(undefined);
1641
- });
1642
-
1643
- it("should allow deregistration", async () => {
1644
- scope.obj = [];
1645
- count = 0;
1646
- let deregister = scope.$watch("obj", (newVal) => {
1647
- logs.push(newVal);
1648
- count++;
1649
- });
1650
-
1651
- scope.obj.push("a");
1652
- await wait();
1653
- expect(logs.length).toBe(2);
1654
- expect(count).toEqual(2);
1655
-
1656
- scope.obj.push("a");
1657
- await wait();
1658
- expect(logs.length).toBe(3);
1659
- expect(count).toEqual(3);
1660
-
1661
- deregister();
1662
- scope.obj.push("a");
1663
- await wait();
1664
- expect(logs.length).toBe(3);
1665
- expect(count).toEqual(3);
1666
- });
1667
-
1668
- it("should not trigger change when object in collection changes", async () => {
1669
- scope.$watch("obj", function () {
1670
- count++;
1671
- });
1672
- scope.obj = [{}];
1673
- await wait();
1674
- expect(count).toEqual(2);
1675
-
1676
- scope.obj[0].name = "foo";
1677
- await wait();
1678
- expect(count).toEqual(2);
1679
- });
1680
-
1681
- it("should watch array properties", async () => {
1682
- let counter = 0;
1683
- scope.obj = [];
1684
- scope.$watch("obj", function () {
1685
- counter++;
1686
- });
1687
- await wait();
1688
- expect(counter).toEqual(1);
1689
-
1690
- scope.obj.push("a");
1691
-
1692
- await wait();
1693
- expect(counter).toEqual(2);
1694
-
1695
- scope.obj[0] = "b";
1696
- await wait();
1697
- expect(counter).toEqual(3);
1698
-
1699
- scope.obj.push([]);
1700
- scope.obj.push({});
1701
- expect(scope.obj.length).toBe(3);
1702
- await wait();
1703
- expect(counter).toEqual(5);
1704
-
1705
- scope.obj.shift();
1706
- await wait();
1707
- expect(counter).toEqual(6);
1708
-
1709
- scope.obj[0] = "c";
1710
- await wait();
1711
- expect(counter).toEqual(7);
1712
-
1713
- scope.obj.pop();
1714
- await wait();
1715
- expect(counter).toEqual(8);
1716
- });
1717
-
1718
- it("should watch array-like objects like arrays", async () => {
1719
- let counter = 0;
1720
- scope.$watch("obj", function () {
1721
- counter++;
1722
- });
1723
- scope.obj = document.getElementsByTagName("src");
1724
- await wait();
1725
- expect(counter).toEqual(2);
1726
- });
1727
- });
1728
-
1729
- describe("watching other proxies", () => {
1730
- it("should register a foreign proxies ", async () => {
1731
- let scope1 = createScope();
1732
- scope1.service = createScope({ b: 2 });
1733
- expect(scope1.$handler.foreignProxies.size).toEqual(1);
1734
- });
1735
-
1736
- it("should detect changes on another proxy", async () => {
1737
- let scope1 = createScope();
1738
- let scope2 = createScope({ b: 2 });
1739
- let count = 0;
1740
-
1741
- scope1.service = scope2;
1742
- scope1.$watch("service.b", () => {
1743
- count++;
1744
- });
1745
-
1746
- scope2.$watch("b", () => {
1747
- count++;
1748
- });
1749
-
1750
- scope2.b = 1;
1751
- await wait();
1752
-
1753
- expect(count).toBe(4);
1754
- });
1755
- });
1756
-
1757
- describe("$watch", () => {
1758
- describe("constiable", () => {
1759
- let deregister;
1760
- beforeEach(async () => {
1761
- logs = [];
1762
-
1763
- deregister = scope.$watch("obj", (newVal) => {
1764
- const msg = { newVal };
1765
- logs.push(msg);
1766
- });
1767
-
1768
- await wait();
1769
- logs = [];
1770
- });
1771
-
1772
- describe("object", () => {
1773
- it("should return undefined for old value the first listener call", async () => {
1774
- scope.obj = { a: "b" };
1775
- await wait();
1776
- expect(logs).toEqual([{ newVal: { a: "b" } }]);
1777
- logs = [];
1778
-
1779
- scope.obj.a = "c";
1780
- await wait();
1781
- expect(logs).toEqual([{ newVal: { a: "c" } }]);
1782
- });
1783
-
1784
- it("should trigger when property changes into object", async () => {
1785
- scope.obj = "test";
1786
- await wait();
1787
- expect(logs).toEqual([{ newVal: "test" }]);
1788
-
1789
- logs = [];
1790
- scope.obj = {};
1791
- await wait();
1792
- expect(logs).toEqual([{ newVal: {} }]);
1793
- });
1794
-
1795
- it("should not trigger change when object in collection changes", async () => {
1796
- scope.obj = { name: {} };
1797
-
1798
- await wait();
1799
-
1800
- expect(logs).toEqual([{ newVal: { name: {} } }]);
1801
- logs = [];
1802
-
1803
- scope.obj.name.bar = "foo";
1804
-
1805
- expect(logs).toEqual([]);
1806
- });
1807
-
1808
- it("should watch object properties", async () => {
1809
- scope.obj = {};
1810
-
1811
- await wait();
1812
- expect(logs).toEqual([{ newVal: {} }]);
1813
-
1814
- logs = [];
1815
-
1816
- scope.obj.a = "A";
1817
- await wait();
1818
-
1819
- expect(logs).toEqual([{ newVal: { a: "A" } }]);
1820
-
1821
- logs = [];
1822
- scope.obj.a = "B";
1823
- await wait();
1824
-
1825
- expect(logs).toEqual([{ newVal: { a: "B" } }]);
1826
-
1827
- logs = [];
1828
-
1829
- scope.obj.b = [];
1830
- await wait();
1831
- expect(logs).toEqual([{ newVal: scope.obj }]);
1832
-
1833
- logs = [];
1834
- scope.obj.c = {};
1835
-
1836
- await wait();
1837
- expect(logs).toEqual([{ newVal: scope.obj }]);
1838
- });
1839
-
1840
- it("should not infinitely digest when current value is NaN", async () => {
1841
- scope.obj = { a: NaN };
1842
- await wait();
1843
- expect(() => {}).not.toThrow();
1844
- });
1845
-
1846
- it("should handle objects created using `Object.create(null)`", async () => {
1847
- scope.obj = Object.create(null);
1848
- scope.obj.a = "a";
1849
- scope.obj.b = "b";
1850
-
1851
- await wait();
1852
- expect(logs[0].newVal).toEqual(scope.obj);
1853
-
1854
- delete scope.obj.b;
1855
-
1856
- await wait();
1857
- expect(logs[0].newVal).toEqual(scope.obj);
1858
- });
1859
- });
1860
- });
1861
-
1862
- describe("literal", () => {
1863
- describe("array", () => {
1864
- beforeEach(async () => {
1865
- logs = [];
1866
- scope.$watch("[obj]", (newVal) => {
1867
- const msg = { newVal };
1868
-
1869
- logs.push(msg);
1870
- });
1871
- await wait();
1872
- logs = [];
1873
- });
1874
-
1875
- it("should trigger when item in array changes", async () => {
1876
- // first time should be identical
1877
- scope.obj = "a";
1878
- await wait();
1879
- expect(logs[0].newVal).toEqual(["a"]);
1880
-
1881
- // second time should be different
1882
- logs = [];
1883
- scope.obj = "b";
1884
- await wait();
1885
- expect(logs[0].newVal).toEqual(["b"]);
1886
- });
1887
-
1888
- it("should trigger when property changes into array", async () => {
1889
- scope.obj = "test";
1890
- await wait();
1891
-
1892
- expect(logs).toEqual([{ newVal: ["test"] }]);
1893
-
1894
- logs = [];
1895
- scope.obj = [];
1896
- await wait();
1897
- expect(logs).toEqual([{ newVal: [[]] }]);
1898
-
1899
- logs = [];
1900
- scope.obj = {};
1901
- await wait();
1902
- expect(logs).toEqual([{ newVal: [{}] }]);
1903
-
1904
- logs = [];
1905
- scope.obj = [];
1906
- await wait();
1907
- expect(logs).toEqual([{ newVal: [[]] }]);
1908
-
1909
- logs = [];
1910
-
1911
- scope.obj = undefined;
1912
- await wait();
1913
- expect(logs).toEqual([{ newVal: [undefined] }]);
1914
- });
1915
-
1916
- it("should not trigger change when object in collection changes", async () => {
1917
- scope.obj = {};
1918
- await wait();
1919
- expect(logs).toEqual([{ newVal: [{}] }]);
1920
-
1921
- logs = [];
1922
- scope.obj.name = "foo";
1923
- await wait();
1924
- expect(logs).toEqual([{ newVal: [{ name: "foo" }] }]);
1925
- });
1926
-
1927
- it("should not infinitely digest when current value is NaN", async () => {
1928
- scope.obj = NaN;
1929
- await wait();
1930
- expect(() => {}).not.toThrow();
1931
- });
1932
- });
1933
-
1934
- describe("object", () => {
1935
- beforeEach(() => {
1936
- logs = [];
1937
- scope.$watch("{a: obj}", (newVal) => {
1938
- const msg = { newVal };
1939
-
1940
- logs.push(msg);
1941
- });
1942
- });
1943
-
1944
- it("should trigger when property changes into object", async () => {
1945
- logs = [];
1946
- scope.obj = {};
1947
- await wait();
1948
- expect(logs[0]).toEqual({ newVal: { a: {} } });
1949
- });
1950
-
1951
- it("should trigger change when deeply nested property in object changes", async () => {
1952
- scope.obj = { name: "foo" };
1953
- await wait();
1954
- expect(logs[0]).toEqual({
1955
- newVal: { a: { name: "foo" } },
1956
- });
1957
-
1958
- logs = [];
1959
- scope.obj.name = "bar";
1960
- await wait();
1961
- expect(logs[0]).toEqual({
1962
- newVal: { a: { name: "bar" } },
1963
- });
1964
- });
1965
-
1966
- it("should not infinitely digest when current value is NaN", async () => {
1967
- scope.obj = NaN;
1968
- await wait();
1969
- expect(() => {}).not.toThrow();
1970
- });
1971
- });
1972
-
1973
- describe("object computed property", () => {
1974
- beforeEach(async () => {
1975
- logs = [];
1976
- scope.$watch("{[key]: obj}", (newVal) => {
1977
- const msg = { newVal };
1978
-
1979
- logs.push(msg);
1980
- });
1981
-
1982
- await wait();
1983
- logs = [];
1984
- });
1985
-
1986
- it("should not trigger when key absent", async () => {
1987
- scope.obj = "test";
1988
- await wait();
1989
- expect(logs).toEqual([]);
1990
- });
1991
-
1992
- it("should trigger when key changes", async () => {
1993
- scope.key = "a";
1994
- scope.obj = "test";
1995
- await wait();
1996
- expect(logs).toEqual([{ newVal: { a: "test" } }]);
1997
-
1998
- logs = [];
1999
- scope.key = "b";
2000
- await wait();
2001
- expect(logs).toEqual([{ newVal: { b: "test" } }]);
2002
-
2003
- logs = [];
2004
- scope.key = true;
2005
- await wait();
2006
- expect(logs).toEqual([{ newVal: { true: "test" } }]);
2007
- });
2008
-
2009
- it("should not trigger change when object in collection changes", async () => {
2010
- scope.key = "a";
2011
- scope.obj = { name: "foo" };
2012
- await wait();
2013
- expect(logs).toEqual([
2014
- {
2015
- newVal: { a: { name: "foo" } },
2016
- },
2017
- ]);
2018
- logs = [];
2019
-
2020
- scope.obj.name = "bar";
2021
- await wait();
2022
- expect(logs).toEqual([]);
2023
- });
2024
-
2025
- it("should not infinitely digest when key value is NaN", () => {
2026
- scope.key = NaN;
2027
- scope.obj = NaN;
2028
- expect(() => {}).not.toThrow();
2029
- });
2030
- });
2031
- });
2032
- });
2033
-
2034
- logs = [];
2035
- function setupWatches(scope, log) {
2036
- scope.$watch(() => {
2037
- logs.push("w1");
2038
- return scope.w1;
2039
- }, log("w1action"));
2040
- scope.$watch(() => {
2041
- logs.push("w2");
2042
- return scope.w2;
2043
- }, log("w2action"));
2044
- scope.$watch(() => {
2045
- logs.push("w3");
2046
- return scope.w3;
2047
- }, log("w3action"));
2048
- console.error(logs.length);
2049
- logs = [];
2050
- }
2051
- });
2052
-
2053
- describe("$eval", () => {
2054
- it("should eval an expression and modify the scope", () => {
2055
- expect(scope.$eval("a=1")).toEqual(1);
2056
- expect(scope.a).toEqual(1);
2057
-
2058
- scope.$eval((self) => {
2059
- self.$proxy.b = 2;
2060
- });
2061
- expect(scope.b).toEqual(2);
2062
- });
2063
-
2064
- it("executes $eval'ed function and returns result", function () {
2065
- scope.aValue = 42;
2066
- const result = scope.$eval(function (scope) {
2067
- return scope.$proxy.aValue;
2068
- });
2069
- expect(result).toBe(42);
2070
- });
2071
-
2072
- it("passes the second $eval argument straight through", function () {
2073
- scope.aValue = 42;
2074
- const result = scope.$eval(function (scope, arg) {
2075
- return scope.$proxy.aValue + arg;
2076
- }, 2);
2077
- expect(result).toBe(44);
2078
- });
2079
-
2080
- it("should allow passing locals to the expression", () => {
2081
- expect(scope.$eval("a+1", { a: 2 })).toBe(3);
2082
-
2083
- scope.$eval(
2084
- (scope, locals) => {
2085
- scope.$proxy.c = locals.b + 4;
2086
- },
2087
- { b: 3 },
2088
- );
2089
- expect(scope.c).toBe(7);
2090
- });
2091
- });
2092
-
2093
- describe("$apply", () => {
2094
- beforeEach(() => (logs = []));
2095
-
2096
- it("should eval an expression, modify the scope and trigger the watches", async () => {
2097
- let counter = 0;
2098
- scope.$watch("a", () => {
2099
- counter++;
2100
- });
2101
- await wait();
2102
- expect(counter).toEqual(1);
2103
-
2104
- scope.$apply("a=1");
2105
- await wait();
2106
- expect(counter).toEqual(2);
2107
- });
2108
-
2109
- it("should update the scope and add values", async () => {
2110
- scope.$apply("a=1");
2111
- await wait();
2112
- expect(scope.a).toEqual(1);
2113
- });
2114
-
2115
- it("should update the scope and remove values", async () => {
2116
- scope.a = 2;
2117
- scope.$apply("a=null");
2118
- await wait();
2119
- expect(scope.a).toBeNull();
2120
- });
2121
-
2122
- it("should update the scope and modify objects", async () => {
2123
- scope.$apply("a={b: 2}");
2124
- await wait();
2125
- expect(scope.a.b).toEqual(2);
2126
-
2127
- scope.$apply("a.b = 3");
2128
- await wait();
2129
- expect(scope.a.b).toEqual(3);
2130
-
2131
- scope.$apply("a={c: 2}");
2132
- await wait();
2133
- expect(scope.a.c).toEqual(2);
2134
- expect(scope.a.b).toBeUndefined();
2135
- });
2136
-
2137
- it("should update arrays", async () => {
2138
- scope.a = [];
2139
- scope.$watch("a", () => count++);
2140
-
2141
- scope.$apply("a.push(1)");
2142
-
2143
- await wait();
2144
- expect(scope.a).toEqual([1]);
2145
- expect(count).toEqual(2);
2146
-
2147
- scope.$apply("a.push(2)");
2148
-
2149
- await wait();
2150
- expect(scope.a).toEqual([1, 2]);
2151
- expect(count).toEqual(3);
2152
- });
2153
-
2154
- it("executes $apply'ed function and starts the digest", async () => {
2155
- scope.aValue = "someValue";
2156
- scope.counter = 0;
2157
- scope.$watch("aValue", () => scope.counter++);
2158
- await wait();
2159
- expect(scope.counter).toBe(1);
2160
-
2161
- scope.$apply(function (scope) {
2162
- scope.aValue = "someOtherValue";
2163
- });
2164
- await wait();
2165
- expect(scope.counter).toBe(2);
2166
- });
2167
-
2168
- it("should apply expression with full lifecycle", async () => {
2169
- let log = "";
2170
- const child = scope.$new();
2171
- scope.$watch("a", (a) => {
2172
- log += "1";
2173
- });
2174
-
2175
- child.$apply("a = 0");
2176
- await wait();
2177
- expect(log).toEqual("11");
2178
- });
2179
-
2180
- it("should catch exceptions", async () => {
2181
- let log = "";
2182
- const child = scope.$new();
2183
- scope.$watch("a", (a) => {
2184
- log += "1";
2185
- });
2186
- scope.a = 0;
2187
- await wait();
2188
- child.$apply(() => {
2189
- throw new Error("MyError");
2190
- });
2191
- await wait();
2192
- expect(log).toEqual("11");
2193
- expect(logs[0].message).toEqual("MyError");
2194
- });
2195
- });
2196
-
2197
- // describe("$applyAsync", () => {
2198
- // beforeEach(() => (logs = []));
2199
- // it("should evaluate in the context of specific $scope", () => {
2200
- // const scope = scope.$new();
2201
- // let id = scope.$applyAsync('x = "CODE ORANGE"');
2202
-
2203
- // $browser.cancel(id);
2204
- // setTimeout(() => {
2205
- // expect(scope.x).toBe("CODE ORANGE");
2206
- // expect(scope.x).toBeUndefined();
2207
- // });
2208
-
2209
- // expect(scope.x).toBeUndefined();
2210
- // });
2211
-
2212
- // it("should evaluate queued expressions in order", () => {
2213
- // scope.x = [];
2214
- // let id1 = scope.$applyAsync('x.push("expr1")');
2215
- // let id2 = scope.$applyAsync('x.push("expr2")');
2216
-
2217
- // $browser.cancel(id1);
2218
- // $browser.cancel(id2);
2219
- // setTimeout(() => {
2220
- // expect(scope.x).toEqual(["expr1", "expr2"]);
2221
- // });
2222
- // expect(scope.x).toEqual([]);
2223
- // });
2224
-
2225
- // it("should evaluate subsequently queued items in same turn", () => {
2226
- // scope.x = [];
2227
- // let id = scope.$applyAsync(() => {
2228
- // scope.x.push("expr1");
2229
- // scope.$applyAsync('x.push("expr2")');
2230
- // expect($browser.deferredFns.length).toBe(0);
2231
- // });
2232
-
2233
- // $browser.cancel(id);
2234
- // setTimeout(() => {
2235
- // expect(scope.x).toEqual(["expr1", "expr2"]);
2236
- // });
2237
- // expect(scope.x).toEqual([]);
2238
- // });
2239
-
2240
- // it("should pass thrown exceptions to $exceptionHandler", () => {
2241
- // let id = scope.$applyAsync(() => {
2242
- // throw "OOPS";
2243
- // });
2244
-
2245
- // $browser.cancel(id);
2246
- // expect(logs).toEqual([]);
2247
- // setTimeout(() => expect(logs[0]).toEqual("OOPS"));
2248
- // });
2249
-
2250
- // it("should evaluate subsequent expressions after an exception is thrown", () => {
2251
- // let id = scope.$applyAsync(() => {
2252
- // throw "OOPS";
2253
- // });
2254
- // let id2 = scope.$applyAsync('x = "All good!"');
2255
-
2256
- // $browser.cancel(id);
2257
- // $browser.cancel(id2);
2258
- // setTimeout(() => expect(scope.x).toBe("All good!"));
2259
- // expect(scope.x).toBeUndefined();
2260
- // });
2261
-
2262
- // it("should be cancelled if a scope digest occurs before the next tick", () => {
2263
- // const cancel = spyOn($browser, "cancel").and.callThrough();
2264
- // const expression = jasmine.createSpy("expr");
2265
-
2266
- // scope.$applyAsync(expression);
2267
-
2268
- // expect(expression).toHaveBeenCalled();
2269
- // expect(cancel).toHaveBeenCalled();
2270
- // expression.calls.reset();
2271
- // cancel.calls.reset();
2272
-
2273
- // // assert that another digest won't call the function again
2274
-
2275
- // expect(expression).not.toHaveBeenCalled();
2276
- // expect(cancel).not.toHaveBeenCalled();
2277
- // });
2278
- // });
2279
-
2280
- describe("$postUpdate", () => {
2281
- beforeEach(() => (logs = []));
2282
- it("should process callbacks as a queue (FIFO) when the scope is digested", async () => {
2283
- let signature = "";
2284
-
2285
- scope.$postUpdate(() => {
2286
- signature += "A";
2287
- scope.$postUpdate(() => {
2288
- signature += "D";
2289
- });
2290
- });
2291
-
2292
- scope.$postUpdate(() => {
2293
- signature += "B";
2294
- });
2295
-
2296
- scope.$postUpdate(() => {
2297
- signature += "C";
2298
- });
2299
-
2300
- expect(signature).toBe("");
2301
- expect($postUpdateQueue.length).toBe(3);
2302
-
2303
- scope.$watch("a", () => {});
2304
- scope.a = 1;
2305
-
2306
- await wait();
2307
-
2308
- expect(signature).toBe("ABCD");
2309
- });
2310
-
2311
- it("should support $apply calls nested in $postUpdate callbacks", async () => {
2312
- let signature = "";
2313
-
2314
- scope.$postUpdate(() => {
2315
- signature += "A";
2316
- });
2317
-
2318
- scope.$postUpdate(() => {
2319
- signature += "B";
2320
- scope.$postUpdate(() => {
2321
- signature += "D";
2322
- });
2323
- scope.$apply("a = 2");
2324
- });
2325
-
2326
- scope.$postUpdate(() => {
2327
- signature += "C";
2328
- });
2329
- expect(signature).toBe("");
2330
-
2331
- scope.$watch("a", () => {});
2332
- scope.a = 1;
2333
- await wait();
2334
-
2335
- expect(signature).toBe("ABCD");
2336
- });
2337
-
2338
- it("should run a $postUpdate call on all child scopes when a parent scope is digested", async () => {
2339
- const parent = scope.$new();
2340
- const child = parent.$new();
2341
- let count = 0;
2342
-
2343
- scope.$postUpdate(() => {
2344
- count++;
2345
- });
2346
-
2347
- parent.$postUpdate(() => {
2348
- count++;
2349
- });
2350
-
2351
- child.$postUpdate(() => {
2352
- count++;
2353
- });
2354
-
2355
- expect(count).toBe(0);
2356
-
2357
- scope.$watch("a", () => {});
2358
- scope.a = 1;
2359
- await wait();
2360
-
2361
- expect(count).toBe(3);
2362
- });
2363
-
2364
- it("should run a $postUpdate call even if the child scope is isolated", async () => {
2365
- const parent = scope.$new();
2366
- const child = parent.$newIsolate();
2367
- let signature = "";
2368
-
2369
- parent.$postUpdate(() => {
2370
- signature += "A";
2371
- });
2372
-
2373
- child.$postUpdate(() => {
2374
- signature += "B";
2375
- });
2376
-
2377
- expect(signature).toBe("");
2378
- scope.$watch("a", () => {});
2379
- scope.a = 1;
2380
- await wait();
2381
- expect(signature).toBe("AB");
2382
- });
2383
- });
2384
-
2385
- describe("events", () => {
2386
- describe("$on", () => {
2387
- it("should add listener to list of listerner", () => {
2388
- const child = scope.$new();
2389
- function eventFn() {}
2390
- child.$on("abc", eventFn);
2391
- expect(child.$handler.$$listeners.get("abc").length).toEqual(1);
2392
-
2393
- child.$on("abc", eventFn);
2394
- expect(child.$handler.$$listeners.get("abc").length).toEqual(2);
2395
- });
2396
-
2397
- it("should return a deregistration function", () => {
2398
- const child = scope.$new();
2399
- function eventFn() {}
2400
- let res = child.$on("abc", eventFn);
2401
- expect(isDefined(res)).toBeDefined();
2402
- });
2403
-
2404
- it("should return a deregistration function that removes a listener", () => {
2405
- const child = scope.$new();
2406
- function eventFn() {}
2407
- let res = child.$on("abc", eventFn);
2408
- expect(isDefined(res)).toBeDefined();
2409
- expect(child.$handler.$$listeners.get("abc").length).toEqual(1);
2410
- let res2 = child.$on("abc", eventFn);
2411
- expect(child.$handler.$$listeners.get("abc").length).toEqual(2);
2412
- res();
2413
- expect(child.$handler.$$listeners.get("abc").length).toEqual(1);
2414
- res2();
2415
- expect(child.$handler.$$listeners.has("abc")).toBeFalse();
2416
- });
2417
-
2418
- it("should add listener for both $emit and $broadcast events", () => {
2419
- logs = "";
2420
- const child = scope.$new();
2421
- function eventFn() {
2422
- logs += "X";
2423
- }
2424
-
2425
- child.$on("abc", eventFn);
2426
- expect(logs).toEqual("");
2427
-
2428
- child.$emit("abc");
2429
- expect(logs).toEqual("X");
2430
-
2431
- child.$broadcast("abc");
2432
- expect(logs).toEqual("XX");
2433
- });
2434
-
2435
- describe("deregistration", () => {
2436
- it("should return a function that deregisters the listener", () => {
2437
- let log = "";
2438
- const child = scope.$new();
2439
- let listenerRemove;
2440
-
2441
- function eventFn() {
2442
- log += "X";
2443
- }
2444
-
2445
- listenerRemove = child.$on("abc", eventFn);
2446
- expect(log).toEqual("");
2447
- expect(listenerRemove).toBeDefined();
2448
-
2449
- child.$emit("abc");
2450
- child.$broadcast("abc");
2451
- expect(log).toEqual("XX");
2452
-
2453
- expect(child.$handler.$$listeners.get("abc").length).toBe(1);
2454
-
2455
- log = "";
2456
- listenerRemove();
2457
- child.$emit("abc");
2458
- child.$broadcast("abc");
2459
- expect(log).toEqual("");
2460
- expect(scope.$handler.$$listeners.get("abc")).toBeUndefined();
2461
- });
2462
-
2463
- it("should deallocate the listener array entry", () => {
2464
- const remove1 = scope.$on("abc", () => {});
2465
- scope.$on("abc", () => {});
2466
-
2467
- expect(scope.$handler.$$listeners.get("abc").length).toBe(2);
2468
-
2469
- remove1();
2470
-
2471
- expect(scope.$handler.$$listeners.get("abc").length).toBe(1);
2472
- });
2473
-
2474
- it("should call next listener after removing the current listener via its own handler", () => {
2475
- const listener1 = jasmine.createSpy("listener1").and.callFake(() => {
2476
- remove1();
2477
- });
2478
- let remove1 = scope.$on("abc", listener1);
2479
-
2480
- const listener2 = jasmine.createSpy("listener2");
2481
- const remove2 = scope.$on("abc", listener2);
2482
-
2483
- const listener3 = jasmine.createSpy("listener3");
2484
- const remove3 = scope.$on("abc", listener3);
2485
-
2486
- scope.$broadcast("abc");
2487
- expect(listener1).toHaveBeenCalled();
2488
- expect(listener2).toHaveBeenCalled();
2489
- expect(listener3).toHaveBeenCalled();
2490
-
2491
- listener1.calls.reset();
2492
- listener2.calls.reset();
2493
- listener3.calls.reset();
2494
-
2495
- scope.$broadcast("abc");
2496
- expect(listener1).not.toHaveBeenCalled();
2497
- expect(listener2).toHaveBeenCalled();
2498
- expect(listener3).toHaveBeenCalled();
2499
- });
2500
-
2501
- it("should call all subsequent listeners when a previous listener is removed via a handler", () => {
2502
- const listener1 = jasmine.createSpy();
2503
- const remove1 = scope.$on("abc", listener1);
2504
-
2505
- const listener2 = jasmine.createSpy().and.callFake(remove1);
2506
- const remove2 = scope.$on("abc", listener2);
2507
-
2508
- const listener3 = jasmine.createSpy();
2509
- const remove3 = scope.$on("abc", listener3);
2510
-
2511
- scope.$broadcast("abc");
2512
- expect(listener1).toHaveBeenCalled();
2513
- expect(listener2).toHaveBeenCalled();
2514
- expect(listener3).toHaveBeenCalled();
2515
-
2516
- listener1.calls.reset();
2517
- listener2.calls.reset();
2518
- listener3.calls.reset();
2519
-
2520
- scope.$broadcast("abc");
2521
- expect(listener1).not.toHaveBeenCalled();
2522
- expect(listener2).toHaveBeenCalled();
2523
- expect(listener3).toHaveBeenCalled();
2524
- });
2525
-
2526
- it("should not call listener when removed by previous", () => {
2527
- const listener1 = jasmine.createSpy("listener1");
2528
- const remove1 = scope.$on("abc", listener1);
2529
-
2530
- const listener2 = jasmine.createSpy("listener2").and.callFake(() => {
2531
- remove3();
2532
- });
2533
- const remove2 = scope.$on("abc", listener2);
2534
-
2535
- const listener3 = jasmine.createSpy("listener3");
2536
- let remove3 = scope.$on("abc", listener3);
2537
-
2538
- const listener4 = jasmine.createSpy("listener4");
2539
- const remove4 = scope.$on("abc", listener4);
2540
-
2541
- scope.$broadcast("abc");
2542
- expect(listener1).toHaveBeenCalled();
2543
- expect(listener2).toHaveBeenCalled();
2544
- expect(listener3).not.toHaveBeenCalled();
2545
- expect(listener4).toHaveBeenCalled();
2546
-
2547
- listener1.calls.reset();
2548
- listener2.calls.reset();
2549
- listener3.calls.reset();
2550
- listener4.calls.reset();
2551
-
2552
- scope.$broadcast("abc");
2553
- expect(listener1).toHaveBeenCalled();
2554
- expect(listener2).toHaveBeenCalled();
2555
- expect(listener3).not.toHaveBeenCalled();
2556
- expect(listener4).toHaveBeenCalled();
2557
- });
2558
- });
2559
- });
2560
-
2561
- describe("$emit", () => {
2562
- let log;
2563
- let child;
2564
- let grandChild;
2565
- let greatGrandChild;
2566
-
2567
- function logger(event) {
2568
- log += `${event.currentScope.$id}>`;
2569
- }
2570
-
2571
- beforeEach(() => {
2572
- log = "";
2573
- logs = [];
2574
- child = scope.$new();
2575
- grandChild = child.$new();
2576
- greatGrandChild = grandChild.$new();
2577
-
2578
- scope.$id = 0;
2579
- child.$id = 1;
2580
- grandChild.$id = 2;
2581
- greatGrandChild.$id = 3;
2582
-
2583
- scope.$on("myEvent", logger);
2584
- child.$on("myEvent", logger);
2585
- grandChild.$on("myEvent", logger);
2586
- greatGrandChild.$on("myEvent", logger);
2587
- });
2588
-
2589
- it("should do nothing on empty listener", () => {
2590
- logs = "";
2591
- const child = scope.$new();
2592
-
2593
- function eventFn() {
2594
- logs += "X";
2595
- }
2596
-
2597
- child.$on("abc", eventFn);
2598
- expect(logs).toEqual("");
2599
-
2600
- child.$emit("none");
2601
- expect(logs).toEqual("");
2602
- });
2603
-
2604
- it("should bubble event up to the root scope", () => {
2605
- grandChild.$emit("myEvent");
2606
- expect(log).toEqual("2>1>0>");
2607
- });
2608
-
2609
- it("should allow all events on the same scope to run even if stopPropagation is called", () => {
2610
- child.$on("myEvent", logger);
2611
- grandChild.$on("myEvent", (e) => {
2612
- e.stopPropagation();
2613
- });
2614
- grandChild.$on("myEvent", logger);
2615
- grandChild.$on("myEvent", logger);
2616
- grandChild.$emit("myEvent");
2617
- expect(log).toEqual("2>2>2>");
2618
- });
2619
-
2620
- it("should dispatch exceptions to the $exceptionHandler", () => {
2621
- child.$on("myEvent", () => {
2622
- throw "bubbleException";
2623
- });
2624
- grandChild.$emit("myEvent");
2625
- expect(log).toEqual("2>1>0>");
2626
- expect(logs).toEqual(["bubbleException"]);
2627
- });
2628
-
2629
- it("should allow stopping event propagation", () => {
2630
- child.$on("myEvent", (event) => {
2631
- event.stopPropagation();
2632
- });
2633
- grandChild.$emit("myEvent");
2634
- expect(log).toEqual("2>1>");
2635
- });
2636
-
2637
- it("should forward method arguments", () => {
2638
- child.$on("abc", (event, arg1, arg2) => {
2639
- expect(event.name).toBe("abc");
2640
- expect(arg1).toBe("arg1");
2641
- expect(arg2).toBe("arg2");
2642
- });
2643
- child.$emit("abc", "arg1", "arg2");
2644
- });
2645
-
2646
- it("should allow removing event listener inside a listener on $emit", () => {
2647
- const spy1 = jasmine.createSpy("1st listener");
2648
- const spy2 = jasmine.createSpy("2nd listener");
2649
- const spy3 = jasmine.createSpy("3rd listener");
2650
-
2651
- const remove1 = child.$on("evt", spy1);
2652
- const remove2 = child.$on("evt", spy2);
2653
- const remove3 = child.$on("evt", spy3);
2654
-
2655
- spy1.and.callFake(remove1);
2656
-
2657
- expect(child.$handler.$$listeners.get("evt").length).toBe(3);
2658
-
2659
- // should call all listeners and remove 1st
2660
- child.$emit("evt");
2661
- expect(spy1).toHaveBeenCalled();
2662
- expect(spy2).toHaveBeenCalled();
2663
- expect(spy3).toHaveBeenCalled();
2664
- expect(child.$handler.$$listeners.get("evt").length).toBe(2);
2665
-
2666
- spy1.calls.reset();
2667
- spy2.calls.reset();
2668
- spy3.calls.reset();
2669
-
2670
- // // should call only 2nd because 1st was already removed and 2nd removes 3rd
2671
- spy2.and.callFake(remove3);
2672
- child.$emit("evt");
2673
- expect(spy1).not.toHaveBeenCalled();
2674
- expect(spy2).toHaveBeenCalled();
2675
- expect(spy3).not.toHaveBeenCalled();
2676
- expect(child.$handler.$$listeners.get("evt").length).toBe(1);
2677
- });
2678
-
2679
- it("should allow removing event listener inside a listener on $broadcast", () => {
2680
- const spy1 = jasmine.createSpy("1st listener");
2681
- const spy2 = jasmine.createSpy("2nd listener");
2682
- const spy3 = jasmine.createSpy("3rd listener");
2683
-
2684
- const remove1 = child.$on("evt", spy1);
2685
- const remove2 = child.$on("evt", spy2);
2686
- const remove3 = child.$on("evt", spy3);
2687
-
2688
- spy1.and.callFake(remove1);
2689
-
2690
- expect(child.$handler.$$listeners.get("evt").length).toBe(3);
2691
-
2692
- // should call all listeners and remove 1st
2693
- child.$broadcast("evt");
2694
- expect(spy1).toHaveBeenCalled();
2695
- expect(spy2).toHaveBeenCalled();
2696
- expect(spy3).toHaveBeenCalled();
2697
- expect(child.$handler.$$listeners.get("evt").length).toBe(2);
2698
-
2699
- spy1.calls.reset();
2700
- spy2.calls.reset();
2701
- spy3.calls.reset();
2702
-
2703
- // should call only 2nd because 1st was already removed and 2nd removes 3rd
2704
- spy2.and.callFake(remove3);
2705
- child.$broadcast("evt");
2706
- expect(spy1).not.toHaveBeenCalled();
2707
- expect(spy2).toHaveBeenCalled();
2708
- expect(spy3).not.toHaveBeenCalled();
2709
- expect(child.$handler.$$listeners.get("evt").length).toBe(1);
2710
- });
2711
-
2712
- describe("event object", () => {
2713
- it("should have methods/properties", () => {
2714
- let eventFired = false;
2715
-
2716
- child.$on("myEvent", (e) => {
2717
- expect(e.targetScope).toBe(grandChild.$handler.$target);
2718
- expect(e.currentScope).toBe(child.$handler.$target);
2719
- expect(e.name).toBe("myEvent");
2720
- eventFired = true;
2721
- });
2722
- grandChild.$emit("myEvent");
2723
- expect(eventFired).toBe(true);
2724
- });
2725
-
2726
- it("should have its `currentScope` property set to null after emit", () => {
2727
- let event;
2728
-
2729
- child.$on("myEvent", (e) => {
2730
- event = e;
2731
- });
2732
- grandChild.$emit("myEvent");
2733
-
2734
- expect(event.currentScope).toBe(null);
2735
- expect(event.targetScope).toBe(grandChild.$target);
2736
- expect(event.name).toBe("myEvent");
2737
- });
2738
-
2739
- it("should have preventDefault method and defaultPrevented property", () => {
2740
- let event = grandChild.$emit("myEvent");
2741
- expect(event.defaultPrevented).toBe(false);
2742
-
2743
- child.$on("myEvent", (event) => {
2744
- event.preventDefault();
2745
- });
2746
- event = grandChild.$emit("myEvent");
2747
- expect(event.defaultPrevented).toBe(true);
2748
- expect(event.currentScope).toBe(null);
2749
- });
2750
- });
2751
- });
2752
-
2753
- describe("$broadcast", () => {
2754
- describe("event propagation", () => {
2755
- let log;
2756
- let child1;
2757
- let child2;
2758
- let child3;
2759
- let grandChild11;
2760
- let grandChild21;
2761
- let grandChild22;
2762
- let grandChild23;
2763
- let greatGrandChild211;
2764
-
2765
- function logger(event) {
2766
- log += `${event.currentScope.$id}>`;
2767
- }
2768
-
2769
- beforeEach(() => {
2770
- log = "";
2771
- child1 = scope.$new();
2772
- child2 = scope.$new();
2773
- child3 = scope.$new();
2774
- grandChild11 = child1.$new();
2775
- grandChild21 = child2.$new();
2776
- grandChild22 = child2.$new();
2777
- grandChild23 = child2.$new();
2778
- greatGrandChild211 = grandChild21.$new();
2779
-
2780
- scope.$id = 0;
2781
- child1.$id = 1;
2782
- child2.$id = 2;
2783
- child3.$id = 3;
2784
- grandChild11.$id = 11;
2785
- grandChild21.$id = 21;
2786
- grandChild22.$id = 22;
2787
- grandChild23.$id = 23;
2788
- greatGrandChild211.$id = 211;
2789
-
2790
- scope.$on("myEvent", logger);
2791
- child1.$on("myEvent", logger);
2792
- child2.$on("myEvent", logger);
2793
- child3.$on("myEvent", logger);
2794
- grandChild11.$on("myEvent", logger);
2795
- grandChild21.$on("myEvent", logger);
2796
- grandChild22.$on("myEvent", logger);
2797
- grandChild23.$on("myEvent", logger);
2798
- greatGrandChild211.$on("myEvent", logger);
2799
-
2800
- // R
2801
- // / | \
2802
- // 1 2 3
2803
- // / / | \
2804
- // 11 21 22 23
2805
- // |
2806
- // 211
2807
- });
2808
-
2809
- it("should broadcast an event from the root scope", () => {
2810
- scope.$broadcast("myEvent");
2811
- expect(log).toBe("0>1>11>2>21>211>22>23>3>");
2812
- });
2813
-
2814
- it("should broadcast an event from a child scope", () => {
2815
- child2.$broadcast("myEvent");
2816
- expect(log).toBe("2>21>211>22>23>");
2817
- });
2818
-
2819
- it("should broadcast an event from a leaf scope with a sibling", () => {
2820
- grandChild22.$broadcast("myEvent");
2821
- expect(log).toBe("22>");
2822
- });
2823
-
2824
- it("should broadcast an event from a leaf scope without a sibling", () => {
2825
- grandChild23.$broadcast("myEvent");
2826
- expect(log).toBe("23>");
2827
- });
2828
-
2829
- it("should not not fire any listeners for other events", () => {
2830
- scope.$broadcast("fooEvent");
2831
- expect(log).toBe("");
2832
- });
2833
-
2834
- it("should return event object", () => {
2835
- const result = child1.$broadcast("some");
2836
-
2837
- expect(result).toBeDefined();
2838
- expect(result.name).toBe("some");
2839
- expect(result.targetScope).toBe(child1.$target);
2840
- });
2841
- });
2842
-
2843
- describe("listener", () => {
2844
- it("should receive event object", () => {
2845
- const child = scope.$new();
2846
- let eventFired = false;
2847
-
2848
- child.$on("fooEvent", (event) => {
2849
- eventFired = true;
2850
- expect(event.name).toBe("fooEvent");
2851
- expect(event.targetScope).toBe(scope.$target);
2852
- expect(event.currentScope).toBe(child.$target);
2853
- });
2854
- scope.$broadcast("fooEvent");
2855
-
2856
- expect(eventFired).toBe(true);
2857
- });
2858
-
2859
- it("should have the event's `currentScope` property set to null after broadcast", () => {
2860
- const child = scope.$new();
2861
- let event;
2862
-
2863
- child.$on("fooEvent", (e) => {
2864
- event = e;
2865
- });
2866
- scope.$broadcast("fooEvent");
2867
-
2868
- expect(event.name).toBe("fooEvent");
2869
- expect(event.targetScope).toBe(scope.$target);
2870
- expect(event.currentScope).toBe(null);
2871
- });
2872
-
2873
- it("should support passing messages as constargs", () => {
2874
- const child = scope.$new();
2875
- let args;
2876
-
2877
- child.$on("fooEvent", function () {
2878
- args = arguments;
2879
- });
2880
- scope.$broadcast("fooEvent", "do", "re", "me", "fa");
2881
-
2882
- expect(args.length).toBe(5);
2883
- expect(sliceArgs(args, 1)).toEqual(["do", "re", "me", "fa"]);
2884
- });
2885
- });
2886
- });
2887
-
2888
- it("should allow recursive $emit/$broadcast", () => {
2889
- let callCount = 0;
2890
- scope.$on("evt", ($event, arg0) => {
2891
- callCount++;
2892
- if (arg0 !== 1234) {
2893
- scope.$emit("evt", 1234);
2894
- scope.$broadcast("evt", 1234);
2895
- }
2896
- });
2897
-
2898
- scope.$emit("evt");
2899
- scope.$broadcast("evt");
2900
- expect(callCount).toBe(6);
2901
- });
2902
-
2903
- it("should allow recursive $emit/$broadcast between parent/child", () => {
2904
- const child = scope.$new();
2905
- let calls = "";
2906
-
2907
- scope.$on("evt", ($event, arg0) => {
2908
- calls += "r"; // For "root".
2909
- if (arg0 === "fromChild") {
2910
- scope.$broadcast("evt", "fromRoot2");
2911
- }
2912
- });
2913
-
2914
- child.$on("evt", ($event, arg0) => {
2915
- calls += "c"; // For "child".
2916
- if (arg0 === "fromRoot1") {
2917
- child.$emit("evt", "fromChild");
2918
- }
2919
- });
2920
-
2921
- scope.$broadcast("evt", "fromRoot1");
2922
- expect(calls).toBe("rccrrc");
2923
- });
2924
- });
2925
-
2926
- describe("$destroy", () => {
2927
- it("should clean up all listeners for root", () => {
2928
- const scope = createScope();
2929
- scope.$on("test", () => {});
2930
- expect(scope.$handler.$$listeners.size).toEqual(1);
2931
-
2932
- scope.$destroy();
2933
- expect(scope.$handler.$$listeners.size).toEqual(0);
2934
- });
2935
-
2936
- it("should clean up all watchers for root", () => {
2937
- const scope = createScope();
2938
- scope.$watch("a", () => {});
2939
- expect(scope.$handler.watchers.size).toEqual(1);
2940
-
2941
- scope.$destroy();
2942
- expect(scope.$handler.watchers.size).toEqual(0);
2943
- });
2944
-
2945
- it("should remove children from parent scopes", async () => {
2946
- const scope = createScope();
2947
- const child = scope.$new();
2948
- expect(scope.$children.length).toEqual(1);
2949
- child.$destroy();
2950
- expect(scope.$children.length).toEqual(0);
2951
- });
2952
-
2953
- it("should clean up all watchers for child", async () => {
2954
- const scope = createScope();
2955
-
2956
- scope.$watch("test", () => {});
2957
- const child = scope.$new();
2958
- child.$watch("test", () => {});
2959
-
2960
- expect(scope.$handler.watchers.size).toEqual(1);
2961
- expect(scope.$handler.watchers.get("test").length).toEqual(2);
2962
- expect(child.$handler.watchers.size).toEqual(1);
2963
- expect(child.$handler.watchers.get("test").length).toEqual(2);
2964
-
2965
- child.$destroy();
2966
- expect(scope.$handler.watchers.get("test").length).toEqual(1);
2967
- });
2968
-
2969
- // it("should clean up all watchers for child", () => {
2970
- // const scope = createScope();
2971
- // scope.$watch("a", () => {});
2972
- // expect(scope.$handler.watchers.size).toEqual(1);
2973
- //
2974
- // scope.$destroy();
2975
- // expect(scope.$handler.watchers.size).toEqual(0);
2976
- // })
2977
- });
2978
-
2979
- describe("doc examples", () => {
2980
- it("should properly fire off watch listeners upon scope changes", async () => {
2981
- // <docs tag="docs1">
2982
- const $scope = scope.$new();
2983
- $scope.salutation = "Hello";
2984
- $scope.name = "World";
2985
- await wait();
2986
- expect($scope.greeting).toEqual(undefined);
2987
-
2988
- $scope.$watch("name", () => {
2989
- $scope.greeting = `${$scope.salutation} ${$scope.name}!`;
2990
- });
2991
-
2992
- expect($scope.greeting).toEqual(undefined);
2993
- expect($scope.greeting).toEqual(undefined);
2994
-
2995
- $scope.name = "Misko";
2996
- await wait();
2997
- expect($scope.greeting).toEqual("Hello Misko!");
2998
- });
2999
- });
3000
- });