@angular-wave/angular.ts 0.9.3 → 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 (703) hide show
  1. package/@types/angular.d.ts +4 -19
  2. package/@types/animations/animate.d.ts +2 -2
  3. package/@types/animations/animation.d.ts +1 -1
  4. package/@types/core/compile/attributes.d.ts +1 -1
  5. package/@types/core/compile/compile.d.ts +2 -2
  6. package/@types/core/controller/controller.d.ts +1 -1
  7. package/@types/core/controller/interface.d.ts +6 -0
  8. package/@types/core/di/ng-module.d.ts +27 -26
  9. package/@types/core/filter/filter.d.ts +5 -5
  10. package/@types/core/interpolate/interface.d.ts +13 -0
  11. package/@types/core/interpolate/interpolate.d.ts +1 -13
  12. package/@types/core/scope/scope.d.ts +4 -1
  13. package/@types/directive/http/http.d.ts +16 -16
  14. package/@types/directive/http/interface.d.ts +27 -0
  15. package/@types/directive/include/include.d.ts +4 -4
  16. package/@types/directive/inject/inject.d.ts +12 -0
  17. package/@types/directive/model/model.d.ts +1 -1
  18. package/@types/directive/script/script.d.ts +2 -2
  19. package/@types/directive/setter/setter.d.ts +4 -4
  20. package/@types/filters/filter.d.ts +2 -2
  21. package/@types/filters/filters.d.ts +2 -2
  22. package/@types/filters/interface.d.ts +8 -0
  23. package/@types/filters/limit-to.d.ts +2 -2
  24. package/@types/filters/order-by.d.ts +2 -2
  25. package/@types/interface.d.ts +105 -82
  26. package/@types/namespace.d.ts +76 -0
  27. package/@types/router/state/interface.d.ts +8 -8
  28. package/@types/router/state-filters.d.ts +4 -4
  29. package/@types/router/template-factory.d.ts +8 -8
  30. package/@types/router/transition/hook-builder.d.ts +5 -2
  31. package/@types/router/transition/hook-registry.d.ts +11 -2
  32. package/@types/router/transition/transition-service.d.ts +6 -2
  33. package/@types/router/transition/transition.d.ts +2 -2
  34. package/@types/router/view/view.d.ts +1 -8
  35. package/@types/router/view-scroll.d.ts +4 -2
  36. package/@types/services/{anchor-scroll.d.ts → anchor-scroll/anchor-scroll.d.ts} +2 -2
  37. package/@types/services/exception/exception-handler.d.ts +2 -2
  38. package/@types/services/exception/interface.d.ts +1 -1
  39. package/@types/services/http/http.d.ts +40 -2
  40. package/@types/services/http/interface.d.ts +11 -0
  41. package/@types/services/location/location.d.ts +1 -4
  42. package/@types/services/sce/sce.d.ts +3 -4
  43. package/@types/services/template-cache/template-cache.d.ts +4 -4
  44. package/@types/services/template-request/interface.d.ts +22 -0
  45. package/@types/services/{template-request.d.ts → template-request/template-request.d.ts} +4 -7
  46. package/@types/shared/common.d.ts +8 -69
  47. package/@types/shared/hof.d.ts +7 -7
  48. package/dist/angular-ts.esm.js +510 -570
  49. package/dist/angular-ts.umd.js +510 -570
  50. package/dist/angular-ts.umd.min.js +1 -1
  51. package/package.json +8 -1
  52. package/.github/workflows/ci.yml +0 -104
  53. package/.github/workflows/gh-pages.yml +0 -75
  54. package/.husky/pre-commit +0 -5
  55. package/.prettierignore +0 -9
  56. package/@types/services/cookie-reader.d.ts +0 -4
  57. package/@types/services/http-backend/http-backend.d.ts +0 -58
  58. package/@types/services/template-cache/interface.d.ts +0 -10
  59. package/CHANGELOG.md +0 -17667
  60. package/CODE_OF_CONDUCT.md +0 -3
  61. package/CONTRIBUTING.md +0 -247
  62. package/DEVELOPERS.md +0 -499
  63. package/Makefile +0 -60
  64. package/RELEASE.md +0 -86
  65. package/TRIAGING.md +0 -127
  66. package/docs/.cspell.yml +0 -8
  67. package/docs/.github/dependabot.yml +0 -14
  68. package/docs/.nvmrc +0 -1
  69. package/docs/CONTRIBUTING.md +0 -28
  70. package/docs/Dockerfile +0 -4
  71. package/docs/LICENSE +0 -201
  72. package/docs/README.md +0 -217
  73. package/docs/assets/icons/logo.svg +0 -1
  74. package/docs/assets/scss/_variables_project.scss +0 -12
  75. package/docs/assets/scss/_variables_project_after_bs.scss +0 -8
  76. package/docs/assets/scss/index.scss +0 -48
  77. package/docs/config.yaml +0 -15
  78. package/docs/content/_index.md +0 -28
  79. package/docs/content/docs/_index.md +0 -61
  80. package/docs/content/docs/directive/_index.md +0 -4
  81. package/docs/content/docs/directive/app.md +0 -11
  82. package/docs/content/docs/directive/aria.md +0 -0
  83. package/docs/content/docs/directive/bind.md +0 -72
  84. package/docs/content/docs/directive/blur.md +0 -38
  85. package/docs/content/docs/directive/channel.md +0 -37
  86. package/docs/content/docs/directive/class-even.md +0 -47
  87. package/docs/content/docs/directive/class-odd.md +0 -48
  88. package/docs/content/docs/directive/class.md +0 -64
  89. package/docs/content/docs/directive/click.md +0 -41
  90. package/docs/content/docs/directive/cloak.md +0 -74
  91. package/docs/content/docs/directive/copy.md +0 -38
  92. package/docs/content/docs/directive/cut.md +0 -40
  93. package/docs/content/docs/directive/dblclick.md +0 -41
  94. package/docs/content/docs/directive/focus.md +0 -38
  95. package/docs/content/docs/directive/get.md +0 -203
  96. package/docs/content/docs/directive/include.md +0 -7
  97. package/docs/content/docs/directive/keydown.md +0 -38
  98. package/docs/content/docs/directive/keyup.md +0 -38
  99. package/docs/content/docs/directive/load.md +0 -43
  100. package/docs/content/docs/directive/mousedown.md +0 -38
  101. package/docs/content/docs/directive/mouseenter.md +0 -38
  102. package/docs/content/docs/directive/mouseleave.md +0 -38
  103. package/docs/content/docs/directive/mousemove.md +0 -38
  104. package/docs/content/docs/directive/mouseout.md +0 -38
  105. package/docs/content/docs/directive/mouseover.md +0 -38
  106. package/docs/content/docs/directive/mouseup.md +0 -38
  107. package/docs/content/docs/directive/non-bindable.md +0 -28
  108. package/docs/content/docs/filter/_index.md +0 -4
  109. package/docs/content/docs/provider/_index.md +0 -4
  110. package/docs/content/docs/provider/eventBusProvider.md +0 -35
  111. package/docs/content/docs/provider/locationProvider.md +0 -26
  112. package/docs/content/docs/provider/logProvider.md +0 -59
  113. package/docs/content/docs/provider/templateCacheProvider.md +0 -100
  114. package/docs/content/docs/service/_index.md +0 -4
  115. package/docs/content/docs/service/eventBus.md +0 -56
  116. package/docs/content/docs/service/location.md +0 -57
  117. package/docs/content/docs/service/log.md +0 -113
  118. package/docs/content/docs/service/templateCache.md +0 -64
  119. package/docs/content/docs/service/url.md +0 -5
  120. package/docs/docker-compose.yaml +0 -12
  121. package/docs/docsy.work +0 -5
  122. package/docs/docsy.work.sum +0 -0
  123. package/docs/go.mod +0 -5
  124. package/docs/go.sum +0 -6
  125. package/docs/hugo-disabled.toml +0 -220
  126. package/docs/hugo.yaml +0 -200
  127. package/docs/layouts/404.html +0 -13
  128. package/docs/layouts/_markup/render-heading.html +0 -1
  129. package/docs/layouts/partials/hooks/head-end.html +0 -3
  130. package/docs/layouts/shortcodes/showcss.html +0 -2
  131. package/docs/layouts/shortcodes/showhtml.html +0 -2
  132. package/docs/layouts/shortcodes/showjs.html +0 -2
  133. package/docs/layouts/shortcodes/showraw.html +0 -1
  134. package/docs/layouts/shortcodes/version.html +0 -1
  135. package/docs/package-lock.json +0 -2293
  136. package/docs/package.json +0 -53
  137. package/docs/static/examples/counter/counter-test.html +0 -13
  138. package/docs/static/examples/counter/counter.html +0 -5
  139. package/docs/static/examples/counter/counter.test.js +0 -28
  140. package/docs/static/examples/eventbus/eventbus-test.html +0 -15
  141. package/docs/static/examples/eventbus/eventbus.html +0 -13
  142. package/docs/static/examples/eventbus/eventbus.js +0 -15
  143. package/docs/static/examples/eventbus/eventbus.test.js +0 -19
  144. package/docs/static/examples/ng-bind/ng-bind.html +0 -9
  145. package/docs/static/examples/ng-blur/ng-blur.html +0 -9
  146. package/docs/static/examples/ng-channel/ng-channel-test.html +0 -17
  147. package/docs/static/examples/ng-channel/ng-channel.html +0 -24
  148. package/docs/static/examples/ng-channel/ng-channel.test.js +0 -31
  149. package/docs/static/examples/ng-class/ng-class.html +0 -71
  150. package/docs/static/examples/ng-class-even/ng-class-even.html +0 -8
  151. package/docs/static/examples/ng-class-odd/ng-class-odd.html +0 -8
  152. package/docs/static/examples/ng-click/ng-click.html +0 -6
  153. package/docs/static/examples/ng-copy/ng-copy.html +0 -6
  154. package/docs/static/examples/ng-cut/ng-cut.html +0 -6
  155. package/docs/static/examples/ng-dblclick/ng-dblclick.html +0 -10
  156. package/docs/static/examples/ng-focus/ng-focus.html +0 -9
  157. package/docs/static/examples/ng-keydown/ng-keydown.html +0 -9
  158. package/docs/static/examples/ng-keyup/ng-keyup.html +0 -9
  159. package/docs/static/examples/ng-load/ng-load.html +0 -8
  160. package/docs/static/examples/ng-mousedown/ng-mousedown.html +0 -6
  161. package/docs/static/examples/ng-mouseenter/ng-mouseenter.html +0 -4
  162. package/docs/static/examples/ng-mouseleave/ng-mouseleave.html +0 -4
  163. package/docs/static/examples/ng-mousemove/ng-mousemove.html +0 -4
  164. package/docs/static/examples/ng-mouseout/ng-mouseout.html +0 -4
  165. package/docs/static/examples/ng-mouseover/ng-mouseover.html +0 -4
  166. package/docs/static/examples/ng-mouseup/ng-mouseup.html +0 -4
  167. package/docs/static/examples/ng-non-bindable/ng-non-bindable-test.html +0 -13
  168. package/docs/static/examples/ng-non-bindable/ng-non-bindable.html +0 -3
  169. package/docs/static/examples/ng-non-bindable/ng-non-bindable.test.js +0 -11
  170. package/docs/static/typedoc/.nojekyll +0 -1
  171. package/docs/static/typedoc/assets/hierarchy.js +0 -1
  172. package/docs/static/typedoc/assets/highlight.css +0 -78
  173. package/docs/static/typedoc/assets/icons.js +0 -18
  174. package/docs/static/typedoc/assets/icons.svg +0 -1
  175. package/docs/static/typedoc/assets/main.js +0 -60
  176. package/docs/static/typedoc/assets/navigation.js +0 -1
  177. package/docs/static/typedoc/assets/search.js +0 -1
  178. package/docs/static/typedoc/assets/style.css +0 -1633
  179. package/docs/static/typedoc/classes/Location.html +0 -55
  180. package/docs/static/typedoc/classes/LocationProvider.html +0 -20
  181. package/docs/static/typedoc/classes/LogProvider.html +0 -6
  182. package/docs/static/typedoc/classes/PubSub.html +0 -71
  183. package/docs/static/typedoc/classes/PubSubProvider.html +0 -3
  184. package/docs/static/typedoc/classes/TemplateCacheProvider.html +0 -5
  185. package/docs/static/typedoc/hierarchy.html +0 -1
  186. package/docs/static/typedoc/index.html +0 -1
  187. package/docs/static/typedoc/interfaces/ChangesObject.html +0 -6
  188. package/docs/static/typedoc/interfaces/ComponentOptions.html +0 -16
  189. package/docs/static/typedoc/interfaces/Controller.html +0 -12
  190. package/docs/static/typedoc/interfaces/DefaultPorts.html +0 -5
  191. package/docs/static/typedoc/interfaces/Directive.html +0 -37
  192. package/docs/static/typedoc/interfaces/DirectivePrePost.html +0 -4
  193. package/docs/static/typedoc/interfaces/Html5Mode.html +0 -23
  194. package/docs/static/typedoc/interfaces/HttpHeadersGetter.html +0 -1
  195. package/docs/static/typedoc/interfaces/HttpProviderDefaults.html +0 -31
  196. package/docs/static/typedoc/interfaces/HttpRequestConfigHeaders.html +0 -6
  197. package/docs/static/typedoc/interfaces/HttpRequestTransformer.html +0 -1
  198. package/docs/static/typedoc/interfaces/HttpResponse.html +0 -7
  199. package/docs/static/typedoc/interfaces/HttpResponseTransformer.html +0 -1
  200. package/docs/static/typedoc/interfaces/HttpService.html +0 -38
  201. package/docs/static/typedoc/interfaces/LogService.html +0 -12
  202. package/docs/static/typedoc/interfaces/NgModelController.html +0 -30
  203. package/docs/static/typedoc/interfaces/NgModelOptions.html +0 -16
  204. package/docs/static/typedoc/interfaces/Provider.html +0 -34
  205. package/docs/static/typedoc/interfaces/RequestConfig.html +0 -48
  206. package/docs/static/typedoc/interfaces/RequestShortcutConfig.html +0 -38
  207. package/docs/static/typedoc/interfaces/ServiceProvider.html +0 -5
  208. package/docs/static/typedoc/interfaces/TemplateCache.html +0 -7
  209. package/docs/static/typedoc/interfaces/TranscludeFunctionObject.html +0 -8
  210. package/docs/static/typedoc/interfaces/UrlParts.html +0 -9
  211. package/docs/static/typedoc/types/AnnotatedDirectiveFactory.html +0 -1
  212. package/docs/static/typedoc/types/AnnotatedFactory.html +0 -8
  213. package/docs/static/typedoc/types/CloneAttachFunction.html +0 -2
  214. package/docs/static/typedoc/types/ControllerConstructor.html +0 -2
  215. package/docs/static/typedoc/types/DirectiveCompileFn.html +0 -2
  216. package/docs/static/typedoc/types/DirectiveController.html +0 -2
  217. package/docs/static/typedoc/types/DirectiveFactory.html +0 -1
  218. package/docs/static/typedoc/types/DirectiveFactoryFn.html +0 -1
  219. package/docs/static/typedoc/types/DirectiveLinkFn.html +0 -2
  220. package/docs/static/typedoc/types/ExpandoStore.html +0 -2
  221. package/docs/static/typedoc/types/Expression.html +0 -6
  222. package/docs/static/typedoc/types/FilterFactory.html +0 -2
  223. package/docs/static/typedoc/types/FilterFn.html +0 -2
  224. package/docs/static/typedoc/types/HttpPromise.html +0 -1
  225. package/docs/static/typedoc/types/HttpResponseStatus.html +0 -1
  226. package/docs/static/typedoc/types/Injectable.html +0 -4
  227. package/docs/static/typedoc/types/InjectableClass.html +0 -1
  228. package/docs/static/typedoc/types/InjectableFactory.html +0 -1
  229. package/docs/static/typedoc/types/LogCall.html +0 -2
  230. package/docs/static/typedoc/types/LogServiceFactory.html +0 -2
  231. package/docs/static/typedoc/types/OnChangesObject.html +0 -2
  232. package/docs/static/typedoc/types/SwapModeType.html +0 -2
  233. package/docs/static/typedoc/types/TController.html +0 -2
  234. package/docs/static/typedoc/types/UrlChangeListener.html +0 -5
  235. package/docs/static/typedoc/variables/EventBus.html +0 -1
  236. package/docs/static/typedoc/variables/SwapMode.html +0 -11
  237. package/docs/static/version.js +0 -13
  238. package/docs/test-results/.last-run.json +0 -4
  239. package/docs/test-results/static-examples-counter-counter-counter-example/error-context.md +0 -50
  240. package/eslint.config.js +0 -26
  241. package/images/android-chrome-192x192.png +0 -0
  242. package/images/android-chrome-512x512.png +0 -0
  243. package/images/apple-touch-icon.png +0 -0
  244. package/images/favicon-16x16.png +0 -0
  245. package/images/favicon-32x32.png +0 -0
  246. package/images/favicon.ico +0 -0
  247. package/images/site.webmanifest +0 -19
  248. package/index.html +0 -86
  249. package/legacy.d.ts +0 -2599
  250. package/playwright.config.ts +0 -81
  251. package/public/jasmine/boot0.js +0 -66
  252. package/public/jasmine/boot1.js +0 -134
  253. package/public/jasmine/jasmine-html.js +0 -970
  254. package/public/jasmine/jasmine.css +0 -323
  255. package/public/jasmine/jasmine.js +0 -11406
  256. package/public/public/README.md +0 -1
  257. package/public/public/circle.html +0 -1
  258. package/public/public/jasmine-helper.css +0 -9
  259. package/public/public/my_child_directive.html +0 -1
  260. package/public/public/my_directive.html +0 -1
  261. package/public/public/my_other_directive.html +0 -1
  262. package/public/public/test.html +0 -1
  263. package/rollup.config.js +0 -51
  264. package/src/angular.js +0 -293
  265. package/src/angular.spec.js +0 -1191
  266. package/src/animations/animate-cache.js +0 -80
  267. package/src/animations/animate-children-directive.js +0 -32
  268. package/src/animations/animate-children-directive.md +0 -80
  269. package/src/animations/animate-css-driver.js +0 -284
  270. package/src/animations/animate-css.html +0 -58
  271. package/src/animations/animate-css.js +0 -915
  272. package/src/animations/animate-css.md +0 -263
  273. package/src/animations/animate-js-driver.js +0 -60
  274. package/src/animations/animate-js.html +0 -47
  275. package/src/animations/animate-js.js +0 -371
  276. package/src/animations/animate-queue.js +0 -859
  277. package/src/animations/animate-runner.js +0 -193
  278. package/src/animations/animate-swap.js +0 -33
  279. package/src/animations/animate-swap.md +0 -88
  280. package/src/animations/animate.html +0 -19
  281. package/src/animations/animate.js +0 -546
  282. package/src/animations/animate.md +0 -933
  283. package/src/animations/animate.spec.js +0 -490
  284. package/src/animations/animation.js +0 -519
  285. package/src/animations/animations.test.js +0 -10
  286. package/src/animations/interface.ts +0 -19
  287. package/src/animations/raf-scheduler.html +0 -19
  288. package/src/animations/raf-scheduler.js +0 -92
  289. package/src/animations/raf-scheduler.spec.js +0 -98
  290. package/src/animations/shared.js +0 -341
  291. package/src/binding.html +0 -19
  292. package/src/binding.spec.js +0 -474
  293. package/src/binding.test.js +0 -10
  294. package/src/core/compile/attributes.js +0 -337
  295. package/src/core/compile/compile.html +0 -19
  296. package/src/core/compile/compile.js +0 -3270
  297. package/src/core/compile/compile.md +0 -1128
  298. package/src/core/compile/compile.spec.js +0 -15574
  299. package/src/core/compile/compile.test.js +0 -12
  300. package/src/core/controller/controller.html +0 -22
  301. package/src/core/controller/controller.js +0 -189
  302. package/src/core/controller/controller.spec.js +0 -334
  303. package/src/core/controller/controller.test.js +0 -12
  304. package/src/core/core.html +0 -20
  305. package/src/core/core.test.js +0 -12
  306. package/src/core/di/injector.html +0 -19
  307. package/src/core/di/injector.js +0 -307
  308. package/src/core/di/injector.md +0 -740
  309. package/src/core/di/injector.spec.js +0 -2310
  310. package/src/core/di/injector.test.js +0 -12
  311. package/src/core/di/internal-injector.js +0 -284
  312. package/src/core/di/ng-module.html +0 -19
  313. package/src/core/di/ng-module.js +0 -226
  314. package/src/core/di/ng-module.spec.js +0 -263
  315. package/src/core/di/ng-module.test.js +0 -12
  316. package/src/core/filter/filter.html +0 -19
  317. package/src/core/filter/filter.js +0 -55
  318. package/src/core/filter/filter.md +0 -132
  319. package/src/core/filter/filter.spec.js +0 -149
  320. package/src/core/filter/filter.test.js +0 -12
  321. package/src/core/interpolate/interpolate.html +0 -22
  322. package/src/core/interpolate/interpolate.js +0 -408
  323. package/src/core/interpolate/interpolate.spec.js +0 -601
  324. package/src/core/interpolate/interpolate.test.js +0 -12
  325. package/src/core/parse/ast/ast-node.ts +0 -81
  326. package/src/core/parse/ast/ast.html +0 -19
  327. package/src/core/parse/ast/ast.js +0 -574
  328. package/src/core/parse/ast/ast.spec.js +0 -1453
  329. package/src/core/parse/ast/ast.test.js +0 -10
  330. package/src/core/parse/ast-type.js +0 -23
  331. package/src/core/parse/interface.ts +0 -84
  332. package/src/core/parse/interpreter.js +0 -915
  333. package/src/core/parse/lexer/lexer.html +0 -19
  334. package/src/core/parse/lexer/lexer.js +0 -338
  335. package/src/core/parse/lexer/lexer.spec.js +0 -303
  336. package/src/core/parse/lexer/lexer.test.js +0 -10
  337. package/src/core/parse/lexer/token.ts +0 -22
  338. package/src/core/parse/parse.html +0 -19
  339. package/src/core/parse/parse.js +0 -337
  340. package/src/core/parse/parse.md +0 -57
  341. package/src/core/parse/parse.spec.js +0 -2107
  342. package/src/core/parse/parse.test.js +0 -10
  343. package/src/core/parse/parser/parser.html +0 -19
  344. package/src/core/parse/parser/parser.js +0 -64
  345. package/src/core/parse/parser/parser.spec.js +0 -8
  346. package/src/core/parse/parser/parser.test.js +0 -10
  347. package/src/core/prop.spec.js +0 -775
  348. package/src/core/root-element.spec.js +0 -14
  349. package/src/core/sanitize/interface.ts +0 -10
  350. package/src/core/sanitize/sanitize-uri.js +0 -75
  351. package/src/core/sanitize/sanitize-uri.spec.js +0 -249
  352. package/src/core/sanitize/sanitize-uri.test.js +0 -12
  353. package/src/core/sanitize/sanitize.html +0 -22
  354. package/src/core/scope/scope.html +0 -19
  355. package/src/core/scope/scope.js +0 -1249
  356. package/src/core/scope/scope.spec.js +0 -3000
  357. package/src/core/scope/scope.test.js +0 -12
  358. package/src/directive/aria/aria.html +0 -19
  359. package/src/directive/aria/aria.js +0 -382
  360. package/src/directive/aria/aria.md +0 -145
  361. package/src/directive/aria/aria.spec.js +0 -1241
  362. package/src/directive/aria/aria.test.js +0 -12
  363. package/src/directive/attrs/attrs.html +0 -19
  364. package/src/directive/attrs/attrs.js +0 -106
  365. package/src/directive/attrs/attrs.md +0 -224
  366. package/src/directive/attrs/attrs.spec.js +0 -71
  367. package/src/directive/attrs/attrs.test.js +0 -12
  368. package/src/directive/attrs/boolean.html +0 -19
  369. package/src/directive/attrs/boolean.spec.js +0 -137
  370. package/src/directive/attrs/boolean.test.js +0 -12
  371. package/src/directive/attrs/element-style.html +0 -22
  372. package/src/directive/attrs/element-style.spec.js +0 -85
  373. package/src/directive/attrs/element-style.test.js +0 -12
  374. package/src/directive/attrs/src.html +0 -19
  375. package/src/directive/attrs/src.spec.js +0 -163
  376. package/src/directive/attrs/src.test.js +0 -12
  377. package/src/directive/bind/bind-html.spec.js +0 -36
  378. package/src/directive/bind/bind.html +0 -20
  379. package/src/directive/bind/bind.js +0 -78
  380. package/src/directive/bind/bind.md +0 -142
  381. package/src/directive/bind/bind.spec.js +0 -314
  382. package/src/directive/bind/bind.test.js +0 -12
  383. package/src/directive/channel/channel.html +0 -19
  384. package/src/directive/channel/channel.js +0 -30
  385. package/src/directive/channel/channel.spec.js +0 -67
  386. package/src/directive/channel/channel.test.js +0 -10
  387. package/src/directive/class/class-test.html +0 -23
  388. package/src/directive/class/class.html +0 -19
  389. package/src/directive/class/class.js +0 -184
  390. package/src/directive/class/class.spec.js +0 -704
  391. package/src/directive/class/class.test.js +0 -12
  392. package/src/directive/cloak/cloak.html +0 -19
  393. package/src/directive/cloak/cloak.js +0 -11
  394. package/src/directive/cloak/cloak.spec.js +0 -44
  395. package/src/directive/cloak/cloak.test.js +0 -12
  396. package/src/directive/controller/controller.html +0 -22
  397. package/src/directive/controller/controller.js +0 -11
  398. package/src/directive/controller/controller.md +0 -46
  399. package/src/directive/controller/controller.spec.js +0 -175
  400. package/src/directive/controller/controller.test.js +0 -12
  401. package/src/directive/events/click.spec.js +0 -35
  402. package/src/directive/events/event.spec.js +0 -267
  403. package/src/directive/events/events-test.html +0 -36
  404. package/src/directive/events/events.html +0 -20
  405. package/src/directive/events/events.js +0 -65
  406. package/src/directive/events/events.md +0 -125
  407. package/src/directive/events/events.test.js +0 -12
  408. package/src/directive/form/form.html +0 -19
  409. package/src/directive/form/form.js +0 -669
  410. package/src/directive/form/form.spec.js +0 -1515
  411. package/src/directive/form/form.test.js +0 -12
  412. package/src/directive/http/delete.spec.js +0 -26
  413. package/src/directive/http/form-router-test.html +0 -44
  414. package/src/directive/http/form-test.html +0 -18
  415. package/src/directive/http/get.spec.js +0 -488
  416. package/src/directive/http/http.html +0 -22
  417. package/src/directive/http/http.js +0 -342
  418. package/src/directive/http/http.test.js +0 -12
  419. package/src/directive/http/post-example.html +0 -30
  420. package/src/directive/http/post.spec.js +0 -521
  421. package/src/directive/http/put.spec.js +0 -26
  422. package/src/directive/if/if-animate-css.html +0 -57
  423. package/src/directive/if/if-animate-svg.html +0 -25
  424. package/src/directive/if/if.html +0 -19
  425. package/src/directive/if/if.js +0 -72
  426. package/src/directive/if/if.md +0 -76
  427. package/src/directive/if/if.spec.js +0 -293
  428. package/src/directive/if/if.test.js +0 -114
  429. package/src/directive/include/include.html +0 -19
  430. package/src/directive/include/include.js +0 -151
  431. package/src/directive/include/include.md +0 -87
  432. package/src/directive/include/include.spec.js +0 -734
  433. package/src/directive/include/include.test.js +0 -12
  434. package/src/directive/init/init.html +0 -19
  435. package/src/directive/init/init.js +0 -22
  436. package/src/directive/init/init.md +0 -41
  437. package/src/directive/init/init.spec.js +0 -68
  438. package/src/directive/init/init.test.js +0 -12
  439. package/src/directive/input/input-example.html +0 -15
  440. package/src/directive/input/input.html +0 -19
  441. package/src/directive/input/input.js +0 -1078
  442. package/src/directive/input/input.md +0 -706
  443. package/src/directive/input/input.spec.js +0 -3700
  444. package/src/directive/input/input.test.js +0 -12
  445. package/src/directive/messages/messages.html +0 -22
  446. package/src/directive/messages/messages.js +0 -349
  447. package/src/directive/messages/messages.md +0 -543
  448. package/src/directive/messages/messages.spec.js +0 -1083
  449. package/src/directive/messages/messages.test.js +0 -12
  450. package/src/directive/model/change.md +0 -25
  451. package/src/directive/model/model.html +0 -19
  452. package/src/directive/model/model.js +0 -1170
  453. package/src/directive/model/model.spec.js +0 -1976
  454. package/src/directive/model/model.test.js +0 -12
  455. package/src/directive/model-options/model-option.test.js +0 -12
  456. package/src/directive/model-options/model-options.html +0 -22
  457. package/src/directive/model-options/model-options.js +0 -142
  458. package/src/directive/model-options/model-options.md +0 -407
  459. package/src/directive/model-options/model-options.spec.js +0 -1022
  460. package/src/directive/non-bindable/non-bindable.html +0 -22
  461. package/src/directive/non-bindable/non-bindable.js +0 -9
  462. package/src/directive/non-bindable/non-bindable.spec.js +0 -59
  463. package/src/directive/non-bindable/non-bindable.test.js +0 -12
  464. package/src/directive/observe/observe-demo.html +0 -184
  465. package/src/directive/observe/observe.html +0 -19
  466. package/src/directive/observe/observe.js +0 -41
  467. package/src/directive/observe/observe.spec.js +0 -106
  468. package/src/directive/observe/observe.test.js +0 -10
  469. package/src/directive/on/on.html +0 -19
  470. package/src/directive/on/on.spec.js +0 -215
  471. package/src/directive/on/on.test.js +0 -12
  472. package/src/directive/options/options-example.html +0 -17
  473. package/src/directive/options/options.html +0 -22
  474. package/src/directive/options/options.js +0 -542
  475. package/src/directive/options/options.md +0 -179
  476. package/src/directive/options/options.spec.js +0 -3554
  477. package/src/directive/options/options.test.js +0 -12
  478. package/src/directive/ref/href.html +0 -19
  479. package/src/directive/ref/href.spec.js +0 -141
  480. package/src/directive/ref/href.test.js +0 -19
  481. package/src/directive/ref/ref.html +0 -19
  482. package/src/directive/ref/ref.js +0 -89
  483. package/src/directive/ref/ref.spec.js +0 -546
  484. package/src/directive/repeat/repeat.html +0 -19
  485. package/src/directive/repeat/repeat.js +0 -333
  486. package/src/directive/repeat/repeat.md +0 -330
  487. package/src/directive/repeat/repeat.spec.js +0 -1209
  488. package/src/directive/repeat/repeat.test.js +0 -12
  489. package/src/directive/script/script.html +0 -19
  490. package/src/directive/script/script.js +0 -17
  491. package/src/directive/script/script.md +0 -11
  492. package/src/directive/script/script.spec.js +0 -47
  493. package/src/directive/script/script.test.js +0 -12
  494. package/src/directive/select/select.html +0 -19
  495. package/src/directive/select/select.js +0 -594
  496. package/src/directive/select/select.md +0 -74
  497. package/src/directive/select/select.spec.js +0 -2566
  498. package/src/directive/select/select.test.js +0 -12
  499. package/src/directive/setter/setter.html +0 -19
  500. package/src/directive/setter/setter.js +0 -59
  501. package/src/directive/setter/setter.spec.js +0 -100
  502. package/src/directive/setter/setter.test.js +0 -12
  503. package/src/directive/show-hide/show-hide.html +0 -22
  504. package/src/directive/show-hide/show-hide.js +0 -65
  505. package/src/directive/show-hide/show-hide.md +0 -255
  506. package/src/directive/show-hide/show-hide.spec.js +0 -268
  507. package/src/directive/show-hide/show-hide.test.js +0 -12
  508. package/src/directive/style/style.html +0 -19
  509. package/src/directive/style/style.js +0 -27
  510. package/src/directive/style/style.md +0 -23
  511. package/src/directive/style/style.spec.js +0 -183
  512. package/src/directive/style/style.test.js +0 -12
  513. package/src/directive/switch/switch.html +0 -19
  514. package/src/directive/switch/switch.js +0 -133
  515. package/src/directive/switch/switch.md +0 -66
  516. package/src/directive/switch/switch.spec.js +0 -509
  517. package/src/directive/switch/switch.test.js +0 -12
  518. package/src/directive/transclude/transclude.js +0 -122
  519. package/src/directive/validators/validators.html +0 -22
  520. package/src/directive/validators/validators.js +0 -346
  521. package/src/directive/validators/validators.spec.js +0 -740
  522. package/src/directive/validators/validators.test.js +0 -12
  523. package/src/filters/filter.js +0 -213
  524. package/src/filters/filter.md +0 -69
  525. package/src/filters/filter.spec.js +0 -719
  526. package/src/filters/filters.html +0 -22
  527. package/src/filters/filters.js +0 -239
  528. package/src/filters/filters.spec.js +0 -36
  529. package/src/filters/filters.test.js +0 -12
  530. package/src/filters/json.md +0 -16
  531. package/src/filters/limit-to.js +0 -55
  532. package/src/filters/limit-to.md +0 -19
  533. package/src/filters/limit-to.spec.js +0 -252
  534. package/src/filters/order-by.js +0 -181
  535. package/src/filters/order-by.md +0 -83
  536. package/src/filters/order-by.spec.js +0 -883
  537. package/src/index.js +0 -6
  538. package/src/index.spec.js +0 -11
  539. package/src/injection-tokens.js +0 -78
  540. package/src/interface.ts +0 -421
  541. package/src/ng.js +0 -289
  542. package/src/ng.spec.js +0 -33
  543. package/src/router/common/trace.js +0 -240
  544. package/src/router/directives/component-example.html +0 -37
  545. package/src/router/directives/state-directives.html +0 -22
  546. package/src/router/directives/state-directives.js +0 -393
  547. package/src/router/directives/state-directives.md +0 -435
  548. package/src/router/directives/state-directives.spec.js +0 -1091
  549. package/src/router/directives/state-directives.test.js +0 -10
  550. package/src/router/directives/view-directive.js +0 -489
  551. package/src/router/directives/view-directive.spec.js +0 -1937
  552. package/src/router/directives/view-directive.test.js +0 -10
  553. package/src/router/directives/view-directives.html +0 -22
  554. package/src/router/glob/glob.html +0 -19
  555. package/src/router/glob/glob.js +0 -102
  556. package/src/router/glob/glob.spec.js +0 -108
  557. package/src/router/glob/glob.test.js +0 -12
  558. package/src/router/hooks/core-resolvables.js +0 -38
  559. package/src/router/hooks/ignored-transition.js +0 -25
  560. package/src/router/hooks/invalid-transition.js +0 -14
  561. package/src/router/hooks/lazy-load.js +0 -104
  562. package/src/router/hooks/on-enter-exit-retain.js +0 -55
  563. package/src/router/hooks/redirect-to.js +0 -38
  564. package/src/router/hooks/resolve.js +0 -57
  565. package/src/router/hooks/update-globals.js +0 -34
  566. package/src/router/hooks/url.js +0 -34
  567. package/src/router/hooks/views.js +0 -41
  568. package/src/router/params/interface.ts +0 -626
  569. package/src/router/params/param-factory.js +0 -23
  570. package/src/router/params/param-type.js +0 -133
  571. package/src/router/params/param-types.js +0 -153
  572. package/src/router/params/param.js +0 -243
  573. package/src/router/params/state-params.js +0 -36
  574. package/src/router/path/path-node.js +0 -78
  575. package/src/router/path/path-utils.js +0 -207
  576. package/src/router/resolve/interface.ts +0 -208
  577. package/src/router/resolve/resolvable.js +0 -123
  578. package/src/router/resolve/resolve-context.js +0 -190
  579. package/src/router/router-test-hashbang.html +0 -45
  580. package/src/router/router-test.html +0 -41
  581. package/src/router/router.html +0 -22
  582. package/src/router/router.js +0 -54
  583. package/src/router/router.test.js +0 -12
  584. package/src/router/services.spec.js +0 -52
  585. package/src/router/state/README.md +0 -21
  586. package/src/router/state/interface.ts +0 -1007
  587. package/src/router/state/state-builder.js +0 -376
  588. package/src/router/state/state-builder.spec.js +0 -86
  589. package/src/router/state/state-matcher.js +0 -64
  590. package/src/router/state/state-object.js +0 -118
  591. package/src/router/state/state-queue-manager.js +0 -95
  592. package/src/router/state/state-registry.js +0 -257
  593. package/src/router/state/state-service.js +0 -699
  594. package/src/router/state/state.html +0 -23
  595. package/src/router/state/state.spec.js +0 -1002
  596. package/src/router/state/state.test.js +0 -12
  597. package/src/router/state/target-state.js +0 -162
  598. package/src/router/state/views.js +0 -195
  599. package/src/router/state-filter.spec.js +0 -139
  600. package/src/router/state-filters.js +0 -46
  601. package/src/router/template-factory.html +0 -19
  602. package/src/router/template-factory.js +0 -249
  603. package/src/router/template-factory.spec.js +0 -155
  604. package/src/router/template-factory.test.js +0 -12
  605. package/src/router/transition/hook-builder.js +0 -133
  606. package/src/router/transition/hook-registry.js +0 -172
  607. package/src/router/transition/interface.js +0 -18
  608. package/src/router/transition/interface.ts +0 -922
  609. package/src/router/transition/reject-factory.js +0 -122
  610. package/src/router/transition/transition-event-type.js +0 -26
  611. package/src/router/transition/transition-hook.js +0 -199
  612. package/src/router/transition/transition-service.js +0 -302
  613. package/src/router/transition/transition.js +0 -652
  614. package/src/router/url/url-config.js +0 -155
  615. package/src/router/url/url-matcher.js +0 -532
  616. package/src/router/url/url-rule.js +0 -231
  617. package/src/router/url/url-rules.js +0 -350
  618. package/src/router/url/url-service.js +0 -446
  619. package/src/router/url/url-service.spec.js +0 -1288
  620. package/src/router/url/url.html +0 -19
  621. package/src/router/url/url.test.js +0 -12
  622. package/src/router/view/interface.ts +0 -51
  623. package/src/router/view/view.html +0 -19
  624. package/src/router/view/view.js +0 -274
  625. package/src/router/view/view.spec.js +0 -100
  626. package/src/router/view/view.test.js +0 -12
  627. package/src/router/view-hook.spec.js +0 -215
  628. package/src/router/view-scroll.js +0 -33
  629. package/src/router/view-scroll.spec.js +0 -72
  630. package/src/services/anchor-scroll.html +0 -76
  631. package/src/services/anchor-scroll.js +0 -147
  632. package/src/services/cookie-reader.js +0 -48
  633. package/src/services/exception/exception-handler.js +0 -75
  634. package/src/services/exception/interface.ts +0 -7
  635. package/src/services/http/http.html +0 -23
  636. package/src/services/http/http.js +0 -922
  637. package/src/services/http/http.md +0 -413
  638. package/src/services/http/http.spec.js +0 -3941
  639. package/src/services/http/http.test.js +0 -11
  640. package/src/services/http/interface.ts +0 -243
  641. package/src/services/http/template-request.spec.js +0 -220
  642. package/src/services/http-backend/http-backend.html +0 -22
  643. package/src/services/http-backend/http-backend.js +0 -158
  644. package/src/services/http-backend/http-backend.spec.js +0 -389
  645. package/src/services/http-backend/http-backend.test.js +0 -12
  646. package/src/services/location/interface.ts +0 -70
  647. package/src/services/location/location.html +0 -22
  648. package/src/services/location/location.js +0 -1006
  649. package/src/services/location/location.spec.js +0 -3792
  650. package/src/services/location/location.test.js +0 -12
  651. package/src/services/log/interface.ts +0 -39
  652. package/src/services/log/log.html +0 -19
  653. package/src/services/log/log.js +0 -74
  654. package/src/services/log/log.spec.js +0 -64
  655. package/src/services/log/log.test.js +0 -12
  656. package/src/services/pubsub/pubsub.html +0 -19
  657. package/src/services/pubsub/pubsub.js +0 -349
  658. package/src/services/pubsub/pubsub.spec.js +0 -400
  659. package/src/services/pubsub/pubsub.test.js +0 -12
  660. package/src/services/sce/sce.html +0 -19
  661. package/src/services/sce/sce.js +0 -847
  662. package/src/services/sce/sce.md +0 -300
  663. package/src/services/sce/sce.spec.js +0 -617
  664. package/src/services/sce/sce.test.js +0 -12
  665. package/src/services/template-cache/interface.ts +0 -10
  666. package/src/services/template-cache/template-cache.html +0 -22
  667. package/src/services/template-cache/template-cache.js +0 -15
  668. package/src/services/template-cache/template-cache.spec.js +0 -134
  669. package/src/services/template-cache/template-cache.test.js +0 -12
  670. package/src/services/template-request.js +0 -142
  671. package/src/shared/cache.js +0 -7
  672. package/src/shared/common.js +0 -438
  673. package/src/shared/common.spec.js +0 -294
  674. package/src/shared/constants.js +0 -21
  675. package/src/shared/dom.js +0 -716
  676. package/src/shared/hof.js +0 -151
  677. package/src/shared/hof.spec.js +0 -60
  678. package/src/shared/interface.ts +0 -21
  679. package/src/shared/min-err.spec.js +0 -178
  680. package/src/shared/noderef.js +0 -225
  681. package/src/shared/predicates.js +0 -34
  682. package/src/shared/queue.js +0 -105
  683. package/src/shared/queue.spec.js +0 -80
  684. package/src/shared/shared.html +0 -24
  685. package/src/shared/shared.test.js +0 -12
  686. package/src/shared/strings.js +0 -142
  687. package/src/shared/strings.spec.js +0 -40
  688. package/src/shared/test-utils.js +0 -47
  689. package/src/shared/url-utils/interface.ts +0 -54
  690. package/src/shared/url-utils/url-utils.html +0 -22
  691. package/src/shared/url-utils/url-utils.js +0 -122
  692. package/src/shared/url-utils/url-utils.spec.js +0 -148
  693. package/src/shared/url-utils/url-utils.test.js +0 -12
  694. package/src/shared/utils.js +0 -1255
  695. package/src/shared/utils.spec.js +0 -178
  696. package/src/src.html +0 -21
  697. package/src/src.test.js +0 -10
  698. package/tsconfig.json +0 -19
  699. package/tsconfig.types.json +0 -14
  700. package/typedoc.json +0 -8
  701. package/utils/express.js +0 -203
  702. package/utils/version.cjs +0 -23
  703. package/vite.config.js +0 -14
@@ -1,3270 +0,0 @@
1
- import {
2
- createElementFromHTML,
3
- createNodelistFromHTML,
4
- emptyElement,
5
- getBooleanAttrName,
6
- getCacheData,
7
- getInheritedData,
8
- isTextNode,
9
- setCacheData,
10
- setIsolateScope,
11
- setScope,
12
- startingTag,
13
- } from "../../shared/dom.js";
14
- import { NodeRef } from "../../shared/noderef.js";
15
- import { identifierForController } from "../controller/controller.js";
16
- import {
17
- minErr,
18
- assertArg,
19
- assertNotHasOwnProperty,
20
- isDefined,
21
- isFunction,
22
- isObject,
23
- isString,
24
- lowercase,
25
- extend,
26
- isScope,
27
- inherit,
28
- isUndefined,
29
- getNodeName,
30
- bind,
31
- trim,
32
- isBoolean,
33
- equals,
34
- simpleCompare,
35
- isError,
36
- directiveNormalize,
37
- isProxy,
38
- hasOwn,
39
- } from "../../shared/utils.js";
40
- import { SCE_CONTEXTS } from "../../services/sce/sce.js";
41
- import { PREFIX_REGEXP } from "../../shared/constants.js";
42
- import { createEventDirective } from "../../directive/events/events.js";
43
- import { Attributes } from "./attributes.js";
44
- import { ngObserveDirective } from "../../directive/observe/observe.js";
45
-
46
- /**
47
- * A function passed as the fifth argument to a {@type PublicLinkFn} link function.
48
- * It behaves like a linking function, with the `scope` argument automatically created
49
- * as a new child of the transcluded parent scope.
50
- *
51
- * The function returns the DOM content to be injected (transcluded) into the directive.
52
- *
53
- * @callback TranscludeFn
54
- * @param {Element | Node | ChildNode | NodeList | Node[]} [clone] - The DOM node to be inserted into the transcluded directive.
55
- * @param {import("../scope/scope.js").Scope} [scope] - The new child scope created from the transcluded parent.
56
- * @returns void
57
-
58
- /**
59
- * A specialized version of {@link TranscludeFn} with the scope argument already bound.
60
- * This function requires no parameters and returns the same result as {@link TranscludeFn}.
61
- *
62
- * @typedef {() => Element|Node} BoundTranscludeFn
63
- */
64
-
65
- /**
66
- * @typedef {Object} SimpleChange
67
- * @property {any} currentValue
68
- * @property {boolean} firstChange
69
- */
70
-
71
- /**
72
- * @description A function returned by the '$compile' service that links a compiled template to a scope.
73
- *
74
- * @callback PublicLinkFn
75
- * @param {import('../scope/scope.js').Scope} scope - Scope to link with element
76
- * @param {TranscludeFn} [cloneConnectFn]
77
- * @param {*} [options]
78
- * @return {Element|Node|ChildNode|Node[]} The nodes to be linked.
79
- */
80
-
81
- /**
82
- * @description Entry point for the '$compile' service.
83
- *
84
- * @callback CompileFn
85
- * @param {string|Element|Node|ChildNode|NodeList} compileNode - The node to be compiled.
86
- * @param {TranscludeFn} [transcludeFn] - An optional transclusion function to be used during compilation.
87
- * @param {number} [maxPriority] - An optional maximum priority for directives.
88
- * @param {string} [ignoreDirective] - An optional directive to ignore during compilation.
89
- * @param {*} [previousCompileContext] - An optional context from a previous compilation. TODO
90
- * @returns {PublicLinkFn} A public link function.
91
- */
92
-
93
- /**
94
- * @typedef {Object} LinkFnMapping
95
- * @property {number} index
96
- * @property {NodeLinkFnCtx} [nodeLinkFnCtx]
97
- * @property {CompositeLinkFn} [childLinkFn]
98
- */
99
-
100
- /**
101
- * @typedef {function(): CompositeLinkFn} CompileNodesFn
102
- */
103
-
104
- /**
105
- * @callback NodeLinkFn
106
- * @returns {Node|Element|NodeList}
107
- */
108
-
109
- /**
110
- * @typedef {Object} NodeLinkFnCtx
111
- * @property {NodeLinkFn} nodeLinkFn
112
- * @property {boolean} terminal
113
- * @property {TranscludeFn} transclude
114
- * @property {boolean} transcludeOnThisElement
115
- * @property {boolean} templateOnThisElement
116
- * @property {boolean} newScope
117
- */
118
-
119
- /**
120
- * @typedef {function(): NodeLinkFn} ApplyDirectivesToNodeFn
121
- */
122
-
123
- /**
124
- * @description Function that aggregates all linking fns for a compilation root (nodeList)
125
- * @callback CompositeLinkFn
126
- * @param {import('../scope/scope.js').Scope} scope - The scope to be linked to the template
127
- * @param {NodeRef} $linkNode - wrapper around a nodeList
128
- * @param {Function} [parentBoundTranscludeFn]
129
- */
130
-
131
- const $compileMinErr = minErr("$compile");
132
- const EXCLUDED_DIRECTIVES = ["ngIf", "ngRepeat"];
133
- const ALL_OR_NOTHING_ATTRS = ["ngSrc", "ngSrcset", "src", "srcset"];
134
- const REQUIRE_PREFIX_REGEXP = /^(?:(\^\^?)?(\?)?(\^\^?)?)?/;
135
- // Ref: http://developers.whatwg.org/webappapis.html#event-handler-idl-attributes
136
- // The assumption is that future DOM event attribute names will begin with
137
- // 'on' and be composed of only English letters.
138
- const EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;
139
- export const DirectiveSuffix = "Directive";
140
-
141
- export class CompileProvider {
142
- /* @ignore */ static $inject = ["$provide", "$$sanitizeUriProvider"];
143
-
144
- /**
145
- * @param {import('../../interface.js').Provider} $provide
146
- * @param {import('../sanitize/sanitize-uri.js').SanitizeUriProvider} $$sanitizeUriProvider
147
- */
148
- constructor($provide, $$sanitizeUriProvider) {
149
- const hasDirectives = {};
150
-
151
- const bindingCache = Object.create(null);
152
-
153
- /**
154
- *
155
- * @param {import("../scope/scope.js").Scope} scope
156
- * @param {string} directiveName
157
- * @param {boolean} isController
158
- * @returns {Object} a configuration object for attribute bindings
159
- */
160
- function parseIsolateBindings(scope, directiveName, isController) {
161
- const LOCAL_REGEXP = /^([@&]|[=<]())(\??)\s*([\w$]*)$/;
162
-
163
- const bindings = Object.create(null);
164
-
165
- Object.entries(scope).forEach(([scopeName, definition]) => {
166
- definition = definition.trim();
167
-
168
- if (definition in bindingCache) {
169
- bindings[scopeName] = bindingCache[definition];
170
- return;
171
- }
172
- const match = definition.match(LOCAL_REGEXP);
173
-
174
- if (!match) {
175
- throw $compileMinErr(
176
- "iscp",
177
- "Invalid {3} for directive '{0}'." +
178
- " Definition: {... {1}: '{2}' ...}",
179
- directiveName,
180
- scopeName,
181
- definition,
182
- isController
183
- ? "controller bindings definition"
184
- : "isolate scope definition",
185
- );
186
- }
187
-
188
- bindings[scopeName] = {
189
- mode: match[1][0],
190
- collection: match[2] === "*",
191
- optional: match[3] === "?",
192
- attrName: match[4] || scopeName,
193
- };
194
- if (match[4]) {
195
- bindingCache[definition] = bindings[scopeName];
196
- }
197
- });
198
-
199
- return bindings;
200
- }
201
-
202
- function parseDirectiveBindings(directive, directiveName) {
203
- const bindings = {
204
- isolateScope: null,
205
- bindToController: null,
206
- };
207
- if (isObject(directive.scope)) {
208
- if (directive.bindToController === true) {
209
- bindings.bindToController = parseIsolateBindings(
210
- directive.scope,
211
- directiveName,
212
- true,
213
- );
214
- bindings.isolateScope = {};
215
- } else {
216
- bindings.isolateScope = parseIsolateBindings(
217
- directive.scope,
218
- directiveName,
219
- false,
220
- );
221
- }
222
- }
223
- if (isObject(directive.bindToController)) {
224
- bindings.bindToController = parseIsolateBindings(
225
- directive.bindToController,
226
- directiveName,
227
- true,
228
- );
229
- }
230
- if (bindings.bindToController && !directive.controller) {
231
- // There is no controller
232
- throw $compileMinErr(
233
- "noctrl",
234
- "Cannot bind to controller without directive '{0}'s controller.",
235
- directiveName,
236
- );
237
- }
238
- return bindings;
239
- }
240
-
241
- function getDirectiveRequire(directive) {
242
- const require =
243
- directive.require || (directive.controller && directive.name);
244
-
245
- if (!Array.isArray(require) && isObject(require)) {
246
- Object.entries(require).forEach(([key, value]) => {
247
- const match = value.match(REQUIRE_PREFIX_REGEXP);
248
- const name = value.substring(match[0].length);
249
- if (!name) {
250
- require[key] = match[0] + key;
251
- }
252
- });
253
- }
254
-
255
- return require;
256
- }
257
-
258
- function getDirectiveRestrict(restrict, name) {
259
- if (restrict && !(isString(restrict) && /[EA]/.test(restrict))) {
260
- throw $compileMinErr(
261
- "badrestrict",
262
- "Restrict property '{0}' of directive '{1}' is invalid",
263
- restrict,
264
- name,
265
- );
266
- }
267
- // Default is element or attribute
268
- return restrict || "EA";
269
- }
270
-
271
- /**
272
- * Register a new directive with the compiler.
273
- *
274
- * @param {string|Object} name Name of the directive in camel-case (i.e. `ngBind` which will match
275
- * as `ng-bind`), or an object map of directives where the keys are the names and the values
276
- * are the factories.
277
- * @param {Function|Array} directiveFactory An injectable directive factory function. See the
278
- * {@link guide/directive directive guide} and the {@link $compile compile API} for more info.
279
- * @returns {CompileProvider} Self for chaining.
280
- */
281
- this.directive = function registerDirective(name, directiveFactory) {
282
- assertArg(name, "name");
283
- assertNotHasOwnProperty(name, "directive");
284
- if (isString(name)) {
285
- assertValidDirectiveName(name);
286
- assertArg(directiveFactory, "directiveFactory");
287
- if (!hasOwn(hasDirectives, name)) {
288
- hasDirectives[name] = [];
289
- $provide.factory(name + DirectiveSuffix, [
290
- "$injector",
291
- "$exceptionHandler",
292
- /**
293
- * @param {import("../../core/di/internal-injector.js").InjectorService} $injector
294
- * @param {import('../../services/exception/exception-handler.js').ErrorHandler} $exceptionHandler
295
- */
296
- function ($injector, $exceptionHandler) {
297
- const directives = [];
298
- hasDirectives[name].forEach((directiveFactory, index) => {
299
- try {
300
- let directive = $injector.invoke(directiveFactory);
301
- const valueFn = (value) => () => value;
302
- if (isFunction(directive)) {
303
- directive = { compile: valueFn(directive) };
304
- } else if (!directive.compile && directive.link) {
305
- directive.compile = valueFn(directive.link);
306
- }
307
-
308
- directive.priority = directive.priority || 0;
309
- directive.index = index;
310
- directive.name = directive.name || name;
311
- directive.require = getDirectiveRequire(directive);
312
- directive.restrict = getDirectiveRestrict(
313
- directive.restrict,
314
- name,
315
- );
316
- directive.$$moduleName = directiveFactory.$$moduleName;
317
- directives.push(directive);
318
- } catch (e) {
319
- $exceptionHandler(e);
320
- }
321
- });
322
- return directives;
323
- },
324
- ]);
325
- }
326
- hasDirectives[name].push(directiveFactory);
327
- } else {
328
- Object.entries(name).forEach(([k, v]) => registerDirective(k, v));
329
- }
330
- return this;
331
- };
332
-
333
- /**
334
- * @param {string|Object} name Name of the component in camelCase (i.e. `myComp` which will match `<my-comp>`),
335
- * or an object map of components where the keys are the names and the values are the component definition objects.
336
- * @param {import("../../interface.js").ComponentOptions} options Component definition object (a simplified
337
- * {directive definition object}),
338
- * with the following properties (all optional):
339
- *
340
- * - `controller` – `{(string|function()=}` – controller constructor function that should be
341
- * associated with newly created scope or the name of a {controller} if passed as a string. An empty `noop` function by default.
342
- * - `controllerAs` – `{string=}` – identifier name for to reference the controller in the component's scope.
343
- * If present, the controller will be published to scope under the `controllerAs` name.
344
- * If not present, this will default to be `$ctrl`.
345
- * - `template` – `{string=|function()=}` – html template as a string or a function that
346
- * returns an html template as a string which should be used as the contents of this component.
347
- * Empty string by default.
348
- *
349
- * If `template` is a function, then it is {injected} with
350
- * the following locals:
351
- *
352
- * - `$element` - Current element
353
- * - `$attrs` - Current attributes object for the element
354
- *
355
- * - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html
356
- * template that should be used as the contents of this component.
357
- *
358
- * If `templateUrl` is a function, then it is {injected} with
359
- * the following locals:
360
- *
361
- * - `$element` - Current element
362
- * - `$attrs` - Current attributes object for the element
363
- *
364
- * - `bindings` – `{object=}` – defines bindings between DOM attributes and component properties.
365
- * Component properties are always bound to the component controller and not to the scope.
366
- * See {`bindToController`}.
367
- * - `transclude` – `{boolean=}` – whether {content transclusion} is enabled.
368
- * Disabled by default.
369
- * - `require` - `{Object<string, string>=}` - requires the controllers of other directives and binds them to
370
- * this component's controller. The object keys specify the property names under which the required
371
- * controllers (object values) will be bound. See {`require`}.
372
- * - `$...` – additional properties to attach to the directive factory function and the controller
373
- * constructor function. (This is used by the component router to annotate)
374
- *
375
- * @returns {CompileProvider} the compile provider itself, for chaining of function calls.
376
- */
377
- this.component = function (name, options) {
378
- if (!isString(name)) {
379
- Object.entries(name).forEach(([key, val]) => this.component(key, val));
380
- return this;
381
- }
382
-
383
- const controller = options.controller || function () {};
384
-
385
- function factory($injector) {
386
- function makeInjectable(fn) {
387
- if (isFunction(fn) || Array.isArray(fn)) {
388
- return function (tElement, tAttrs) {
389
- return $injector.invoke(fn, this, {
390
- $element: tElement,
391
- $attrs: tAttrs,
392
- });
393
- };
394
- }
395
- return fn;
396
- }
397
-
398
- const template =
399
- !options.template && !options.templateUrl ? "" : options.template;
400
- const ddo = {
401
- controller,
402
- controllerAs:
403
- identifierForController(options.controller) ||
404
- options.controllerAs ||
405
- "$ctrl",
406
- template: makeInjectable(template),
407
- templateUrl: makeInjectable(options.templateUrl),
408
- transclude: options.transclude,
409
- scope: {},
410
- bindToController: options.bindings || {},
411
- restrict: "E",
412
- require: options.require,
413
- };
414
-
415
- // Copy annotations (starting with $) over to the DDO
416
- Object.entries(options).forEach(([key, val]) => {
417
- if (key.charAt(0) === "$") {
418
- ddo[key] = val;
419
- }
420
- });
421
-
422
- return ddo;
423
- }
424
-
425
- // Copy any annotation properties (starting with $) over to the factory and controller constructor functions
426
- // These could be used by libraries such as the new component router
427
- Object.entries(options).forEach(([key, val]) => {
428
- if (key.charAt(0) === "$") {
429
- factory[key] = val;
430
- // Don't try to copy over annotations to named controller
431
- if (isFunction(controller)) {
432
- controller[key] = val;
433
- }
434
- }
435
- });
436
-
437
- factory.$inject = ["$injector"];
438
-
439
- return this.directive(name, factory);
440
- };
441
-
442
- /**
443
- * Retrieves or overrides the default regular expression that is used for determining trusted safe
444
- * urls during a[href] sanitization.
445
- *
446
- * The sanitization is a security measure aimed at preventing XSS attacks via html links.
447
- *
448
- * Any url about to be assigned to a[href] via data-binding is first normalized and turned into
449
- * an absolute url. Afterwards, the url is matched against the `aHrefSanitizationTrustedUrlList`
450
- * regular expression. If a match is found, the original url is written into the dom. Otherwise,
451
- * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
452
- *
453
- * @param {RegExp=} regexp New regexp to trust urls with.
454
- * @returns {RegExp|import('../sanitize/sanitize-uri.js').SanitizeUriProvider} Current RegExp if called without value or self for
455
- * chaining otherwise.
456
- */
457
- this.aHrefSanitizationTrustedUrlList = function (regexp) {
458
- if (isDefined(regexp)) {
459
- $$sanitizeUriProvider.aHrefSanitizationTrustedUrlList(regexp);
460
- return;
461
- }
462
- return $$sanitizeUriProvider.aHrefSanitizationTrustedUrlList();
463
- };
464
-
465
- /**
466
- * Retrieves or overrides the default regular expression that is used for determining trusted safe
467
- * urls during img[src] sanitization.
468
- *
469
- * The sanitization is a security measure aimed at prevent XSS attacks via html links.
470
- *
471
- * Any url about to be assigned to img[src] via data-binding is first normalized and turned into
472
- * an absolute url. Afterwards, the url is matched against the `imgSrcSanitizationTrustedUrlList`
473
- * regular expression. If a match is found, the original url is written into the dom. Otherwise,
474
- * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
475
- *
476
- * @param {RegExp=} regexp New regexp to trust urls with.
477
- * @returns {RegExp|import('../sanitize/sanitize-uri.js').SanitizeUriProvider} Current RegExp if called without value or self for
478
- * chaining otherwise.
479
- */
480
- this.imgSrcSanitizationTrustedUrlList = function (regexp) {
481
- if (isDefined(regexp)) {
482
- $$sanitizeUriProvider.imgSrcSanitizationTrustedUrlList(regexp);
483
- return;
484
- }
485
- return $$sanitizeUriProvider.imgSrcSanitizationTrustedUrlList();
486
- };
487
-
488
- /**
489
- * @param {boolean=} enabled update the strictComponentBindingsEnabled state if provided,
490
- * otherwise return the current strictComponentBindingsEnabled state.
491
- * @returns {*} current value if used as getter or itself (chaining) if used as setter
492
- *
493
- * Call this method to enable / disable the strict component bindings check. If enabled, the
494
- * compiler will enforce that all scope / controller bindings of a
495
- * {@link $compileProvider#directive directive} / {@link $compileProvider#component component}
496
- * that are not set as optional with `?`, must be provided when the directive is instantiated.
497
- * If not provided, the compiler will throw the
498
- * {@link error/$compile/missingattr $compile:missingattr error}.
499
- *
500
- * The default value is false.
501
- */
502
- let strictComponentBindingsEnabled = false;
503
- this.strictComponentBindingsEnabled = function (enabled) {
504
- if (isDefined(enabled)) {
505
- strictComponentBindingsEnabled = enabled;
506
- return this;
507
- }
508
- return strictComponentBindingsEnabled;
509
- };
510
-
511
- /**
512
- * The security context of DOM Properties.
513
- */
514
- const PROP_CONTEXTS = Object.create(null);
515
-
516
- /**
517
- * Defines the security context for DOM properties bound by ng-prop-*.
518
- *
519
- * @param {string} elementName The element name or '*' to match any element.
520
- * @param {string} propertyName The DOM property name.
521
- * @param {string} ctx The {@link $sce} security context in which this value is safe for use, e.g. `$sce.URL`
522
- * @returns {object} `this` for chaining
523
- */
524
- this.addPropertySecurityContext = function (
525
- elementName,
526
- propertyName,
527
- ctx,
528
- ) {
529
- const key = `${elementName.toLowerCase()}|${propertyName.toLowerCase()}`;
530
-
531
- if (key in PROP_CONTEXTS && PROP_CONTEXTS[key] !== ctx) {
532
- throw $compileMinErr(
533
- "ctxoverride",
534
- "Property context '{0}.{1}' already set to '{2}', cannot override to '{3}'.",
535
- elementName,
536
- propertyName,
537
- PROP_CONTEXTS[key],
538
- ctx,
539
- );
540
- }
541
-
542
- PROP_CONTEXTS[key] = ctx;
543
- return this;
544
- };
545
-
546
- /* Default property contexts.
547
- *
548
- * Copy of https://github.com/angular/angular/blob/6.0.6/packages/compiler/src/schema/dom_security_schema.ts#L31-L58
549
- * Changing:
550
- * - SecurityContext.* => SCE_CONTEXTS/$sce.*
551
- * - STYLE => CSS
552
- * - various URL => MEDIA_URL
553
- * - *|formAction, form|action URL => RESOURCE_URL (like the attribute)
554
- */
555
- (function registerNativePropertyContexts() {
556
- function registerContext(ctx, values) {
557
- values.forEach((v) => {
558
- PROP_CONTEXTS[v.toLowerCase()] = ctx;
559
- });
560
- }
561
-
562
- registerContext(SCE_CONTEXTS.HTML, [
563
- "iframe|srcdoc",
564
- "*|innerHTML",
565
- "*|outerHTML",
566
- ]);
567
- registerContext(SCE_CONTEXTS.CSS, ["*|style"]);
568
- registerContext(SCE_CONTEXTS.URL, [
569
- "area|href",
570
- "area|ping",
571
- "a|href",
572
- "a|ping",
573
- "blockquote|cite",
574
- "body|background",
575
- "del|cite",
576
- "input|src",
577
- "ins|cite",
578
- "q|cite",
579
- ]);
580
- registerContext(SCE_CONTEXTS.MEDIA_URL, [
581
- "audio|src",
582
- "img|src",
583
- "img|srcset",
584
- "source|src",
585
- "source|srcset",
586
- "track|src",
587
- "video|src",
588
- "video|poster",
589
- ]);
590
- registerContext(SCE_CONTEXTS.RESOURCE_URL, [
591
- "*|formAction",
592
- "applet|code",
593
- "applet|codebase",
594
- "base|href",
595
- "embed|src",
596
- "frame|src",
597
- "form|action",
598
- "head|profile",
599
- "html|manifest",
600
- "iframe|src",
601
- "link|href",
602
- "media|src",
603
- "object|codebase",
604
- "object|data",
605
- "script|src",
606
- ]);
607
- })();
608
-
609
- this.$get = [
610
- "$injector",
611
- "$interpolate",
612
- "$exceptionHandler",
613
- "$templateRequest",
614
- "$parse",
615
- "$controller",
616
- "$rootScope",
617
- "$sce",
618
- "$animate",
619
- /**
620
- * @param {import("../../core/di/internal-injector.js").InjectorService} $injector
621
- * @param {*} $interpolate
622
- * @param {import("../../services/exception/exception-handler.js").ErrorHandler} $exceptionHandler
623
- * @param {*} $templateRequest
624
- * @param {import("../parse/interface.ts").ParseService} $parse
625
- * @param {*} $controller
626
- * @param {import('../scope/scope.js').Scope} $rootScope
627
- * @param {*} $sce
628
- * @param {*} $animate
629
- * @returns
630
- */
631
- function (
632
- $injector,
633
- $interpolate,
634
- $exceptionHandler,
635
- $templateRequest,
636
- $parse,
637
- $controller,
638
- $rootScope,
639
- $sce,
640
- $animate,
641
- ) {
642
- // The onChanges hooks should all be run together in a single digest
643
- // When changes occur, the call to trigger their hooks will be added to this queue
644
- let onChangesQueue;
645
-
646
- // This function is called in a $postUpdate to trigger all the onChanges hooks in a single digest
647
- function flushOnChangesQueue() {
648
- for (let i = 0, ii = onChangesQueue.length; i < ii; ++i) {
649
- try {
650
- onChangesQueue[i]();
651
- } catch (e) {
652
- $exceptionHandler(e);
653
- }
654
- }
655
- // Reset the queue to trigger a new schedule next time there is a change
656
- onChangesQueue = undefined;
657
- }
658
-
659
- const startSymbol = $interpolate.startSymbol();
660
- const endSymbol = $interpolate.endSymbol();
661
- /** @type {(string) => string} */
662
- const denormalizeTemplate =
663
- startSymbol === "{{" && endSymbol === "}}"
664
- ? (x) => x
665
- : (x) => x.replace(/\{\{/g, startSymbol).replace(/}}/g, endSymbol);
666
-
667
- const NG_PREFIX_BINDING = /^ng(Attr|Prop|On|Observe)([A-Z].*)$/;
668
- return compile;
669
-
670
- //= ===============================
671
- /**
672
- * @type {CompileFn}
673
- */
674
- function compile(
675
- element,
676
- transcludeFn,
677
- maxPriority,
678
- ignoreDirective,
679
- previousCompileContext,
680
- ) {
681
- /** @type {NodeRef | null } */
682
- let nodeRef = new NodeRef(element);
683
- /**
684
- * The composite link function is a composite of individual node linking functions.
685
- * It will be invoke by the public link function below.
686
- * @type {CompositeLinkFn}
687
- */
688
- let compositeLinkFn = compileNodes(
689
- nodeRef,
690
- transcludeFn,
691
- maxPriority,
692
- ignoreDirective,
693
- previousCompileContext,
694
- );
695
-
696
- let namespace = null;
697
- return publicLinkFn;
698
-
699
- /** @type {PublicLinkFn} */
700
- function publicLinkFn(scope, cloneConnectFn, options) {
701
- if (!nodeRef) {
702
- throw $compileMinErr(
703
- "multilink",
704
- "This element has already been linked.",
705
- );
706
- }
707
-
708
- assertArg(scope, "scope");
709
- // could be empty nodelist
710
- if (nodeRef.getAny()) {
711
- setScope(nodeRef.getAny(), scope);
712
- }
713
-
714
- if (
715
- previousCompileContext &&
716
- previousCompileContext.needsNewScope
717
- ) {
718
- // A parent directive did a replace and a directive on this element asked
719
- // for transclusion, which caused us to lose a layer of element on which
720
- // we could hold the new transclusion scope, so we will create it manually
721
- // here.
722
- scope = scope.$parent.$new();
723
- }
724
-
725
- options = options || {};
726
- let {
727
- transcludeControllers,
728
- parentBoundTranscludeFn,
729
- futureParentElement,
730
- } = options;
731
-
732
- // When `parentBoundTranscludeFn` is passed, it is a
733
- // `controllersBoundTransclude` function (it was previously passed
734
- // as `transclude` to directive.link) so we must unwrap it to get
735
- // its `boundTranscludeFn`
736
- if (
737
- parentBoundTranscludeFn &&
738
- parentBoundTranscludeFn.$$boundTransclude
739
- ) {
740
- parentBoundTranscludeFn =
741
- parentBoundTranscludeFn.$$boundTransclude;
742
- }
743
-
744
- if (!namespace) {
745
- namespace = detectNamespaceForChildElements(futureParentElement);
746
- }
747
- /** @type {NodeRef} */
748
- let $linkNode;
749
-
750
- if (namespace !== "html") {
751
- // When using a directive with replace:true and templateUrl the jqCompileNodes
752
- // (or a child element inside of them)
753
- // might change, so we need to recreate the namespace adapted compileNodes
754
- // for call to the link function.
755
- // Note: This will already clone the nodes...
756
- const fragment = createElementFromHTML("<div></div>");
757
- fragment.append(nodeRef.node);
758
- const wrappedTemplate = wrapTemplate(
759
- namespace,
760
- fragment.innerHTML,
761
- );
762
- $linkNode = new NodeRef(wrappedTemplate[0]);
763
- } else if (cloneConnectFn) {
764
- $linkNode = nodeRef.clone();
765
- } else {
766
- $linkNode = nodeRef;
767
- }
768
-
769
- if (transcludeControllers) {
770
- for (const controllerName in transcludeControllers) {
771
- assertArg($linkNode.element, "element");
772
- setCacheData(
773
- $linkNode.element,
774
- `$${controllerName}Controller`,
775
- transcludeControllers[controllerName].instance,
776
- );
777
- }
778
- }
779
- if (cloneConnectFn) {
780
- cloneConnectFn($linkNode.dom, scope);
781
- }
782
-
783
- if (compositeLinkFn) {
784
- compositeLinkFn(scope, $linkNode, parentBoundTranscludeFn);
785
- }
786
-
787
- if (!cloneConnectFn) {
788
- nodeRef = compositeLinkFn = null;
789
- }
790
-
791
- $linkNode.linked = true;
792
-
793
- return $linkNode.getAll();
794
- }
795
- }
796
-
797
- function detectNamespaceForChildElements(parentElement) {
798
- // TODO: Make this detect MathML as well...
799
- const node = parentElement;
800
- if (!node) {
801
- return "html";
802
- }
803
- return getNodeName(node) !== "foreignobject" &&
804
- toString.call(node).match(/SVG/)
805
- ? "svg"
806
- : "html";
807
- }
808
-
809
- /**
810
- * Compile function matches each node in nodeList against the directives. Once all directives
811
- * for a particular node are collected their compile functions are executed. The compile
812
- * functions return values - the linking functions - are combined into a composite linking
813
- * function, which is a linking function for the node.
814
- *
815
- * @param {NodeRef} nodeRefList a node or an array of nodes or NodeList to compile
816
- * @param {*} transcludeFn A linking function, where the
817
- * scope argument is auto-generated to the new child of the transcluded parent scope.
818
- * @param {number=} [maxPriority] Max directive priority.
819
- * @param {*} [ignoreDirective]
820
- * @param {*} [previousCompileContext]
821
- * @returns {CompositeLinkFn} A composite linking function of all of the matched directives or null.
822
- */
823
- function compileNodes(
824
- nodeRefList,
825
- transcludeFn,
826
- maxPriority,
827
- ignoreDirective,
828
- previousCompileContext,
829
- ) {
830
- /**
831
- * Aggregates for the composite linking function, where a node in a node list is mapped
832
- * to a corresponding link function. For single elements, the node should be mapped to
833
- * a single node link function.
834
- * @type {LinkFnMapping[]}
835
- */
836
- const linkFnsList = []; // An array to hold node indices and their linkFns
837
- let nodeLinkFnFound;
838
- let linkFnFound = false;
839
- for (let i = 0; i < nodeRefList.size; i++) {
840
- const attrs = new Attributes(
841
- $rootScope,
842
- $animate,
843
- $exceptionHandler,
844
- $sce,
845
- );
846
-
847
- const directives = collectDirectives(
848
- /** @type Element */ (nodeRefList.getIndex(i)),
849
- attrs,
850
- i === 0 ? maxPriority : undefined,
851
- ignoreDirective,
852
- );
853
-
854
- /** @type {NodeLinkFnCtx} */
855
- let nodeLinkFnCtx;
856
-
857
- if (directives.length) {
858
- nodeLinkFnCtx = applyDirectivesToNode(
859
- directives,
860
- nodeRefList.getIndex(i),
861
- attrs,
862
- transcludeFn,
863
- null,
864
- [],
865
- [],
866
- Object.assign({}, previousCompileContext, {
867
- index: i,
868
- parentNodeRef: nodeRefList,
869
- ctxNodeRef: nodeRefList,
870
- }),
871
- );
872
- }
873
-
874
- let childLinkFn;
875
- let childNodes;
876
- let nodeLinkFn = nodeLinkFnCtx?.nodeLinkFn;
877
- if (
878
- (nodeLinkFn && nodeLinkFnCtx.terminal) ||
879
- !(childNodes = nodeRefList.getIndex(i).childNodes) ||
880
- !childNodes.length
881
- ) {
882
- childLinkFn = null;
883
- } else {
884
- let transcluded = nodeLinkFn
885
- ? (nodeLinkFnCtx.transcludeOnThisElement ||
886
- !nodeLinkFnCtx.templateOnThisElement) &&
887
- nodeLinkFnCtx.transclude
888
- : transcludeFn;
889
- // recursive call
890
- const childNodeRef = new NodeRef(childNodes);
891
- childLinkFn = compileNodes(childNodeRef, transcluded);
892
- }
893
-
894
- if (nodeLinkFn || childLinkFn) {
895
- linkFnsList.push({
896
- index: i,
897
- nodeLinkFnCtx: nodeLinkFnCtx,
898
- childLinkFn: childLinkFn,
899
- });
900
- linkFnFound = true;
901
- nodeLinkFnFound = nodeLinkFnFound || nodeLinkFn;
902
- }
903
-
904
- // use the previous context only for the first element in the virtual group
905
- previousCompileContext = null;
906
- }
907
-
908
- // return a composite linking function if we have found anything, null otherwise
909
- return linkFnFound ? compositeLinkFn : null;
910
-
911
- /**
912
- * The composite link function links all the individual nodes
913
- *
914
- * @param {import("../scope/scope.js").Scope} scope
915
- * @param {NodeRef} nodeRef
916
- * @param {*} [parentBoundTranscludeFn]
917
- */
918
- function compositeLinkFn(scope, nodeRef, parentBoundTranscludeFn) {
919
- assertArg(nodeRef, "nodeRef");
920
- let stableNodeList = [];
921
- if (nodeLinkFnFound) {
922
- // create a stable copy of the nodeList, only copying elements with linkFns
923
- const stableLength = nodeRef.isList ? nodeRef.nodes.length : 1;
924
- stableNodeList = new Array(stableLength);
925
- // create a sparse array by only copying the elements which have a linkFn
926
- linkFnsList.forEach((val) => {
927
- let idx = val.index;
928
- if (idx === 0) {
929
- stableNodeList[idx] = nodeRef.isList
930
- ? nodeRef.nodes[idx]
931
- : nodeRef.node;
932
- } else {
933
- if (nodeRefList.getIndex(idx)) {
934
- stableNodeList[idx] = nodeRef.nodes[idx];
935
- }
936
- }
937
- });
938
- } else {
939
- if (nodeRef.isList) {
940
- nodeRef.nodes.forEach((elem) => stableNodeList.push(elem));
941
- } else {
942
- stableNodeList.push(nodeRef.node);
943
- }
944
- }
945
-
946
- linkFnsList.forEach(({ index, nodeLinkFnCtx, childLinkFn }) => {
947
- const node = stableNodeList[index];
948
- node.stable = true;
949
- let childScope;
950
- let childBoundTranscludeFn;
951
-
952
- if (nodeLinkFnCtx?.nodeLinkFn) {
953
- childScope = nodeLinkFnCtx.newScope ? scope.$new() : scope;
954
-
955
- if (nodeLinkFnCtx.transcludeOnThisElement) {
956
- // bind proper scope for the translusion function
957
- childBoundTranscludeFn = createBoundTranscludeFn(
958
- scope,
959
- nodeLinkFnCtx.transclude,
960
- parentBoundTranscludeFn,
961
- );
962
- } else if (
963
- !nodeLinkFnCtx.templateOnThisElement &&
964
- parentBoundTranscludeFn
965
- ) {
966
- childBoundTranscludeFn = parentBoundTranscludeFn;
967
- } else if (!parentBoundTranscludeFn && transcludeFn) {
968
- childBoundTranscludeFn = createBoundTranscludeFn(
969
- scope,
970
- transcludeFn,
971
- );
972
- } else {
973
- childBoundTranscludeFn = null;
974
- }
975
-
976
- // attach new scope to element
977
- if (nodeLinkFnCtx?.newScope) {
978
- setScope(node, childScope);
979
- }
980
- // @ts-ignore
981
- nodeLinkFnCtx.nodeLinkFn(
982
- // @ts-ignore
983
- childLinkFn,
984
- childScope,
985
- node,
986
- childBoundTranscludeFn,
987
- );
988
- } else if (childLinkFn) {
989
- childLinkFn(
990
- scope,
991
- new NodeRef(node.childNodes),
992
- parentBoundTranscludeFn,
993
- );
994
- }
995
- });
996
- }
997
- }
998
-
999
- /**
1000
- * Prebinds the transclusion function to a scope
1001
- * @param {import("../scope/scope.js").Scope} scope
1002
- * @param {*} transcludeFn
1003
- * @param {*} previousBoundTranscludeFn
1004
- * @returns {BoundTranscludeFn}
1005
- */
1006
- function createBoundTranscludeFn(
1007
- scope,
1008
- transcludeFn,
1009
- previousBoundTranscludeFn,
1010
- ) {
1011
- function boundTranscludeFn(
1012
- transcludedScope,
1013
- cloneFn,
1014
- controllers,
1015
- futureParentElement,
1016
- containingScope,
1017
- ) {
1018
- if (!transcludedScope) {
1019
- transcludedScope = scope.$transcluded(containingScope);
1020
- transcludedScope.$$transcluded = true;
1021
- }
1022
-
1023
- const transcludeRes = transcludeFn(transcludedScope, cloneFn, {
1024
- parentBoundTranscludeFn: previousBoundTranscludeFn,
1025
- transcludeControllers: controllers,
1026
- futureParentElement,
1027
- });
1028
-
1029
- return transcludeRes;
1030
- }
1031
-
1032
- // We need to attach the transclusion slots onto the `boundTranscludeFn`
1033
- // so that they are available inside the `controllersBoundTransclude` function
1034
- const boundSlots = (boundTranscludeFn.$$slots = Object.create(null));
1035
- for (const slotName in transcludeFn.$$slots) {
1036
- if (transcludeFn.$$slots[slotName]) {
1037
- boundSlots[slotName] = createBoundTranscludeFn(
1038
- scope,
1039
- transcludeFn.$$slots[slotName],
1040
- previousBoundTranscludeFn,
1041
- );
1042
- } else {
1043
- boundSlots[slotName] = null;
1044
- }
1045
- }
1046
-
1047
- return boundTranscludeFn;
1048
- }
1049
-
1050
- /**
1051
- * Looks for directives on the given node and adds them to the directive collection which is
1052
- * sorted.
1053
- *
1054
- * @param {Element} node Node to search.
1055
- * @param {Attributes|any} attrs The shared attrs object which is used to populate the normalized attributes.
1056
- * @param {number=} maxPriority Max directive priority.
1057
- * @param {string} [ignoreDirective]
1058
- * @return {import('../../interface.ts').Directive[]} An array to which the directives are added to. This array is sorted before the function returns.
1059
- */
1060
- function collectDirectives(node, attrs, maxPriority, ignoreDirective) {
1061
- /**
1062
- * @type {import('../../interface.ts').Directive[]}
1063
- */
1064
- const directives = [];
1065
- const { nodeType } = node;
1066
- const attrsMap = attrs.$attr;
1067
- let nodeName;
1068
-
1069
- switch (nodeType) {
1070
- case Node.ELEMENT_NODE /* Element */:
1071
- nodeName = node.nodeName.toLowerCase();
1072
- if (ignoreDirective !== directiveNormalize(nodeName)) {
1073
- // use the node name: <directive>
1074
- addDirective(
1075
- directives,
1076
- directiveNormalize(nodeName),
1077
- "E",
1078
- maxPriority,
1079
- );
1080
- }
1081
-
1082
- // iterate over the attributes
1083
- for (let j = 0; j < node.attributes?.length; j++) {
1084
- let isNgAttr = false;
1085
- let isNgProp = false;
1086
- let isNgEvent = false;
1087
- let isNgObserve = false;
1088
-
1089
- let attr = node.attributes[j];
1090
- let name = attr.name;
1091
- let value = attr.value;
1092
- let nName = directiveNormalize(name.toLowerCase());
1093
-
1094
- // Support ng-attr-*, ng-prop-* and ng-on-*
1095
- const ngPrefixMatch = nName.match(NG_PREFIX_BINDING);
1096
- if (ngPrefixMatch) {
1097
- isNgAttr = ngPrefixMatch[1] === "Attr";
1098
- isNgProp = ngPrefixMatch[1] === "Prop";
1099
- isNgEvent = ngPrefixMatch[1] === "On";
1100
- isNgObserve = ngPrefixMatch[1] === "Observe";
1101
-
1102
- // Normalize the non-prefixed name
1103
- name = name
1104
- .replace(PREFIX_REGEXP, "")
1105
- .toLowerCase()
1106
- .substring(4 + ngPrefixMatch[1].length)
1107
- .replace(/_(.)/g, (match, letter) => letter.toUpperCase());
1108
- }
1109
-
1110
- if (isNgProp || isNgEvent) {
1111
- attrs[nName] = value;
1112
- attrsMap[nName] = attr.name;
1113
-
1114
- if (isNgProp) {
1115
- addPropertyDirective(node, directives, nName, name);
1116
- } else {
1117
- directives.push(
1118
- createEventDirective(
1119
- $parse,
1120
- $exceptionHandler,
1121
- nName,
1122
- name,
1123
- ),
1124
- );
1125
- }
1126
- } else if (isNgObserve) {
1127
- directives.push(ngObserveDirective(name, value));
1128
- } else {
1129
- // Update nName for cases where a prefix was removed
1130
- // NOTE: the .toLowerCase() is unnecessary and causes https://github.com/angular/angular.js/issues/16624 for ng-attr-*
1131
- nName = directiveNormalize(name.toLowerCase());
1132
- attrsMap[nName] = name;
1133
-
1134
- if (isNgAttr || !hasOwn(attrs, nName)) {
1135
- attrs[nName] = value;
1136
- if (getBooleanAttrName(node, nName)) {
1137
- attrs[nName] = true; // presence means true
1138
- }
1139
- }
1140
-
1141
- addAttrInterpolateDirective(
1142
- node,
1143
- directives,
1144
- value,
1145
- nName,
1146
- isNgAttr,
1147
- );
1148
-
1149
- if (nName !== ignoreDirective) {
1150
- addDirective(directives, nName, "A", maxPriority);
1151
- }
1152
- }
1153
- }
1154
-
1155
- if (
1156
- nodeName === "input" &&
1157
- node.getAttribute("type") === "hidden"
1158
- ) {
1159
- // Hidden input elements can have strange behaviour when navigating back to the page
1160
- // This tells the browser not to try to cache and reinstate previous values
1161
- node.setAttribute("autocomplete", "off");
1162
- }
1163
-
1164
- break;
1165
- case Node.TEXT_NODE:
1166
- addTextInterpolateDirective(directives, node.nodeValue);
1167
- break;
1168
- default:
1169
- break;
1170
- }
1171
-
1172
- directives.sort(byPriority);
1173
- return directives;
1174
- }
1175
-
1176
- /**
1177
- * A function generator that is used to support both eager and lazy compilation
1178
- * linking function.
1179
- * @param eager
1180
- * @param {NodeList|Node} compileNodes
1181
- * @param transcludeFn
1182
- * @param maxPriority
1183
- * @param ignoreDirective
1184
- * @param previousCompileContext
1185
- * @returns {PublicLinkFn|TranscludeFn}
1186
- */
1187
- function compilationGenerator(
1188
- eager,
1189
- compileNodes,
1190
- transcludeFn,
1191
- maxPriority,
1192
- ignoreDirective,
1193
- previousCompileContext,
1194
- ) {
1195
- let compiled;
1196
- if (eager) {
1197
- return compile(
1198
- compileNodes,
1199
- transcludeFn,
1200
- maxPriority,
1201
- ignoreDirective,
1202
- previousCompileContext,
1203
- );
1204
- }
1205
-
1206
- return function lazyCompilation() {
1207
- if (!compiled) {
1208
- compiled = compile(
1209
- compileNodes,
1210
- transcludeFn,
1211
- maxPriority,
1212
- ignoreDirective,
1213
- previousCompileContext,
1214
- );
1215
-
1216
- // Null out all of these references for garbage collection
1217
- compileNodes = transcludeFn = previousCompileContext = null;
1218
- }
1219
- return compiled.apply(this, arguments);
1220
- };
1221
- }
1222
-
1223
- /**
1224
- * Once the directives have been collected, their compile functions are executed. This method
1225
- * is responsible for inlining directive templates as well as terminating the application
1226
- * of the directives if the terminal directive has been reached.
1227
- *
1228
- * @param {Array} directives Array of collected directives to execute their compile function.
1229
- * this needs to be pre-sorted by priority order.
1230
- * @param {Node | Element} compileNode DOM node to apply the compile functions to
1231
- * @param {Attributes} templateAttrs The shared attribute function
1232
- * @param {TranscludeFn} transcludeFn
1233
- * @param {Object=} originalReplaceDirective An optional directive that will be ignored when
1234
- * compiling the transclusion.
1235
- * @param {Array.<Function>} [preLinkFns]
1236
- * @param {Array.<Function>} [postLinkFns]
1237
- * @param {Object} [previousCompileContext] Context used for previous compilation of the current
1238
- * node
1239
- * @returns {NodeLinkFnCtx} node link function
1240
- */
1241
- function applyDirectivesToNode(
1242
- directives,
1243
- compileNode,
1244
- templateAttrs,
1245
- transcludeFn,
1246
- originalReplaceDirective,
1247
- preLinkFns,
1248
- postLinkFns,
1249
- previousCompileContext,
1250
- ) {
1251
- previousCompileContext = previousCompileContext || {};
1252
-
1253
- let terminalPriority = -Number.MAX_VALUE;
1254
- let terminal = false;
1255
- let {
1256
- newScopeDirective,
1257
- controllerDirectives,
1258
- newIsolateScopeDirective,
1259
- templateDirective,
1260
- nonTlbTranscludeDirective,
1261
- hasElementTranscludeDirective,
1262
- ctxNodeRef,
1263
- parentNodeRef,
1264
- } = previousCompileContext;
1265
- let hasTranscludeDirective = false;
1266
- let hasTemplate = false;
1267
- let compileNodeRef = new NodeRef(compileNode);
1268
- const index = previousCompileContext.index;
1269
- templateAttrs.$nodeRef = compileNodeRef;
1270
- let directive;
1271
- let directiveName;
1272
- let $template;
1273
- let replaceDirective = originalReplaceDirective;
1274
- /** @type {TranscludeFn} */
1275
- let childTranscludeFn = transcludeFn;
1276
-
1277
- let didScanForMultipleTransclusion = false;
1278
- let mightHaveMultipleTransclusionError = false;
1279
- let directiveValue;
1280
-
1281
- /**
1282
- * Links all the directives of a single node.
1283
- * @type {NodeLinkFn}
1284
- */
1285
- // @ts-ignore
1286
- let nodeLinkFn = function (
1287
- childLinkFn,
1288
- scope,
1289
- linkNode,
1290
- boundTranscludeFn,
1291
- ) {
1292
- let i;
1293
- let ii;
1294
- let isolateScope;
1295
- let controllerScope;
1296
- let elementControllers;
1297
- let transcludeFn;
1298
- let scopeToChild = scope;
1299
-
1300
- /** @type {NodeRef} */
1301
- let $element;
1302
- /** @type {Attributes} */
1303
- let attrs;
1304
- let scopeBindingInfo;
1305
-
1306
- if (compileNode === linkNode) {
1307
- attrs = templateAttrs;
1308
- $element = templateAttrs.$nodeRef;
1309
- } else {
1310
- $element = new NodeRef(linkNode);
1311
- attrs = new Attributes(
1312
- $rootScope,
1313
- $animate,
1314
- $exceptionHandler,
1315
- $sce,
1316
- $element,
1317
- templateAttrs,
1318
- );
1319
- }
1320
-
1321
- controllerScope = scope;
1322
- if (newIsolateScopeDirective) {
1323
- isolateScope = scope.$newIsolate();
1324
- } else if (newScopeDirective) {
1325
- controllerScope = scope.$parent;
1326
- }
1327
-
1328
- if (boundTranscludeFn) {
1329
- // track `boundTranscludeFn` so it can be unwrapped if `transcludeFn`
1330
- // is later passed as `parentBoundTranscludeFn` to `publicLinkFn`
1331
- transcludeFn = controllersBoundTransclude;
1332
- transcludeFn["$$boundTransclude"] = boundTranscludeFn;
1333
- // expose the slots on the `$transclude` function
1334
- transcludeFn["isSlotFilled"] = function (slotName) {
1335
- return !!boundTranscludeFn.$$slots[slotName];
1336
- };
1337
- }
1338
-
1339
- if (controllerDirectives) {
1340
- elementControllers = setupControllers(
1341
- $element,
1342
- attrs,
1343
- transcludeFn,
1344
- controllerDirectives,
1345
- isolateScope,
1346
- scope,
1347
- newIsolateScopeDirective,
1348
- );
1349
- }
1350
-
1351
- if (newIsolateScopeDirective) {
1352
- isolateScope.$target.$$isolateBindings =
1353
- newIsolateScopeDirective.$$isolateBindings;
1354
- scopeBindingInfo = initializeDirectiveBindings(
1355
- scope,
1356
- attrs,
1357
- isolateScope,
1358
- isolateScope.$$isolateBindings,
1359
- newIsolateScopeDirective,
1360
- );
1361
- if (scopeBindingInfo.removeWatches) {
1362
- isolateScope.$on("$destroy", scopeBindingInfo.removeWatches);
1363
- }
1364
- }
1365
-
1366
- // Initialize bindToController bindings
1367
- for (const name in elementControllers) {
1368
- const controllerDirective = controllerDirectives[name];
1369
- const controller = elementControllers[name];
1370
- const bindings = controllerDirective.$$bindings.bindToController;
1371
-
1372
- // Controller instance is bound to the scope
1373
- const controllerInstance = controller();
1374
- controller.instance = controllerScope.$new(controllerInstance);
1375
- setCacheData(
1376
- $element.node,
1377
- `$${controllerDirective.name}Controller`,
1378
- controller.instance,
1379
- );
1380
- controller.bindingInfo = initializeDirectiveBindings(
1381
- controllerScope,
1382
- attrs,
1383
- controller.instance,
1384
- bindings,
1385
- controllerDirective,
1386
- );
1387
- }
1388
-
1389
- // Bind the required controllers to the controller, if `require` is an object and `bindToController` is truthy
1390
- if (controllerDirectives) {
1391
- Object.entries(controllerDirectives).forEach(
1392
- ([name, controllerDirective]) => {
1393
- const { require } = controllerDirective;
1394
- if (
1395
- controllerDirective.bindToController &&
1396
- !Array.isArray(require) &&
1397
- isObject(require)
1398
- ) {
1399
- extend(
1400
- elementControllers[name].instance,
1401
- getControllers(
1402
- name,
1403
- require,
1404
- $element.element,
1405
- elementControllers,
1406
- ),
1407
- );
1408
- }
1409
- },
1410
- );
1411
- }
1412
-
1413
- // Handle the init and destroy lifecycle hooks on all controllers that have them
1414
- if (elementControllers) {
1415
- Object.values(elementControllers).forEach((controller) => {
1416
- const controllerInstance = controller.instance;
1417
- if (isFunction(controllerInstance.$onChanges)) {
1418
- try {
1419
- controllerInstance.$onChanges(
1420
- controller.bindingInfo.initialChanges,
1421
- );
1422
- } catch (e) {
1423
- $exceptionHandler(e);
1424
- }
1425
- }
1426
- if (isFunction(controllerInstance.$onInit)) {
1427
- try {
1428
- controllerInstance.$target.$onInit();
1429
- } catch (e) {
1430
- $exceptionHandler(e);
1431
- }
1432
- }
1433
- if (isFunction(controllerInstance.$onDestroy)) {
1434
- controllerScope.$on("$destroy", () => {
1435
- controllerInstance.$onDestroy();
1436
- });
1437
- }
1438
- });
1439
- }
1440
-
1441
- // PRELINKING
1442
- for (i = 0, ii = preLinkFns.length; i < ii; i++) {
1443
- let preLinkFn = preLinkFns[i];
1444
- const controllers =
1445
- preLinkFn["require"] &&
1446
- getControllers(
1447
- preLinkFn["directiveName"],
1448
- preLinkFn["require"],
1449
- $element.element,
1450
- elementControllers,
1451
- );
1452
-
1453
- // invoke link function
1454
- try {
1455
- preLinkFn(
1456
- preLinkFn["isolateScope"] ? isolateScope : scope,
1457
- $element.node, // Prelink functions accept a Node
1458
- attrs,
1459
- controllers,
1460
- transcludeFn,
1461
- );
1462
- } catch (e) {
1463
- $exceptionHandler(e, startingTag($element.getAny()));
1464
- }
1465
- }
1466
-
1467
- // RECURSION
1468
- // We only pass the isolate scope, if the isolate directive has a template,
1469
- // otherwise the child elements do not belong to the isolate directive.
1470
-
1471
- if (
1472
- newIsolateScopeDirective &&
1473
- (newIsolateScopeDirective.template ||
1474
- newIsolateScopeDirective.templateUrl === null)
1475
- ) {
1476
- scopeToChild = isolateScope;
1477
- }
1478
- if (
1479
- childLinkFn &&
1480
- linkNode &&
1481
- linkNode.childNodes &&
1482
- linkNode.childNodes.length
1483
- ) {
1484
- childLinkFn(
1485
- scopeToChild,
1486
- new NodeRef(linkNode.childNodes),
1487
- boundTranscludeFn,
1488
- );
1489
- }
1490
- // POSTLINKING
1491
- for (i = postLinkFns.length - 1; i >= 0; i--) {
1492
- let postLinkFn = postLinkFns[i];
1493
- const controllers =
1494
- postLinkFn["require"] &&
1495
- getControllers(
1496
- postLinkFn["directiveName"],
1497
- postLinkFn["require"],
1498
- /** @type {Element} */ ($element.node),
1499
- elementControllers,
1500
- );
1501
-
1502
- // invoke link function
1503
- try {
1504
- if (postLinkFn["isolateScope"]) {
1505
- setIsolateScope($element.element, isolateScope);
1506
- }
1507
-
1508
- postLinkFn(
1509
- postLinkFn["isolateScope"] ? isolateScope : scope,
1510
- $element.node,
1511
- attrs,
1512
- controllers,
1513
- transcludeFn,
1514
- );
1515
- } catch (e) {
1516
- $exceptionHandler(e, startingTag($element.getAny()));
1517
- }
1518
- }
1519
-
1520
- if (elementControllers) {
1521
- // Trigger $postLink lifecycle hooks
1522
- Object.values(elementControllers).forEach((controller) => {
1523
- const controllerInstance = controller.instance;
1524
- if (isFunction(controllerInstance.$postLink)) {
1525
- controllerInstance.$postLink();
1526
- }
1527
- });
1528
- }
1529
-
1530
- // This is the function that is injected as `$transclude` or
1531
- // the fifth parameter to the link function.
1532
- // Example: function link (scope, element, attrs, ctrl, transclude) {}
1533
- // Note: all arguments are optional!
1534
- function controllersBoundTransclude(
1535
- scope,
1536
- cloneAttachFn,
1537
- futureParentElement,
1538
- slotName,
1539
- ) {
1540
- let transcludeControllers;
1541
- // No scope passed in:
1542
- if (!isScope(scope)) {
1543
- slotName = futureParentElement;
1544
- futureParentElement = cloneAttachFn;
1545
- cloneAttachFn = scope;
1546
- scope = undefined;
1547
- }
1548
- if (hasElementTranscludeDirective) {
1549
- transcludeControllers = elementControllers;
1550
- }
1551
- if (!futureParentElement) {
1552
- futureParentElement = hasElementTranscludeDirective
1553
- ? $element.node.parentElement
1554
- : $element.node;
1555
- }
1556
- if (slotName) {
1557
- // slotTranscludeFn can be one of three things:
1558
- // * a transclude function - a filled slot
1559
- // * `null` - an optional slot that was not filled
1560
- // * `undefined` - a slot that was not declared (i.e. invalid)
1561
- const slotTranscludeFn = boundTranscludeFn.$$slots[slotName];
1562
- if (slotTranscludeFn) {
1563
- return slotTranscludeFn(
1564
- scope,
1565
- cloneAttachFn,
1566
- transcludeControllers,
1567
- futureParentElement,
1568
- scopeToChild,
1569
- );
1570
- }
1571
-
1572
- if (isUndefined(slotTranscludeFn)) {
1573
- throw $compileMinErr(
1574
- "noslot",
1575
- 'No parent directive that requires a transclusion with slot name "{0}". ' +
1576
- "Element: {1}",
1577
- slotName,
1578
- startingTag($element.element),
1579
- );
1580
- }
1581
- } else {
1582
- return boundTranscludeFn(
1583
- scope,
1584
- cloneAttachFn,
1585
- transcludeControllers,
1586
- futureParentElement,
1587
- scopeToChild,
1588
- );
1589
- }
1590
- }
1591
- };
1592
-
1593
- // executes all directives on the current element
1594
- for (let i = 0, ii = directives.length; i < ii; i++) {
1595
- directive = directives[i];
1596
- $template = undefined;
1597
-
1598
- if (terminalPriority > directive.priority) {
1599
- break; // prevent further processing of directives
1600
- }
1601
-
1602
- directiveValue = directive.scope;
1603
-
1604
- if (directiveValue) {
1605
- // skip the check for directives with async templates, we'll check the derived sync
1606
- // directive when the template arrives
1607
- if (!directive.templateUrl) {
1608
- if (isObject(directiveValue)) {
1609
- // This directive is trying to add an isolated scope.
1610
- // Check that there is no scope of any kind already
1611
- assertNoDuplicate(
1612
- "new/isolated scope",
1613
- newIsolateScopeDirective || newScopeDirective,
1614
- directive,
1615
- compileNodeRef,
1616
- );
1617
- newIsolateScopeDirective = directive;
1618
- } else {
1619
- // This directive is trying to add a child scope.
1620
- // Check that there is no isolated scope already
1621
- assertNoDuplicate(
1622
- "new/isolated scope",
1623
- newIsolateScopeDirective,
1624
- directive,
1625
- compileNodeRef,
1626
- );
1627
- }
1628
- }
1629
-
1630
- newScopeDirective = newScopeDirective || directive;
1631
- }
1632
-
1633
- directiveName = directive.name;
1634
-
1635
- // If we encounter a condition that can result in transclusion on the directive,
1636
- // then scan ahead in the remaining directives for others that may cause a multiple
1637
- // transclusion error to be thrown during the compilation process. If a matching directive
1638
- // is found, then we know that when we encounter a transcluded directive, we need to eagerly
1639
- // compile the `transclude` function rather than doing it lazily in order to throw
1640
- // exceptions at the correct time
1641
- const hasReplacedTemplate =
1642
- directive.replace &&
1643
- (directive.templateUrl || directive.template);
1644
- const shouldTransclude =
1645
- directive.transclude &&
1646
- !EXCLUDED_DIRECTIVES.includes(directive.name);
1647
- if (
1648
- !didScanForMultipleTransclusion &&
1649
- (hasReplacedTemplate || shouldTransclude)
1650
- ) {
1651
- let candidateDirective;
1652
-
1653
- for (
1654
- let scanningIndex = i + 1;
1655
- (candidateDirective = directives[scanningIndex++]);
1656
-
1657
- ) {
1658
- if (
1659
- (candidateDirective.transclude &&
1660
- !EXCLUDED_DIRECTIVES.includes(candidateDirective.name)) ||
1661
- (candidateDirective.replace &&
1662
- (candidateDirective.templateUrl ||
1663
- candidateDirective.template))
1664
- ) {
1665
- mightHaveMultipleTransclusionError = true;
1666
- break;
1667
- }
1668
- }
1669
-
1670
- didScanForMultipleTransclusion = true;
1671
- }
1672
-
1673
- if (!directive.templateUrl && directive.controller) {
1674
- controllerDirectives =
1675
- controllerDirectives || Object.create(null);
1676
- assertNoDuplicate(
1677
- `'${directiveName}' controller`,
1678
- controllerDirectives[directiveName],
1679
- directive,
1680
- compileNodeRef,
1681
- );
1682
- controllerDirectives[directiveName] = directive;
1683
- }
1684
-
1685
- directiveValue = directive.transclude;
1686
-
1687
- if (directiveValue) {
1688
- hasTranscludeDirective = true;
1689
-
1690
- // Special case ngIf and ngRepeat so that we don't complain about duplicate transclusion.
1691
- // This option should only be used by directives that know how to safely handle element transclusion,
1692
- // where the transcluded nodes are added or replaced after linking.
1693
- if (!EXCLUDED_DIRECTIVES.includes(directive.name)) {
1694
- assertNoDuplicate(
1695
- "transclusion",
1696
- nonTlbTranscludeDirective,
1697
- directive,
1698
- compileNodeRef,
1699
- );
1700
- nonTlbTranscludeDirective = directive;
1701
- }
1702
-
1703
- if (directiveValue === "element") {
1704
- hasElementTranscludeDirective = true;
1705
- terminalPriority = directive.priority;
1706
- $template = compileNodeRef;
1707
- compileNodeRef = new NodeRef(document.createComment(""));
1708
- templateAttrs.$nodeRef = compileNodeRef;
1709
- compileNode = compileNodeRef.node;
1710
- ctxNodeRef.node = compileNode;
1711
- replaceWith(
1712
- new NodeRef($template.getAny()),
1713
- compileNode,
1714
- index,
1715
- );
1716
-
1717
- // @ts-ignore
1718
- childTranscludeFn = compilationGenerator(
1719
- mightHaveMultipleTransclusionError,
1720
- $template.getAny(),
1721
- transcludeFn,
1722
- terminalPriority,
1723
- replaceDirective && replaceDirective.name,
1724
- {
1725
- // Don't pass in:
1726
- // - controllerDirectives - otherwise we'll create duplicates controllers
1727
- // - newIsolateScopeDirective or templateDirective - combining templates with
1728
- // element transclusion doesn't make sense.
1729
- //
1730
- // We need only nonTlbTranscludeDirective so that we prevent putting transclusion
1731
- // on the same element more than once.
1732
- nonTlbTranscludeDirective,
1733
- },
1734
- );
1735
- } else {
1736
- const slots = Object.create(null);
1737
-
1738
- if (!isObject(directiveValue)) {
1739
- //
1740
- // Clone childnodes before clearing contents on transcluded directives
1741
- $template = compileNode.cloneNode(true).childNodes;
1742
- } else {
1743
- // We have transclusion slots,
1744
- // collect them up, compile them and store their transclusion functions
1745
- $template = document.createDocumentFragment();
1746
-
1747
- const slotMap = Object.create(null);
1748
- const filledSlots = Object.create(null);
1749
-
1750
- // Parse the element selectors
1751
- Object.entries(directiveValue).forEach(
1752
- ([slotName, elementSelector]) => {
1753
- // If an element selector starts with a ? then it is optional
1754
- const optional = elementSelector.charAt(0) === "?";
1755
- elementSelector = optional
1756
- ? elementSelector.substring(1)
1757
- : elementSelector;
1758
-
1759
- slotMap[elementSelector] = slotName;
1760
-
1761
- // We explicitly assign `null` since this implies that a slot was defined but not filled.
1762
- // Later when calling boundTransclusion functions with a slot name we only error if the
1763
- // slot is `undefined`
1764
- slots[slotName] = null;
1765
-
1766
- // filledSlots contains `true` for all slots that are either optional or have been
1767
- // filled. This is used to check that we have not missed any required slots
1768
- filledSlots[slotName] = optional;
1769
- },
1770
- );
1771
-
1772
- // Add the matching elements into their slot
1773
- compileNodeRef.element.childNodes.forEach((node) => {
1774
- const slotName =
1775
- slotMap[
1776
- directiveNormalize(
1777
- getNodeName(/** @type {Element} */ (node)),
1778
- )
1779
- ];
1780
- if (slotName) {
1781
- filledSlots[slotName] = true;
1782
- slots[slotName] =
1783
- slots[slotName] || document.createDocumentFragment();
1784
- slots[slotName].appendChild(node);
1785
- } else {
1786
- $template.appendChild(node);
1787
- }
1788
- });
1789
-
1790
- // Check for required slots that were not filled
1791
- Object.entries(filledSlots).forEach(([slotName, filled]) => {
1792
- if (!filled) {
1793
- throw $compileMinErr(
1794
- "reqslot",
1795
- "Required transclusion slot `{0}` was not filled.",
1796
- slotName,
1797
- );
1798
- }
1799
- });
1800
-
1801
- for (const slotName in slots) {
1802
- if (slots[slotName]) {
1803
- // Only define a transclusion function if the slot was filled
1804
- const slotCompileNodes = slots[slotName].childNodes;
1805
- slots[slotName] = compilationGenerator(
1806
- mightHaveMultipleTransclusionError,
1807
- slotCompileNodes,
1808
- transcludeFn,
1809
- );
1810
- }
1811
- }
1812
-
1813
- $template = $template.childNodes;
1814
- }
1815
-
1816
- emptyElement(/** @type {Element} */ (compileNode)); // clear contents on transcluded directives
1817
-
1818
- // lazily compile transcluded template and generate a transcluded link function
1819
- // @ts-ignore
1820
- childTranscludeFn = compilationGenerator(
1821
- mightHaveMultipleTransclusionError,
1822
- $template,
1823
- transcludeFn,
1824
- undefined,
1825
- undefined,
1826
- {
1827
- needsNewScope:
1828
- directive.$$isolateScope || directive.$$newScope,
1829
- },
1830
- );
1831
- childTranscludeFn["$$slots"] = slots;
1832
- }
1833
- }
1834
-
1835
- if (directive.template) {
1836
- hasTemplate = true;
1837
- assertNoDuplicate(
1838
- "template",
1839
- templateDirective,
1840
- directive,
1841
- compileNodeRef,
1842
- );
1843
- templateDirective = directive;
1844
-
1845
- directiveValue = isFunction(directive.template)
1846
- ? directive.template(compileNodeRef.node, templateAttrs)
1847
- : directive.template;
1848
-
1849
- directiveValue = denormalizeTemplate(directiveValue);
1850
- if (directive.replace) {
1851
- replaceDirective = directive;
1852
- if (isTextNode(directiveValue)) {
1853
- $template = [];
1854
- } else {
1855
- $template = removeComments(
1856
- wrapTemplate(
1857
- directive.templateNamespace,
1858
- trim(directiveValue),
1859
- ),
1860
- );
1861
- }
1862
-
1863
- if (isString($template)) {
1864
- $template = Array.from(
1865
- createNodelistFromHTML($template),
1866
- ).filter((x) => x.nodeType === Node.ELEMENT_NODE);
1867
- }
1868
- compileNode = $template[0];
1869
-
1870
- if (
1871
- $template.length !== 1 ||
1872
- compileNode.nodeType !== Node.ELEMENT_NODE
1873
- ) {
1874
- throw $compileMinErr(
1875
- "tplrt",
1876
- "Template for directive '{0}' must have exactly one root element. {1}",
1877
- directiveName,
1878
- "",
1879
- );
1880
- }
1881
-
1882
- replaceWith(compileNodeRef, compileNode);
1883
-
1884
- if (parentNodeRef) {
1885
- parentNodeRef.setIndex(index, compileNode);
1886
- }
1887
-
1888
- const newTemplateAttrs = { $attr: {} };
1889
-
1890
- // combine directives from the original node and from the template:
1891
- // - take the array of directives for this element
1892
- // - split it into two parts, those that already applied (processed) and those that weren't (unprocessed)
1893
- // - collect directives from the template and sort them by priority
1894
- // - combine directives as: processed + template + unprocessed
1895
- const templateDirectives = collectDirectives(
1896
- /** @type {Element} */ (compileNode),
1897
- newTemplateAttrs,
1898
- );
1899
- const unprocessedDirectives = directives.splice(
1900
- i + 1,
1901
- directives.length - (i + 1),
1902
- );
1903
-
1904
- if (newIsolateScopeDirective || newScopeDirective) {
1905
- // The original directive caused the current element to be replaced but this element
1906
- // also needs to have a new scope, so we need to tell the template directives
1907
- // that they would need to get their scope from further up, if they require transclusion
1908
- markDirectiveScope(
1909
- templateDirectives,
1910
- newIsolateScopeDirective,
1911
- newScopeDirective,
1912
- );
1913
- }
1914
- directives = directives
1915
- .concat(templateDirectives)
1916
- .concat(unprocessedDirectives);
1917
-
1918
- mergeTemplateAttributes(templateAttrs, newTemplateAttrs);
1919
-
1920
- ii = directives.length;
1921
- } else {
1922
- if (compileNodeRef.isElement()) {
1923
- compileNodeRef.element.innerHTML = directiveValue;
1924
- }
1925
- }
1926
- }
1927
-
1928
- if (directive.templateUrl) {
1929
- hasTemplate = true;
1930
- assertNoDuplicate(
1931
- "template",
1932
- templateDirective,
1933
- directive,
1934
- compileNodeRef,
1935
- );
1936
- templateDirective = directive;
1937
-
1938
- if (directive.replace) {
1939
- replaceDirective = directive;
1940
- }
1941
- // @ts-ignore
1942
- nodeLinkFn = compileTemplateUrl(
1943
- directives.splice(i, directives.length - i),
1944
- compileNodeRef,
1945
- templateAttrs,
1946
- /** @type {Element} */ (compileNode),
1947
- hasTranscludeDirective && childTranscludeFn,
1948
- preLinkFns,
1949
- postLinkFns,
1950
- {
1951
- index,
1952
- controllerDirectives,
1953
- newScopeDirective:
1954
- newScopeDirective !== directive && newScopeDirective,
1955
- newIsolateScopeDirective,
1956
- templateDirective,
1957
- nonTlbTranscludeDirective,
1958
- futureParentElement:
1959
- previousCompileContext.futureParentElement,
1960
- },
1961
- );
1962
- ii = directives.length;
1963
- } else if (directive.compile) {
1964
- try {
1965
- /** @type {PublicLinkFn} */
1966
- const linkFn = directive.compile(
1967
- compileNodeRef.getAny(),
1968
- templateAttrs,
1969
- childTranscludeFn,
1970
- );
1971
- const context = directive.$$originalDirective || directive;
1972
- if (isFunction(linkFn)) {
1973
- addLinkFns(null, bind(context, linkFn));
1974
- } else if (linkFn) {
1975
- addLinkFns(
1976
- bind(context, linkFn["pre"]),
1977
- bind(context, linkFn["post"]),
1978
- );
1979
- }
1980
- } catch (e) {
1981
- $exceptionHandler(e, startingTag(compileNodeRef.getAny()));
1982
- }
1983
- }
1984
-
1985
- if (directive.terminal) {
1986
- terminal = true;
1987
- terminalPriority = Math.max(terminalPriority, directive.priority);
1988
- }
1989
- }
1990
-
1991
- previousCompileContext.hasElementTranscludeDirective =
1992
- hasElementTranscludeDirective;
1993
-
1994
- // might be normal or delayed nodeLinkFn depending on if templateUrl is present
1995
- return {
1996
- nodeLinkFn,
1997
- terminal,
1998
- transclude: childTranscludeFn,
1999
- transcludeOnThisElement: hasTranscludeDirective,
2000
- templateOnThisElement: hasTemplate,
2001
- newScope: newScopeDirective && newScopeDirective.scope === true,
2002
- };
2003
-
2004
- /// /////////////////
2005
- function addLinkFns(pre, post) {
2006
- if (pre) {
2007
- pre.require = directive.require;
2008
- pre.directiveName = directiveName;
2009
- if (
2010
- newIsolateScopeDirective === directive ||
2011
- directive.$$isolateScope
2012
- ) {
2013
- pre = cloneAndAnnotateFn(pre, { isolateScope: true });
2014
- }
2015
- preLinkFns.push(pre);
2016
- }
2017
- if (post) {
2018
- post.require = directive.require;
2019
- post.directiveName = directiveName;
2020
- if (
2021
- newIsolateScopeDirective === directive ||
2022
- directive.$$isolateScope
2023
- ) {
2024
- post = cloneAndAnnotateFn(post, { isolateScope: true });
2025
- }
2026
- postLinkFns.push(post);
2027
- }
2028
- }
2029
- }
2030
-
2031
- /**
2032
- *
2033
- * @param {*} directiveName
2034
- * @param {*} require
2035
- * @param {Element} $element
2036
- * @param {*} elementControllers
2037
- * @returns
2038
- */
2039
- function getControllers(
2040
- directiveName,
2041
- require,
2042
- $element,
2043
- elementControllers,
2044
- ) {
2045
- let value;
2046
-
2047
- if (isString(require)) {
2048
- const match = require.match(REQUIRE_PREFIX_REGEXP);
2049
- const name = require.substring(match[0].length);
2050
- const inheritType = match[1] || match[3];
2051
- const optional = match[2] === "?";
2052
-
2053
- // If only parents then start at the parent element
2054
- if (inheritType === "^^") {
2055
- if ($element.parentElement) {
2056
- $element = $element.parentElement;
2057
- } else {
2058
- $element = undefined;
2059
- }
2060
- // Otherwise attempt getting the controller from elementControllers in case
2061
- // the element is transcluded (and has no data) and to avoid .data if possible
2062
- } else {
2063
- value = elementControllers && elementControllers[name];
2064
- value = value && value.instance;
2065
- }
2066
-
2067
- if (!value) {
2068
- const dataName = `$${name}Controller`;
2069
- if (
2070
- inheritType === "^^" &&
2071
- $element &&
2072
- $element.nodeType === Node.DOCUMENT_NODE
2073
- ) {
2074
- // inheritedData() uses the documentElement when it finds the document, so we would
2075
- // require from the element itself.
2076
- value = null;
2077
- } else {
2078
- value = $element
2079
- ? inheritType
2080
- ? getInheritedData($element, dataName)
2081
- : getCacheData($element, dataName)
2082
- : undefined;
2083
- }
2084
- }
2085
- if (!value && !optional) {
2086
- throw $compileMinErr(
2087
- "ctreq",
2088
- "Controller '{0}', required by directive '{1}', can't be found!",
2089
- name,
2090
- directiveName,
2091
- );
2092
- }
2093
- } else if (Array.isArray(require)) {
2094
- value = [];
2095
- for (let i = 0, ii = require.length; i < ii; i++) {
2096
- value[i] = getControllers(
2097
- directiveName,
2098
- require[i],
2099
- $element,
2100
- elementControllers,
2101
- );
2102
- }
2103
- } else if (isObject(require)) {
2104
- value = {};
2105
- Object.entries(require).forEach(([property, controller]) => {
2106
- value[property] = getControllers(
2107
- directiveName,
2108
- controller,
2109
- $element,
2110
- elementControllers,
2111
- );
2112
- });
2113
- }
2114
-
2115
- return value || null;
2116
- }
2117
-
2118
- /**
2119
- * @param {NodeRef} $element
2120
- * @param attrs
2121
- * @param transcludeFn
2122
- * @param controllerDirectives
2123
- * @param isolateScope
2124
- * @param scope
2125
- * @param newIsolateScopeDirective
2126
- * @returns {any}
2127
- */
2128
- function setupControllers(
2129
- $element,
2130
- attrs,
2131
- transcludeFn,
2132
- controllerDirectives,
2133
- isolateScope,
2134
- scope,
2135
- newIsolateScopeDirective,
2136
- ) {
2137
- const elementControllers = Object.create(null);
2138
- for (const controllerKey in controllerDirectives) {
2139
- const directive = controllerDirectives[controllerKey];
2140
- const locals = {
2141
- $scope:
2142
- directive === newIsolateScopeDirective ||
2143
- directive.$$isolateScope
2144
- ? isolateScope
2145
- : scope,
2146
- $element: $element.node,
2147
- $attrs: attrs,
2148
- $transclude: transcludeFn,
2149
- };
2150
-
2151
- let { controller } = directive;
2152
- if (controller === "@") {
2153
- controller = attrs[directive.name];
2154
- }
2155
-
2156
- const controllerInstance = $controller(
2157
- controller,
2158
- locals,
2159
- true,
2160
- directive.controllerAs,
2161
- );
2162
-
2163
- // For directives with element transclusion the element is a comment.
2164
- // In this case .data will not attach any data.
2165
- // Instead, we save the controllers for the element in a local hash and attach to .data
2166
- // later, once we have the actual element.
2167
- elementControllers[directive.name] = controllerInstance;
2168
- if ($element.isElement()) {
2169
- setCacheData(
2170
- $element.element,
2171
- `$${directive.name}Controller`,
2172
- controllerInstance.instance,
2173
- );
2174
- }
2175
- }
2176
- return elementControllers;
2177
- }
2178
-
2179
- // Depending upon the context in which a directive finds itself it might need to have a new isolated
2180
- // or child scope created. For instance:
2181
- // * if the directive has been pulled into a template because another directive with a higher priority
2182
- // asked for element transclusion
2183
- // * if the directive itself asks for transclusion but it is at the root of a template and the original
2184
- // element was replaced. See https://github.com/angular/angular.js/issues/12936
2185
- function markDirectiveScope(directives, isolateScope, newScope) {
2186
- for (let j = 0, jj = directives.length; j < jj; j++) {
2187
- directives[j] = inherit(directives[j], {
2188
- $$isolateScope: isolateScope,
2189
- $$newScope: newScope,
2190
- });
2191
- }
2192
- }
2193
-
2194
- /**
2195
- * looks up the directive and decorates it with exception handling and proper parameters. We
2196
- * call this the boundDirective.
2197
- *
2198
- * @param {string} name name of the directive to look up.
2199
- * @param {string} location The directive must be found in specific format.
2200
- * String containing any of these characters:
2201
- *
2202
- * * `E`: element name
2203
- * * `A': attribute
2204
- * @returns {boolean} true if directive was added.
2205
- */
2206
- function addDirective(tDirectives, name, location, maxPriority) {
2207
- let match = false;
2208
- if (hasOwn(hasDirectives, name)) {
2209
- for (
2210
- let directive,
2211
- directives = $injector.get(name + DirectiveSuffix),
2212
- i = 0,
2213
- ii = directives.length;
2214
- i < ii;
2215
- i++
2216
- ) {
2217
- directive = directives[i];
2218
- if (
2219
- (isUndefined(maxPriority) ||
2220
- maxPriority > directive.priority) &&
2221
- directive.restrict.indexOf(location) !== -1
2222
- ) {
2223
- if (!directive.$$bindings) {
2224
- const bindings = (directive.$$bindings =
2225
- parseDirectiveBindings(directive, directive.name));
2226
- if (isObject(bindings.isolateScope)) {
2227
- directive.$$isolateBindings = bindings.isolateScope;
2228
- }
2229
- }
2230
- tDirectives.push(directive);
2231
- match = directive;
2232
- }
2233
- }
2234
- }
2235
- return match;
2236
- }
2237
-
2238
- /**
2239
- * When the element is replaced with HTML template then the new attributes
2240
- * on the template need to be merged with the existing attributes in the DOM.
2241
- * The desired effect is to have both of the attributes present.
2242
- *
2243
- * @param {object} dst destination attributes (original DOM)
2244
- * @param {object} src source attributes (from the directive template)
2245
- */
2246
- function mergeTemplateAttributes(dst, src) {
2247
- const srcAttr = src.$attr;
2248
- const dstAttr = dst.$attr;
2249
-
2250
- // reapply the old attributes to the new element
2251
- Object.entries(dst).forEach(([key, value]) => {
2252
- if (key.charAt(0) !== "$") {
2253
- if (src[key] && src[key] !== value) {
2254
- if (value.length) {
2255
- value += (key === "style" ? ";" : " ") + src[key];
2256
- } else {
2257
- value = src[key];
2258
- }
2259
- }
2260
- dst.$set(key, value, true, srcAttr[key]);
2261
- }
2262
- });
2263
-
2264
- // copy the new attributes on the old attrs object
2265
- Object.entries(src).forEach(([key, value]) => {
2266
- // Check if we already set this attribute in the loop above.
2267
- // `dst` will never contain hasOwnProperty as DOM parser won't let it.
2268
- // You will get an "InvalidCharacterError: DOM Exception 5" error if you
2269
- // have an attribute like "has-own-property" or "data-has-own-property", etc.
2270
- if (!hasOwn(dst, key) && key.charAt(0) !== "$") {
2271
- dst[key] = value;
2272
-
2273
- if (key !== "class" && key !== "style") {
2274
- dstAttr[key] = srcAttr[key];
2275
- }
2276
- }
2277
- });
2278
- }
2279
-
2280
- /**
2281
- *
2282
- * @param {import("../../interface.ts").Directive[]} directives
2283
- * @param {NodeRef} $compileNode
2284
- * @param {Attributes} tAttrs
2285
- * @param {Element} $rootElement
2286
- * @param {*} childTranscludeFn
2287
- * @param {Array} preLinkFns
2288
- * @param {Array} postLinkFns
2289
- * @param {*} previousCompileContext
2290
- * @returns
2291
- */
2292
- function compileTemplateUrl(
2293
- directives,
2294
- $compileNode,
2295
- tAttrs,
2296
- $rootElement,
2297
- childTranscludeFn,
2298
- preLinkFns,
2299
- postLinkFns,
2300
- previousCompileContext,
2301
- ) {
2302
- let linkQueue = [];
2303
- /** @type {any} */
2304
- let afterTemplateNodeLinkFn;
2305
- let afterTemplateChildLinkFn;
2306
- let afterTemplateNodeLinkFnCtx;
2307
- const beforeTemplateCompileNode = $compileNode.getAny();
2308
- const origAsyncDirective = directives.shift();
2309
- const derivedSyncDirective = inherit(origAsyncDirective, {
2310
- templateUrl: null,
2311
- transclude: null,
2312
- replace: null,
2313
- $$originalDirective: origAsyncDirective,
2314
- });
2315
- const templateUrl = isFunction(origAsyncDirective.templateUrl)
2316
- ? /** @type { ((element: Element, tAttrs: Attributes) => string) } */ (
2317
- origAsyncDirective.templateUrl
2318
- )($compileNode.element, tAttrs)
2319
- : origAsyncDirective.templateUrl;
2320
- const { templateNamespace } = origAsyncDirective;
2321
-
2322
- emptyElement($compileNode.element);
2323
-
2324
- $templateRequest(templateUrl)
2325
- .then((content) => {
2326
- /** @type {Element} */
2327
- let compileNode;
2328
- let tempTemplateAttrs;
2329
- let $template;
2330
- let childBoundTranscludeFn;
2331
-
2332
- content = denormalizeTemplate(content);
2333
-
2334
- if (origAsyncDirective.replace) {
2335
- if (isTextNode(content)) {
2336
- $template = [];
2337
- } else if (isString(content)) {
2338
- $template = Array.from(
2339
- createNodelistFromHTML(content),
2340
- ).filter(
2341
- (node) =>
2342
- node.nodeType !== Node.COMMENT_NODE &&
2343
- node.nodeType !== Node.TEXT_NODE,
2344
- );
2345
- } else {
2346
- $template = removeComments(
2347
- wrapTemplate(templateNamespace, trim(content)),
2348
- );
2349
- }
2350
- compileNode = $template[0];
2351
- if (
2352
- $template.length !== 1 ||
2353
- compileNode.nodeType !== Node.ELEMENT_NODE
2354
- ) {
2355
- throw $compileMinErr(
2356
- "tplrt",
2357
- "Template for directive '{0}' must have exactly one root element. {1}",
2358
- origAsyncDirective.name,
2359
- templateUrl,
2360
- );
2361
- }
2362
-
2363
- tempTemplateAttrs = { $attr: {} };
2364
-
2365
- replaceWith(
2366
- $compileNode,
2367
- compileNode,
2368
- previousCompileContext.index,
2369
- );
2370
-
2371
- const templateDirectives = collectDirectives(
2372
- compileNode,
2373
- tempTemplateAttrs,
2374
- );
2375
-
2376
- if (isObject(origAsyncDirective.scope)) {
2377
- // the original directive that caused the template to be loaded async required
2378
- // an isolate scope
2379
- markDirectiveScope(templateDirectives, true);
2380
- }
2381
- directives = templateDirectives.concat(directives);
2382
-
2383
- mergeTemplateAttributes(tAttrs, tempTemplateAttrs);
2384
- } else {
2385
- compileNode = /** @type {Element} */ (
2386
- beforeTemplateCompileNode
2387
- );
2388
- $compileNode.element.innerHTML = content;
2389
- }
2390
-
2391
- directives.unshift(derivedSyncDirective);
2392
- afterTemplateNodeLinkFnCtx = applyDirectivesToNode(
2393
- directives,
2394
- compileNode,
2395
- tAttrs,
2396
- childTranscludeFn,
2397
- origAsyncDirective,
2398
- preLinkFns,
2399
- postLinkFns,
2400
- { ...previousCompileContext, ctxNodeRef: $compileNode },
2401
- );
2402
-
2403
- afterTemplateNodeLinkFn = afterTemplateNodeLinkFnCtx?.nodeLinkFn;
2404
- if ($rootElement) {
2405
- Object.entries($rootElement).forEach(([i, node]) => {
2406
- if (node === compileNode) {
2407
- $rootElement[i] = $compileNode;
2408
- }
2409
- });
2410
- }
2411
- afterTemplateChildLinkFn = compileNodes(
2412
- new NodeRef($compileNode.getAny().childNodes),
2413
- childTranscludeFn,
2414
- );
2415
-
2416
- while (linkQueue.length) {
2417
- const scope = linkQueue.shift();
2418
- const beforeTemplateLinkNode = linkQueue.shift();
2419
- const boundTranscludeFn = linkQueue.shift();
2420
- let linkNode = $compileNode.getAny();
2421
-
2422
- if (scope.$$destroyed) {
2423
- continue;
2424
- }
2425
-
2426
- if (beforeTemplateLinkNode !== beforeTemplateCompileNode) {
2427
- const oldClasses = beforeTemplateLinkNode.className;
2428
-
2429
- if (
2430
- !(
2431
- previousCompileContext.hasElementTranscludeDirective &&
2432
- origAsyncDirective.replace
2433
- )
2434
- ) {
2435
- // it was cloned therefore we have to clone as well.
2436
- linkNode = compileNode.cloneNode(true);
2437
- beforeTemplateLinkNode.appendChild(linkNode);
2438
- }
2439
- // Copy in CSS classes from original node
2440
- try {
2441
- if (oldClasses !== "") {
2442
- $compileNode.element.classList.forEach((cls) =>
2443
- beforeTemplateLinkNode.classList.add(cls),
2444
- );
2445
- }
2446
- } catch {
2447
- // ignore, since it means that we are trying to set class on
2448
- // SVG element, where class name is read-only.
2449
- }
2450
- }
2451
- if (afterTemplateNodeLinkFnCtx.transcludeOnThisElement) {
2452
- childBoundTranscludeFn = createBoundTranscludeFn(
2453
- scope,
2454
- afterTemplateNodeLinkFnCtx.transclude,
2455
- boundTranscludeFn,
2456
- );
2457
- } else {
2458
- childBoundTranscludeFn = boundTranscludeFn;
2459
- }
2460
-
2461
- afterTemplateNodeLinkFn(
2462
- afterTemplateChildLinkFn,
2463
- scope,
2464
- linkNode,
2465
- childBoundTranscludeFn,
2466
- );
2467
- }
2468
- linkQueue = null;
2469
- })
2470
- .catch((error) => {
2471
- if (isError(error)) {
2472
- $exceptionHandler(error);
2473
- } else {
2474
- $exceptionHandler(new Error(error));
2475
- }
2476
- });
2477
-
2478
- return function delayedNodeLinkFn(
2479
- _ignoreChildLinkFn,
2480
- scope,
2481
- node,
2482
- rootElement,
2483
- boundTranscludeFn,
2484
- ) {
2485
- let childBoundTranscludeFn = boundTranscludeFn;
2486
- if (scope.$$destroyed) {
2487
- return;
2488
- }
2489
- if (linkQueue) {
2490
- linkQueue.push(scope, node, rootElement);
2491
- } else {
2492
- if (afterTemplateNodeLinkFn.transcludeOnThisElement) {
2493
- childBoundTranscludeFn = createBoundTranscludeFn(
2494
- scope,
2495
- afterTemplateNodeLinkFn.transclude,
2496
- boundTranscludeFn,
2497
- );
2498
- }
2499
- afterTemplateNodeLinkFn(
2500
- afterTemplateChildLinkFn,
2501
- scope,
2502
- node,
2503
- rootElement,
2504
- childBoundTranscludeFn,
2505
- );
2506
- }
2507
- };
2508
- }
2509
-
2510
- /**
2511
- * Sorting function for bound directives.
2512
- */
2513
- function byPriority(a, b) {
2514
- const diff = b.priority - a.priority;
2515
- if (diff !== 0) {
2516
- return diff;
2517
- }
2518
- if (a.name !== b.name) {
2519
- return a.name < b.name ? -1 : 1;
2520
- }
2521
- return a.index - b.index;
2522
- }
2523
-
2524
- function assertNoDuplicate(
2525
- what,
2526
- previousDirective,
2527
- directive,
2528
- element,
2529
- ) {
2530
- function wrapModuleNameIfDefined(moduleName) {
2531
- return moduleName ? ` (module: ${moduleName})` : "";
2532
- }
2533
-
2534
- if (previousDirective) {
2535
- throw $compileMinErr(
2536
- "multidir",
2537
- "Multiple directives [{0}{1}, {2}{3}] asking for {4} on: {5}",
2538
- previousDirective.name,
2539
- wrapModuleNameIfDefined(previousDirective.$$moduleName),
2540
- directive.name,
2541
- wrapModuleNameIfDefined(directive.$$moduleName),
2542
- what,
2543
- startingTag(element.getAny()),
2544
- );
2545
- }
2546
- }
2547
-
2548
- function addTextInterpolateDirective(directives, text) {
2549
- const interpolateFn = $interpolate(text, true);
2550
- if (interpolateFn) {
2551
- directives.push({
2552
- priority: 0,
2553
- compile: () => (scope, node) => {
2554
- interpolateFn.expressions.forEach((x) => {
2555
- scope.$watch(x, () => {
2556
- const res = interpolateFn(
2557
- isProxy(scope) ? scope.$target : scope,
2558
- );
2559
- switch (node.nodeType) {
2560
- case 1:
2561
- node.innerHTML = res;
2562
- break;
2563
- default:
2564
- node.nodeValue = res;
2565
- }
2566
- });
2567
- });
2568
- },
2569
- });
2570
- }
2571
- }
2572
-
2573
- /**
2574
- * @param {string} type
2575
- * @param {string} template
2576
- * @returns
2577
- */
2578
- function wrapTemplate(type, template) {
2579
- type = (type || "html").toLowerCase();
2580
- switch (type) {
2581
- case "svg":
2582
- case "math": {
2583
- const wrapper =
2584
- /** @type {HTMLDivElement} */ document.createElement("div");
2585
- wrapper.innerHTML = `<${type}>${template}</${type}>`;
2586
- return wrapper.childNodes[0].childNodes;
2587
- }
2588
- default:
2589
- return template;
2590
- }
2591
- }
2592
-
2593
- function getTrustedAttrContext(nodeName, attrNormalizedName) {
2594
- if (attrNormalizedName === "srcdoc") {
2595
- return $sce.HTML;
2596
- }
2597
- // All nodes with src attributes require a RESOURCE_URL value, except for
2598
- // img and various html5 media nodes, which require the MEDIA_URL context.
2599
- if (attrNormalizedName === "src" || attrNormalizedName === "ngSrc") {
2600
- if (
2601
- ["img", "video", "audio", "source", "track"].indexOf(nodeName) ===
2602
- -1
2603
- ) {
2604
- return $sce.RESOURCE_URL;
2605
- }
2606
- return $sce.MEDIA_URL;
2607
- }
2608
- if (attrNormalizedName === "xlinkHref") {
2609
- // Some xlink:href are okay, most aren't
2610
- if (nodeName === "image") {
2611
- return $sce.MEDIA_URL;
2612
- }
2613
- if (nodeName === "a") {
2614
- return $sce.URL;
2615
- }
2616
- return $sce.RESOURCE_URL;
2617
- }
2618
- if (
2619
- // Formaction
2620
- (nodeName === "form" && attrNormalizedName === "action") ||
2621
- // If relative URLs can go where they are not expected to, then
2622
- // all sorts of trust issues can arise.
2623
- (nodeName === "base" && attrNormalizedName === "href") ||
2624
- // links can be stylesheets or imports, which can run script in the current origin
2625
- (nodeName === "link" && attrNormalizedName === "href")
2626
- ) {
2627
- return $sce.RESOURCE_URL;
2628
- }
2629
- if (
2630
- nodeName === "a" &&
2631
- (attrNormalizedName === "href" || attrNormalizedName === "ngHref")
2632
- ) {
2633
- return $sce.URL;
2634
- }
2635
- }
2636
-
2637
- function getTrustedPropContext(nodeName, propNormalizedName) {
2638
- const prop = propNormalizedName.toLowerCase();
2639
- return (
2640
- PROP_CONTEXTS[`${nodeName}|${prop}`] || PROP_CONTEXTS[`*|${prop}`]
2641
- );
2642
- }
2643
-
2644
- function sanitizeSrcset(value, invokeType) {
2645
- if (!value) {
2646
- return value;
2647
- }
2648
- if (!isString(value)) {
2649
- throw $compileMinErr(
2650
- "srcset",
2651
- 'Can\'t pass trusted values to `{0}`: "{1}"',
2652
- invokeType,
2653
- value.toString(),
2654
- );
2655
- }
2656
-
2657
- // Such values are a bit too complex to handle automatically inside $sce.
2658
- // Instead, we sanitize each of the URIs individually, which works, even dynamically.
2659
- // It's not possible to work around this using `$sce.trustAsMediaUrl`.
2660
- // If you want to programmatically set explicitly trusted unsafe URLs, you should use
2661
- // `$sce.trustAsHtml` on the whole `img` tag and inject it into the DOM using the
2662
- // `ng-bind-html` directive.
2663
- let result = "";
2664
-
2665
- // first check if there are spaces because it's not the same pattern
2666
- const trimmedSrcset = trim(value);
2667
- // ( 999x ,| 999w ,| ,|, )
2668
- const srcPattern = /(\s+\d+x\s*,|\s+\d+w\s*,|\s+,|,\s+)/;
2669
- const pattern = /\s/.test(trimmedSrcset) ? srcPattern : /(,)/;
2670
-
2671
- // split srcset into tuple of uri and descriptor except for the last item
2672
- const rawUris = trimmedSrcset.split(pattern);
2673
-
2674
- // for each tuples
2675
- const nbrUrisWith2parts = Math.floor(rawUris.length / 2);
2676
- let i;
2677
- for (i = 0; i < nbrUrisWith2parts; i++) {
2678
- const innerIdx = i * 2;
2679
- // sanitize the uri
2680
- result += $sce.getTrustedMediaUrl(trim(rawUris[innerIdx]));
2681
- // add the descriptor
2682
- result += " " + trim(rawUris[innerIdx + 1]);
2683
- }
2684
-
2685
- // split the last item into uri and descriptor
2686
- const lastTuple = trim(rawUris[i * 2]).split(/\s/);
2687
-
2688
- // sanitize the last uri
2689
- result += $sce.getTrustedMediaUrl(trim(lastTuple[0]));
2690
-
2691
- // and add the last descriptor if any
2692
- if (lastTuple.length === 2) {
2693
- result += " " + trim(lastTuple[1]);
2694
- }
2695
- return result;
2696
- }
2697
-
2698
- function addPropertyDirective(node, directives, attrName, propName) {
2699
- if (EVENT_HANDLER_ATTR_REGEXP.test(propName)) {
2700
- throw $compileMinErr(
2701
- "nodomevents",
2702
- "Property bindings for HTML DOM event properties are disallowed",
2703
- );
2704
- }
2705
-
2706
- const nodeName = getNodeName(node);
2707
- const trustedContext = getTrustedPropContext(nodeName, propName);
2708
-
2709
- let sanitizer = (x) => x;
2710
- // Sanitize img[srcset] + source[srcset] values.
2711
- if (
2712
- propName === "srcset" &&
2713
- (nodeName === "img" || nodeName === "source")
2714
- ) {
2715
- sanitizer = (value) =>
2716
- sanitizeSrcset($sce.valueOf(value), "ng-prop-srcset");
2717
- } else if (trustedContext) {
2718
- sanitizer = $sce.getTrusted.bind($sce, trustedContext);
2719
- }
2720
-
2721
- directives.push({
2722
- priority: 100,
2723
- compile: function ngPropCompileFn(_, attr) {
2724
- const ngPropGetter = $parse(attr[attrName]);
2725
- return {
2726
- pre: function ngPropPreLinkFn(scope, $element) {
2727
- function applyPropValue() {
2728
- const propValue = ngPropGetter(scope);
2729
- $element[propName] = sanitizer(propValue);
2730
- }
2731
-
2732
- applyPropValue();
2733
- scope.$watch(propName, applyPropValue);
2734
- scope.$watch(attr[attrName], (val) => {
2735
- $sce.valueOf(val);
2736
- applyPropValue();
2737
- });
2738
- },
2739
- };
2740
- },
2741
- });
2742
- }
2743
-
2744
- function addAttrInterpolateDirective(
2745
- node,
2746
- directives,
2747
- value,
2748
- name,
2749
- isNgAttr,
2750
- ) {
2751
- const nodeName = getNodeName(node);
2752
- const trustedContext = getTrustedAttrContext(nodeName, name);
2753
- const mustHaveExpression = !isNgAttr;
2754
- const allOrNothing = ALL_OR_NOTHING_ATTRS.includes(name) || isNgAttr;
2755
-
2756
- let interpolateFn = $interpolate(
2757
- value,
2758
- mustHaveExpression,
2759
- trustedContext,
2760
- allOrNothing,
2761
- );
2762
-
2763
- // no interpolation found -> ignore
2764
- if (!interpolateFn) {
2765
- return;
2766
- }
2767
-
2768
- if (name === "multiple" && nodeName === "select") {
2769
- throw $compileMinErr(
2770
- "selmulti",
2771
- "Binding to the 'multiple' attribute is not supported. Element: {0}",
2772
- startingTag(node.outerHTML),
2773
- );
2774
- }
2775
-
2776
- if (EVENT_HANDLER_ATTR_REGEXP.test(name)) {
2777
- throw $compileMinErr(
2778
- "nodomevents",
2779
- "Interpolations for HTML DOM event attributes are disallowed",
2780
- );
2781
- }
2782
-
2783
- directives.push({
2784
- priority: 100,
2785
- compile() {
2786
- return {
2787
- pre: function attrInterpolatePreLinkFn(scope, element, attr) {
2788
- const $$observers =
2789
- attr.$$observers ||
2790
- (attr.$$observers = Object.create(null));
2791
-
2792
- // If the attribute has changed since last $interpolate()ed
2793
- const newValue = attr[name];
2794
- if (newValue !== value) {
2795
- // we need to interpolate again since the attribute value has been updated
2796
- // (e.g. by another directive's compile function)
2797
- // ensure unset/empty values make interpolateFn falsy
2798
- interpolateFn =
2799
- newValue &&
2800
- $interpolate(
2801
- newValue,
2802
- true,
2803
- trustedContext,
2804
- allOrNothing,
2805
- );
2806
- value = newValue;
2807
- }
2808
-
2809
- // if attribute was updated so that there is no interpolation going on we don't want to
2810
- // register any observers
2811
- if (!interpolateFn) {
2812
- return;
2813
- }
2814
-
2815
- // initialize attr object so that it's ready in case we need the value for isolate
2816
- // scope initialization, otherwise the value would not be available from isolate
2817
- // directive's linking fn during linking phase
2818
- attr[name] = interpolateFn(scope);
2819
-
2820
- ($$observers[name] || ($$observers[name] = [])).$$inter =
2821
- true;
2822
- interpolateFn.expressions.forEach((x) => {
2823
- const targetScope =
2824
- (attr.$$observers && attr.$$observers[name].$$scope) ||
2825
- scope;
2826
- targetScope.$watch(x, () => {
2827
- let newValue = interpolateFn(scope);
2828
- // special case for class attribute addition + removal
2829
- // so that class changes can tap into the animation
2830
- // hooks provided by the $animate service. Be sure to
2831
- // skip animations when the first digest occurs (when
2832
- // both the new and the old values are the same) since
2833
- // the CSS classes are the non-interpolated values
2834
- if (name === "class") {
2835
- attr.$updateClass(
2836
- newValue,
2837
- attr.$$element.classList.value,
2838
- );
2839
- } else {
2840
- attr.$set(name, newValue);
2841
- }
2842
- });
2843
- });
2844
-
2845
- if (interpolateFn.expressions.length == 0) {
2846
- // if there is nothing to watch, its a constant
2847
- attr.$set(name, newValue);
2848
- }
2849
- },
2850
- };
2851
- },
2852
- });
2853
- }
2854
-
2855
- /**
2856
- *
2857
- * @param {NodeRef} elementsToRemove The JQLite element which we are going to replace. We keep
2858
- * the shell, but replace its DOM node reference.
2859
- * @param {Node} newNode The new DOM node.
2860
- * @param {number} [index] Parent node index.
2861
- */
2862
- function replaceWith(elementsToRemove, newNode, index) {
2863
- const firstElementToRemove = elementsToRemove.getAny();
2864
- // const removeCount = elementsToRemove.length;
2865
- const parent = firstElementToRemove.parentNode;
2866
-
2867
- if (parent) {
2868
- if (isDefined(index)) {
2869
- const oldChild = parent.childNodes[index];
2870
- if (oldChild) {
2871
- parent.replaceChild(newNode, oldChild);
2872
- }
2873
- } else {
2874
- parent.insertBefore(newNode, parent.firstChild);
2875
- //parent.append(newNode);
2876
- }
2877
- }
2878
-
2879
- // Append all the `elementsToRemove` to a fragment. This will...
2880
- // - remove them from the DOM
2881
- // - allow them to still be traversed with .nextSibling
2882
- // - allow a single fragment.qSA to fetch all elements being removed
2883
- const fragment = document.createDocumentFragment();
2884
- elementsToRemove.collection().forEach((element) => {
2885
- fragment.appendChild(element);
2886
- });
2887
-
2888
- elementsToRemove.node = newNode;
2889
- }
2890
-
2891
- function cloneAndAnnotateFn(fn, annotation) {
2892
- return extend(
2893
- function () {
2894
- return fn.apply(null, arguments);
2895
- },
2896
- fn,
2897
- annotation,
2898
- );
2899
- }
2900
-
2901
- function strictBindingsCheck(attrName, directiveName) {
2902
- if (strictComponentBindingsEnabled) {
2903
- throw $compileMinErr(
2904
- "missingattr",
2905
- "Attribute '{0}' of '{1}' is non-optional and must be set!",
2906
- attrName,
2907
- directiveName,
2908
- );
2909
- }
2910
- }
2911
-
2912
- // Set up $watches for isolate scope and controller bindings.
2913
- /**
2914
- *
2915
- * @param {import('../scope/scope.js').Scope} scope
2916
- * @param {*} attrs
2917
- * @param {import('../scope/scope.js').Scope} destination - child scope or isolate scope
2918
- * @param {*} bindings
2919
- * @param {*} directive
2920
- * @returns
2921
- */
2922
- function initializeDirectiveBindings(
2923
- scope,
2924
- attrs,
2925
- destination,
2926
- bindings,
2927
- directive,
2928
- ) {
2929
- const removeWatchCollection = [];
2930
- const initialChanges = {};
2931
- let changes;
2932
-
2933
- if (bindings) {
2934
- Object.entries(bindings).forEach(([scopeName, definition]) => {
2935
- const {
2936
- attrName,
2937
- optional,
2938
- mode, // @, =, <, or &
2939
- } = definition;
2940
- let lastValue;
2941
- let parentGet;
2942
- let parentSet;
2943
- let compare;
2944
- let removeWatch;
2945
- let firstCall = true;
2946
- let firstChange = true;
2947
-
2948
- switch (mode) {
2949
- case "@":
2950
- if (!optional && !hasOwn(attrs, attrName)) {
2951
- strictBindingsCheck(attrName, directive.name);
2952
- destination[scopeName] = attrs[attrName] = undefined;
2953
- }
2954
-
2955
- removeWatch = attrs.$observe(attrName, (value) => {
2956
- if (isString(value) || isBoolean(value)) {
2957
- recordChanges(scopeName, value, firstChange);
2958
-
2959
- destination[scopeName] = value;
2960
- if (firstCall) {
2961
- firstCall = false;
2962
- } else {
2963
- triggerOnChangesHook();
2964
- firstChange = false;
2965
- }
2966
- }
2967
- });
2968
- attrs.$$observers[attrName].$$scope = scope;
2969
- lastValue = attrs[attrName];
2970
- if (isString(lastValue)) {
2971
- // If the attribute has been provided then we trigger an interpolation to ensure
2972
- // the value is there for use in the link fn
2973
- destination[scopeName] = $interpolate(lastValue)(scope);
2974
- } else if (isBoolean(lastValue)) {
2975
- // If the attributes is one of the BOOLEAN_ATTR then AngularTS will have converted
2976
- // the value to boolean rather than a string, so we special case this situation
2977
- destination[scopeName] = lastValue;
2978
- }
2979
-
2980
- /**
2981
- * @type {SimpleChange}
2982
- */
2983
- initialChanges[scopeName] = {
2984
- currentValue: destination[scopeName],
2985
- firstChange: true,
2986
- };
2987
- removeWatchCollection.push(removeWatch);
2988
- break;
2989
-
2990
- case "=": {
2991
- if (!hasOwn(attrs, attrName)) {
2992
- if (optional) {
2993
- break;
2994
- }
2995
- strictBindingsCheck(attrName, directive.name);
2996
- attrs[attrName] = undefined;
2997
- }
2998
- if (optional && !attrs[attrName]) {
2999
- break;
3000
- }
3001
-
3002
- parentGet = $parse(attrs[attrName]);
3003
- if (parentGet.literal) {
3004
- compare = equals;
3005
- } else {
3006
- compare = simpleCompare;
3007
- }
3008
-
3009
- parentSet =
3010
- parentGet.assign ||
3011
- function () {
3012
- // reset the change, or we will throw this exception on every $digest
3013
- lastValue = destination.$target[scopeName] =
3014
- parentGet(scope);
3015
- throw $compileMinErr(
3016
- "nonassign",
3017
- "Expression '{0}' in attribute '{1}' used with directive '{2}' is non-assignable!",
3018
- attrs[attrName],
3019
- attrName,
3020
- directive.name,
3021
- );
3022
- };
3023
- // store the value that the parent scope had after the last check:
3024
- lastValue = destination.$target[scopeName] = parentGet(
3025
- scope.$target,
3026
- );
3027
- const parentValueWatch = function parentValueWatch(
3028
- parentValue,
3029
- ) {
3030
- if (!compare(parentValue, destination[scopeName])) {
3031
- // we are out of sync and need to copy
3032
- if (!compare(parentValue, lastValue)) {
3033
- // parent changed and it has precedence
3034
- destination[scopeName] = parentValue;
3035
- } else {
3036
- // if the parent can be assigned then do so
3037
- parentSet(
3038
- scope,
3039
- (parentValue = destination[scopeName]),
3040
- );
3041
- }
3042
- }
3043
- lastValue = parentValue;
3044
- return lastValue;
3045
- };
3046
- parentValueWatch.$stateful = true;
3047
- if (definition.collection) {
3048
- removeWatch = scope.$watch(
3049
- attrs[attrName],
3050
- parentValueWatch,
3051
- );
3052
- } else {
3053
- if (attrs[attrName]) {
3054
- let expr = attrs[attrName];
3055
- // make it lazy as we dont want to trigger the two way data binding at this point
3056
- scope.$watch(
3057
- expr,
3058
- (val) => {
3059
- const res = $parse(attrs[attrName], parentValueWatch);
3060
- if (val) {
3061
- if (parentGet.literal) {
3062
- scope.$target[attrName] = val;
3063
- } else {
3064
- scope[attrName] = val;
3065
- }
3066
- res(scope);
3067
- } else {
3068
- scope[attrName] = scope[attrs[attrName]];
3069
- }
3070
- },
3071
- true,
3072
- );
3073
- }
3074
-
3075
- removeWatch = destination.$watch(
3076
- attrName,
3077
- (val) => {
3078
- if (
3079
- val === lastValue &&
3080
- !isUndefined(attrs[attrName])
3081
- ) {
3082
- return;
3083
- }
3084
- if (
3085
- (!!parentGet.inputs && !parentGet.literal) ||
3086
- (isUndefined(attrs[attrName]) && isDefined(val))
3087
- ) {
3088
- destination.$target[attrName] = lastValue;
3089
- throw $compileMinErr(
3090
- "nonassign",
3091
- "Expression '{0}' in attribute '{1}' used with directive '{2}' is non-assignable!",
3092
- attrs[attrName],
3093
- attrName,
3094
- directive.name,
3095
- );
3096
- } else {
3097
- // manually set the handler to avoid watch cycles
3098
- if (isObject(val)) {
3099
- Object.entries(val).forEach(([key, value]) => {
3100
- scope.$target[key] = value;
3101
- });
3102
- } else {
3103
- parentSet(scope.$target, (lastValue = val));
3104
- scope.$handler.watchers
3105
- .get(attrs[attrName])
3106
- ?.forEach((watchFn) => {
3107
- watchFn.listenerFn(val);
3108
- });
3109
- }
3110
- }
3111
- },
3112
- true,
3113
- );
3114
- }
3115
- removeWatchCollection.push(removeWatch);
3116
- break;
3117
- }
3118
-
3119
- case "<":
3120
- if (!hasOwn(attrs, attrName)) {
3121
- if (optional) {
3122
- break;
3123
- }
3124
- strictBindingsCheck(attrName, directive.name);
3125
- attrs[attrName] = undefined;
3126
- }
3127
- if (optional && !attrs[attrName]) {
3128
- break;
3129
- }
3130
-
3131
- parentGet = $parse(attrs[attrName]);
3132
-
3133
- destination.$target[scopeName] = parentGet(scope.$target);
3134
- /** @type {SimpleChange} */
3135
- initialChanges[scopeName] = {
3136
- currentValue: destination.$target[scopeName],
3137
- firstChange: firstChange,
3138
- };
3139
- scope.$target.attrs = attrs;
3140
-
3141
- if (attrs[attrName]) {
3142
- removeWatch = scope.$watch(
3143
- attrs[attrName],
3144
- (val) => {
3145
- destination.$target[scopeName] = val;
3146
- recordChanges(scopeName, val, firstChange);
3147
- if (firstChange) {
3148
- firstChange = false;
3149
- }
3150
- },
3151
- true,
3152
- );
3153
- removeWatchCollection.push(removeWatch);
3154
- }
3155
- break;
3156
-
3157
- case "&":
3158
- if (!optional && !hasOwn(attrs, attrName)) {
3159
- strictBindingsCheck(attrName, directive.name);
3160
- }
3161
- // Don't assign Object.prototype method to scope
3162
- parentGet = hasOwn(attrs, attrName)
3163
- ? $parse(attrs[attrName])
3164
- : () => {};
3165
-
3166
- // Don't assign noop to destination if expression is not valid
3167
- if (
3168
- parentGet.toString() === (() => {}).toString() &&
3169
- optional
3170
- ) {
3171
- break;
3172
- }
3173
-
3174
- destination.$target[scopeName] = function (locals) {
3175
- return parentGet(scope.$target, locals);
3176
- };
3177
-
3178
- break;
3179
- }
3180
- });
3181
- }
3182
-
3183
- function recordChanges(key, currentValue, initial) {
3184
- if (isFunction(destination["$onChanges"])) {
3185
- // If we have not already scheduled the top level onChangesQueue handler then do so now
3186
- if (!onChangesQueue) {
3187
- scope.$postUpdate(flushOnChangesQueue);
3188
- onChangesQueue = [];
3189
- }
3190
- // If we have not already queued a trigger of onChanges for this controller then do so now
3191
- if (!changes) {
3192
- changes = {};
3193
- onChangesQueue.push(triggerOnChangesHook);
3194
- }
3195
- // Store this change
3196
- changes[key] = {
3197
- currentValue: currentValue,
3198
- firstChange: initial,
3199
- };
3200
- }
3201
- }
3202
-
3203
- function triggerOnChangesHook() {
3204
- destination["$onChanges"] &&
3205
- changes &&
3206
- destination["$onChanges"](changes);
3207
- // Now clear the changes so that we schedule onChanges when more changes arrive
3208
- changes = undefined;
3209
- }
3210
-
3211
- return {
3212
- initialChanges,
3213
- removeWatches:
3214
- removeWatchCollection.length &&
3215
- function removeWatches() {
3216
- for (
3217
- let i = 0, ii = removeWatchCollection.length;
3218
- i < ii;
3219
- ++i
3220
- ) {
3221
- removeWatchCollection[i]();
3222
- }
3223
- },
3224
- };
3225
- }
3226
- },
3227
- ];
3228
- }
3229
- }
3230
-
3231
- function removeComments(jqNodes) {
3232
- let i = jqNodes.length;
3233
-
3234
- if (i <= 1) {
3235
- return jqNodes;
3236
- }
3237
-
3238
- while (i--) {
3239
- const node = jqNodes[i];
3240
- if (
3241
- node.nodeType === Node.COMMENT_NODE ||
3242
- (node.nodeType === Node.TEXT_NODE && node.nodeValue.trim() === "")
3243
- ) {
3244
- [].splice.call(jqNodes, i, 1);
3245
- }
3246
- }
3247
- return jqNodes;
3248
- }
3249
-
3250
- /**
3251
- * @param {String} name
3252
- * @returns {void}
3253
- */
3254
- function assertValidDirectiveName(name) {
3255
- const letter = name.charAt(0);
3256
- if (!letter || letter !== lowercase(letter)) {
3257
- throw $compileMinErr(
3258
- "baddir",
3259
- "Directive/Component name '{0}' is invalid. The first character must be a lowercase letter",
3260
- name,
3261
- );
3262
- }
3263
- if (name !== name.trim()) {
3264
- throw $compileMinErr(
3265
- "baddir",
3266
- "Directive/Component name '{0}' is invalid. The name should not contain leading or trailing whitespaces",
3267
- name,
3268
- );
3269
- }
3270
- }