@vonage/vivid 3.0.0-next.7 → 3.0.0-test.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (390) hide show
  1. package/accordion/index.js +61 -0
  2. package/accordion-item/index.js +125 -0
  3. package/badge/index.js +64 -0
  4. package/banner/index.js +212 -0
  5. package/breadcrumb/index.js +100 -0
  6. package/breadcrumb-item/index.js +55 -0
  7. package/button/index.js +761 -0
  8. package/calendar/index.js +1521 -0
  9. package/elevation/index.js +31 -0
  10. package/focus/index.js +3 -0
  11. package/icon/index.js +34 -0
  12. package/{src/index.ts → index.d.ts} +2 -2
  13. package/index.js +32 -0
  14. package/layout/index.js +53 -0
  15. package/lib/accordion/accordion.d.ts +9 -0
  16. package/lib/accordion/accordion.template.d.ts +4 -0
  17. package/lib/accordion/index.d.ts +2 -0
  18. package/lib/accordion-item/accordion-item.d.ts +13 -0
  19. package/lib/accordion-item/accordion-item.template.d.ts +4 -0
  20. package/lib/accordion-item/index.d.ts +3 -0
  21. package/lib/badge/badge.d.ts +17 -0
  22. package/lib/badge/badge.template.d.ts +4 -0
  23. package/lib/badge/index.d.ts +3 -0
  24. package/lib/banner/banner.d.ts +20 -0
  25. package/lib/banner/banner.template.d.ts +6 -0
  26. package/lib/banner/index.d.ts +2 -0
  27. package/lib/breadcrumb/breadcrumb.d.ts +3 -0
  28. package/lib/breadcrumb/index.d.ts +2 -0
  29. package/lib/breadcrumb-item/breadcrumb-item.d.ts +5 -0
  30. package/lib/breadcrumb-item/breadcrumb-item.template.d.ts +4 -0
  31. package/lib/breadcrumb-item/index.d.ts +3 -0
  32. package/lib/button/button.d.ts +17 -0
  33. package/lib/button/button.template.d.ts +4 -0
  34. package/lib/button/index.d.ts +21 -0
  35. package/lib/calendar/calendar.d.ts +11 -0
  36. package/lib/calendar/calendar.template.d.ts +4 -0
  37. package/lib/calendar/helpers/calendar.date-functions.d.ts +2 -0
  38. package/lib/calendar/helpers/calendar.event-context.d.ts +6 -0
  39. package/lib/calendar/helpers/calendar.keyboard-interactions.d.ts +9 -0
  40. package/lib/calendar/index.d.ts +3 -0
  41. package/{src/lib/components.ts → lib/components.d.ts} +16 -16
  42. package/lib/elevation/elevation.d.ts +4 -0
  43. package/lib/elevation/elevation.template.d.ts +4 -0
  44. package/lib/elevation/index.d.ts +2 -0
  45. package/lib/enums.d.ts +45 -0
  46. package/lib/focus/focus.d.ts +3 -0
  47. package/lib/focus/focus.template.d.ts +4 -0
  48. package/lib/focus/index.d.ts +2 -0
  49. package/lib/icon/icon.d.ts +11 -0
  50. package/lib/icon/icon.placeholder.d.ts +1 -0
  51. package/lib/icon/icon.template.d.ts +4 -0
  52. package/lib/icon/index.d.ts +2 -0
  53. package/lib/layout/index.d.ts +2 -0
  54. package/lib/layout/layout.d.ts +16 -0
  55. package/lib/layout/layout.template.d.ts +4 -0
  56. package/lib/popup/index.d.ts +4 -0
  57. package/lib/popup/popup.d.ts +17 -0
  58. package/lib/popup/popup.template.d.ts +4 -0
  59. package/lib/progress/index.d.ts +2 -0
  60. package/lib/progress/progress.d.ts +9 -0
  61. package/lib/progress/progress.template.d.ts +5 -0
  62. package/lib/progress-ring/index.d.ts +2 -0
  63. package/lib/progress-ring/progress-ring.d.ts +6 -0
  64. package/lib/progress-ring/progress-ring.template.d.ts +4 -0
  65. package/lib/side-drawer/index.d.ts +2 -0
  66. package/lib/side-drawer/side-drawer.d.ts +8 -0
  67. package/lib/side-drawer/side-drawer.template.d.ts +4 -0
  68. package/lib/sidenav-item/index.d.ts +3 -0
  69. package/lib/sidenav-item/sidenav-item.d.ts +6 -0
  70. package/lib/sidenav-item/sidenav-item.template.d.ts +4 -0
  71. package/lib/text/index.d.ts +2 -0
  72. package/lib/text/text.d.ts +10 -0
  73. package/lib/text/text.template.d.ts +4 -0
  74. package/lib/text-anchor/index.d.ts +2 -0
  75. package/lib/text-anchor/text-anchor.d.ts +7 -0
  76. package/lib/text-anchor/text-anchor.template.d.ts +4 -0
  77. package/lib/tooltip/index.d.ts +3 -0
  78. package/lib/tooltip/tooltip.d.ts +8 -0
  79. package/lib/tooltip/tooltip.template.d.ts +4 -0
  80. package/package.json +13 -3
  81. package/popup/index.js +2065 -0
  82. package/progress/index.js +98 -0
  83. package/progress-ring/index.js +76 -0
  84. package/shared/_has.js +58 -0
  85. package/shared/affix.js +29 -0
  86. package/shared/anchor.js +78 -0
  87. package/shared/apply-mixins.js +22 -0
  88. package/shared/aria-global.js +156 -0
  89. package/shared/base-progress.js +65 -0
  90. package/shared/breadcrumb-item.js +25 -0
  91. package/shared/class-names.js +15 -0
  92. package/shared/design-system/index.d.ts +3 -0
  93. package/shared/es.object.assign.js +68 -0
  94. package/shared/icon.js +1393 -0
  95. package/shared/index.js +4998 -0
  96. package/shared/index2.js +21 -0
  97. package/shared/patterns/affix.d.ts +9 -0
  98. package/{src/shared/patterns/index.ts → shared/patterns/index.d.ts} +1 -1
  99. package/shared/slotted.js +119 -0
  100. package/shared/style-inject.es.js +28 -0
  101. package/shared/text-anchor.js +21 -0
  102. package/shared/text-anchor.template.js +54 -0
  103. package/shared/web.dom-collections.iterator.js +1479 -0
  104. package/shared/when.js +15 -0
  105. package/side-drawer/index.js +81 -0
  106. package/sidenav-item/index.js +38 -0
  107. package/styles/fonts/spezia.css +23 -0
  108. package/styles/themes/dark.css +205 -0
  109. package/styles/themes/light.css +205 -0
  110. package/text/index.js +45 -0
  111. package/text-anchor/index.js +19 -0
  112. package/tooltip/index.js +65 -0
  113. package/.babelrc +0 -3
  114. package/.eslintrc.json +0 -70
  115. package/.stylelintrc.json +0 -8
  116. package/CHANGELOG.json +0 -343
  117. package/CHANGELOG.md +0 -45
  118. package/jest.config.cjs +0 -20
  119. package/playwright.config.dev.ts +0 -21
  120. package/playwright.config.ts +0 -34
  121. package/project.json +0 -122
  122. package/rollup.config.prod.ts +0 -50
  123. package/setupJestTests.js +0 -17
  124. package/src/lib/accordion/README.md +0 -55
  125. package/src/lib/accordion/accordion.scss +0 -10
  126. package/src/lib/accordion/accordion.spec.ts +0 -91
  127. package/src/lib/accordion/accordion.template.ts +0 -23
  128. package/src/lib/accordion/accordion.ts +0 -49
  129. package/src/lib/accordion/index.ts +0 -14
  130. package/src/lib/accordion/ui.test.ts +0 -37
  131. package/src/lib/accordion/ui.test.ts-snapshots/snapshots-accordion-Chrome-Stable-darwin.png +0 -0
  132. package/src/lib/accordion/ui.test.ts-snapshots/snapshots-accordion-Chrome-Stable-linux.png +0 -0
  133. package/src/lib/accordion/ui.test.ts-snapshots/snapshots-accordion-Desktop-Firefox-darwin.png +0 -0
  134. package/src/lib/accordion/ui.test.ts-snapshots/snapshots-accordion-Desktop-Firefox-linux.png +0 -0
  135. package/src/lib/accordion/ui.test.ts-snapshots/snapshots-accordion-Desktop-Safari-darwin.png +0 -0
  136. package/src/lib/accordion/ui.test.ts-snapshots/snapshots-accordion-Desktop-Safari-linux.png +0 -0
  137. package/src/lib/accordion-item/README.md +0 -113
  138. package/src/lib/accordion-item/accordion-item.scss +0 -91
  139. package/src/lib/accordion-item/accordion-item.spec.ts +0 -103
  140. package/src/lib/accordion-item/accordion-item.template.ts +0 -62
  141. package/src/lib/accordion-item/accordion-item.ts +0 -67
  142. package/src/lib/accordion-item/index.ts +0 -14
  143. package/src/lib/accordion-item/partials/variables.scss +0 -1
  144. package/src/lib/accordion-item/ui.test.ts +0 -37
  145. package/src/lib/accordion-item/ui.test.ts-snapshots/snapshots-accordion-item-Chrome-Stable-darwin.png +0 -0
  146. package/src/lib/accordion-item/ui.test.ts-snapshots/snapshots-accordion-item-Chrome-Stable-linux.png +0 -0
  147. package/src/lib/accordion-item/ui.test.ts-snapshots/snapshots-accordion-item-Desktop-Firefox-darwin.png +0 -0
  148. package/src/lib/accordion-item/ui.test.ts-snapshots/snapshots-accordion-item-Desktop-Firefox-linux.png +0 -0
  149. package/src/lib/accordion-item/ui.test.ts-snapshots/snapshots-accordion-item-Desktop-Safari-darwin.png +0 -0
  150. package/src/lib/accordion-item/ui.test.ts-snapshots/snapshots-accordion-item-Desktop-Safari-linux.png +0 -0
  151. package/src/lib/badge/README.md +0 -112
  152. package/src/lib/badge/badge.scss +0 -64
  153. package/src/lib/badge/badge.spec.ts +0 -114
  154. package/src/lib/badge/badge.template.ts +0 -36
  155. package/src/lib/badge/badge.ts +0 -97
  156. package/src/lib/badge/index.ts +0 -23
  157. package/src/lib/badge/ui.test.ts +0 -28
  158. package/src/lib/badge/ui.test.ts-snapshots/snapshots-badge-Chrome-Stable-darwin.png +0 -0
  159. package/src/lib/badge/ui.test.ts-snapshots/snapshots-badge-Chrome-Stable-linux.png +0 -0
  160. package/src/lib/badge/ui.test.ts-snapshots/snapshots-badge-Desktop-Firefox-darwin.png +0 -0
  161. package/src/lib/badge/ui.test.ts-snapshots/snapshots-badge-Desktop-Firefox-linux.png +0 -0
  162. package/src/lib/badge/ui.test.ts-snapshots/snapshots-badge-Desktop-Safari-darwin.png +0 -0
  163. package/src/lib/badge/ui.test.ts-snapshots/snapshots-badge-Desktop-Safari-linux.png +0 -0
  164. package/src/lib/banner/README.md +0 -117
  165. package/src/lib/banner/banner.scss +0 -71
  166. package/src/lib/banner/banner.spec.ts +0 -355
  167. package/src/lib/banner/banner.template.ts +0 -61
  168. package/src/lib/banner/banner.ts +0 -77
  169. package/src/lib/banner/index.ts +0 -14
  170. package/src/lib/banner/ui.test.ts +0 -64
  171. package/src/lib/banner/ui.test.ts-snapshots/snapshots-banner-Chrome-Stable-darwin.png +0 -0
  172. package/src/lib/banner/ui.test.ts-snapshots/snapshots-banner-Chrome-Stable-linux.png +0 -0
  173. package/src/lib/banner/ui.test.ts-snapshots/snapshots-banner-Desktop-Firefox-darwin.png +0 -0
  174. package/src/lib/banner/ui.test.ts-snapshots/snapshots-banner-Desktop-Firefox-linux.png +0 -0
  175. package/src/lib/banner/ui.test.ts-snapshots/snapshots-banner-Desktop-Safari-darwin.png +0 -0
  176. package/src/lib/banner/ui.test.ts-snapshots/snapshots-banner-Desktop-Safari-linux.png +0 -0
  177. package/src/lib/breadcrumb/README.md +0 -25
  178. package/src/lib/breadcrumb/breadcrumb.scss +0 -3
  179. package/src/lib/breadcrumb/breadcrumb.spec.ts +0 -78
  180. package/src/lib/breadcrumb/breadcrumb.ts +0 -10
  181. package/src/lib/breadcrumb/index.ts +0 -13
  182. package/src/lib/breadcrumb/ui.test.ts +0 -36
  183. package/src/lib/breadcrumb/ui.test.ts-snapshots/snapshots-breadcrumb-Chrome-Stable-darwin.png +0 -0
  184. package/src/lib/breadcrumb/ui.test.ts-snapshots/snapshots-breadcrumb-Chrome-Stable-linux.png +0 -0
  185. package/src/lib/breadcrumb/ui.test.ts-snapshots/snapshots-breadcrumb-Desktop-Firefox-darwin.png +0 -0
  186. package/src/lib/breadcrumb/ui.test.ts-snapshots/snapshots-breadcrumb-Desktop-Firefox-linux.png +0 -0
  187. package/src/lib/breadcrumb/ui.test.ts-snapshots/snapshots-breadcrumb-Desktop-Safari-darwin.png +0 -0
  188. package/src/lib/breadcrumb/ui.test.ts-snapshots/snapshots-breadcrumb-Desktop-Safari-linux.png +0 -0
  189. package/src/lib/breadcrumb-item/README.md +0 -40
  190. package/src/lib/breadcrumb-item/breadcrumb-item.scss +0 -28
  191. package/src/lib/breadcrumb-item/breadcrumb-item.spec.ts +0 -192
  192. package/src/lib/breadcrumb-item/breadcrumb-item.template.ts +0 -37
  193. package/src/lib/breadcrumb-item/breadcrumb-item.ts +0 -15
  194. package/src/lib/breadcrumb-item/index.ts +0 -16
  195. package/src/lib/breadcrumb-item/ui.test.ts +0 -38
  196. package/src/lib/breadcrumb-item/ui.test.ts-snapshots/snapshots-breadcrumb-item-Chrome-Stable-darwin.png +0 -0
  197. package/src/lib/breadcrumb-item/ui.test.ts-snapshots/snapshots-breadcrumb-item-Chrome-Stable-linux.png +0 -0
  198. package/src/lib/breadcrumb-item/ui.test.ts-snapshots/snapshots-breadcrumb-item-Desktop-Firefox-darwin.png +0 -0
  199. package/src/lib/breadcrumb-item/ui.test.ts-snapshots/snapshots-breadcrumb-item-Desktop-Firefox-linux.png +0 -0
  200. package/src/lib/breadcrumb-item/ui.test.ts-snapshots/snapshots-breadcrumb-item-Desktop-Safari-darwin.png +0 -0
  201. package/src/lib/breadcrumb-item/ui.test.ts-snapshots/snapshots-breadcrumb-item-Desktop-Safari-linux.png +0 -0
  202. package/src/lib/button/README.md +0 -120
  203. package/src/lib/button/button.scss +0 -142
  204. package/src/lib/button/button.spec.ts +0 -131
  205. package/src/lib/button/button.template.ts +0 -89
  206. package/src/lib/button/button.ts +0 -95
  207. package/src/lib/button/index.ts +0 -25
  208. package/src/lib/button/partials/variables.scss +0 -2
  209. package/src/lib/button/ui.test.ts +0 -32
  210. package/src/lib/button/ui.test.ts-snapshots/snapshots-button-Chrome-Stable-darwin.png +0 -0
  211. package/src/lib/button/ui.test.ts-snapshots/snapshots-button-Chrome-Stable-linux.png +0 -0
  212. package/src/lib/button/ui.test.ts-snapshots/snapshots-button-Desktop-Firefox-darwin.png +0 -0
  213. package/src/lib/button/ui.test.ts-snapshots/snapshots-button-Desktop-Firefox-linux.png +0 -0
  214. package/src/lib/button/ui.test.ts-snapshots/snapshots-button-Desktop-Safari-darwin.png +0 -0
  215. package/src/lib/button/ui.test.ts-snapshots/snapshots-button-Desktop-Safari-linux.png +0 -0
  216. package/src/lib/calendar/README.md +0 -70
  217. package/src/lib/calendar/calendar.scss +0 -176
  218. package/src/lib/calendar/calendar.spec.ts +0 -341
  219. package/src/lib/calendar/calendar.template.ts +0 -93
  220. package/src/lib/calendar/calendar.ts +0 -139
  221. package/src/lib/calendar/helpers/calendar.date-functions.ts +0 -31
  222. package/src/lib/calendar/helpers/calendar.event-context.ts +0 -72
  223. package/src/lib/calendar/helpers/calendar.keyboard-interactions.ts +0 -65
  224. package/src/lib/calendar/index.ts +0 -16
  225. package/src/lib/calendar/partials/_variables.scss +0 -15
  226. package/src/lib/calendar/ui.test.ts +0 -32
  227. package/src/lib/calendar/ui.test.ts-snapshots/snapshots-calendar-Chrome-Stable-darwin.png +0 -0
  228. package/src/lib/calendar/ui.test.ts-snapshots/snapshots-calendar-Chrome-Stable-linux.png +0 -0
  229. package/src/lib/calendar/ui.test.ts-snapshots/snapshots-calendar-Desktop-Firefox-darwin.png +0 -0
  230. package/src/lib/calendar/ui.test.ts-snapshots/snapshots-calendar-Desktop-Firefox-linux.png +0 -0
  231. package/src/lib/calendar/ui.test.ts-snapshots/snapshots-calendar-Desktop-Safari-darwin.png +0 -0
  232. package/src/lib/calendar/ui.test.ts-snapshots/snapshots-calendar-Desktop-Safari-linux.png +0 -0
  233. package/src/lib/components.spec.ts +0 -7
  234. package/src/lib/elevation/README.md +0 -99
  235. package/src/lib/elevation/elevation.scss +0 -15
  236. package/src/lib/elevation/elevation.spec.ts +0 -55
  237. package/src/lib/elevation/elevation.template.ts +0 -26
  238. package/src/lib/elevation/elevation.ts +0 -17
  239. package/src/lib/elevation/index.ts +0 -17
  240. package/src/lib/elevation/partials/_elevation.mixin.scss +0 -4
  241. package/src/lib/elevation/ui.test.ts +0 -32
  242. package/src/lib/elevation/ui.test.ts-snapshots/snapshots-elevation-Chrome-Stable-darwin.png +0 -0
  243. package/src/lib/elevation/ui.test.ts-snapshots/snapshots-elevation-Chrome-Stable-linux.png +0 -0
  244. package/src/lib/elevation/ui.test.ts-snapshots/snapshots-elevation-Desktop-Firefox-darwin.png +0 -0
  245. package/src/lib/elevation/ui.test.ts-snapshots/snapshots-elevation-Desktop-Firefox-linux.png +0 -0
  246. package/src/lib/elevation/ui.test.ts-snapshots/snapshots-elevation-Desktop-Safari-darwin.png +0 -0
  247. package/src/lib/elevation/ui.test.ts-snapshots/snapshots-elevation-Desktop-Safari-linux.png +0 -0
  248. package/src/lib/enums.ts +0 -55
  249. package/src/lib/focus/README.md +0 -1
  250. package/src/lib/focus/focus.scss +0 -17
  251. package/src/lib/focus/focus.template.ts +0 -16
  252. package/src/lib/focus/focus.ts +0 -10
  253. package/src/lib/focus/index.ts +0 -21
  254. package/src/lib/focus/partials/variables.scss +0 -2
  255. package/src/lib/icon/README.md +0 -70
  256. package/src/lib/icon/__snapshots__/icon.spec.ts.snap +0 -16
  257. package/src/lib/icon/icon.placeholder.ts +0 -12
  258. package/src/lib/icon/icon.scss +0 -52
  259. package/src/lib/icon/icon.spec.ts +0 -106
  260. package/src/lib/icon/icon.template.ts +0 -23
  261. package/src/lib/icon/icon.ts +0 -93
  262. package/src/lib/icon/index.ts +0 -14
  263. package/src/lib/layout/README.md +0 -154
  264. package/src/lib/layout/index.ts +0 -18
  265. package/src/lib/layout/layout.scss +0 -40
  266. package/src/lib/layout/layout.spec.ts +0 -73
  267. package/src/lib/layout/layout.template.ts +0 -29
  268. package/src/lib/layout/layout.ts +0 -46
  269. package/src/lib/layout/partials/_functions.scss +0 -15
  270. package/src/lib/layout/partials/_mixins.scss +0 -5
  271. package/src/lib/layout/partials/_variables.scss +0 -23
  272. package/src/lib/layout/ui.test.ts +0 -32
  273. package/src/lib/layout/ui.test.ts-snapshots/snapshots-layout-Chrome-Stable-darwin.png +0 -0
  274. package/src/lib/layout/ui.test.ts-snapshots/snapshots-layout-Chrome-Stable-linux.png +0 -0
  275. package/src/lib/layout/ui.test.ts-snapshots/snapshots-layout-Desktop-Firefox-darwin.png +0 -0
  276. package/src/lib/layout/ui.test.ts-snapshots/snapshots-layout-Desktop-Firefox-linux.png +0 -0
  277. package/src/lib/layout/ui.test.ts-snapshots/snapshots-layout-Desktop-Safari-darwin.png +0 -0
  278. package/src/lib/layout/ui.test.ts-snapshots/snapshots-layout-Desktop-Safari-linux.png +0 -0
  279. package/src/lib/popup/README.md +0 -261
  280. package/src/lib/popup/index.ts +0 -21
  281. package/src/lib/popup/popup.scss +0 -43
  282. package/src/lib/popup/popup.spec.ts +0 -265
  283. package/src/lib/popup/popup.template.ts +0 -41
  284. package/src/lib/popup/popup.ts +0 -158
  285. package/src/lib/popup/ui.test.ts +0 -111
  286. package/src/lib/popup/ui.test.ts-snapshots/snapshots-popup-Chrome-Stable-darwin.png +0 -0
  287. package/src/lib/popup/ui.test.ts-snapshots/snapshots-popup-Chrome-Stable-linux.png +0 -0
  288. package/src/lib/popup/ui.test.ts-snapshots/snapshots-popup-Desktop-Firefox-darwin.png +0 -0
  289. package/src/lib/popup/ui.test.ts-snapshots/snapshots-popup-Desktop-Firefox-linux.png +0 -0
  290. package/src/lib/popup/ui.test.ts-snapshots/snapshots-popup-Desktop-Safari-darwin.png +0 -0
  291. package/src/lib/popup/ui.test.ts-snapshots/snapshots-popup-Desktop-Safari-linux.png +0 -0
  292. package/src/lib/progress/README.md +0 -107
  293. package/src/lib/progress/index.ts +0 -14
  294. package/src/lib/progress/progress.scss +0 -133
  295. package/src/lib/progress/progress.spec.ts +0 -173
  296. package/src/lib/progress/progress.template.ts +0 -62
  297. package/src/lib/progress/progress.ts +0 -25
  298. package/src/lib/progress/ui.test.ts +0 -70
  299. package/src/lib/progress/ui.test.ts-snapshots/snapshots-progress-Chrome-Stable-darwin.png +0 -0
  300. package/src/lib/progress/ui.test.ts-snapshots/snapshots-progress-Chrome-Stable-linux.png +0 -0
  301. package/src/lib/progress/ui.test.ts-snapshots/snapshots-progress-Desktop-Firefox-darwin.png +0 -0
  302. package/src/lib/progress/ui.test.ts-snapshots/snapshots-progress-Desktop-Firefox-linux.png +0 -0
  303. package/src/lib/progress/ui.test.ts-snapshots/snapshots-progress-Desktop-Safari-darwin.png +0 -0
  304. package/src/lib/progress/ui.test.ts-snapshots/snapshots-progress-Desktop-Safari-linux.png +0 -0
  305. package/src/lib/progress-ring/README.md +0 -90
  306. package/src/lib/progress-ring/index.ts +0 -15
  307. package/src/lib/progress-ring/progress-ring.scss +0 -75
  308. package/src/lib/progress-ring/progress-ring.spec.ts +0 -139
  309. package/src/lib/progress-ring/progress-ring.template.ts +0 -82
  310. package/src/lib/progress-ring/progress-ring.ts +0 -18
  311. package/src/lib/progress-ring/ui.test.ts +0 -35
  312. package/src/lib/progress-ring/ui.test.ts-snapshots/snapshots-progress-ring-Chrome-Stable-darwin.png +0 -0
  313. package/src/lib/progress-ring/ui.test.ts-snapshots/snapshots-progress-ring-Chrome-Stable-linux.png +0 -0
  314. package/src/lib/progress-ring/ui.test.ts-snapshots/snapshots-progress-ring-Desktop-Firefox-darwin.png +0 -0
  315. package/src/lib/progress-ring/ui.test.ts-snapshots/snapshots-progress-ring-Desktop-Firefox-linux.png +0 -0
  316. package/src/lib/progress-ring/ui.test.ts-snapshots/snapshots-progress-ring-Desktop-Safari-darwin.png +0 -0
  317. package/src/lib/progress-ring/ui.test.ts-snapshots/snapshots-progress-ring-Desktop-Safari-linux.png +0 -0
  318. package/src/lib/side-drawer/README.md +0 -304
  319. package/src/lib/side-drawer/index.ts +0 -16
  320. package/src/lib/side-drawer/partials/variables.scss +0 -6
  321. package/src/lib/side-drawer/side-drawer.scss +0 -109
  322. package/src/lib/side-drawer/side-drawer.spec.ts +0 -118
  323. package/src/lib/side-drawer/side-drawer.template.ts +0 -51
  324. package/src/lib/side-drawer/side-drawer.ts +0 -58
  325. package/src/lib/side-drawer/ui.test.ts +0 -102
  326. package/src/lib/side-drawer/ui.test.ts-snapshots/snapshots-side-drawer-Chrome-Stable-darwin.png +0 -0
  327. package/src/lib/side-drawer/ui.test.ts-snapshots/snapshots-side-drawer-Chrome-Stable-linux.png +0 -0
  328. package/src/lib/side-drawer/ui.test.ts-snapshots/snapshots-side-drawer-Desktop-Firefox-darwin.png +0 -0
  329. package/src/lib/side-drawer/ui.test.ts-snapshots/snapshots-side-drawer-Desktop-Firefox-linux.png +0 -0
  330. package/src/lib/side-drawer/ui.test.ts-snapshots/snapshots-side-drawer-Desktop-Safari-darwin.png +0 -0
  331. package/src/lib/side-drawer/ui.test.ts-snapshots/snapshots-side-drawer-Desktop-Safari-linux.png +0 -0
  332. package/src/lib/side-drawer/ui.test.ts-snapshots/snapshots-side-drawer-modal-Chrome-Stable-darwin.png +0 -0
  333. package/src/lib/side-drawer/ui.test.ts-snapshots/snapshots-side-drawer-modal-Chrome-Stable-linux.png +0 -0
  334. package/src/lib/side-drawer/ui.test.ts-snapshots/snapshots-side-drawer-modal-Desktop-Firefox-darwin.png +0 -0
  335. package/src/lib/side-drawer/ui.test.ts-snapshots/snapshots-side-drawer-modal-Desktop-Firefox-linux.png +0 -0
  336. package/src/lib/side-drawer/ui.test.ts-snapshots/snapshots-side-drawer-modal-Desktop-Safari-darwin.png +0 -0
  337. package/src/lib/side-drawer/ui.test.ts-snapshots/snapshots-side-drawer-modal-Desktop-Safari-linux.png +0 -0
  338. package/src/lib/sidenav-item/README.md +0 -41
  339. package/src/lib/sidenav-item/index.ts +0 -20
  340. package/src/lib/sidenav-item/sidenav-item.scss +0 -51
  341. package/src/lib/sidenav-item/sidenav-item.spec.ts +0 -64
  342. package/src/lib/sidenav-item/sidenav-item.template.ts +0 -25
  343. package/src/lib/sidenav-item/sidenav-item.ts +0 -15
  344. package/src/lib/sidenav-item/ui.test.ts +0 -32
  345. package/src/lib/sidenav-item/ui.test.ts-snapshots/snapshots-sidenav-item-Chrome-Stable-darwin.png +0 -0
  346. package/src/lib/sidenav-item/ui.test.ts-snapshots/snapshots-sidenav-item-Chrome-Stable-linux.png +0 -0
  347. package/src/lib/sidenav-item/ui.test.ts-snapshots/snapshots-sidenav-item-Desktop-Firefox-darwin.png +0 -0
  348. package/src/lib/sidenav-item/ui.test.ts-snapshots/snapshots-sidenav-item-Desktop-Firefox-linux.png +0 -0
  349. package/src/lib/sidenav-item/ui.test.ts-snapshots/snapshots-sidenav-item-Desktop-Safari-darwin.png +0 -0
  350. package/src/lib/sidenav-item/ui.test.ts-snapshots/snapshots-sidenav-item-Desktop-Safari-linux.png +0 -0
  351. package/src/lib/text/README.md +0 -119
  352. package/src/lib/text/index.ts +0 -14
  353. package/src/lib/text/text.scss +0 -92
  354. package/src/lib/text/text.spec.ts +0 -54
  355. package/src/lib/text/text.template.ts +0 -28
  356. package/src/lib/text/text.ts +0 -55
  357. package/src/lib/text/ui.test.ts +0 -39
  358. package/src/lib/text/ui.test.ts-snapshots/snapshots-text-Chrome-Stable-darwin.png +0 -0
  359. package/src/lib/text/ui.test.ts-snapshots/snapshots-text-Chrome-Stable-linux.png +0 -0
  360. package/src/lib/text/ui.test.ts-snapshots/snapshots-text-Desktop-Firefox-darwin.png +0 -0
  361. package/src/lib/text/ui.test.ts-snapshots/snapshots-text-Desktop-Firefox-linux.png +0 -0
  362. package/src/lib/text/ui.test.ts-snapshots/snapshots-text-Desktop-Safari-darwin.png +0 -0
  363. package/src/lib/text/ui.test.ts-snapshots/snapshots-text-Desktop-Safari-linux.png +0 -0
  364. package/src/lib/text-anchor/README.md +0 -5
  365. package/src/lib/text-anchor/index.ts +0 -12
  366. package/src/lib/text-anchor/text-anchor.spec.ts +0 -153
  367. package/src/lib/text-anchor/text-anchor.template.ts +0 -66
  368. package/src/lib/text-anchor/text-anchor.ts +0 -22
  369. package/src/lib/tooltip/README.md +0 -132
  370. package/src/lib/tooltip/index.ts +0 -16
  371. package/src/lib/tooltip/partials/variables.scss +0 -1
  372. package/src/lib/tooltip/tooltip.scss +0 -18
  373. package/src/lib/tooltip/tooltip.spec.ts +0 -70
  374. package/src/lib/tooltip/tooltip.template.ts +0 -30
  375. package/src/lib/tooltip/tooltip.ts +0 -44
  376. package/src/lib/tooltip/ui.test.ts +0 -53
  377. package/src/lib/tooltip/ui.test.ts-snapshots/snapshots-tooltip-Chrome-Stable-darwin.png +0 -0
  378. package/src/lib/tooltip/ui.test.ts-snapshots/snapshots-tooltip-Chrome-Stable-linux.png +0 -0
  379. package/src/lib/tooltip/ui.test.ts-snapshots/snapshots-tooltip-Desktop-Firefox-darwin.png +0 -0
  380. package/src/lib/tooltip/ui.test.ts-snapshots/snapshots-tooltip-Desktop-Firefox-linux.png +0 -0
  381. package/src/lib/tooltip/ui.test.ts-snapshots/snapshots-tooltip-Desktop-Safari-darwin.png +0 -0
  382. package/src/lib/tooltip/ui.test.ts-snapshots/snapshots-tooltip-Desktop-Safari-linux.png +0 -0
  383. package/src/shared/design-system/index.ts +0 -12
  384. package/src/shared/patterns/affix.ts +0 -56
  385. package/src/types/extract-gfm.d.ts +0 -5
  386. package/src/types/style.d.ts +0 -4
  387. package/src/visual-tests/visual-tests-utils.ts +0 -76
  388. package/tsconfig.json +0 -36
  389. package/tsconfig.lib.json +0 -11
  390. package/tsconfig.spec.json +0 -16
@@ -0,0 +1,4998 @@
1
+ /**
2
+ * A reference to globalThis, with support
3
+ * for browsers that don't yet support the spec.
4
+ * @public
5
+ */
6
+ const $global = (function () {
7
+ if (typeof globalThis !== "undefined") {
8
+ // We're running in a modern environment.
9
+ return globalThis;
10
+ }
11
+ if (typeof global !== "undefined") {
12
+ // We're running in NodeJS
13
+ return global;
14
+ }
15
+ if (typeof self !== "undefined") {
16
+ // We're running in a worker.
17
+ return self;
18
+ }
19
+ if (typeof window !== "undefined") {
20
+ // We're running in the browser's main thread.
21
+ return window;
22
+ }
23
+ try {
24
+ // Hopefully we never get here...
25
+ // Not all environments allow eval and Function. Use only as a last resort:
26
+ // eslint-disable-next-line no-new-func
27
+ return new Function("return this")();
28
+ }
29
+ catch (_a) {
30
+ // If all fails, give up and create an object.
31
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
32
+ return {};
33
+ }
34
+ })();
35
+ // API-only Polyfill for trustedTypes
36
+ if ($global.trustedTypes === void 0) {
37
+ $global.trustedTypes = { createPolicy: (n, r) => r };
38
+ }
39
+ const propConfig = {
40
+ configurable: false,
41
+ enumerable: false,
42
+ writable: false,
43
+ };
44
+ if ($global.FAST === void 0) {
45
+ Reflect.defineProperty($global, "FAST", Object.assign({ value: Object.create(null) }, propConfig));
46
+ }
47
+ /**
48
+ * The FAST global.
49
+ * @internal
50
+ */
51
+ const FAST = $global.FAST;
52
+ if (FAST.getById === void 0) {
53
+ const storage = Object.create(null);
54
+ Reflect.defineProperty(FAST, "getById", Object.assign({ value(id, initialize) {
55
+ let found = storage[id];
56
+ if (found === void 0) {
57
+ found = initialize ? (storage[id] = initialize()) : null;
58
+ }
59
+ return found;
60
+ } }, propConfig));
61
+ }
62
+ /**
63
+ * A readonly, empty array.
64
+ * @remarks
65
+ * Typically returned by APIs that return arrays when there are
66
+ * no actual items to return.
67
+ * @internal
68
+ */
69
+ const emptyArray = Object.freeze([]);
70
+
71
+ const updateQueue = $global.FAST.getById(1 /* updateQueue */, () => {
72
+ const tasks = [];
73
+ const pendingErrors = [];
74
+ function throwFirstError() {
75
+ if (pendingErrors.length) {
76
+ throw pendingErrors.shift();
77
+ }
78
+ }
79
+ function tryRunTask(task) {
80
+ try {
81
+ task.call();
82
+ }
83
+ catch (error) {
84
+ pendingErrors.push(error);
85
+ setTimeout(throwFirstError, 0);
86
+ }
87
+ }
88
+ function process() {
89
+ const capacity = 1024;
90
+ let index = 0;
91
+ while (index < tasks.length) {
92
+ tryRunTask(tasks[index]);
93
+ index++;
94
+ // Prevent leaking memory for long chains of recursive calls to `DOM.queueUpdate`.
95
+ // If we call `DOM.queueUpdate` within a task scheduled by `DOM.queueUpdate`, the queue will
96
+ // grow, but to avoid an O(n) walk for every task we execute, we don't
97
+ // shift tasks off the queue after they have been executed.
98
+ // Instead, we periodically shift 1024 tasks off the queue.
99
+ if (index > capacity) {
100
+ // Manually shift all values starting at the index back to the
101
+ // beginning of the queue.
102
+ for (let scan = 0, newLength = tasks.length - index; scan < newLength; scan++) {
103
+ tasks[scan] = tasks[scan + index];
104
+ }
105
+ tasks.length -= index;
106
+ index = 0;
107
+ }
108
+ }
109
+ tasks.length = 0;
110
+ }
111
+ function enqueue(callable) {
112
+ if (tasks.length < 1) {
113
+ $global.requestAnimationFrame(process);
114
+ }
115
+ tasks.push(callable);
116
+ }
117
+ return Object.freeze({
118
+ enqueue,
119
+ process,
120
+ });
121
+ });
122
+ /* eslint-disable */
123
+ const fastHTMLPolicy = $global.trustedTypes.createPolicy("fast-html", {
124
+ createHTML: html => html,
125
+ });
126
+ /* eslint-enable */
127
+ let htmlPolicy = fastHTMLPolicy;
128
+ const marker = `fast-${Math.random().toString(36).substring(2, 8)}`;
129
+ /** @internal */
130
+ const _interpolationStart = `${marker}{`;
131
+ /** @internal */
132
+ const _interpolationEnd = `}${marker}`;
133
+ /**
134
+ * Common DOM APIs.
135
+ * @public
136
+ */
137
+ const DOM = Object.freeze({
138
+ /**
139
+ * Indicates whether the DOM supports the adoptedStyleSheets feature.
140
+ */
141
+ supportsAdoptedStyleSheets: Array.isArray(document.adoptedStyleSheets) &&
142
+ "replace" in CSSStyleSheet.prototype,
143
+ /**
144
+ * Sets the HTML trusted types policy used by the templating engine.
145
+ * @param policy - The policy to set for HTML.
146
+ * @remarks
147
+ * This API can only be called once, for security reasons. It should be
148
+ * called by the application developer at the start of their program.
149
+ */
150
+ setHTMLPolicy(policy) {
151
+ if (htmlPolicy !== fastHTMLPolicy) {
152
+ throw new Error("The HTML policy can only be set once.");
153
+ }
154
+ htmlPolicy = policy;
155
+ },
156
+ /**
157
+ * Turns a string into trusted HTML using the configured trusted types policy.
158
+ * @param html - The string to turn into trusted HTML.
159
+ * @remarks
160
+ * Used internally by the template engine when creating templates
161
+ * and setting innerHTML.
162
+ */
163
+ createHTML(html) {
164
+ return htmlPolicy.createHTML(html);
165
+ },
166
+ /**
167
+ * Determines if the provided node is a template marker used by the runtime.
168
+ * @param node - The node to test.
169
+ */
170
+ isMarker(node) {
171
+ return node && node.nodeType === 8 && node.data.startsWith(marker);
172
+ },
173
+ /**
174
+ * Given a marker node, extract the {@link HTMLDirective} index from the placeholder.
175
+ * @param node - The marker node to extract the index from.
176
+ */
177
+ extractDirectiveIndexFromMarker(node) {
178
+ return parseInt(node.data.replace(`${marker}:`, ""));
179
+ },
180
+ /**
181
+ * Creates a placeholder string suitable for marking out a location *within*
182
+ * an attribute value or HTML content.
183
+ * @param index - The directive index to create the placeholder for.
184
+ * @remarks
185
+ * Used internally by binding directives.
186
+ */
187
+ createInterpolationPlaceholder(index) {
188
+ return `${_interpolationStart}${index}${_interpolationEnd}`;
189
+ },
190
+ /**
191
+ * Creates a placeholder that manifests itself as an attribute on an
192
+ * element.
193
+ * @param attributeName - The name of the custom attribute.
194
+ * @param index - The directive index to create the placeholder for.
195
+ * @remarks
196
+ * Used internally by attribute directives such as `ref`, `slotted`, and `children`.
197
+ */
198
+ createCustomAttributePlaceholder(attributeName, index) {
199
+ return `${attributeName}="${this.createInterpolationPlaceholder(index)}"`;
200
+ },
201
+ /**
202
+ * Creates a placeholder that manifests itself as a marker within the DOM structure.
203
+ * @param index - The directive index to create the placeholder for.
204
+ * @remarks
205
+ * Used internally by structural directives such as `repeat`.
206
+ */
207
+ createBlockPlaceholder(index) {
208
+ return `<!--${marker}:${index}-->`;
209
+ },
210
+ /**
211
+ * Schedules DOM update work in the next async batch.
212
+ * @param callable - The callable function or object to queue.
213
+ */
214
+ queueUpdate: updateQueue.enqueue,
215
+ /**
216
+ * Immediately processes all work previously scheduled
217
+ * through queueUpdate.
218
+ * @remarks
219
+ * This also forces nextUpdate promises
220
+ * to resolve.
221
+ */
222
+ processUpdates: updateQueue.process,
223
+ /**
224
+ * Resolves with the next DOM update.
225
+ */
226
+ nextUpdate() {
227
+ return new Promise(updateQueue.enqueue);
228
+ },
229
+ /**
230
+ * Sets an attribute value on an element.
231
+ * @param element - The element to set the attribute value on.
232
+ * @param attributeName - The attribute name to set.
233
+ * @param value - The value of the attribute to set.
234
+ * @remarks
235
+ * If the value is `null` or `undefined`, the attribute is removed, otherwise
236
+ * it is set to the provided value using the standard `setAttribute` API.
237
+ */
238
+ setAttribute(element, attributeName, value) {
239
+ if (value === null || value === undefined) {
240
+ element.removeAttribute(attributeName);
241
+ }
242
+ else {
243
+ element.setAttribute(attributeName, value);
244
+ }
245
+ },
246
+ /**
247
+ * Sets a boolean attribute value.
248
+ * @param element - The element to set the boolean attribute value on.
249
+ * @param attributeName - The attribute name to set.
250
+ * @param value - The value of the attribute to set.
251
+ * @remarks
252
+ * If the value is true, the attribute is added; otherwise it is removed.
253
+ */
254
+ setBooleanAttribute(element, attributeName, value) {
255
+ value
256
+ ? element.setAttribute(attributeName, "")
257
+ : element.removeAttribute(attributeName);
258
+ },
259
+ /**
260
+ * Removes all the child nodes of the provided parent node.
261
+ * @param parent - The node to remove the children from.
262
+ */
263
+ removeChildNodes(parent) {
264
+ for (let child = parent.firstChild; child !== null; child = parent.firstChild) {
265
+ parent.removeChild(child);
266
+ }
267
+ },
268
+ /**
269
+ * Creates a TreeWalker configured to walk a template fragment.
270
+ * @param fragment - The fragment to walk.
271
+ */
272
+ createTemplateWalker(fragment) {
273
+ return document.createTreeWalker(fragment, 133, // element, text, comment
274
+ null, false);
275
+ },
276
+ });
277
+
278
+ function spilloverSubscribe(subscriber) {
279
+ const spillover = this.spillover;
280
+ const index = spillover.indexOf(subscriber);
281
+ if (index === -1) {
282
+ spillover.push(subscriber);
283
+ }
284
+ }
285
+ function spilloverUnsubscribe(subscriber) {
286
+ const spillover = this.spillover;
287
+ const index = spillover.indexOf(subscriber);
288
+ if (index !== -1) {
289
+ spillover.splice(index, 1);
290
+ }
291
+ }
292
+ function spilloverNotifySubscribers(args) {
293
+ const spillover = this.spillover;
294
+ const source = this.source;
295
+ for (let i = 0, ii = spillover.length; i < ii; ++i) {
296
+ spillover[i].handleChange(source, args);
297
+ }
298
+ }
299
+ function spilloverHas(subscriber) {
300
+ return this.spillover.indexOf(subscriber) !== -1;
301
+ }
302
+ /**
303
+ * An implementation of {@link Notifier} that efficiently keeps track of
304
+ * subscribers interested in a specific change notification on an
305
+ * observable source.
306
+ *
307
+ * @remarks
308
+ * This set is optimized for the most common scenario of 1 or 2 subscribers.
309
+ * With this in mind, it can store a subscriber in an internal field, allowing it to avoid Array#push operations.
310
+ * If the set ever exceeds two subscribers, it upgrades to an array automatically.
311
+ * @public
312
+ */
313
+ class SubscriberSet {
314
+ /**
315
+ * Creates an instance of SubscriberSet for the specified source.
316
+ * @param source - The object source that subscribers will receive notifications from.
317
+ * @param initialSubscriber - An initial subscriber to changes.
318
+ */
319
+ constructor(source, initialSubscriber) {
320
+ this.sub1 = void 0;
321
+ this.sub2 = void 0;
322
+ this.spillover = void 0;
323
+ this.source = source;
324
+ this.sub1 = initialSubscriber;
325
+ }
326
+ /**
327
+ * Checks whether the provided subscriber has been added to this set.
328
+ * @param subscriber - The subscriber to test for inclusion in this set.
329
+ */
330
+ has(subscriber) {
331
+ return this.sub1 === subscriber || this.sub2 === subscriber;
332
+ }
333
+ /**
334
+ * Subscribes to notification of changes in an object's state.
335
+ * @param subscriber - The object that is subscribing for change notification.
336
+ */
337
+ subscribe(subscriber) {
338
+ if (this.has(subscriber)) {
339
+ return;
340
+ }
341
+ if (this.sub1 === void 0) {
342
+ this.sub1 = subscriber;
343
+ return;
344
+ }
345
+ if (this.sub2 === void 0) {
346
+ this.sub2 = subscriber;
347
+ return;
348
+ }
349
+ this.spillover = [this.sub1, this.sub2, subscriber];
350
+ this.subscribe = spilloverSubscribe;
351
+ this.unsubscribe = spilloverUnsubscribe;
352
+ this.notify = spilloverNotifySubscribers;
353
+ this.has = spilloverHas;
354
+ this.sub1 = void 0;
355
+ this.sub2 = void 0;
356
+ }
357
+ /**
358
+ * Unsubscribes from notification of changes in an object's state.
359
+ * @param subscriber - The object that is unsubscribing from change notification.
360
+ */
361
+ unsubscribe(subscriber) {
362
+ if (this.sub1 === subscriber) {
363
+ this.sub1 = void 0;
364
+ }
365
+ else if (this.sub2 === subscriber) {
366
+ this.sub2 = void 0;
367
+ }
368
+ }
369
+ /**
370
+ * Notifies all subscribers.
371
+ * @param args - Data passed along to subscribers during notification.
372
+ */
373
+ notify(args) {
374
+ const sub1 = this.sub1;
375
+ const sub2 = this.sub2;
376
+ const source = this.source;
377
+ if (sub1 !== void 0) {
378
+ sub1.handleChange(source, args);
379
+ }
380
+ if (sub2 !== void 0) {
381
+ sub2.handleChange(source, args);
382
+ }
383
+ }
384
+ }
385
+ /**
386
+ * An implementation of Notifier that allows subscribers to be notified
387
+ * of individual property changes on an object.
388
+ * @public
389
+ */
390
+ class PropertyChangeNotifier {
391
+ /**
392
+ * Creates an instance of PropertyChangeNotifier for the specified source.
393
+ * @param source - The object source that subscribers will receive notifications from.
394
+ */
395
+ constructor(source) {
396
+ this.subscribers = {};
397
+ this.sourceSubscribers = null;
398
+ this.source = source;
399
+ }
400
+ /**
401
+ * Notifies all subscribers, based on the specified property.
402
+ * @param propertyName - The property name, passed along to subscribers during notification.
403
+ */
404
+ notify(propertyName) {
405
+ var _a;
406
+ const subscribers = this.subscribers[propertyName];
407
+ if (subscribers !== void 0) {
408
+ subscribers.notify(propertyName);
409
+ }
410
+ (_a = this.sourceSubscribers) === null || _a === void 0 ? void 0 : _a.notify(propertyName);
411
+ }
412
+ /**
413
+ * Subscribes to notification of changes in an object's state.
414
+ * @param subscriber - The object that is subscribing for change notification.
415
+ * @param propertyToWatch - The name of the property that the subscriber is interested in watching for changes.
416
+ */
417
+ subscribe(subscriber, propertyToWatch) {
418
+ var _a;
419
+ if (propertyToWatch) {
420
+ let subscribers = this.subscribers[propertyToWatch];
421
+ if (subscribers === void 0) {
422
+ this.subscribers[propertyToWatch] = subscribers = new SubscriberSet(this.source);
423
+ }
424
+ subscribers.subscribe(subscriber);
425
+ }
426
+ else {
427
+ this.sourceSubscribers = (_a = this.sourceSubscribers) !== null && _a !== void 0 ? _a : new SubscriberSet(this.source);
428
+ this.sourceSubscribers.subscribe(subscriber);
429
+ }
430
+ }
431
+ /**
432
+ * Unsubscribes from notification of changes in an object's state.
433
+ * @param subscriber - The object that is unsubscribing from change notification.
434
+ * @param propertyToUnwatch - The name of the property that the subscriber is no longer interested in watching.
435
+ */
436
+ unsubscribe(subscriber, propertyToUnwatch) {
437
+ var _a;
438
+ if (propertyToUnwatch) {
439
+ const subscribers = this.subscribers[propertyToUnwatch];
440
+ if (subscribers !== void 0) {
441
+ subscribers.unsubscribe(subscriber);
442
+ }
443
+ }
444
+ else {
445
+ (_a = this.sourceSubscribers) === null || _a === void 0 ? void 0 : _a.unsubscribe(subscriber);
446
+ }
447
+ }
448
+ }
449
+
450
+ /**
451
+ * Common Observable APIs.
452
+ * @public
453
+ */
454
+ const Observable = FAST.getById(2 /* observable */, () => {
455
+ const volatileRegex = /(:|&&|\|\||if)/;
456
+ const notifierLookup = new WeakMap();
457
+ const accessorLookup = new WeakMap();
458
+ const queueUpdate = DOM.queueUpdate;
459
+ let watcher = void 0;
460
+ let createArrayObserver = (array) => {
461
+ throw new Error("Must call enableArrayObservation before observing arrays.");
462
+ };
463
+ function getNotifier(source) {
464
+ let found = source.$fastController || notifierLookup.get(source);
465
+ if (found === void 0) {
466
+ if (Array.isArray(source)) {
467
+ found = createArrayObserver(source);
468
+ }
469
+ else {
470
+ notifierLookup.set(source, (found = new PropertyChangeNotifier(source)));
471
+ }
472
+ }
473
+ return found;
474
+ }
475
+ function getAccessors(target) {
476
+ let accessors = accessorLookup.get(target);
477
+ if (accessors === void 0) {
478
+ let currentTarget = Reflect.getPrototypeOf(target);
479
+ while (accessors === void 0 && currentTarget !== null) {
480
+ accessors = accessorLookup.get(currentTarget);
481
+ currentTarget = Reflect.getPrototypeOf(currentTarget);
482
+ }
483
+ if (accessors === void 0) {
484
+ accessors = [];
485
+ }
486
+ else {
487
+ accessors = accessors.slice(0);
488
+ }
489
+ accessorLookup.set(target, accessors);
490
+ }
491
+ return accessors;
492
+ }
493
+ class DefaultObservableAccessor {
494
+ constructor(name) {
495
+ this.name = name;
496
+ this.field = `_${name}`;
497
+ this.callback = `${name}Changed`;
498
+ }
499
+ getValue(source) {
500
+ if (watcher !== void 0) {
501
+ watcher.watch(source, this.name);
502
+ }
503
+ return source[this.field];
504
+ }
505
+ setValue(source, newValue) {
506
+ const field = this.field;
507
+ const oldValue = source[field];
508
+ if (oldValue !== newValue) {
509
+ source[field] = newValue;
510
+ const callback = source[this.callback];
511
+ if (typeof callback === "function") {
512
+ callback.call(source, oldValue, newValue);
513
+ }
514
+ getNotifier(source).notify(this.name);
515
+ }
516
+ }
517
+ }
518
+ class BindingObserverImplementation extends SubscriberSet {
519
+ constructor(binding, initialSubscriber, isVolatileBinding = false) {
520
+ super(binding, initialSubscriber);
521
+ this.binding = binding;
522
+ this.isVolatileBinding = isVolatileBinding;
523
+ this.needsRefresh = true;
524
+ this.needsQueue = true;
525
+ this.first = this;
526
+ this.last = null;
527
+ this.propertySource = void 0;
528
+ this.propertyName = void 0;
529
+ this.notifier = void 0;
530
+ this.next = void 0;
531
+ }
532
+ observe(source, context) {
533
+ if (this.needsRefresh && this.last !== null) {
534
+ this.disconnect();
535
+ }
536
+ const previousWatcher = watcher;
537
+ watcher = this.needsRefresh ? this : void 0;
538
+ this.needsRefresh = this.isVolatileBinding;
539
+ const result = this.binding(source, context);
540
+ watcher = previousWatcher;
541
+ return result;
542
+ }
543
+ disconnect() {
544
+ if (this.last !== null) {
545
+ let current = this.first;
546
+ while (current !== void 0) {
547
+ current.notifier.unsubscribe(this, current.propertyName);
548
+ current = current.next;
549
+ }
550
+ this.last = null;
551
+ this.needsRefresh = this.needsQueue = true;
552
+ }
553
+ }
554
+ watch(propertySource, propertyName) {
555
+ const prev = this.last;
556
+ const notifier = getNotifier(propertySource);
557
+ const current = prev === null ? this.first : {};
558
+ current.propertySource = propertySource;
559
+ current.propertyName = propertyName;
560
+ current.notifier = notifier;
561
+ notifier.subscribe(this, propertyName);
562
+ if (prev !== null) {
563
+ if (!this.needsRefresh) {
564
+ // Declaring the variable prior to assignment below circumvents
565
+ // a bug in Angular's optimization process causing infinite recursion
566
+ // of this watch() method. Details https://github.com/microsoft/fast/issues/4969
567
+ let prevValue;
568
+ watcher = void 0;
569
+ /* eslint-disable-next-line */
570
+ prevValue = prev.propertySource[prev.propertyName];
571
+ watcher = this;
572
+ if (propertySource === prevValue) {
573
+ this.needsRefresh = true;
574
+ }
575
+ }
576
+ prev.next = current;
577
+ }
578
+ this.last = current;
579
+ }
580
+ handleChange() {
581
+ if (this.needsQueue) {
582
+ this.needsQueue = false;
583
+ queueUpdate(this);
584
+ }
585
+ }
586
+ call() {
587
+ if (this.last !== null) {
588
+ this.needsQueue = true;
589
+ this.notify(this);
590
+ }
591
+ }
592
+ records() {
593
+ let next = this.first;
594
+ return {
595
+ next: () => {
596
+ const current = next;
597
+ if (current === undefined) {
598
+ return { value: void 0, done: true };
599
+ }
600
+ else {
601
+ next = next.next;
602
+ return {
603
+ value: current,
604
+ done: false,
605
+ };
606
+ }
607
+ },
608
+ [Symbol.iterator]: function () {
609
+ return this;
610
+ },
611
+ };
612
+ }
613
+ }
614
+ return Object.freeze({
615
+ /**
616
+ * @internal
617
+ * @param factory - The factory used to create array observers.
618
+ */
619
+ setArrayObserverFactory(factory) {
620
+ createArrayObserver = factory;
621
+ },
622
+ /**
623
+ * Gets a notifier for an object or Array.
624
+ * @param source - The object or Array to get the notifier for.
625
+ */
626
+ getNotifier,
627
+ /**
628
+ * Records a property change for a source object.
629
+ * @param source - The object to record the change against.
630
+ * @param propertyName - The property to track as changed.
631
+ */
632
+ track(source, propertyName) {
633
+ if (watcher !== void 0) {
634
+ watcher.watch(source, propertyName);
635
+ }
636
+ },
637
+ /**
638
+ * Notifies watchers that the currently executing property getter or function is volatile
639
+ * with respect to its observable dependencies.
640
+ */
641
+ trackVolatile() {
642
+ if (watcher !== void 0) {
643
+ watcher.needsRefresh = true;
644
+ }
645
+ },
646
+ /**
647
+ * Notifies subscribers of a source object of changes.
648
+ * @param source - the object to notify of changes.
649
+ * @param args - The change args to pass to subscribers.
650
+ */
651
+ notify(source, args) {
652
+ getNotifier(source).notify(args);
653
+ },
654
+ /**
655
+ * Defines an observable property on an object or prototype.
656
+ * @param target - The target object to define the observable on.
657
+ * @param nameOrAccessor - The name of the property to define as observable;
658
+ * or a custom accessor that specifies the property name and accessor implementation.
659
+ */
660
+ defineProperty(target, nameOrAccessor) {
661
+ if (typeof nameOrAccessor === "string") {
662
+ nameOrAccessor = new DefaultObservableAccessor(nameOrAccessor);
663
+ }
664
+ getAccessors(target).push(nameOrAccessor);
665
+ Reflect.defineProperty(target, nameOrAccessor.name, {
666
+ enumerable: true,
667
+ get: function () {
668
+ return nameOrAccessor.getValue(this);
669
+ },
670
+ set: function (newValue) {
671
+ nameOrAccessor.setValue(this, newValue);
672
+ },
673
+ });
674
+ },
675
+ /**
676
+ * Finds all the observable accessors defined on the target,
677
+ * including its prototype chain.
678
+ * @param target - The target object to search for accessor on.
679
+ */
680
+ getAccessors,
681
+ /**
682
+ * Creates a {@link BindingObserver} that can watch the
683
+ * provided {@link Binding} for changes.
684
+ * @param binding - The binding to observe.
685
+ * @param initialSubscriber - An initial subscriber to changes in the binding value.
686
+ * @param isVolatileBinding - Indicates whether the binding's dependency list must be re-evaluated on every value evaluation.
687
+ */
688
+ binding(binding, initialSubscriber, isVolatileBinding = this.isVolatileBinding(binding)) {
689
+ return new BindingObserverImplementation(binding, initialSubscriber, isVolatileBinding);
690
+ },
691
+ /**
692
+ * Determines whether a binding expression is volatile and needs to have its dependency list re-evaluated
693
+ * on every evaluation of the value.
694
+ * @param binding - The binding to inspect.
695
+ */
696
+ isVolatileBinding(binding) {
697
+ return volatileRegex.test(binding.toString());
698
+ },
699
+ });
700
+ });
701
+ /**
702
+ * Decorator: Defines an observable property on the target.
703
+ * @param target - The target to define the observable on.
704
+ * @param nameOrAccessor - The property name or accessor to define the observable as.
705
+ * @public
706
+ */
707
+ function observable(target, nameOrAccessor) {
708
+ Observable.defineProperty(target, nameOrAccessor);
709
+ }
710
+ const contextEvent = FAST.getById(3 /* contextEvent */, () => {
711
+ let current = null;
712
+ return {
713
+ get() {
714
+ return current;
715
+ },
716
+ set(event) {
717
+ current = event;
718
+ },
719
+ };
720
+ });
721
+ /**
722
+ * Provides additional contextual information available to behaviors and expressions.
723
+ * @public
724
+ */
725
+ class ExecutionContext {
726
+ constructor() {
727
+ /**
728
+ * The index of the current item within a repeat context.
729
+ */
730
+ this.index = 0;
731
+ /**
732
+ * The length of the current collection within a repeat context.
733
+ */
734
+ this.length = 0;
735
+ /**
736
+ * The parent data object within a repeat context.
737
+ */
738
+ this.parent = null;
739
+ /**
740
+ * The parent execution context when in nested context scenarios.
741
+ */
742
+ this.parentContext = null;
743
+ }
744
+ /**
745
+ * The current event within an event handler.
746
+ */
747
+ get event() {
748
+ return contextEvent.get();
749
+ }
750
+ /**
751
+ * Indicates whether the current item within a repeat context
752
+ * has an even index.
753
+ */
754
+ get isEven() {
755
+ return this.index % 2 === 0;
756
+ }
757
+ /**
758
+ * Indicates whether the current item within a repeat context
759
+ * has an odd index.
760
+ */
761
+ get isOdd() {
762
+ return this.index % 2 !== 0;
763
+ }
764
+ /**
765
+ * Indicates whether the current item within a repeat context
766
+ * is the first item in the collection.
767
+ */
768
+ get isFirst() {
769
+ return this.index === 0;
770
+ }
771
+ /**
772
+ * Indicates whether the current item within a repeat context
773
+ * is somewhere in the middle of the collection.
774
+ */
775
+ get isInMiddle() {
776
+ return !this.isFirst && !this.isLast;
777
+ }
778
+ /**
779
+ * Indicates whether the current item within a repeat context
780
+ * is the last item in the collection.
781
+ */
782
+ get isLast() {
783
+ return this.index === this.length - 1;
784
+ }
785
+ /**
786
+ * Sets the event for the current execution context.
787
+ * @param event - The event to set.
788
+ * @internal
789
+ */
790
+ static setEvent(event) {
791
+ contextEvent.set(event);
792
+ }
793
+ }
794
+ Observable.defineProperty(ExecutionContext.prototype, "index");
795
+ Observable.defineProperty(ExecutionContext.prototype, "length");
796
+ /**
797
+ * The default execution context used in binding expressions.
798
+ * @public
799
+ */
800
+ const defaultExecutionContext = Object.seal(new ExecutionContext());
801
+
802
+ /**
803
+ * Instructs the template engine to apply behavior to a node.
804
+ * @public
805
+ */
806
+ class HTMLDirective {
807
+ constructor() {
808
+ /**
809
+ * The index of the DOM node to which the created behavior will apply.
810
+ */
811
+ this.targetIndex = 0;
812
+ }
813
+ }
814
+ /**
815
+ * A {@link HTMLDirective} that targets a named attribute or property on a node.
816
+ * @public
817
+ */
818
+ class TargetedHTMLDirective extends HTMLDirective {
819
+ constructor() {
820
+ super(...arguments);
821
+ /**
822
+ * Creates a placeholder string based on the directive's index within the template.
823
+ * @param index - The index of the directive within the template.
824
+ */
825
+ this.createPlaceholder = DOM.createInterpolationPlaceholder;
826
+ }
827
+ }
828
+ /**
829
+ * A directive that attaches special behavior to an element via a custom attribute.
830
+ * @public
831
+ */
832
+ class AttachedBehaviorHTMLDirective extends HTMLDirective {
833
+ /**
834
+ *
835
+ * @param name - The name of the behavior; used as a custom attribute on the element.
836
+ * @param behavior - The behavior to instantiate and attach to the element.
837
+ * @param options - Options to pass to the behavior during creation.
838
+ */
839
+ constructor(name, behavior, options) {
840
+ super();
841
+ this.name = name;
842
+ this.behavior = behavior;
843
+ this.options = options;
844
+ }
845
+ /**
846
+ * Creates a placeholder string based on the directive's index within the template.
847
+ * @param index - The index of the directive within the template.
848
+ * @remarks
849
+ * Creates a custom attribute placeholder.
850
+ */
851
+ createPlaceholder(index) {
852
+ return DOM.createCustomAttributePlaceholder(this.name, index);
853
+ }
854
+ /**
855
+ * Creates a behavior for the provided target node.
856
+ * @param target - The node instance to create the behavior for.
857
+ * @remarks
858
+ * Creates an instance of the `behavior` type this directive was constructed with
859
+ * and passes the target and options to that `behavior`'s constructor.
860
+ */
861
+ createBehavior(target) {
862
+ return new this.behavior(target, this.options);
863
+ }
864
+ }
865
+
866
+ function normalBind(source, context) {
867
+ this.source = source;
868
+ this.context = context;
869
+ if (this.bindingObserver === null) {
870
+ this.bindingObserver = Observable.binding(this.binding, this, this.isBindingVolatile);
871
+ }
872
+ this.updateTarget(this.bindingObserver.observe(source, context));
873
+ }
874
+ function triggerBind(source, context) {
875
+ this.source = source;
876
+ this.context = context;
877
+ this.target.addEventListener(this.targetName, this);
878
+ }
879
+ function normalUnbind() {
880
+ this.bindingObserver.disconnect();
881
+ this.source = null;
882
+ this.context = null;
883
+ }
884
+ function contentUnbind() {
885
+ this.bindingObserver.disconnect();
886
+ this.source = null;
887
+ this.context = null;
888
+ const view = this.target.$fastView;
889
+ if (view !== void 0 && view.isComposed) {
890
+ view.unbind();
891
+ view.needsBindOnly = true;
892
+ }
893
+ }
894
+ function triggerUnbind() {
895
+ this.target.removeEventListener(this.targetName, this);
896
+ this.source = null;
897
+ this.context = null;
898
+ }
899
+ function updateAttributeTarget(value) {
900
+ DOM.setAttribute(this.target, this.targetName, value);
901
+ }
902
+ function updateBooleanAttributeTarget(value) {
903
+ DOM.setBooleanAttribute(this.target, this.targetName, value);
904
+ }
905
+ function updateContentTarget(value) {
906
+ // If there's no actual value, then this equates to the
907
+ // empty string for the purposes of content bindings.
908
+ if (value === null || value === undefined) {
909
+ value = "";
910
+ }
911
+ // If the value has a "create" method, then it's a template-like.
912
+ if (value.create) {
913
+ this.target.textContent = "";
914
+ let view = this.target.$fastView;
915
+ // If there's no previous view that we might be able to
916
+ // reuse then create a new view from the template.
917
+ if (view === void 0) {
918
+ view = value.create();
919
+ }
920
+ else {
921
+ // If there is a previous view, but it wasn't created
922
+ // from the same template as the new value, then we
923
+ // need to remove the old view if it's still in the DOM
924
+ // and create a new view from the template.
925
+ if (this.target.$fastTemplate !== value) {
926
+ if (view.isComposed) {
927
+ view.remove();
928
+ view.unbind();
929
+ }
930
+ view = value.create();
931
+ }
932
+ }
933
+ // It's possible that the value is the same as the previous template
934
+ // and that there's actually no need to compose it.
935
+ if (!view.isComposed) {
936
+ view.isComposed = true;
937
+ view.bind(this.source, this.context);
938
+ view.insertBefore(this.target);
939
+ this.target.$fastView = view;
940
+ this.target.$fastTemplate = value;
941
+ }
942
+ else if (view.needsBindOnly) {
943
+ view.needsBindOnly = false;
944
+ view.bind(this.source, this.context);
945
+ }
946
+ }
947
+ else {
948
+ const view = this.target.$fastView;
949
+ // If there is a view and it's currently composed into
950
+ // the DOM, then we need to remove it.
951
+ if (view !== void 0 && view.isComposed) {
952
+ view.isComposed = false;
953
+ view.remove();
954
+ if (view.needsBindOnly) {
955
+ view.needsBindOnly = false;
956
+ }
957
+ else {
958
+ view.unbind();
959
+ }
960
+ }
961
+ this.target.textContent = value;
962
+ }
963
+ }
964
+ function updatePropertyTarget(value) {
965
+ this.target[this.targetName] = value;
966
+ }
967
+ function updateClassTarget(value) {
968
+ const classVersions = this.classVersions || Object.create(null);
969
+ const target = this.target;
970
+ let version = this.version || 0;
971
+ // Add the classes, tracking the version at which they were added.
972
+ if (value !== null && value !== undefined && value.length) {
973
+ const names = value.split(/\s+/);
974
+ for (let i = 0, ii = names.length; i < ii; ++i) {
975
+ const currentName = names[i];
976
+ if (currentName === "") {
977
+ continue;
978
+ }
979
+ classVersions[currentName] = version;
980
+ target.classList.add(currentName);
981
+ }
982
+ }
983
+ this.classVersions = classVersions;
984
+ this.version = version + 1;
985
+ // If this is the first call to add classes, there's no need to remove old ones.
986
+ if (version === 0) {
987
+ return;
988
+ }
989
+ // Remove classes from the previous version.
990
+ version -= 1;
991
+ for (const name in classVersions) {
992
+ if (classVersions[name] === version) {
993
+ target.classList.remove(name);
994
+ }
995
+ }
996
+ }
997
+ /**
998
+ * A directive that configures data binding to element content and attributes.
999
+ * @public
1000
+ */
1001
+ class HTMLBindingDirective extends TargetedHTMLDirective {
1002
+ /**
1003
+ * Creates an instance of BindingDirective.
1004
+ * @param binding - A binding that returns the data used to update the DOM.
1005
+ */
1006
+ constructor(binding) {
1007
+ super();
1008
+ this.binding = binding;
1009
+ this.bind = normalBind;
1010
+ this.unbind = normalUnbind;
1011
+ this.updateTarget = updateAttributeTarget;
1012
+ this.isBindingVolatile = Observable.isVolatileBinding(this.binding);
1013
+ }
1014
+ /**
1015
+ * Gets/sets the name of the attribute or property that this
1016
+ * binding is targeting.
1017
+ */
1018
+ get targetName() {
1019
+ return this.originalTargetName;
1020
+ }
1021
+ set targetName(value) {
1022
+ this.originalTargetName = value;
1023
+ if (value === void 0) {
1024
+ return;
1025
+ }
1026
+ switch (value[0]) {
1027
+ case ":":
1028
+ this.cleanedTargetName = value.substr(1);
1029
+ this.updateTarget = updatePropertyTarget;
1030
+ if (this.cleanedTargetName === "innerHTML") {
1031
+ const binding = this.binding;
1032
+ this.binding = (s, c) => DOM.createHTML(binding(s, c));
1033
+ }
1034
+ break;
1035
+ case "?":
1036
+ this.cleanedTargetName = value.substr(1);
1037
+ this.updateTarget = updateBooleanAttributeTarget;
1038
+ break;
1039
+ case "@":
1040
+ this.cleanedTargetName = value.substr(1);
1041
+ this.bind = triggerBind;
1042
+ this.unbind = triggerUnbind;
1043
+ break;
1044
+ default:
1045
+ this.cleanedTargetName = value;
1046
+ if (value === "class") {
1047
+ this.updateTarget = updateClassTarget;
1048
+ }
1049
+ break;
1050
+ }
1051
+ }
1052
+ /**
1053
+ * Makes this binding target the content of an element rather than
1054
+ * a particular attribute or property.
1055
+ */
1056
+ targetAtContent() {
1057
+ this.updateTarget = updateContentTarget;
1058
+ this.unbind = contentUnbind;
1059
+ }
1060
+ /**
1061
+ * Creates the runtime BindingBehavior instance based on the configuration
1062
+ * information stored in the BindingDirective.
1063
+ * @param target - The target node that the binding behavior should attach to.
1064
+ */
1065
+ createBehavior(target) {
1066
+ /* eslint-disable-next-line @typescript-eslint/no-use-before-define */
1067
+ return new BindingBehavior(target, this.binding, this.isBindingVolatile, this.bind, this.unbind, this.updateTarget, this.cleanedTargetName);
1068
+ }
1069
+ }
1070
+ /**
1071
+ * A behavior that updates content and attributes based on a configured
1072
+ * BindingDirective.
1073
+ * @public
1074
+ */
1075
+ class BindingBehavior {
1076
+ /**
1077
+ * Creates an instance of BindingBehavior.
1078
+ * @param target - The target of the data updates.
1079
+ * @param binding - The binding that returns the latest value for an update.
1080
+ * @param isBindingVolatile - Indicates whether the binding has volatile dependencies.
1081
+ * @param bind - The operation to perform during binding.
1082
+ * @param unbind - The operation to perform during unbinding.
1083
+ * @param updateTarget - The operation to perform when updating.
1084
+ * @param targetName - The name of the target attribute or property to update.
1085
+ */
1086
+ constructor(target, binding, isBindingVolatile, bind, unbind, updateTarget, targetName) {
1087
+ /** @internal */
1088
+ this.source = null;
1089
+ /** @internal */
1090
+ this.context = null;
1091
+ /** @internal */
1092
+ this.bindingObserver = null;
1093
+ this.target = target;
1094
+ this.binding = binding;
1095
+ this.isBindingVolatile = isBindingVolatile;
1096
+ this.bind = bind;
1097
+ this.unbind = unbind;
1098
+ this.updateTarget = updateTarget;
1099
+ this.targetName = targetName;
1100
+ }
1101
+ /** @internal */
1102
+ handleChange() {
1103
+ this.updateTarget(this.bindingObserver.observe(this.source, this.context));
1104
+ }
1105
+ /** @internal */
1106
+ handleEvent(event) {
1107
+ ExecutionContext.setEvent(event);
1108
+ const result = this.binding(this.source, this.context);
1109
+ ExecutionContext.setEvent(null);
1110
+ if (result !== true) {
1111
+ event.preventDefault();
1112
+ }
1113
+ }
1114
+ }
1115
+
1116
+ let sharedContext = null;
1117
+ class CompilationContext {
1118
+ addFactory(factory) {
1119
+ factory.targetIndex = this.targetIndex;
1120
+ this.behaviorFactories.push(factory);
1121
+ }
1122
+ captureContentBinding(directive) {
1123
+ directive.targetAtContent();
1124
+ this.addFactory(directive);
1125
+ }
1126
+ reset() {
1127
+ this.behaviorFactories = [];
1128
+ this.targetIndex = -1;
1129
+ }
1130
+ release() {
1131
+ sharedContext = this;
1132
+ }
1133
+ static borrow(directives) {
1134
+ const shareable = sharedContext || new CompilationContext();
1135
+ shareable.directives = directives;
1136
+ shareable.reset();
1137
+ sharedContext = null;
1138
+ return shareable;
1139
+ }
1140
+ }
1141
+ function createAggregateBinding(parts) {
1142
+ if (parts.length === 1) {
1143
+ return parts[0];
1144
+ }
1145
+ let targetName;
1146
+ const partCount = parts.length;
1147
+ const finalParts = parts.map((x) => {
1148
+ if (typeof x === "string") {
1149
+ return () => x;
1150
+ }
1151
+ targetName = x.targetName || targetName;
1152
+ return x.binding;
1153
+ });
1154
+ const binding = (scope, context) => {
1155
+ let output = "";
1156
+ for (let i = 0; i < partCount; ++i) {
1157
+ output += finalParts[i](scope, context);
1158
+ }
1159
+ return output;
1160
+ };
1161
+ const directive = new HTMLBindingDirective(binding);
1162
+ directive.targetName = targetName;
1163
+ return directive;
1164
+ }
1165
+ const interpolationEndLength = _interpolationEnd.length;
1166
+ function parseContent(context, value) {
1167
+ const valueParts = value.split(_interpolationStart);
1168
+ if (valueParts.length === 1) {
1169
+ return null;
1170
+ }
1171
+ const bindingParts = [];
1172
+ for (let i = 0, ii = valueParts.length; i < ii; ++i) {
1173
+ const current = valueParts[i];
1174
+ const index = current.indexOf(_interpolationEnd);
1175
+ let literal;
1176
+ if (index === -1) {
1177
+ literal = current;
1178
+ }
1179
+ else {
1180
+ const directiveIndex = parseInt(current.substring(0, index));
1181
+ bindingParts.push(context.directives[directiveIndex]);
1182
+ literal = current.substring(index + interpolationEndLength);
1183
+ }
1184
+ if (literal !== "") {
1185
+ bindingParts.push(literal);
1186
+ }
1187
+ }
1188
+ return bindingParts;
1189
+ }
1190
+ function compileAttributes(context, node, includeBasicValues = false) {
1191
+ const attributes = node.attributes;
1192
+ for (let i = 0, ii = attributes.length; i < ii; ++i) {
1193
+ const attr = attributes[i];
1194
+ const attrValue = attr.value;
1195
+ const parseResult = parseContent(context, attrValue);
1196
+ let result = null;
1197
+ if (parseResult === null) {
1198
+ if (includeBasicValues) {
1199
+ result = new HTMLBindingDirective(() => attrValue);
1200
+ result.targetName = attr.name;
1201
+ }
1202
+ }
1203
+ else {
1204
+ result = createAggregateBinding(parseResult);
1205
+ }
1206
+ if (result !== null) {
1207
+ node.removeAttributeNode(attr);
1208
+ i--;
1209
+ ii--;
1210
+ context.addFactory(result);
1211
+ }
1212
+ }
1213
+ }
1214
+ function compileContent(context, node, walker) {
1215
+ const parseResult = parseContent(context, node.textContent);
1216
+ if (parseResult !== null) {
1217
+ let lastNode = node;
1218
+ for (let i = 0, ii = parseResult.length; i < ii; ++i) {
1219
+ const currentPart = parseResult[i];
1220
+ const currentNode = i === 0
1221
+ ? node
1222
+ : lastNode.parentNode.insertBefore(document.createTextNode(""), lastNode.nextSibling);
1223
+ if (typeof currentPart === "string") {
1224
+ currentNode.textContent = currentPart;
1225
+ }
1226
+ else {
1227
+ currentNode.textContent = " ";
1228
+ context.captureContentBinding(currentPart);
1229
+ }
1230
+ lastNode = currentNode;
1231
+ context.targetIndex++;
1232
+ if (currentNode !== node) {
1233
+ walker.nextNode();
1234
+ }
1235
+ }
1236
+ context.targetIndex--;
1237
+ }
1238
+ }
1239
+ /**
1240
+ * Compiles a template and associated directives into a raw compilation
1241
+ * result which include a cloneable DocumentFragment and factories capable
1242
+ * of attaching runtime behavior to nodes within the fragment.
1243
+ * @param template - The template to compile.
1244
+ * @param directives - The directives referenced by the template.
1245
+ * @remarks
1246
+ * The template that is provided for compilation is altered in-place
1247
+ * and cannot be compiled again. If the original template must be preserved,
1248
+ * it is recommended that you clone the original and pass the clone to this API.
1249
+ * @public
1250
+ */
1251
+ function compileTemplate(template, directives) {
1252
+ const fragment = template.content;
1253
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=1111864
1254
+ document.adoptNode(fragment);
1255
+ const context = CompilationContext.borrow(directives);
1256
+ compileAttributes(context, template, true);
1257
+ const hostBehaviorFactories = context.behaviorFactories;
1258
+ context.reset();
1259
+ const walker = DOM.createTemplateWalker(fragment);
1260
+ let node;
1261
+ while ((node = walker.nextNode())) {
1262
+ context.targetIndex++;
1263
+ switch (node.nodeType) {
1264
+ case 1: // element node
1265
+ compileAttributes(context, node);
1266
+ break;
1267
+ case 3: // text node
1268
+ compileContent(context, node, walker);
1269
+ break;
1270
+ case 8: // comment
1271
+ if (DOM.isMarker(node)) {
1272
+ context.addFactory(directives[DOM.extractDirectiveIndexFromMarker(node)]);
1273
+ }
1274
+ }
1275
+ }
1276
+ let targetOffset = 0;
1277
+ if (
1278
+ // If the first node in a fragment is a marker, that means it's an unstable first node,
1279
+ // because something like a when, repeat, etc. could add nodes before the marker.
1280
+ // To mitigate this, we insert a stable first node. However, if we insert a node,
1281
+ // that will alter the result of the TreeWalker. So, we also need to offset the target index.
1282
+ DOM.isMarker(fragment.firstChild) ||
1283
+ // Or if there is only one node and a directive, it means the template's content
1284
+ // is *only* the directive. In that case, HTMLView.dispose() misses any nodes inserted by
1285
+ // the directive. Inserting a new node ensures proper disposal of nodes added by the directive.
1286
+ (fragment.childNodes.length === 1 && directives.length)) {
1287
+ fragment.insertBefore(document.createComment(""), fragment.firstChild);
1288
+ targetOffset = -1;
1289
+ }
1290
+ const viewBehaviorFactories = context.behaviorFactories;
1291
+ context.release();
1292
+ return {
1293
+ fragment,
1294
+ viewBehaviorFactories,
1295
+ hostBehaviorFactories,
1296
+ targetOffset,
1297
+ };
1298
+ }
1299
+
1300
+ // A singleton Range instance used to efficiently remove ranges of DOM nodes.
1301
+ // See the implementation of HTMLView below for further details.
1302
+ const range = document.createRange();
1303
+ /**
1304
+ * The standard View implementation, which also implements ElementView and SyntheticView.
1305
+ * @public
1306
+ */
1307
+ class HTMLView {
1308
+ /**
1309
+ * Constructs an instance of HTMLView.
1310
+ * @param fragment - The html fragment that contains the nodes for this view.
1311
+ * @param behaviors - The behaviors to be applied to this view.
1312
+ */
1313
+ constructor(fragment, behaviors) {
1314
+ this.fragment = fragment;
1315
+ this.behaviors = behaviors;
1316
+ /**
1317
+ * The data that the view is bound to.
1318
+ */
1319
+ this.source = null;
1320
+ /**
1321
+ * The execution context the view is running within.
1322
+ */
1323
+ this.context = null;
1324
+ this.firstChild = fragment.firstChild;
1325
+ this.lastChild = fragment.lastChild;
1326
+ }
1327
+ /**
1328
+ * Appends the view's DOM nodes to the referenced node.
1329
+ * @param node - The parent node to append the view's DOM nodes to.
1330
+ */
1331
+ appendTo(node) {
1332
+ node.appendChild(this.fragment);
1333
+ }
1334
+ /**
1335
+ * Inserts the view's DOM nodes before the referenced node.
1336
+ * @param node - The node to insert the view's DOM before.
1337
+ */
1338
+ insertBefore(node) {
1339
+ if (this.fragment.hasChildNodes()) {
1340
+ node.parentNode.insertBefore(this.fragment, node);
1341
+ }
1342
+ else {
1343
+ const parentNode = node.parentNode;
1344
+ const end = this.lastChild;
1345
+ let current = this.firstChild;
1346
+ let next;
1347
+ while (current !== end) {
1348
+ next = current.nextSibling;
1349
+ parentNode.insertBefore(current, node);
1350
+ current = next;
1351
+ }
1352
+ parentNode.insertBefore(end, node);
1353
+ }
1354
+ }
1355
+ /**
1356
+ * Removes the view's DOM nodes.
1357
+ * The nodes are not disposed and the view can later be re-inserted.
1358
+ */
1359
+ remove() {
1360
+ const fragment = this.fragment;
1361
+ const end = this.lastChild;
1362
+ let current = this.firstChild;
1363
+ let next;
1364
+ while (current !== end) {
1365
+ next = current.nextSibling;
1366
+ fragment.appendChild(current);
1367
+ current = next;
1368
+ }
1369
+ fragment.appendChild(end);
1370
+ }
1371
+ /**
1372
+ * Removes the view and unbinds its behaviors, disposing of DOM nodes afterward.
1373
+ * Once a view has been disposed, it cannot be inserted or bound again.
1374
+ */
1375
+ dispose() {
1376
+ const parent = this.firstChild.parentNode;
1377
+ const end = this.lastChild;
1378
+ let current = this.firstChild;
1379
+ let next;
1380
+ while (current !== end) {
1381
+ next = current.nextSibling;
1382
+ parent.removeChild(current);
1383
+ current = next;
1384
+ }
1385
+ parent.removeChild(end);
1386
+ const behaviors = this.behaviors;
1387
+ const oldSource = this.source;
1388
+ for (let i = 0, ii = behaviors.length; i < ii; ++i) {
1389
+ behaviors[i].unbind(oldSource);
1390
+ }
1391
+ }
1392
+ /**
1393
+ * Binds a view's behaviors to its binding source.
1394
+ * @param source - The binding source for the view's binding behaviors.
1395
+ * @param context - The execution context to run the behaviors within.
1396
+ */
1397
+ bind(source, context) {
1398
+ const behaviors = this.behaviors;
1399
+ if (this.source === source) {
1400
+ return;
1401
+ }
1402
+ else if (this.source !== null) {
1403
+ const oldSource = this.source;
1404
+ this.source = source;
1405
+ this.context = context;
1406
+ for (let i = 0, ii = behaviors.length; i < ii; ++i) {
1407
+ const current = behaviors[i];
1408
+ current.unbind(oldSource);
1409
+ current.bind(source, context);
1410
+ }
1411
+ }
1412
+ else {
1413
+ this.source = source;
1414
+ this.context = context;
1415
+ for (let i = 0, ii = behaviors.length; i < ii; ++i) {
1416
+ behaviors[i].bind(source, context);
1417
+ }
1418
+ }
1419
+ }
1420
+ /**
1421
+ * Unbinds a view's behaviors from its binding source.
1422
+ */
1423
+ unbind() {
1424
+ if (this.source === null) {
1425
+ return;
1426
+ }
1427
+ const behaviors = this.behaviors;
1428
+ const oldSource = this.source;
1429
+ for (let i = 0, ii = behaviors.length; i < ii; ++i) {
1430
+ behaviors[i].unbind(oldSource);
1431
+ }
1432
+ this.source = null;
1433
+ }
1434
+ /**
1435
+ * Efficiently disposes of a contiguous range of synthetic view instances.
1436
+ * @param views - A contiguous range of views to be disposed.
1437
+ */
1438
+ static disposeContiguousBatch(views) {
1439
+ if (views.length === 0) {
1440
+ return;
1441
+ }
1442
+ range.setStartBefore(views[0].firstChild);
1443
+ range.setEndAfter(views[views.length - 1].lastChild);
1444
+ range.deleteContents();
1445
+ for (let i = 0, ii = views.length; i < ii; ++i) {
1446
+ const view = views[i];
1447
+ const behaviors = view.behaviors;
1448
+ const oldSource = view.source;
1449
+ for (let j = 0, jj = behaviors.length; j < jj; ++j) {
1450
+ behaviors[j].unbind(oldSource);
1451
+ }
1452
+ }
1453
+ }
1454
+ }
1455
+
1456
+ /**
1457
+ * A template capable of creating HTMLView instances or rendering directly to DOM.
1458
+ * @public
1459
+ */
1460
+ /* eslint-disable-next-line @typescript-eslint/no-unused-vars */
1461
+ class ViewTemplate {
1462
+ /**
1463
+ * Creates an instance of ViewTemplate.
1464
+ * @param html - The html representing what this template will instantiate, including placeholders for directives.
1465
+ * @param directives - The directives that will be connected to placeholders in the html.
1466
+ */
1467
+ constructor(html, directives) {
1468
+ this.behaviorCount = 0;
1469
+ this.hasHostBehaviors = false;
1470
+ this.fragment = null;
1471
+ this.targetOffset = 0;
1472
+ this.viewBehaviorFactories = null;
1473
+ this.hostBehaviorFactories = null;
1474
+ this.html = html;
1475
+ this.directives = directives;
1476
+ }
1477
+ /**
1478
+ * Creates an HTMLView instance based on this template definition.
1479
+ * @param hostBindingTarget - The element that host behaviors will be bound to.
1480
+ */
1481
+ create(hostBindingTarget) {
1482
+ if (this.fragment === null) {
1483
+ let template;
1484
+ const html = this.html;
1485
+ if (typeof html === "string") {
1486
+ template = document.createElement("template");
1487
+ template.innerHTML = DOM.createHTML(html);
1488
+ const fec = template.content.firstElementChild;
1489
+ if (fec !== null && fec.tagName === "TEMPLATE") {
1490
+ template = fec;
1491
+ }
1492
+ }
1493
+ else {
1494
+ template = html;
1495
+ }
1496
+ const result = compileTemplate(template, this.directives);
1497
+ this.fragment = result.fragment;
1498
+ this.viewBehaviorFactories = result.viewBehaviorFactories;
1499
+ this.hostBehaviorFactories = result.hostBehaviorFactories;
1500
+ this.targetOffset = result.targetOffset;
1501
+ this.behaviorCount =
1502
+ this.viewBehaviorFactories.length + this.hostBehaviorFactories.length;
1503
+ this.hasHostBehaviors = this.hostBehaviorFactories.length > 0;
1504
+ }
1505
+ const fragment = this.fragment.cloneNode(true);
1506
+ const viewFactories = this.viewBehaviorFactories;
1507
+ const behaviors = new Array(this.behaviorCount);
1508
+ const walker = DOM.createTemplateWalker(fragment);
1509
+ let behaviorIndex = 0;
1510
+ let targetIndex = this.targetOffset;
1511
+ let node = walker.nextNode();
1512
+ for (let ii = viewFactories.length; behaviorIndex < ii; ++behaviorIndex) {
1513
+ const factory = viewFactories[behaviorIndex];
1514
+ const factoryIndex = factory.targetIndex;
1515
+ while (node !== null) {
1516
+ if (targetIndex === factoryIndex) {
1517
+ behaviors[behaviorIndex] = factory.createBehavior(node);
1518
+ break;
1519
+ }
1520
+ else {
1521
+ node = walker.nextNode();
1522
+ targetIndex++;
1523
+ }
1524
+ }
1525
+ }
1526
+ if (this.hasHostBehaviors) {
1527
+ const hostFactories = this.hostBehaviorFactories;
1528
+ for (let i = 0, ii = hostFactories.length; i < ii; ++i, ++behaviorIndex) {
1529
+ behaviors[behaviorIndex] = hostFactories[i].createBehavior(hostBindingTarget);
1530
+ }
1531
+ }
1532
+ return new HTMLView(fragment, behaviors);
1533
+ }
1534
+ /**
1535
+ * Creates an HTMLView from this template, binds it to the source, and then appends it to the host.
1536
+ * @param source - The data source to bind the template to.
1537
+ * @param host - The Element where the template will be rendered.
1538
+ * @param hostBindingTarget - An HTML element to target the host bindings at if different from the
1539
+ * host that the template is being attached to.
1540
+ */
1541
+ render(source, host, hostBindingTarget) {
1542
+ if (typeof host === "string") {
1543
+ host = document.getElementById(host);
1544
+ }
1545
+ if (hostBindingTarget === void 0) {
1546
+ hostBindingTarget = host;
1547
+ }
1548
+ const view = this.create(hostBindingTarget);
1549
+ view.bind(source, defaultExecutionContext);
1550
+ view.appendTo(host);
1551
+ return view;
1552
+ }
1553
+ }
1554
+ // Much thanks to LitHTML for working this out!
1555
+ const lastAttributeNameRegex =
1556
+ /* eslint-disable-next-line no-control-regex */
1557
+ /([ \x09\x0a\x0c\x0d])([^\0-\x1F\x7F-\x9F "'>=/]+)([ \x09\x0a\x0c\x0d]*=[ \x09\x0a\x0c\x0d]*(?:[^ \x09\x0a\x0c\x0d"'`<>=]*|"[^"]*|'[^']*))$/;
1558
+ /**
1559
+ * Transforms a template literal string into a renderable ViewTemplate.
1560
+ * @param strings - The string fragments that are interpolated with the values.
1561
+ * @param values - The values that are interpolated with the string fragments.
1562
+ * @remarks
1563
+ * The html helper supports interpolation of strings, numbers, binding expressions,
1564
+ * other template instances, and Directive instances.
1565
+ * @public
1566
+ */
1567
+ function html(strings, ...values) {
1568
+ const directives = [];
1569
+ let html = "";
1570
+ for (let i = 0, ii = strings.length - 1; i < ii; ++i) {
1571
+ const currentString = strings[i];
1572
+ let value = values[i];
1573
+ html += currentString;
1574
+ if (value instanceof ViewTemplate) {
1575
+ const template = value;
1576
+ value = () => template;
1577
+ }
1578
+ if (typeof value === "function") {
1579
+ value = new HTMLBindingDirective(value);
1580
+ }
1581
+ if (value instanceof TargetedHTMLDirective) {
1582
+ const match = lastAttributeNameRegex.exec(currentString);
1583
+ if (match !== null) {
1584
+ value.targetName = match[2];
1585
+ }
1586
+ }
1587
+ if (value instanceof HTMLDirective) {
1588
+ // Since not all values are directives, we can't use i
1589
+ // as the index for the placeholder. Instead, we need to
1590
+ // use directives.length to get the next index.
1591
+ html += value.createPlaceholder(directives.length);
1592
+ directives.push(value);
1593
+ }
1594
+ else {
1595
+ html += value;
1596
+ }
1597
+ }
1598
+ html += strings[strings.length - 1];
1599
+ return new ViewTemplate(html, directives);
1600
+ }
1601
+
1602
+ /**
1603
+ * Represents styles that can be applied to a custom element.
1604
+ * @public
1605
+ */
1606
+ class ElementStyles {
1607
+ constructor() {
1608
+ this.targets = new WeakSet();
1609
+ /** @internal */
1610
+ this.behaviors = null;
1611
+ }
1612
+ /** @internal */
1613
+ addStylesTo(target) {
1614
+ this.targets.add(target);
1615
+ }
1616
+ /** @internal */
1617
+ removeStylesFrom(target) {
1618
+ this.targets.delete(target);
1619
+ }
1620
+ /** @internal */
1621
+ isAttachedTo(target) {
1622
+ return this.targets.has(target);
1623
+ }
1624
+ /**
1625
+ * Associates behaviors with this set of styles.
1626
+ * @param behaviors - The behaviors to associate.
1627
+ */
1628
+ withBehaviors(...behaviors) {
1629
+ this.behaviors =
1630
+ this.behaviors === null ? behaviors : this.behaviors.concat(behaviors);
1631
+ return this;
1632
+ }
1633
+ }
1634
+ /**
1635
+ * Create ElementStyles from ComposableStyles.
1636
+ */
1637
+ ElementStyles.create = (() => {
1638
+ if (DOM.supportsAdoptedStyleSheets) {
1639
+ const styleSheetCache = new Map();
1640
+ return (styles) =>
1641
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
1642
+ new AdoptedStyleSheetsStyles(styles, styleSheetCache);
1643
+ }
1644
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
1645
+ return (styles) => new StyleElementStyles(styles);
1646
+ })();
1647
+ function reduceStyles(styles) {
1648
+ return styles
1649
+ .map((x) => x instanceof ElementStyles ? reduceStyles(x.styles) : [x])
1650
+ .reduce((prev, curr) => prev.concat(curr), []);
1651
+ }
1652
+ function reduceBehaviors(styles) {
1653
+ return styles
1654
+ .map((x) => (x instanceof ElementStyles ? x.behaviors : null))
1655
+ .reduce((prev, curr) => {
1656
+ if (curr === null) {
1657
+ return prev;
1658
+ }
1659
+ if (prev === null) {
1660
+ prev = [];
1661
+ }
1662
+ return prev.concat(curr);
1663
+ }, null);
1664
+ }
1665
+ /**
1666
+ * https://wicg.github.io/construct-stylesheets/
1667
+ * https://developers.google.com/web/updates/2019/02/constructable-stylesheets
1668
+ *
1669
+ * @internal
1670
+ */
1671
+ class AdoptedStyleSheetsStyles extends ElementStyles {
1672
+ constructor(styles, styleSheetCache) {
1673
+ super();
1674
+ this.styles = styles;
1675
+ this.styleSheetCache = styleSheetCache;
1676
+ this._styleSheets = void 0;
1677
+ this.behaviors = reduceBehaviors(styles);
1678
+ }
1679
+ get styleSheets() {
1680
+ if (this._styleSheets === void 0) {
1681
+ const styles = this.styles;
1682
+ const styleSheetCache = this.styleSheetCache;
1683
+ this._styleSheets = reduceStyles(styles).map((x) => {
1684
+ if (x instanceof CSSStyleSheet) {
1685
+ return x;
1686
+ }
1687
+ let sheet = styleSheetCache.get(x);
1688
+ if (sheet === void 0) {
1689
+ sheet = new CSSStyleSheet();
1690
+ sheet.replaceSync(x);
1691
+ styleSheetCache.set(x, sheet);
1692
+ }
1693
+ return sheet;
1694
+ });
1695
+ }
1696
+ return this._styleSheets;
1697
+ }
1698
+ addStylesTo(target) {
1699
+ target.adoptedStyleSheets = [...target.adoptedStyleSheets, ...this.styleSheets];
1700
+ super.addStylesTo(target);
1701
+ }
1702
+ removeStylesFrom(target) {
1703
+ const sourceSheets = this.styleSheets;
1704
+ target.adoptedStyleSheets = target.adoptedStyleSheets.filter((x) => sourceSheets.indexOf(x) === -1);
1705
+ super.removeStylesFrom(target);
1706
+ }
1707
+ }
1708
+ let styleClassId = 0;
1709
+ function getNextStyleClass() {
1710
+ return `fast-style-class-${++styleClassId}`;
1711
+ }
1712
+ /**
1713
+ * @internal
1714
+ */
1715
+ class StyleElementStyles extends ElementStyles {
1716
+ constructor(styles) {
1717
+ super();
1718
+ this.styles = styles;
1719
+ this.behaviors = null;
1720
+ this.behaviors = reduceBehaviors(styles);
1721
+ this.styleSheets = reduceStyles(styles);
1722
+ this.styleClass = getNextStyleClass();
1723
+ }
1724
+ addStylesTo(target) {
1725
+ const styleSheets = this.styleSheets;
1726
+ const styleClass = this.styleClass;
1727
+ target = this.normalizeTarget(target);
1728
+ for (let i = 0; i < styleSheets.length; i++) {
1729
+ const element = document.createElement("style");
1730
+ element.innerHTML = styleSheets[i];
1731
+ element.className = styleClass;
1732
+ target.append(element);
1733
+ }
1734
+ super.addStylesTo(target);
1735
+ }
1736
+ removeStylesFrom(target) {
1737
+ target = this.normalizeTarget(target);
1738
+ const styles = target.querySelectorAll(`.${this.styleClass}`);
1739
+ for (let i = 0, ii = styles.length; i < ii; ++i) {
1740
+ target.removeChild(styles[i]);
1741
+ }
1742
+ super.removeStylesFrom(target);
1743
+ }
1744
+ isAttachedTo(target) {
1745
+ return super.isAttachedTo(this.normalizeTarget(target));
1746
+ }
1747
+ normalizeTarget(target) {
1748
+ return target === document ? document.body : target;
1749
+ }
1750
+ }
1751
+
1752
+ /**
1753
+ * A {@link ValueConverter} that converts to and from `boolean` values.
1754
+ * @remarks
1755
+ * Used automatically when the `boolean` {@link AttributeMode} is selected.
1756
+ * @public
1757
+ */
1758
+ const booleanConverter = {
1759
+ toView(value) {
1760
+ return value ? "true" : "false";
1761
+ },
1762
+ fromView(value) {
1763
+ if (value === null ||
1764
+ value === void 0 ||
1765
+ value === "false" ||
1766
+ value === false ||
1767
+ value === 0) {
1768
+ return false;
1769
+ }
1770
+ return true;
1771
+ },
1772
+ };
1773
+ /**
1774
+ * A {@link ValueConverter} that converts to and from `number` values.
1775
+ * @remarks
1776
+ * This converter allows for nullable numbers, returning `null` if the
1777
+ * input was `null`, `undefined`, or `NaN`.
1778
+ * @public
1779
+ */
1780
+ const nullableNumberConverter = {
1781
+ toView(value) {
1782
+ if (value === null || value === undefined) {
1783
+ return null;
1784
+ }
1785
+ const number = value * 1;
1786
+ return isNaN(number) ? null : number.toString();
1787
+ },
1788
+ fromView(value) {
1789
+ if (value === null || value === undefined) {
1790
+ return null;
1791
+ }
1792
+ const number = value * 1;
1793
+ return isNaN(number) ? null : number;
1794
+ },
1795
+ };
1796
+ /**
1797
+ * An implementation of {@link Accessor} that supports reactivity,
1798
+ * change callbacks, attribute reflection, and type conversion for
1799
+ * custom elements.
1800
+ * @public
1801
+ */
1802
+ class AttributeDefinition {
1803
+ /**
1804
+ * Creates an instance of AttributeDefinition.
1805
+ * @param Owner - The class constructor that owns this attribute.
1806
+ * @param name - The name of the property associated with the attribute.
1807
+ * @param attribute - The name of the attribute in HTML.
1808
+ * @param mode - The {@link AttributeMode} that describes the behavior of this attribute.
1809
+ * @param converter - A {@link ValueConverter} that integrates with the property getter/setter
1810
+ * to convert values to and from a DOM string.
1811
+ */
1812
+ constructor(Owner, name, attribute = name.toLowerCase(), mode = "reflect", converter) {
1813
+ this.guards = new Set();
1814
+ this.Owner = Owner;
1815
+ this.name = name;
1816
+ this.attribute = attribute;
1817
+ this.mode = mode;
1818
+ this.converter = converter;
1819
+ this.fieldName = `_${name}`;
1820
+ this.callbackName = `${name}Changed`;
1821
+ this.hasCallback = this.callbackName in Owner.prototype;
1822
+ if (mode === "boolean" && converter === void 0) {
1823
+ this.converter = booleanConverter;
1824
+ }
1825
+ }
1826
+ /**
1827
+ * Sets the value of the attribute/property on the source element.
1828
+ * @param source - The source element to access.
1829
+ * @param value - The value to set the attribute/property to.
1830
+ */
1831
+ setValue(source, newValue) {
1832
+ const oldValue = source[this.fieldName];
1833
+ const converter = this.converter;
1834
+ if (converter !== void 0) {
1835
+ newValue = converter.fromView(newValue);
1836
+ }
1837
+ if (oldValue !== newValue) {
1838
+ source[this.fieldName] = newValue;
1839
+ this.tryReflectToAttribute(source);
1840
+ if (this.hasCallback) {
1841
+ source[this.callbackName](oldValue, newValue);
1842
+ }
1843
+ source.$fastController.notify(this.name);
1844
+ }
1845
+ }
1846
+ /**
1847
+ * Gets the value of the attribute/property on the source element.
1848
+ * @param source - The source element to access.
1849
+ */
1850
+ getValue(source) {
1851
+ Observable.track(source, this.name);
1852
+ return source[this.fieldName];
1853
+ }
1854
+ /** @internal */
1855
+ onAttributeChangedCallback(element, value) {
1856
+ if (this.guards.has(element)) {
1857
+ return;
1858
+ }
1859
+ this.guards.add(element);
1860
+ this.setValue(element, value);
1861
+ this.guards.delete(element);
1862
+ }
1863
+ tryReflectToAttribute(element) {
1864
+ const mode = this.mode;
1865
+ const guards = this.guards;
1866
+ if (guards.has(element) || mode === "fromView") {
1867
+ return;
1868
+ }
1869
+ DOM.queueUpdate(() => {
1870
+ guards.add(element);
1871
+ const latestValue = element[this.fieldName];
1872
+ switch (mode) {
1873
+ case "reflect":
1874
+ const converter = this.converter;
1875
+ DOM.setAttribute(element, this.attribute, converter !== void 0 ? converter.toView(latestValue) : latestValue);
1876
+ break;
1877
+ case "boolean":
1878
+ DOM.setBooleanAttribute(element, this.attribute, latestValue);
1879
+ break;
1880
+ }
1881
+ guards.delete(element);
1882
+ });
1883
+ }
1884
+ /**
1885
+ * Collects all attribute definitions associated with the owner.
1886
+ * @param Owner - The class constructor to collect attribute for.
1887
+ * @param attributeLists - Any existing attributes to collect and merge with those associated with the owner.
1888
+ * @internal
1889
+ */
1890
+ static collect(Owner, ...attributeLists) {
1891
+ const attributes = [];
1892
+ attributeLists.push(Owner.attributes);
1893
+ for (let i = 0, ii = attributeLists.length; i < ii; ++i) {
1894
+ const list = attributeLists[i];
1895
+ if (list === void 0) {
1896
+ continue;
1897
+ }
1898
+ for (let j = 0, jj = list.length; j < jj; ++j) {
1899
+ const config = list[j];
1900
+ if (typeof config === "string") {
1901
+ attributes.push(new AttributeDefinition(Owner, config));
1902
+ }
1903
+ else {
1904
+ attributes.push(new AttributeDefinition(Owner, config.property, config.attribute, config.mode, config.converter));
1905
+ }
1906
+ }
1907
+ }
1908
+ return attributes;
1909
+ }
1910
+ }
1911
+ function attr(configOrTarget, prop) {
1912
+ let config;
1913
+ function decorator($target, $prop) {
1914
+ if (arguments.length > 1) {
1915
+ // Non invocation:
1916
+ // - @attr
1917
+ // Invocation with or w/o opts:
1918
+ // - @attr()
1919
+ // - @attr({...opts})
1920
+ config.property = $prop;
1921
+ }
1922
+ const attributes = $target.constructor.attributes ||
1923
+ ($target.constructor.attributes = []);
1924
+ attributes.push(config);
1925
+ }
1926
+ if (arguments.length > 1) {
1927
+ // Non invocation:
1928
+ // - @attr
1929
+ config = {};
1930
+ decorator(configOrTarget, prop);
1931
+ return;
1932
+ }
1933
+ // Invocation with or w/o opts:
1934
+ // - @attr()
1935
+ // - @attr({...opts})
1936
+ config = configOrTarget === void 0 ? {} : configOrTarget;
1937
+ return decorator;
1938
+ }
1939
+
1940
+ const defaultShadowOptions = { mode: "open" };
1941
+ const defaultElementOptions = {};
1942
+ const fastRegistry = FAST.getById(4 /* elementRegistry */, () => {
1943
+ const typeToDefinition = new Map();
1944
+ return Object.freeze({
1945
+ register(definition) {
1946
+ if (typeToDefinition.has(definition.type)) {
1947
+ return false;
1948
+ }
1949
+ typeToDefinition.set(definition.type, definition);
1950
+ return true;
1951
+ },
1952
+ getByType(key) {
1953
+ return typeToDefinition.get(key);
1954
+ },
1955
+ });
1956
+ });
1957
+ /**
1958
+ * Defines metadata for a FASTElement.
1959
+ * @public
1960
+ */
1961
+ class FASTElementDefinition {
1962
+ /**
1963
+ * Creates an instance of FASTElementDefinition.
1964
+ * @param type - The type this definition is being created for.
1965
+ * @param nameOrConfig - The name of the element to define or a config object
1966
+ * that describes the element to define.
1967
+ */
1968
+ constructor(type, nameOrConfig = type.definition) {
1969
+ if (typeof nameOrConfig === "string") {
1970
+ nameOrConfig = { name: nameOrConfig };
1971
+ }
1972
+ this.type = type;
1973
+ this.name = nameOrConfig.name;
1974
+ this.template = nameOrConfig.template;
1975
+ const attributes = AttributeDefinition.collect(type, nameOrConfig.attributes);
1976
+ const observedAttributes = new Array(attributes.length);
1977
+ const propertyLookup = {};
1978
+ const attributeLookup = {};
1979
+ for (let i = 0, ii = attributes.length; i < ii; ++i) {
1980
+ const current = attributes[i];
1981
+ observedAttributes[i] = current.attribute;
1982
+ propertyLookup[current.name] = current;
1983
+ attributeLookup[current.attribute] = current;
1984
+ }
1985
+ this.attributes = attributes;
1986
+ this.observedAttributes = observedAttributes;
1987
+ this.propertyLookup = propertyLookup;
1988
+ this.attributeLookup = attributeLookup;
1989
+ this.shadowOptions =
1990
+ nameOrConfig.shadowOptions === void 0
1991
+ ? defaultShadowOptions
1992
+ : nameOrConfig.shadowOptions === null
1993
+ ? void 0
1994
+ : Object.assign(Object.assign({}, defaultShadowOptions), nameOrConfig.shadowOptions);
1995
+ this.elementOptions =
1996
+ nameOrConfig.elementOptions === void 0
1997
+ ? defaultElementOptions
1998
+ : Object.assign(Object.assign({}, defaultElementOptions), nameOrConfig.elementOptions);
1999
+ this.styles =
2000
+ nameOrConfig.styles === void 0
2001
+ ? void 0
2002
+ : Array.isArray(nameOrConfig.styles)
2003
+ ? ElementStyles.create(nameOrConfig.styles)
2004
+ : nameOrConfig.styles instanceof ElementStyles
2005
+ ? nameOrConfig.styles
2006
+ : ElementStyles.create([nameOrConfig.styles]);
2007
+ }
2008
+ /**
2009
+ * Indicates if this element has been defined in at least one registry.
2010
+ */
2011
+ get isDefined() {
2012
+ return !!fastRegistry.getByType(this.type);
2013
+ }
2014
+ /**
2015
+ * Defines a custom element based on this definition.
2016
+ * @param registry - The element registry to define the element in.
2017
+ */
2018
+ define(registry = customElements) {
2019
+ const type = this.type;
2020
+ if (fastRegistry.register(this)) {
2021
+ const attributes = this.attributes;
2022
+ const proto = type.prototype;
2023
+ for (let i = 0, ii = attributes.length; i < ii; ++i) {
2024
+ Observable.defineProperty(proto, attributes[i]);
2025
+ }
2026
+ Reflect.defineProperty(type, "observedAttributes", {
2027
+ value: this.observedAttributes,
2028
+ enumerable: true,
2029
+ });
2030
+ }
2031
+ if (!registry.get(this.name)) {
2032
+ registry.define(this.name, type, this.elementOptions);
2033
+ }
2034
+ return this;
2035
+ }
2036
+ }
2037
+ /**
2038
+ * Gets the element definition associated with the specified type.
2039
+ * @param type - The custom element type to retrieve the definition for.
2040
+ */
2041
+ FASTElementDefinition.forType = fastRegistry.getByType;
2042
+
2043
+ const shadowRoots = new WeakMap();
2044
+ const defaultEventOptions = {
2045
+ bubbles: true,
2046
+ composed: true,
2047
+ cancelable: true,
2048
+ };
2049
+ function getShadowRoot(element) {
2050
+ return element.shadowRoot || shadowRoots.get(element) || null;
2051
+ }
2052
+ /**
2053
+ * Controls the lifecycle and rendering of a `FASTElement`.
2054
+ * @public
2055
+ */
2056
+ class Controller extends PropertyChangeNotifier {
2057
+ /**
2058
+ * Creates a Controller to control the specified element.
2059
+ * @param element - The element to be controlled by this controller.
2060
+ * @param definition - The element definition metadata that instructs this
2061
+ * controller in how to handle rendering and other platform integrations.
2062
+ * @internal
2063
+ */
2064
+ constructor(element, definition) {
2065
+ super(element);
2066
+ this.boundObservables = null;
2067
+ this.behaviors = null;
2068
+ this.needsInitialization = true;
2069
+ this._template = null;
2070
+ this._styles = null;
2071
+ this._isConnected = false;
2072
+ /**
2073
+ * This allows Observable.getNotifier(...) to return the Controller
2074
+ * when the notifier for the Controller itself is being requested. The
2075
+ * result is that the Observable system does not need to create a separate
2076
+ * instance of Notifier for observables on the Controller. The component and
2077
+ * the controller will now share the same notifier, removing one-object construct
2078
+ * per web component instance.
2079
+ */
2080
+ this.$fastController = this;
2081
+ /**
2082
+ * The view associated with the custom element.
2083
+ * @remarks
2084
+ * If `null` then the element is managing its own rendering.
2085
+ */
2086
+ this.view = null;
2087
+ this.element = element;
2088
+ this.definition = definition;
2089
+ const shadowOptions = definition.shadowOptions;
2090
+ if (shadowOptions !== void 0) {
2091
+ const shadowRoot = element.attachShadow(shadowOptions);
2092
+ if (shadowOptions.mode === "closed") {
2093
+ shadowRoots.set(element, shadowRoot);
2094
+ }
2095
+ }
2096
+ // Capture any observable values that were set by the binding engine before
2097
+ // the browser upgraded the element. Then delete the property since it will
2098
+ // shadow the getter/setter that is required to make the observable operate.
2099
+ // Later, in the connect callback, we'll re-apply the values.
2100
+ const accessors = Observable.getAccessors(element);
2101
+ if (accessors.length > 0) {
2102
+ const boundObservables = (this.boundObservables = Object.create(null));
2103
+ for (let i = 0, ii = accessors.length; i < ii; ++i) {
2104
+ const propertyName = accessors[i].name;
2105
+ const value = element[propertyName];
2106
+ if (value !== void 0) {
2107
+ delete element[propertyName];
2108
+ boundObservables[propertyName] = value;
2109
+ }
2110
+ }
2111
+ }
2112
+ }
2113
+ /**
2114
+ * Indicates whether or not the custom element has been
2115
+ * connected to the document.
2116
+ */
2117
+ get isConnected() {
2118
+ Observable.track(this, "isConnected");
2119
+ return this._isConnected;
2120
+ }
2121
+ setIsConnected(value) {
2122
+ this._isConnected = value;
2123
+ Observable.notify(this, "isConnected");
2124
+ }
2125
+ /**
2126
+ * Gets/sets the template used to render the component.
2127
+ * @remarks
2128
+ * This value can only be accurately read after connect but can be set at any time.
2129
+ */
2130
+ get template() {
2131
+ return this._template;
2132
+ }
2133
+ set template(value) {
2134
+ if (this._template === value) {
2135
+ return;
2136
+ }
2137
+ this._template = value;
2138
+ if (!this.needsInitialization) {
2139
+ this.renderTemplate(value);
2140
+ }
2141
+ }
2142
+ /**
2143
+ * Gets/sets the primary styles used for the component.
2144
+ * @remarks
2145
+ * This value can only be accurately read after connect but can be set at any time.
2146
+ */
2147
+ get styles() {
2148
+ return this._styles;
2149
+ }
2150
+ set styles(value) {
2151
+ if (this._styles === value) {
2152
+ return;
2153
+ }
2154
+ if (this._styles !== null) {
2155
+ this.removeStyles(this._styles);
2156
+ }
2157
+ this._styles = value;
2158
+ if (!this.needsInitialization && value !== null) {
2159
+ this.addStyles(value);
2160
+ }
2161
+ }
2162
+ /**
2163
+ * Adds styles to this element. Providing an HTMLStyleElement will attach the element instance to the shadowRoot.
2164
+ * @param styles - The styles to add.
2165
+ */
2166
+ addStyles(styles) {
2167
+ const target = getShadowRoot(this.element) ||
2168
+ this.element.getRootNode();
2169
+ if (styles instanceof HTMLStyleElement) {
2170
+ target.append(styles);
2171
+ }
2172
+ else if (!styles.isAttachedTo(target)) {
2173
+ const sourceBehaviors = styles.behaviors;
2174
+ styles.addStylesTo(target);
2175
+ if (sourceBehaviors !== null) {
2176
+ this.addBehaviors(sourceBehaviors);
2177
+ }
2178
+ }
2179
+ }
2180
+ /**
2181
+ * Removes styles from this element. Providing an HTMLStyleElement will detach the element instance from the shadowRoot.
2182
+ * @param styles - the styles to remove.
2183
+ */
2184
+ removeStyles(styles) {
2185
+ const target = getShadowRoot(this.element) ||
2186
+ this.element.getRootNode();
2187
+ if (styles instanceof HTMLStyleElement) {
2188
+ target.removeChild(styles);
2189
+ }
2190
+ else if (styles.isAttachedTo(target)) {
2191
+ const sourceBehaviors = styles.behaviors;
2192
+ styles.removeStylesFrom(target);
2193
+ if (sourceBehaviors !== null) {
2194
+ this.removeBehaviors(sourceBehaviors);
2195
+ }
2196
+ }
2197
+ }
2198
+ /**
2199
+ * Adds behaviors to this element.
2200
+ * @param behaviors - The behaviors to add.
2201
+ */
2202
+ addBehaviors(behaviors) {
2203
+ const targetBehaviors = this.behaviors || (this.behaviors = new Map());
2204
+ const length = behaviors.length;
2205
+ const behaviorsToBind = [];
2206
+ for (let i = 0; i < length; ++i) {
2207
+ const behavior = behaviors[i];
2208
+ if (targetBehaviors.has(behavior)) {
2209
+ targetBehaviors.set(behavior, targetBehaviors.get(behavior) + 1);
2210
+ }
2211
+ else {
2212
+ targetBehaviors.set(behavior, 1);
2213
+ behaviorsToBind.push(behavior);
2214
+ }
2215
+ }
2216
+ if (this._isConnected) {
2217
+ const element = this.element;
2218
+ for (let i = 0; i < behaviorsToBind.length; ++i) {
2219
+ behaviorsToBind[i].bind(element, defaultExecutionContext);
2220
+ }
2221
+ }
2222
+ }
2223
+ /**
2224
+ * Removes behaviors from this element.
2225
+ * @param behaviors - The behaviors to remove.
2226
+ * @param force - Forces unbinding of behaviors.
2227
+ */
2228
+ removeBehaviors(behaviors, force = false) {
2229
+ const targetBehaviors = this.behaviors;
2230
+ if (targetBehaviors === null) {
2231
+ return;
2232
+ }
2233
+ const length = behaviors.length;
2234
+ const behaviorsToUnbind = [];
2235
+ for (let i = 0; i < length; ++i) {
2236
+ const behavior = behaviors[i];
2237
+ if (targetBehaviors.has(behavior)) {
2238
+ const count = targetBehaviors.get(behavior) - 1;
2239
+ count === 0 || force
2240
+ ? targetBehaviors.delete(behavior) && behaviorsToUnbind.push(behavior)
2241
+ : targetBehaviors.set(behavior, count);
2242
+ }
2243
+ }
2244
+ if (this._isConnected) {
2245
+ const element = this.element;
2246
+ for (let i = 0; i < behaviorsToUnbind.length; ++i) {
2247
+ behaviorsToUnbind[i].unbind(element);
2248
+ }
2249
+ }
2250
+ }
2251
+ /**
2252
+ * Runs connected lifecycle behavior on the associated element.
2253
+ */
2254
+ onConnectedCallback() {
2255
+ if (this._isConnected) {
2256
+ return;
2257
+ }
2258
+ const element = this.element;
2259
+ if (this.needsInitialization) {
2260
+ this.finishInitialization();
2261
+ }
2262
+ else if (this.view !== null) {
2263
+ this.view.bind(element, defaultExecutionContext);
2264
+ }
2265
+ const behaviors = this.behaviors;
2266
+ if (behaviors !== null) {
2267
+ for (const [behavior] of behaviors) {
2268
+ behavior.bind(element, defaultExecutionContext);
2269
+ }
2270
+ }
2271
+ this.setIsConnected(true);
2272
+ }
2273
+ /**
2274
+ * Runs disconnected lifecycle behavior on the associated element.
2275
+ */
2276
+ onDisconnectedCallback() {
2277
+ if (!this._isConnected) {
2278
+ return;
2279
+ }
2280
+ this.setIsConnected(false);
2281
+ const view = this.view;
2282
+ if (view !== null) {
2283
+ view.unbind();
2284
+ }
2285
+ const behaviors = this.behaviors;
2286
+ if (behaviors !== null) {
2287
+ const element = this.element;
2288
+ for (const [behavior] of behaviors) {
2289
+ behavior.unbind(element);
2290
+ }
2291
+ }
2292
+ }
2293
+ /**
2294
+ * Runs the attribute changed callback for the associated element.
2295
+ * @param name - The name of the attribute that changed.
2296
+ * @param oldValue - The previous value of the attribute.
2297
+ * @param newValue - The new value of the attribute.
2298
+ */
2299
+ onAttributeChangedCallback(name, oldValue, newValue) {
2300
+ const attrDef = this.definition.attributeLookup[name];
2301
+ if (attrDef !== void 0) {
2302
+ attrDef.onAttributeChangedCallback(this.element, newValue);
2303
+ }
2304
+ }
2305
+ /**
2306
+ * Emits a custom HTML event.
2307
+ * @param type - The type name of the event.
2308
+ * @param detail - The event detail object to send with the event.
2309
+ * @param options - The event options. By default bubbles and composed.
2310
+ * @remarks
2311
+ * Only emits events if connected.
2312
+ */
2313
+ emit(type, detail, options) {
2314
+ if (this._isConnected) {
2315
+ return this.element.dispatchEvent(new CustomEvent(type, Object.assign(Object.assign({ detail }, defaultEventOptions), options)));
2316
+ }
2317
+ return false;
2318
+ }
2319
+ finishInitialization() {
2320
+ const element = this.element;
2321
+ const boundObservables = this.boundObservables;
2322
+ // If we have any observables that were bound, re-apply their values.
2323
+ if (boundObservables !== null) {
2324
+ const propertyNames = Object.keys(boundObservables);
2325
+ for (let i = 0, ii = propertyNames.length; i < ii; ++i) {
2326
+ const propertyName = propertyNames[i];
2327
+ element[propertyName] = boundObservables[propertyName];
2328
+ }
2329
+ this.boundObservables = null;
2330
+ }
2331
+ const definition = this.definition;
2332
+ // 1. Template overrides take top precedence.
2333
+ if (this._template === null) {
2334
+ if (this.element.resolveTemplate) {
2335
+ // 2. Allow for element instance overrides next.
2336
+ this._template = this.element.resolveTemplate();
2337
+ }
2338
+ else if (definition.template) {
2339
+ // 3. Default to the static definition.
2340
+ this._template = definition.template || null;
2341
+ }
2342
+ }
2343
+ // If we have a template after the above process, render it.
2344
+ // If there's no template, then the element author has opted into
2345
+ // custom rendering and they will managed the shadow root's content themselves.
2346
+ if (this._template !== null) {
2347
+ this.renderTemplate(this._template);
2348
+ }
2349
+ // 1. Styles overrides take top precedence.
2350
+ if (this._styles === null) {
2351
+ if (this.element.resolveStyles) {
2352
+ // 2. Allow for element instance overrides next.
2353
+ this._styles = this.element.resolveStyles();
2354
+ }
2355
+ else if (definition.styles) {
2356
+ // 3. Default to the static definition.
2357
+ this._styles = definition.styles || null;
2358
+ }
2359
+ }
2360
+ // If we have styles after the above process, add them.
2361
+ if (this._styles !== null) {
2362
+ this.addStyles(this._styles);
2363
+ }
2364
+ this.needsInitialization = false;
2365
+ }
2366
+ renderTemplate(template) {
2367
+ const element = this.element;
2368
+ // When getting the host to render to, we start by looking
2369
+ // up the shadow root. If there isn't one, then that means
2370
+ // we're doing a Light DOM render to the element's direct children.
2371
+ const host = getShadowRoot(element) || element;
2372
+ if (this.view !== null) {
2373
+ // If there's already a view, we need to unbind and remove through dispose.
2374
+ this.view.dispose();
2375
+ this.view = null;
2376
+ }
2377
+ else if (!this.needsInitialization) {
2378
+ // If there was previous custom rendering, we need to clear out the host.
2379
+ DOM.removeChildNodes(host);
2380
+ }
2381
+ if (template) {
2382
+ // If a new template was provided, render it.
2383
+ this.view = template.render(element, host, element);
2384
+ }
2385
+ }
2386
+ /**
2387
+ * Locates or creates a controller for the specified element.
2388
+ * @param element - The element to return the controller for.
2389
+ * @remarks
2390
+ * The specified element must have a {@link FASTElementDefinition}
2391
+ * registered either through the use of the {@link customElement}
2392
+ * decorator or a call to `FASTElement.define`.
2393
+ */
2394
+ static forCustomElement(element) {
2395
+ const controller = element.$fastController;
2396
+ if (controller !== void 0) {
2397
+ return controller;
2398
+ }
2399
+ const definition = FASTElementDefinition.forType(element.constructor);
2400
+ if (definition === void 0) {
2401
+ throw new Error("Missing FASTElement definition.");
2402
+ }
2403
+ return (element.$fastController = new Controller(element, definition));
2404
+ }
2405
+ }
2406
+
2407
+ /* eslint-disable-next-line @typescript-eslint/explicit-function-return-type */
2408
+ function createFASTElement(BaseType) {
2409
+ return class extends BaseType {
2410
+ constructor() {
2411
+ /* eslint-disable-next-line */
2412
+ super();
2413
+ Controller.forCustomElement(this);
2414
+ }
2415
+ $emit(type, detail, options) {
2416
+ return this.$fastController.emit(type, detail, options);
2417
+ }
2418
+ connectedCallback() {
2419
+ this.$fastController.onConnectedCallback();
2420
+ }
2421
+ disconnectedCallback() {
2422
+ this.$fastController.onDisconnectedCallback();
2423
+ }
2424
+ attributeChangedCallback(name, oldValue, newValue) {
2425
+ this.$fastController.onAttributeChangedCallback(name, oldValue, newValue);
2426
+ }
2427
+ };
2428
+ }
2429
+ /**
2430
+ * A minimal base class for FASTElements that also provides
2431
+ * static helpers for working with FASTElements.
2432
+ * @public
2433
+ */
2434
+ const FASTElement = Object.assign(createFASTElement(HTMLElement), {
2435
+ /**
2436
+ * Creates a new FASTElement base class inherited from the
2437
+ * provided base type.
2438
+ * @param BaseType - The base element type to inherit from.
2439
+ */
2440
+ from(BaseType) {
2441
+ return createFASTElement(BaseType);
2442
+ },
2443
+ /**
2444
+ * Defines a platform custom element based on the provided type and definition.
2445
+ * @param type - The custom element type to define.
2446
+ * @param nameOrDef - The name of the element to define or a definition object
2447
+ * that describes the element to define.
2448
+ */
2449
+ define(type, nameOrDef) {
2450
+ return new FASTElementDefinition(type, nameOrDef).define().type;
2451
+ },
2452
+ });
2453
+
2454
+ /**
2455
+ * Directive for use in {@link css}.
2456
+ *
2457
+ * @public
2458
+ */
2459
+ class CSSDirective {
2460
+ /**
2461
+ * Creates a CSS fragment to interpolate into the CSS document.
2462
+ * @returns - the string to interpolate into CSS
2463
+ */
2464
+ createCSS() {
2465
+ return "";
2466
+ }
2467
+ /**
2468
+ * Creates a behavior to bind to the host element.
2469
+ * @returns - the behavior to bind to the host element, or undefined.
2470
+ */
2471
+ createBehavior() {
2472
+ return undefined;
2473
+ }
2474
+ }
2475
+
2476
+ /******************************************************************************
2477
+ Copyright (c) Microsoft Corporation.
2478
+
2479
+ Permission to use, copy, modify, and/or distribute this software for any
2480
+ purpose with or without fee is hereby granted.
2481
+
2482
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
2483
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
2484
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
2485
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
2486
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
2487
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2488
+ PERFORMANCE OF THIS SOFTWARE.
2489
+ ***************************************************************************** */
2490
+
2491
+ function __decorate(decorators, target, key, desc) {
2492
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2493
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2494
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2495
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2496
+ }
2497
+
2498
+ function __metadata(metadataKey, metadataValue) {
2499
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
2500
+ }
2501
+
2502
+ function __classPrivateFieldGet(receiver, state, kind, f) {
2503
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
2504
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
2505
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
2506
+ }
2507
+
2508
+ function __classPrivateFieldSet(receiver, state, value, kind, f) {
2509
+ if (kind === "m") throw new TypeError("Private method is not writable");
2510
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
2511
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
2512
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
2513
+ }
2514
+
2515
+ /**
2516
+ * Big thanks to https://github.com/fkleuver and the https://github.com/aurelia/aurelia project
2517
+ * for the bulk of this code and many of the associated tests.
2518
+ */
2519
+ // Tiny polyfill for TypeScript's Reflect metadata API.
2520
+ const metadataByTarget = new Map();
2521
+ if (!("metadata" in Reflect)) {
2522
+ Reflect.metadata = function (key, value) {
2523
+ return function (target) {
2524
+ Reflect.defineMetadata(key, value, target);
2525
+ };
2526
+ };
2527
+ Reflect.defineMetadata = function (key, value, target) {
2528
+ let metadata = metadataByTarget.get(target);
2529
+ if (metadata === void 0) {
2530
+ metadataByTarget.set(target, (metadata = new Map()));
2531
+ }
2532
+ metadata.set(key, value);
2533
+ };
2534
+ Reflect.getOwnMetadata = function (key, target) {
2535
+ const metadata = metadataByTarget.get(target);
2536
+ if (metadata !== void 0) {
2537
+ return metadata.get(key);
2538
+ }
2539
+ return void 0;
2540
+ };
2541
+ }
2542
+ /**
2543
+ * A utility class used that constructs and registers resolvers for a dependency
2544
+ * injection container. Supports a standard set of object lifetimes.
2545
+ * @public
2546
+ */
2547
+ class ResolverBuilder {
2548
+ /**
2549
+ *
2550
+ * @param container - The container to create resolvers for.
2551
+ * @param key - The key to register resolvers under.
2552
+ */
2553
+ constructor(container, key) {
2554
+ this.container = container;
2555
+ this.key = key;
2556
+ }
2557
+ /**
2558
+ * Creates a resolver for an existing object instance.
2559
+ * @param value - The instance to resolve.
2560
+ * @returns The resolver.
2561
+ */
2562
+ instance(value) {
2563
+ return this.registerResolver(0 /* instance */, value);
2564
+ }
2565
+ /**
2566
+ * Creates a resolver that enforces a singleton lifetime.
2567
+ * @param value - The type to create and cache the singleton for.
2568
+ * @returns The resolver.
2569
+ */
2570
+ singleton(value) {
2571
+ return this.registerResolver(1 /* singleton */, value);
2572
+ }
2573
+ /**
2574
+ * Creates a resolver that creates a new instance for every dependency request.
2575
+ * @param value - The type to create instances of.
2576
+ * @returns - The resolver.
2577
+ */
2578
+ transient(value) {
2579
+ return this.registerResolver(2 /* transient */, value);
2580
+ }
2581
+ /**
2582
+ * Creates a resolver that invokes a callback function for every dependency resolution
2583
+ * request, allowing custom logic to return the dependency.
2584
+ * @param value - The callback to call during resolution.
2585
+ * @returns The resolver.
2586
+ */
2587
+ callback(value) {
2588
+ return this.registerResolver(3 /* callback */, value);
2589
+ }
2590
+ /**
2591
+ * Creates a resolver that invokes a callback function the first time that a dependency
2592
+ * resolution is requested. The returned value is then cached and provided for all
2593
+ * subsequent requests.
2594
+ * @param value - The callback to call during the first resolution.
2595
+ * @returns The resolver.
2596
+ */
2597
+ cachedCallback(value) {
2598
+ return this.registerResolver(3 /* callback */, cacheCallbackResult(value));
2599
+ }
2600
+ /**
2601
+ * Aliases the current key to a different key.
2602
+ * @param destinationKey - The key to point the alias to.
2603
+ * @returns The resolver.
2604
+ */
2605
+ aliasTo(destinationKey) {
2606
+ return this.registerResolver(5 /* alias */, destinationKey);
2607
+ }
2608
+ registerResolver(strategy, state) {
2609
+ const { container, key } = this;
2610
+ /* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */
2611
+ this.container = this.key = (void 0);
2612
+ return container.registerResolver(key, new ResolverImpl(key, strategy, state));
2613
+ }
2614
+ }
2615
+ function cloneArrayWithPossibleProps(source) {
2616
+ const clone = source.slice();
2617
+ const keys = Object.keys(source);
2618
+ const len = keys.length;
2619
+ let key;
2620
+ for (let i = 0; i < len; ++i) {
2621
+ key = keys[i];
2622
+ if (!isArrayIndex(key)) {
2623
+ clone[key] = source[key];
2624
+ }
2625
+ }
2626
+ return clone;
2627
+ }
2628
+ /**
2629
+ * A set of default resolvers useful in configuring a container.
2630
+ * @public
2631
+ */
2632
+ const DefaultResolver = Object.freeze({
2633
+ /**
2634
+ * Disables auto-registration and throws for all un-registered dependencies.
2635
+ * @param key - The key to create the resolver for.
2636
+ */
2637
+ none(key) {
2638
+ throw Error(`${key.toString()} not registered, did you forget to add @singleton()?`);
2639
+ },
2640
+ /**
2641
+ * Provides default singleton resolution behavior during auto-registration.
2642
+ * @param key - The key to create the resolver for.
2643
+ * @returns The resolver.
2644
+ */
2645
+ singleton(key) {
2646
+ return new ResolverImpl(key, 1 /* singleton */, key);
2647
+ },
2648
+ /**
2649
+ * Provides default transient resolution behavior during auto-registration.
2650
+ * @param key - The key to create the resolver for.
2651
+ * @returns The resolver.
2652
+ */
2653
+ transient(key) {
2654
+ return new ResolverImpl(key, 2 /* transient */, key);
2655
+ },
2656
+ });
2657
+ /**
2658
+ * Configuration for a dependency injection container.
2659
+ * @public
2660
+ */
2661
+ const ContainerConfiguration = Object.freeze({
2662
+ /**
2663
+ * The default configuration used when creating a DOM-disconnected container.
2664
+ * @remarks
2665
+ * The default creates a root container, with no parent container. It does not handle
2666
+ * owner requests and it uses singleton resolution behavior for auto-registration.
2667
+ */
2668
+ default: Object.freeze({
2669
+ parentLocator: () => null,
2670
+ responsibleForOwnerRequests: false,
2671
+ defaultResolver: DefaultResolver.singleton,
2672
+ }),
2673
+ });
2674
+ const dependencyLookup = new Map();
2675
+ function getParamTypes(key) {
2676
+ return (Type) => {
2677
+ return Reflect.getOwnMetadata(key, Type);
2678
+ };
2679
+ }
2680
+ let rootDOMContainer = null;
2681
+ /**
2682
+ * The gateway to dependency injection APIs.
2683
+ * @public
2684
+ */
2685
+ const DI = Object.freeze({
2686
+ /**
2687
+ * Creates a new dependency injection container.
2688
+ * @param config - The configuration for the container.
2689
+ * @returns A newly created dependency injection container.
2690
+ */
2691
+ createContainer(config) {
2692
+ return new ContainerImpl(null, Object.assign({}, ContainerConfiguration.default, config));
2693
+ },
2694
+ /**
2695
+ * Finds the dependency injection container responsible for providing dependencies
2696
+ * to the specified node.
2697
+ * @param node - The node to find the responsible container for.
2698
+ * @returns The container responsible for providing dependencies to the node.
2699
+ * @remarks
2700
+ * This will be the same as the parent container if the specified node
2701
+ * does not itself host a container configured with responsibleForOwnerRequests.
2702
+ */
2703
+ findResponsibleContainer(node) {
2704
+ const owned = node.$$container$$;
2705
+ if (owned && owned.responsibleForOwnerRequests) {
2706
+ return owned;
2707
+ }
2708
+ return DI.findParentContainer(node);
2709
+ },
2710
+ /**
2711
+ * Find the dependency injection container up the DOM tree from this node.
2712
+ * @param node - The node to find the parent container for.
2713
+ * @returns The parent container of this node.
2714
+ * @remarks
2715
+ * This will be the same as the responsible container if the specified node
2716
+ * does not itself host a container configured with responsibleForOwnerRequests.
2717
+ */
2718
+ findParentContainer(node) {
2719
+ const event = new CustomEvent(DILocateParentEventType, {
2720
+ bubbles: true,
2721
+ composed: true,
2722
+ cancelable: true,
2723
+ detail: { container: void 0 },
2724
+ });
2725
+ node.dispatchEvent(event);
2726
+ return event.detail.container || DI.getOrCreateDOMContainer();
2727
+ },
2728
+ /**
2729
+ * Returns a dependency injection container if one is explicitly owned by the specified
2730
+ * node. If one is not owned, then a new container is created and assigned to the node.
2731
+ * @param node - The node to find or create the container for.
2732
+ * @param config - The configuration for the container if one needs to be created.
2733
+ * @returns The located or created container.
2734
+ * @remarks
2735
+ * This API does not search for a responsible or parent container. It looks only for a container
2736
+ * directly defined on the specified node and creates one at that location if one does not
2737
+ * already exist.
2738
+ */
2739
+ getOrCreateDOMContainer(node, config) {
2740
+ if (!node) {
2741
+ return (rootDOMContainer ||
2742
+ (rootDOMContainer = new ContainerImpl(null, Object.assign({}, ContainerConfiguration.default, config, {
2743
+ parentLocator: () => null,
2744
+ }))));
2745
+ }
2746
+ return (node.$$container$$ ||
2747
+ new ContainerImpl(node, Object.assign({}, ContainerConfiguration.default, config, {
2748
+ parentLocator: DI.findParentContainer,
2749
+ })));
2750
+ },
2751
+ /**
2752
+ * Gets the "design:paramtypes" metadata for the specified type.
2753
+ * @param Type - The type to get the metadata for.
2754
+ * @returns The metadata array or undefined if no metadata is found.
2755
+ */
2756
+ getDesignParamtypes: getParamTypes("design:paramtypes"),
2757
+ /**
2758
+ * Gets the "di:paramtypes" metadata for the specified type.
2759
+ * @param Type - The type to get the metadata for.
2760
+ * @returns The metadata array or undefined if no metadata is found.
2761
+ */
2762
+ getAnnotationParamtypes: getParamTypes("di:paramtypes"),
2763
+ /**
2764
+ *
2765
+ * @param Type - Gets the "di:paramtypes" metadata for the specified type. If none is found,
2766
+ * an empty metadata array is created and added.
2767
+ * @returns The metadata array.
2768
+ */
2769
+ getOrCreateAnnotationParamTypes(Type) {
2770
+ let annotationParamtypes = this.getAnnotationParamtypes(Type);
2771
+ if (annotationParamtypes === void 0) {
2772
+ Reflect.defineMetadata("di:paramtypes", (annotationParamtypes = []), Type);
2773
+ }
2774
+ return annotationParamtypes;
2775
+ },
2776
+ /**
2777
+ * Gets the dependency keys representing what is needed to instantiate the specified type.
2778
+ * @param Type - The type to get the dependencies for.
2779
+ * @returns An array of dependency keys.
2780
+ */
2781
+ getDependencies(Type) {
2782
+ // Note: Every detail of this getDependencies method is pretty deliberate at the moment, and probably not yet 100% tested from every possible angle,
2783
+ // so be careful with making changes here as it can have a huge impact on complex end user apps.
2784
+ // Preferably, only make changes to the dependency resolution process via a RFC.
2785
+ let dependencies = dependencyLookup.get(Type);
2786
+ if (dependencies === void 0) {
2787
+ // Type.length is the number of constructor parameters. If this is 0, it could mean the class has an empty constructor
2788
+ // but it could also mean the class has no constructor at all (in which case it inherits the constructor from the prototype).
2789
+ // Non-zero constructor length + no paramtypes means emitDecoratorMetadata is off, or the class has no decorator.
2790
+ // We're not doing anything with the above right now, but it's good to keep in mind for any future issues.
2791
+ const inject = Type.inject;
2792
+ if (inject === void 0) {
2793
+ // design:paramtypes is set by tsc when emitDecoratorMetadata is enabled.
2794
+ const designParamtypes = DI.getDesignParamtypes(Type);
2795
+ // di:paramtypes is set by the parameter decorator from DI.createInterface or by @inject
2796
+ const annotationParamtypes = DI.getAnnotationParamtypes(Type);
2797
+ if (designParamtypes === void 0) {
2798
+ if (annotationParamtypes === void 0) {
2799
+ // Only go up the prototype if neither static inject nor any of the paramtypes is defined, as
2800
+ // there is no sound way to merge a type's deps with its prototype's deps
2801
+ const Proto = Object.getPrototypeOf(Type);
2802
+ if (typeof Proto === "function" && Proto !== Function.prototype) {
2803
+ dependencies = cloneArrayWithPossibleProps(DI.getDependencies(Proto));
2804
+ }
2805
+ else {
2806
+ dependencies = [];
2807
+ }
2808
+ }
2809
+ else {
2810
+ // No design:paramtypes so just use the di:paramtypes
2811
+ dependencies = cloneArrayWithPossibleProps(annotationParamtypes);
2812
+ }
2813
+ }
2814
+ else if (annotationParamtypes === void 0) {
2815
+ // No di:paramtypes so just use the design:paramtypes
2816
+ dependencies = cloneArrayWithPossibleProps(designParamtypes);
2817
+ }
2818
+ else {
2819
+ // We've got both, so merge them (in case of conflict on same index, di:paramtypes take precedence)
2820
+ dependencies = cloneArrayWithPossibleProps(designParamtypes);
2821
+ let len = annotationParamtypes.length;
2822
+ let auAnnotationParamtype;
2823
+ for (let i = 0; i < len; ++i) {
2824
+ auAnnotationParamtype = annotationParamtypes[i];
2825
+ if (auAnnotationParamtype !== void 0) {
2826
+ dependencies[i] = auAnnotationParamtype;
2827
+ }
2828
+ }
2829
+ const keys = Object.keys(annotationParamtypes);
2830
+ len = keys.length;
2831
+ let key;
2832
+ for (let i = 0; i < len; ++i) {
2833
+ key = keys[i];
2834
+ if (!isArrayIndex(key)) {
2835
+ dependencies[key] = annotationParamtypes[key];
2836
+ }
2837
+ }
2838
+ }
2839
+ }
2840
+ else {
2841
+ // Ignore paramtypes if we have static inject
2842
+ dependencies = cloneArrayWithPossibleProps(inject);
2843
+ }
2844
+ dependencyLookup.set(Type, dependencies);
2845
+ }
2846
+ return dependencies;
2847
+ },
2848
+ /**
2849
+ * Defines a property on a web component class. The value of this property will
2850
+ * be resolved from the dependency injection container responsible for the element
2851
+ * instance, based on where it is connected in the DOM.
2852
+ * @param target - The target to define the property on.
2853
+ * @param propertyName - The name of the property to define.
2854
+ * @param key - The dependency injection key.
2855
+ * @param respectConnection - Indicates whether or not to update the property value if the
2856
+ * hosting component is disconnected and then re-connected at a different location in the DOM.
2857
+ * @remarks
2858
+ * The respectConnection option is only applicable to elements that descend from FASTElement.
2859
+ */
2860
+ defineProperty(target, propertyName, key, respectConnection = false) {
2861
+ const diPropertyKey = `$di_${propertyName}`;
2862
+ Reflect.defineProperty(target, propertyName, {
2863
+ get: function () {
2864
+ let value = this[diPropertyKey];
2865
+ if (value === void 0) {
2866
+ const container = this instanceof HTMLElement
2867
+ ? DI.findResponsibleContainer(this)
2868
+ : DI.getOrCreateDOMContainer();
2869
+ value = container.get(key);
2870
+ this[diPropertyKey] = value;
2871
+ if (respectConnection && this instanceof FASTElement) {
2872
+ const notifier = this.$fastController;
2873
+ const handleChange = () => {
2874
+ const newContainer = DI.findResponsibleContainer(this);
2875
+ const newValue = newContainer.get(key);
2876
+ const oldValue = this[diPropertyKey];
2877
+ if (newValue !== oldValue) {
2878
+ this[diPropertyKey] = value;
2879
+ notifier.notify(propertyName);
2880
+ }
2881
+ };
2882
+ notifier.subscribe({ handleChange }, "isConnected");
2883
+ }
2884
+ }
2885
+ return value;
2886
+ },
2887
+ });
2888
+ },
2889
+ /**
2890
+ * Creates a dependency injection key.
2891
+ * @param nameConfigOrCallback - A friendly name for the key or a lambda that configures a
2892
+ * default resolution for the dependency.
2893
+ * @param configuror - If a friendly name was provided for the first parameter, then an optional
2894
+ * lambda that configures a default resolution for the dependency can be provided second.
2895
+ * @returns The created key.
2896
+ * @remarks
2897
+ * The created key can be used as a property decorator or constructor parameter decorator,
2898
+ * in addition to its standard use in an inject array or through direct container APIs.
2899
+ */
2900
+ createInterface(nameConfigOrCallback, configuror) {
2901
+ const configure = typeof nameConfigOrCallback === "function"
2902
+ ? nameConfigOrCallback
2903
+ : configuror;
2904
+ const friendlyName = typeof nameConfigOrCallback === "string"
2905
+ ? nameConfigOrCallback
2906
+ : nameConfigOrCallback && "friendlyName" in nameConfigOrCallback
2907
+ ? nameConfigOrCallback.friendlyName || defaultFriendlyName
2908
+ : defaultFriendlyName;
2909
+ const respectConnection = typeof nameConfigOrCallback === "string"
2910
+ ? false
2911
+ : nameConfigOrCallback && "respectConnection" in nameConfigOrCallback
2912
+ ? nameConfigOrCallback.respectConnection || false
2913
+ : false;
2914
+ const Interface = function (target, property, index) {
2915
+ if (target == null || new.target !== undefined) {
2916
+ throw new Error(`No registration for interface: '${Interface.friendlyName}'`);
2917
+ }
2918
+ if (property) {
2919
+ DI.defineProperty(target, property, Interface, respectConnection);
2920
+ }
2921
+ else {
2922
+ const annotationParamtypes = DI.getOrCreateAnnotationParamTypes(target);
2923
+ annotationParamtypes[index] = Interface;
2924
+ }
2925
+ };
2926
+ Interface.$isInterface = true;
2927
+ Interface.friendlyName = friendlyName == null ? "(anonymous)" : friendlyName;
2928
+ if (configure != null) {
2929
+ Interface.register = function (container, key) {
2930
+ return configure(new ResolverBuilder(container, key !== null && key !== void 0 ? key : Interface));
2931
+ };
2932
+ }
2933
+ Interface.toString = function toString() {
2934
+ return `InterfaceSymbol<${Interface.friendlyName}>`;
2935
+ };
2936
+ return Interface;
2937
+ },
2938
+ /**
2939
+ * A decorator that specifies what to inject into its target.
2940
+ * @param dependencies - The dependencies to inject.
2941
+ * @returns The decorator to be applied to the target class.
2942
+ * @remarks
2943
+ * The decorator can be used to decorate a class, listing all of the classes dependencies.
2944
+ * Or it can be used to decorate a constructor paramter, indicating what to inject for that
2945
+ * parameter.
2946
+ * Or it can be used for a web component property, indicating what that property should resolve to.
2947
+ */
2948
+ inject(...dependencies) {
2949
+ return function (target, key, descriptor) {
2950
+ if (typeof descriptor === "number") {
2951
+ // It's a parameter decorator.
2952
+ const annotationParamtypes = DI.getOrCreateAnnotationParamTypes(target);
2953
+ const dep = dependencies[0];
2954
+ if (dep !== void 0) {
2955
+ annotationParamtypes[descriptor] = dep;
2956
+ }
2957
+ }
2958
+ else if (key) {
2959
+ DI.defineProperty(target, key, dependencies[0]);
2960
+ }
2961
+ else {
2962
+ const annotationParamtypes = descriptor
2963
+ ? DI.getOrCreateAnnotationParamTypes(descriptor.value)
2964
+ : DI.getOrCreateAnnotationParamTypes(target);
2965
+ let dep;
2966
+ for (let i = 0; i < dependencies.length; ++i) {
2967
+ dep = dependencies[i];
2968
+ if (dep !== void 0) {
2969
+ annotationParamtypes[i] = dep;
2970
+ }
2971
+ }
2972
+ }
2973
+ };
2974
+ },
2975
+ /**
2976
+ * Registers the `target` class as a transient dependency; each time the dependency is resolved
2977
+ * a new instance will be created.
2978
+ *
2979
+ * @param target - The class / constructor function to register as transient.
2980
+ * @returns The same class, with a static `register` method that takes a container and returns the appropriate resolver.
2981
+ *
2982
+ * @example
2983
+ * On an existing class
2984
+ * ```ts
2985
+ * class Foo { }
2986
+ * DI.transient(Foo);
2987
+ * ```
2988
+ *
2989
+ * @example
2990
+ * Inline declaration
2991
+ *
2992
+ * ```ts
2993
+ * const Foo = DI.transient(class { });
2994
+ * // Foo is now strongly typed with register
2995
+ * Foo.register(container);
2996
+ * ```
2997
+ *
2998
+ * @public
2999
+ */
3000
+ transient(target) {
3001
+ target.register = function register(container) {
3002
+ const registration = Registration.transient(target, target);
3003
+ return registration.register(container);
3004
+ };
3005
+ target.registerInRequestor = false;
3006
+ return target;
3007
+ },
3008
+ /**
3009
+ * Registers the `target` class as a singleton dependency; the class will only be created once. Each
3010
+ * consecutive time the dependency is resolved, the same instance will be returned.
3011
+ *
3012
+ * @param target - The class / constructor function to register as a singleton.
3013
+ * @returns The same class, with a static `register` method that takes a container and returns the appropriate resolver.
3014
+ * @example
3015
+ * On an existing class
3016
+ * ```ts
3017
+ * class Foo { }
3018
+ * DI.singleton(Foo);
3019
+ * ```
3020
+ *
3021
+ * @example
3022
+ * Inline declaration
3023
+ * ```ts
3024
+ * const Foo = DI.singleton(class { });
3025
+ * // Foo is now strongly typed with register
3026
+ * Foo.register(container);
3027
+ * ```
3028
+ *
3029
+ * @public
3030
+ */
3031
+ singleton(target, options = defaultSingletonOptions) {
3032
+ target.register = function register(container) {
3033
+ const registration = Registration.singleton(target, target);
3034
+ return registration.register(container);
3035
+ };
3036
+ target.registerInRequestor = options.scoped;
3037
+ return target;
3038
+ },
3039
+ });
3040
+ /**
3041
+ * The interface key that resolves the dependency injection container itself.
3042
+ * @public
3043
+ */
3044
+ const Container = DI.createInterface("Container");
3045
+ /**
3046
+ * A decorator that specifies what to inject into its target.
3047
+ * @param dependencies - The dependencies to inject.
3048
+ * @returns The decorator to be applied to the target class.
3049
+ * @remarks
3050
+ * The decorator can be used to decorate a class, listing all of the classes dependencies.
3051
+ * Or it can be used to decorate a constructor paramter, indicating what to inject for that
3052
+ * parameter.
3053
+ * Or it can be used for a web component property, indicating what that property should resolve to.
3054
+ *
3055
+ * @public
3056
+ */
3057
+ DI.inject;
3058
+ const defaultSingletonOptions = { scoped: false };
3059
+ /** @internal */
3060
+ class ResolverImpl {
3061
+ constructor(key, strategy, state) {
3062
+ this.key = key;
3063
+ this.strategy = strategy;
3064
+ this.state = state;
3065
+ this.resolving = false;
3066
+ }
3067
+ get $isResolver() {
3068
+ return true;
3069
+ }
3070
+ register(container) {
3071
+ return container.registerResolver(this.key, this);
3072
+ }
3073
+ resolve(handler, requestor) {
3074
+ switch (this.strategy) {
3075
+ case 0 /* instance */:
3076
+ return this.state;
3077
+ case 1 /* singleton */: {
3078
+ if (this.resolving) {
3079
+ throw new Error(`Cyclic dependency found: ${this.state.name}`);
3080
+ }
3081
+ this.resolving = true;
3082
+ this.state = handler
3083
+ .getFactory(this.state)
3084
+ .construct(requestor);
3085
+ this.strategy = 0 /* instance */;
3086
+ this.resolving = false;
3087
+ return this.state;
3088
+ }
3089
+ case 2 /* transient */: {
3090
+ // Always create transients from the requesting container
3091
+ const factory = handler.getFactory(this.state);
3092
+ if (factory === null) {
3093
+ throw new Error(`Resolver for ${String(this.key)} returned a null factory`);
3094
+ }
3095
+ return factory.construct(requestor);
3096
+ }
3097
+ case 3 /* callback */:
3098
+ return this.state(handler, requestor, this);
3099
+ case 4 /* array */:
3100
+ return this.state[0].resolve(handler, requestor);
3101
+ case 5 /* alias */:
3102
+ return requestor.get(this.state);
3103
+ default:
3104
+ throw new Error(`Invalid resolver strategy specified: ${this.strategy}.`);
3105
+ }
3106
+ }
3107
+ getFactory(container) {
3108
+ var _a, _b, _c;
3109
+ switch (this.strategy) {
3110
+ case 1 /* singleton */:
3111
+ case 2 /* transient */:
3112
+ return container.getFactory(this.state);
3113
+ case 5 /* alias */:
3114
+ return (_c = (_b = (_a = container.getResolver(this.state)) === null || _a === void 0 ? void 0 : _a.getFactory) === null || _b === void 0 ? void 0 : _b.call(_a, container)) !== null && _c !== void 0 ? _c : null;
3115
+ default:
3116
+ return null;
3117
+ }
3118
+ }
3119
+ }
3120
+ function containerGetKey(d) {
3121
+ return this.get(d);
3122
+ }
3123
+ function transformInstance(inst, transform) {
3124
+ return transform(inst);
3125
+ }
3126
+ /** @internal */
3127
+ class FactoryImpl {
3128
+ constructor(Type, dependencies) {
3129
+ this.Type = Type;
3130
+ this.dependencies = dependencies;
3131
+ this.transformers = null;
3132
+ }
3133
+ construct(container, dynamicDependencies) {
3134
+ let instance;
3135
+ if (dynamicDependencies === void 0) {
3136
+ instance = new this.Type(...this.dependencies.map(containerGetKey, container));
3137
+ }
3138
+ else {
3139
+ instance = new this.Type(...this.dependencies.map(containerGetKey, container), ...dynamicDependencies);
3140
+ }
3141
+ if (this.transformers == null) {
3142
+ return instance;
3143
+ }
3144
+ return this.transformers.reduce(transformInstance, instance);
3145
+ }
3146
+ registerTransformer(transformer) {
3147
+ (this.transformers || (this.transformers = [])).push(transformer);
3148
+ }
3149
+ }
3150
+ const containerResolver = {
3151
+ $isResolver: true,
3152
+ resolve(handler, requestor) {
3153
+ return requestor;
3154
+ },
3155
+ };
3156
+ function isRegistry(obj) {
3157
+ return typeof obj.register === "function";
3158
+ }
3159
+ function isSelfRegistry(obj) {
3160
+ return isRegistry(obj) && typeof obj.registerInRequestor === "boolean";
3161
+ }
3162
+ function isRegisterInRequester(obj) {
3163
+ return isSelfRegistry(obj) && obj.registerInRequestor;
3164
+ }
3165
+ function isClass(obj) {
3166
+ return obj.prototype !== void 0;
3167
+ }
3168
+ const InstrinsicTypeNames = new Set([
3169
+ "Array",
3170
+ "ArrayBuffer",
3171
+ "Boolean",
3172
+ "DataView",
3173
+ "Date",
3174
+ "Error",
3175
+ "EvalError",
3176
+ "Float32Array",
3177
+ "Float64Array",
3178
+ "Function",
3179
+ "Int8Array",
3180
+ "Int16Array",
3181
+ "Int32Array",
3182
+ "Map",
3183
+ "Number",
3184
+ "Object",
3185
+ "Promise",
3186
+ "RangeError",
3187
+ "ReferenceError",
3188
+ "RegExp",
3189
+ "Set",
3190
+ "SharedArrayBuffer",
3191
+ "String",
3192
+ "SyntaxError",
3193
+ "TypeError",
3194
+ "Uint8Array",
3195
+ "Uint8ClampedArray",
3196
+ "Uint16Array",
3197
+ "Uint32Array",
3198
+ "URIError",
3199
+ "WeakMap",
3200
+ "WeakSet",
3201
+ ]);
3202
+ const DILocateParentEventType = "__DI_LOCATE_PARENT__";
3203
+ const factories = new Map();
3204
+ /**
3205
+ * @internal
3206
+ */
3207
+ class ContainerImpl {
3208
+ constructor(owner, config) {
3209
+ this.owner = owner;
3210
+ this.config = config;
3211
+ this._parent = void 0;
3212
+ this.registerDepth = 0;
3213
+ this.context = null;
3214
+ if (owner !== null) {
3215
+ owner.$$container$$ = this;
3216
+ }
3217
+ this.resolvers = new Map();
3218
+ this.resolvers.set(Container, containerResolver);
3219
+ if (owner instanceof Node) {
3220
+ owner.addEventListener(DILocateParentEventType, (e) => {
3221
+ if (e.composedPath()[0] !== this.owner) {
3222
+ e.detail.container = this;
3223
+ e.stopImmediatePropagation();
3224
+ }
3225
+ });
3226
+ }
3227
+ }
3228
+ get parent() {
3229
+ if (this._parent === void 0) {
3230
+ this._parent = this.config.parentLocator(this.owner);
3231
+ }
3232
+ return this._parent;
3233
+ }
3234
+ get depth() {
3235
+ return this.parent === null ? 0 : this.parent.depth + 1;
3236
+ }
3237
+ get responsibleForOwnerRequests() {
3238
+ return this.config.responsibleForOwnerRequests;
3239
+ }
3240
+ registerWithContext(context, ...params) {
3241
+ this.context = context;
3242
+ this.register(...params);
3243
+ this.context = null;
3244
+ return this;
3245
+ }
3246
+ register(...params) {
3247
+ if (++this.registerDepth === 100) {
3248
+ throw new Error("Unable to autoregister dependency");
3249
+ // Most likely cause is trying to register a plain object that does not have a
3250
+ // register method and is not a class constructor
3251
+ }
3252
+ let current;
3253
+ let keys;
3254
+ let value;
3255
+ let j;
3256
+ let jj;
3257
+ const context = this.context;
3258
+ for (let i = 0, ii = params.length; i < ii; ++i) {
3259
+ current = params[i];
3260
+ if (!isObject(current)) {
3261
+ continue;
3262
+ }
3263
+ if (isRegistry(current)) {
3264
+ current.register(this, context);
3265
+ }
3266
+ else if (isClass(current)) {
3267
+ Registration.singleton(current, current).register(this);
3268
+ }
3269
+ else {
3270
+ keys = Object.keys(current);
3271
+ j = 0;
3272
+ jj = keys.length;
3273
+ for (; j < jj; ++j) {
3274
+ value = current[keys[j]];
3275
+ if (!isObject(value)) {
3276
+ continue;
3277
+ }
3278
+ // note: we could remove this if-branch and call this.register directly
3279
+ // - the extra check is just a perf tweak to create fewer unnecessary arrays by the spread operator
3280
+ if (isRegistry(value)) {
3281
+ value.register(this, context);
3282
+ }
3283
+ else {
3284
+ this.register(value);
3285
+ }
3286
+ }
3287
+ }
3288
+ }
3289
+ --this.registerDepth;
3290
+ return this;
3291
+ }
3292
+ registerResolver(key, resolver) {
3293
+ validateKey(key);
3294
+ const resolvers = this.resolvers;
3295
+ const result = resolvers.get(key);
3296
+ if (result == null) {
3297
+ resolvers.set(key, resolver);
3298
+ }
3299
+ else if (result instanceof ResolverImpl &&
3300
+ result.strategy === 4 /* array */) {
3301
+ result.state.push(resolver);
3302
+ }
3303
+ else {
3304
+ resolvers.set(key, new ResolverImpl(key, 4 /* array */, [result, resolver]));
3305
+ }
3306
+ return resolver;
3307
+ }
3308
+ registerTransformer(key, transformer) {
3309
+ const resolver = this.getResolver(key);
3310
+ if (resolver == null) {
3311
+ return false;
3312
+ }
3313
+ if (resolver.getFactory) {
3314
+ const factory = resolver.getFactory(this);
3315
+ if (factory == null) {
3316
+ return false;
3317
+ }
3318
+ // This type cast is a bit of a hacky one, necessary due to the duplicity of IResolverLike.
3319
+ // Problem is that that interface's type arg can be of type Key, but the getFactory method only works on
3320
+ // type Constructable. So the return type of that optional method has this additional constraint, which
3321
+ // seems to confuse the type checker.
3322
+ factory.registerTransformer(transformer);
3323
+ return true;
3324
+ }
3325
+ return false;
3326
+ }
3327
+ getResolver(key, autoRegister = true) {
3328
+ validateKey(key);
3329
+ if (key.resolve !== void 0) {
3330
+ return key;
3331
+ }
3332
+ /* eslint-disable-next-line @typescript-eslint/no-this-alias */
3333
+ let current = this;
3334
+ let resolver;
3335
+ while (current != null) {
3336
+ resolver = current.resolvers.get(key);
3337
+ if (resolver == null) {
3338
+ if (current.parent == null) {
3339
+ const handler = isRegisterInRequester(key)
3340
+ ? this
3341
+ : current;
3342
+ return autoRegister ? this.jitRegister(key, handler) : null;
3343
+ }
3344
+ current = current.parent;
3345
+ }
3346
+ else {
3347
+ return resolver;
3348
+ }
3349
+ }
3350
+ return null;
3351
+ }
3352
+ has(key, searchAncestors = false) {
3353
+ return this.resolvers.has(key)
3354
+ ? true
3355
+ : searchAncestors && this.parent != null
3356
+ ? this.parent.has(key, true)
3357
+ : false;
3358
+ }
3359
+ get(key) {
3360
+ validateKey(key);
3361
+ if (key.$isResolver) {
3362
+ return key.resolve(this, this);
3363
+ }
3364
+ /* eslint-disable-next-line @typescript-eslint/no-this-alias */
3365
+ let current = this;
3366
+ let resolver;
3367
+ while (current != null) {
3368
+ resolver = current.resolvers.get(key);
3369
+ if (resolver == null) {
3370
+ if (current.parent == null) {
3371
+ const handler = isRegisterInRequester(key)
3372
+ ? this
3373
+ : current;
3374
+ resolver = this.jitRegister(key, handler);
3375
+ return resolver.resolve(current, this);
3376
+ }
3377
+ current = current.parent;
3378
+ }
3379
+ else {
3380
+ return resolver.resolve(current, this);
3381
+ }
3382
+ }
3383
+ throw new Error(`Unable to resolve key: ${key}`);
3384
+ }
3385
+ getAll(key, searchAncestors = false) {
3386
+ validateKey(key);
3387
+ /* eslint-disable-next-line @typescript-eslint/no-this-alias */
3388
+ const requestor = this;
3389
+ let current = requestor;
3390
+ let resolver;
3391
+ if (searchAncestors) {
3392
+ let resolutions = emptyArray;
3393
+ while (current != null) {
3394
+ resolver = current.resolvers.get(key);
3395
+ if (resolver != null) {
3396
+ resolutions = resolutions.concat(
3397
+ /* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */
3398
+ buildAllResponse(resolver, current, requestor));
3399
+ }
3400
+ current = current.parent;
3401
+ }
3402
+ return resolutions;
3403
+ }
3404
+ else {
3405
+ while (current != null) {
3406
+ resolver = current.resolvers.get(key);
3407
+ if (resolver == null) {
3408
+ current = current.parent;
3409
+ if (current == null) {
3410
+ return emptyArray;
3411
+ }
3412
+ }
3413
+ else {
3414
+ return buildAllResponse(resolver, current, requestor);
3415
+ }
3416
+ }
3417
+ }
3418
+ return emptyArray;
3419
+ }
3420
+ getFactory(Type) {
3421
+ let factory = factories.get(Type);
3422
+ if (factory === void 0) {
3423
+ if (isNativeFunction(Type)) {
3424
+ throw new Error(`${Type.name} is a native function and therefore cannot be safely constructed by DI. If this is intentional, please use a callback or cachedCallback resolver.`);
3425
+ }
3426
+ factories.set(Type, (factory = new FactoryImpl(Type, DI.getDependencies(Type))));
3427
+ }
3428
+ return factory;
3429
+ }
3430
+ registerFactory(key, factory) {
3431
+ factories.set(key, factory);
3432
+ }
3433
+ createChild(config) {
3434
+ return new ContainerImpl(null, Object.assign({}, this.config, config, { parentLocator: () => this }));
3435
+ }
3436
+ jitRegister(keyAsValue, handler) {
3437
+ if (typeof keyAsValue !== "function") {
3438
+ throw new Error(`Attempted to jitRegister something that is not a constructor: '${keyAsValue}'. Did you forget to register this dependency?`);
3439
+ }
3440
+ if (InstrinsicTypeNames.has(keyAsValue.name)) {
3441
+ throw new Error(`Attempted to jitRegister an intrinsic type: ${keyAsValue.name}. Did you forget to add @inject(Key)`);
3442
+ }
3443
+ if (isRegistry(keyAsValue)) {
3444
+ const registrationResolver = keyAsValue.register(handler);
3445
+ if (!(registrationResolver instanceof Object) ||
3446
+ registrationResolver.resolve == null) {
3447
+ const newResolver = handler.resolvers.get(keyAsValue);
3448
+ if (newResolver != void 0) {
3449
+ return newResolver;
3450
+ }
3451
+ throw new Error("A valid resolver was not returned from the static register method");
3452
+ }
3453
+ return registrationResolver;
3454
+ }
3455
+ else if (keyAsValue.$isInterface) {
3456
+ throw new Error(`Attempted to jitRegister an interface: ${keyAsValue.friendlyName}`);
3457
+ }
3458
+ else {
3459
+ const resolver = this.config.defaultResolver(keyAsValue, handler);
3460
+ handler.resolvers.set(keyAsValue, resolver);
3461
+ return resolver;
3462
+ }
3463
+ }
3464
+ }
3465
+ const cache = new WeakMap();
3466
+ function cacheCallbackResult(fun) {
3467
+ return function (handler, requestor, resolver) {
3468
+ if (cache.has(resolver)) {
3469
+ return cache.get(resolver);
3470
+ }
3471
+ const t = fun(handler, requestor, resolver);
3472
+ cache.set(resolver, t);
3473
+ return t;
3474
+ };
3475
+ }
3476
+ /**
3477
+ * You can use the resulting Registration of any of the factory methods
3478
+ * to register with the container.
3479
+ *
3480
+ * @example
3481
+ * ```
3482
+ * class Foo {}
3483
+ * const container = DI.createContainer();
3484
+ * container.register(Registration.instance(Foo, new Foo()));
3485
+ * container.get(Foo);
3486
+ * ```
3487
+ *
3488
+ * @public
3489
+ */
3490
+ const Registration = Object.freeze({
3491
+ /**
3492
+ * Allows you to pass an instance.
3493
+ * Every time you request this {@link Key} you will get this instance back.
3494
+ *
3495
+ * @example
3496
+ * ```
3497
+ * Registration.instance(Foo, new Foo()));
3498
+ * ```
3499
+ *
3500
+ * @param key - The key to register the instance under.
3501
+ * @param value - The instance to return when the key is requested.
3502
+ */
3503
+ instance(key, value) {
3504
+ return new ResolverImpl(key, 0 /* instance */, value);
3505
+ },
3506
+ /**
3507
+ * Creates an instance from the class.
3508
+ * Every time you request this {@link Key} you will get the same one back.
3509
+ *
3510
+ * @example
3511
+ * ```
3512
+ * Registration.singleton(Foo, Foo);
3513
+ * ```
3514
+ *
3515
+ * @param key - The key to register the singleton under.
3516
+ * @param value - The class to instantiate as a singleton when first requested.
3517
+ */
3518
+ singleton(key, value) {
3519
+ return new ResolverImpl(key, 1 /* singleton */, value);
3520
+ },
3521
+ /**
3522
+ * Creates an instance from a class.
3523
+ * Every time you request this {@link Key} you will get a new instance.
3524
+ *
3525
+ * @example
3526
+ * ```
3527
+ * Registration.instance(Foo, Foo);
3528
+ * ```
3529
+ *
3530
+ * @param key - The key to register the instance type under.
3531
+ * @param value - The class to instantiate each time the key is requested.
3532
+ */
3533
+ transient(key, value) {
3534
+ return new ResolverImpl(key, 2 /* transient */, value);
3535
+ },
3536
+ /**
3537
+ * Delegates to a callback function to provide the dependency.
3538
+ * Every time you request this {@link Key} the callback will be invoked to provide
3539
+ * the dependency.
3540
+ *
3541
+ * @example
3542
+ * ```
3543
+ * Registration.callback(Foo, () => new Foo());
3544
+ * Registration.callback(Bar, (c: Container) => new Bar(c.get(Foo)));
3545
+ * ```
3546
+ *
3547
+ * @param key - The key to register the callback for.
3548
+ * @param callback - The function that is expected to return the dependency.
3549
+ */
3550
+ callback(key, callback) {
3551
+ return new ResolverImpl(key, 3 /* callback */, callback);
3552
+ },
3553
+ /**
3554
+ * Delegates to a callback function to provide the dependency and then caches the
3555
+ * dependency for future requests.
3556
+ *
3557
+ * @example
3558
+ * ```
3559
+ * Registration.cachedCallback(Foo, () => new Foo());
3560
+ * Registration.cachedCallback(Bar, (c: Container) => new Bar(c.get(Foo)));
3561
+ * ```
3562
+ *
3563
+ * @param key - The key to register the callback for.
3564
+ * @param callback - The function that is expected to return the dependency.
3565
+ * @remarks
3566
+ * If you pass the same Registration to another container, the same cached value will be used.
3567
+ * Should all references to the resolver returned be removed, the cache will expire.
3568
+ */
3569
+ cachedCallback(key, callback) {
3570
+ return new ResolverImpl(key, 3 /* callback */, cacheCallbackResult(callback));
3571
+ },
3572
+ /**
3573
+ * Creates an alternate {@link Key} to retrieve an instance by.
3574
+ *
3575
+ * @example
3576
+ * ```
3577
+ * Register.singleton(Foo, Foo)
3578
+ * Register.aliasTo(Foo, MyFoos);
3579
+ *
3580
+ * container.getAll(MyFoos) // contains an instance of Foo
3581
+ * ```
3582
+ *
3583
+ * @param originalKey - The original key that has been registered.
3584
+ * @param aliasKey - The alias to the original key.
3585
+ */
3586
+ aliasTo(originalKey, aliasKey) {
3587
+ return new ResolverImpl(aliasKey, 5 /* alias */, originalKey);
3588
+ },
3589
+ });
3590
+ /** @internal */
3591
+ function validateKey(key) {
3592
+ if (key === null || key === void 0) {
3593
+ throw new Error("key/value cannot be null or undefined. Are you trying to inject/register something that doesn't exist with DI?");
3594
+ }
3595
+ }
3596
+ function buildAllResponse(resolver, handler, requestor) {
3597
+ if (resolver instanceof ResolverImpl &&
3598
+ resolver.strategy === 4 /* array */) {
3599
+ const state = resolver.state;
3600
+ let i = state.length;
3601
+ const results = new Array(i);
3602
+ while (i--) {
3603
+ results[i] = state[i].resolve(handler, requestor);
3604
+ }
3605
+ return results;
3606
+ }
3607
+ return [resolver.resolve(handler, requestor)];
3608
+ }
3609
+ const defaultFriendlyName = "(anonymous)";
3610
+ function isObject(value) {
3611
+ return (typeof value === "object" && value !== null) || typeof value === "function";
3612
+ }
3613
+ /**
3614
+ * Determine whether the value is a native function.
3615
+ *
3616
+ * @param fn - The function to check.
3617
+ * @returns `true` is the function is a native function, otherwise `false`
3618
+ */
3619
+ const isNativeFunction = (function () {
3620
+ const lookup = new WeakMap();
3621
+ let isNative = false;
3622
+ let sourceText = "";
3623
+ let i = 0;
3624
+ return function (fn) {
3625
+ isNative = lookup.get(fn);
3626
+ if (isNative === void 0) {
3627
+ sourceText = fn.toString();
3628
+ i = sourceText.length;
3629
+ // http://www.ecma-international.org/ecma-262/#prod-NativeFunction
3630
+ isNative =
3631
+ // 29 is the length of 'function () { [native code] }' which is the smallest length of a native function string
3632
+ i >= 29 &&
3633
+ // 100 seems to be a safe upper bound of the max length of a native function. In Chrome and FF it's 56, in Edge it's 61.
3634
+ i <= 100 &&
3635
+ // This whole heuristic *could* be tricked by a comment. Do we need to care about that?
3636
+ sourceText.charCodeAt(i - 1) === 0x7d && // }
3637
+ // TODO: the spec is a little vague about the precise constraints, so we do need to test this across various browsers to make sure just one whitespace is a safe assumption.
3638
+ sourceText.charCodeAt(i - 2) <= 0x20 && // whitespace
3639
+ sourceText.charCodeAt(i - 3) === 0x5d && // ]
3640
+ sourceText.charCodeAt(i - 4) === 0x65 && // e
3641
+ sourceText.charCodeAt(i - 5) === 0x64 && // d
3642
+ sourceText.charCodeAt(i - 6) === 0x6f && // o
3643
+ sourceText.charCodeAt(i - 7) === 0x63 && // c
3644
+ sourceText.charCodeAt(i - 8) === 0x20 && //
3645
+ sourceText.charCodeAt(i - 9) === 0x65 && // e
3646
+ sourceText.charCodeAt(i - 10) === 0x76 && // v
3647
+ sourceText.charCodeAt(i - 11) === 0x69 && // i
3648
+ sourceText.charCodeAt(i - 12) === 0x74 && // t
3649
+ sourceText.charCodeAt(i - 13) === 0x61 && // a
3650
+ sourceText.charCodeAt(i - 14) === 0x6e && // n
3651
+ sourceText.charCodeAt(i - 15) === 0x58; // [
3652
+ lookup.set(fn, isNative);
3653
+ }
3654
+ return isNative;
3655
+ };
3656
+ })();
3657
+ const isNumericLookup = {};
3658
+ function isArrayIndex(value) {
3659
+ switch (typeof value) {
3660
+ case "number":
3661
+ return value >= 0 && (value | 0) === value;
3662
+ case "string": {
3663
+ const result = isNumericLookup[value];
3664
+ if (result !== void 0) {
3665
+ return result;
3666
+ }
3667
+ const length = value.length;
3668
+ if (length === 0) {
3669
+ return (isNumericLookup[value] = false);
3670
+ }
3671
+ let ch = 0;
3672
+ for (let i = 0; i < length; ++i) {
3673
+ ch = value.charCodeAt(i);
3674
+ if ((i === 0 && ch === 0x30 && length > 1) /* must not start with 0 */ ||
3675
+ ch < 0x30 /* 0 */ ||
3676
+ ch > 0x39 /* 9 */) {
3677
+ return (isNumericLookup[value] = false);
3678
+ }
3679
+ }
3680
+ return (isNumericLookup[value] = true);
3681
+ }
3682
+ default:
3683
+ return false;
3684
+ }
3685
+ }
3686
+
3687
+ function presentationKeyFromTag(tagName) {
3688
+ return `${tagName.toLowerCase()}:presentation`;
3689
+ }
3690
+ const presentationRegistry = new Map();
3691
+ /**
3692
+ * An API gateway to component presentation features.
3693
+ * @public
3694
+ */
3695
+ const ComponentPresentation = Object.freeze({
3696
+ /**
3697
+ * Defines a component presentation for an element.
3698
+ * @param tagName - The element name to define the presentation for.
3699
+ * @param presentation - The presentation that will be applied to matching elements.
3700
+ * @param container - The dependency injection container to register the configuration in.
3701
+ * @public
3702
+ */
3703
+ define(tagName, presentation, container) {
3704
+ const key = presentationKeyFromTag(tagName);
3705
+ const existing = presentationRegistry.get(key);
3706
+ if (existing === void 0) {
3707
+ presentationRegistry.set(key, presentation);
3708
+ }
3709
+ else {
3710
+ // false indicates that we have more than one presentation
3711
+ // registered for a tagName and we must resolve through DI
3712
+ presentationRegistry.set(key, false);
3713
+ }
3714
+ container.register(Registration.instance(key, presentation));
3715
+ },
3716
+ /**
3717
+ * Finds a component presentation for the specified element name,
3718
+ * searching the DOM hierarchy starting from the provided element.
3719
+ * @param tagName - The name of the element to locate the presentation for.
3720
+ * @param element - The element to begin the search from.
3721
+ * @returns The component presentation or null if none is found.
3722
+ * @public
3723
+ */
3724
+ forTag(tagName, element) {
3725
+ const key = presentationKeyFromTag(tagName);
3726
+ const existing = presentationRegistry.get(key);
3727
+ if (existing === false) {
3728
+ const container = DI.findResponsibleContainer(element);
3729
+ return container.get(key);
3730
+ }
3731
+ return existing || null;
3732
+ },
3733
+ });
3734
+ /**
3735
+ * The default implementation of ComponentPresentation, used by FoundationElement.
3736
+ * @public
3737
+ */
3738
+ class DefaultComponentPresentation {
3739
+ /**
3740
+ * Creates an instance of DefaultComponentPresentation.
3741
+ * @param template - The template to apply to the element.
3742
+ * @param styles - The styles to apply to the element.
3743
+ * @public
3744
+ */
3745
+ constructor(template, styles) {
3746
+ this.template = template || null;
3747
+ this.styles =
3748
+ styles === void 0
3749
+ ? null
3750
+ : Array.isArray(styles)
3751
+ ? ElementStyles.create(styles)
3752
+ : styles instanceof ElementStyles
3753
+ ? styles
3754
+ : ElementStyles.create([styles]);
3755
+ }
3756
+ /**
3757
+ * Applies the presentation details to the specified element.
3758
+ * @param element - The element to apply the presentation details to.
3759
+ * @public
3760
+ */
3761
+ applyTo(element) {
3762
+ const controller = element.$fastController;
3763
+ if (controller.template === null) {
3764
+ controller.template = this.template;
3765
+ }
3766
+ if (controller.styles === null) {
3767
+ controller.styles = this.styles;
3768
+ }
3769
+ }
3770
+ }
3771
+
3772
+ /**
3773
+ * Defines a foundation element class that:
3774
+ * 1. Connects the element to its ComponentPresentation
3775
+ * 2. Allows resolving the element template from the instance or ComponentPresentation
3776
+ * 3. Allows resolving the element styles from the instance or ComponentPresentation
3777
+ *
3778
+ * @public
3779
+ */
3780
+ class FoundationElement extends FASTElement {
3781
+ constructor() {
3782
+ super(...arguments);
3783
+ this._presentation = void 0;
3784
+ }
3785
+ /**
3786
+ * A property which resolves the ComponentPresentation instance
3787
+ * for the current component.
3788
+ * @public
3789
+ */
3790
+ get $presentation() {
3791
+ if (this._presentation === void 0) {
3792
+ this._presentation = ComponentPresentation.forTag(this.tagName, this);
3793
+ }
3794
+ return this._presentation;
3795
+ }
3796
+ templateChanged() {
3797
+ if (this.template !== undefined) {
3798
+ this.$fastController.template = this.template;
3799
+ }
3800
+ }
3801
+ stylesChanged() {
3802
+ if (this.styles !== undefined) {
3803
+ this.$fastController.styles = this.styles;
3804
+ }
3805
+ }
3806
+ /**
3807
+ * The connected callback for this FASTElement.
3808
+ * @remarks
3809
+ * This method is invoked by the platform whenever this FoundationElement
3810
+ * becomes connected to the document.
3811
+ * @public
3812
+ */
3813
+ connectedCallback() {
3814
+ if (this.$presentation !== null) {
3815
+ this.$presentation.applyTo(this);
3816
+ }
3817
+ super.connectedCallback();
3818
+ }
3819
+ /**
3820
+ * Defines an element registry function with a set of element definition defaults.
3821
+ * @param elementDefinition - The definition of the element to create the registry
3822
+ * function for.
3823
+ * @public
3824
+ */
3825
+ static compose(elementDefinition) {
3826
+ return (overrideDefinition = {}) => new FoundationElementRegistry(this === FoundationElement
3827
+ ? class extends FoundationElement {
3828
+ }
3829
+ : this, elementDefinition, overrideDefinition);
3830
+ }
3831
+ }
3832
+ __decorate([
3833
+ observable
3834
+ ], FoundationElement.prototype, "template", void 0);
3835
+ __decorate([
3836
+ observable
3837
+ ], FoundationElement.prototype, "styles", void 0);
3838
+ function resolveOption(option, context, definition) {
3839
+ if (typeof option === "function") {
3840
+ return option(context, definition);
3841
+ }
3842
+ return option;
3843
+ }
3844
+ /**
3845
+ * Registry capable of defining presentation properties for a DOM Container hierarchy.
3846
+ *
3847
+ * @internal
3848
+ */
3849
+ /* eslint-disable @typescript-eslint/no-unused-vars */
3850
+ class FoundationElementRegistry {
3851
+ constructor(type, elementDefinition, overrideDefinition) {
3852
+ this.type = type;
3853
+ this.elementDefinition = elementDefinition;
3854
+ this.overrideDefinition = overrideDefinition;
3855
+ this.definition = Object.assign(Object.assign({}, this.elementDefinition), this.overrideDefinition);
3856
+ }
3857
+ register(container, context) {
3858
+ const definition = this.definition;
3859
+ const overrideDefinition = this.overrideDefinition;
3860
+ const prefix = definition.prefix || context.elementPrefix;
3861
+ const name = `${prefix}-${definition.baseName}`;
3862
+ context.tryDefineElement({
3863
+ name,
3864
+ type: this.type,
3865
+ baseClass: this.elementDefinition.baseClass,
3866
+ callback: x => {
3867
+ const presentation = new DefaultComponentPresentation(resolveOption(definition.template, x, definition), resolveOption(definition.styles, x, definition));
3868
+ x.definePresentation(presentation);
3869
+ let shadowOptions = resolveOption(definition.shadowOptions, x, definition);
3870
+ if (x.shadowRootMode) {
3871
+ // If the design system has overridden the shadow root mode, we need special handling.
3872
+ if (shadowOptions) {
3873
+ // If there are shadow options present in the definition, then
3874
+ // either the component itself has specified an option or the
3875
+ // registry function has overridden it.
3876
+ if (!overrideDefinition.shadowOptions) {
3877
+ // There were shadow options provided by the component and not overridden by
3878
+ // the registry.
3879
+ shadowOptions.mode = x.shadowRootMode;
3880
+ }
3881
+ }
3882
+ else if (shadowOptions !== null) {
3883
+ // If the component author did not provide shadow options,
3884
+ // and did not null them out (light dom opt-in) then they
3885
+ // were relying on the FASTElement default. So, if the
3886
+ // design system provides a mode, we need to create the options
3887
+ // to override the default.
3888
+ shadowOptions = { mode: x.shadowRootMode };
3889
+ }
3890
+ }
3891
+ x.defineElement({
3892
+ elementOptions: resolveOption(definition.elementOptions, x, definition),
3893
+ shadowOptions,
3894
+ attributes: resolveOption(definition.attributes, x, definition),
3895
+ });
3896
+ },
3897
+ });
3898
+ }
3899
+ }
3900
+ /* eslint-enable @typescript-eslint/no-unused-vars */
3901
+
3902
+ /**
3903
+ * Retrieves the "composed parent" element of a node, ignoring DOM tree boundaries.
3904
+ * When the parent of a node is a shadow-root, it will return the host
3905
+ * element of the shadow root. Otherwise it will return the parent node or null if
3906
+ * no parent node exists.
3907
+ * @param element - The element for which to retrieve the composed parent
3908
+ *
3909
+ * @public
3910
+ */
3911
+ function composedParent(element) {
3912
+ const parentNode = element.parentElement;
3913
+ if (parentNode) {
3914
+ return parentNode;
3915
+ }
3916
+ else {
3917
+ const rootNode = element.getRootNode();
3918
+ if (rootNode.host instanceof HTMLElement) {
3919
+ // this is shadow-root
3920
+ return rootNode.host;
3921
+ }
3922
+ }
3923
+ return null;
3924
+ }
3925
+
3926
+ /**
3927
+ * Determines if the reference element contains the test element in a "composed" DOM tree that
3928
+ * ignores shadow DOM boundaries.
3929
+ *
3930
+ * Returns true of the test element is a descendent of the reference, or exist in
3931
+ * a shadow DOM that is a logical descendent of the reference. Otherwise returns false.
3932
+ * @param reference - The element to test for containment against.
3933
+ * @param test - The element being tested for containment.
3934
+ *
3935
+ * @public
3936
+ */
3937
+ function composedContains(reference, test) {
3938
+ let current = test;
3939
+ while (current !== null) {
3940
+ if (current === reference) {
3941
+ return true;
3942
+ }
3943
+ current = composedParent(current);
3944
+ }
3945
+ return false;
3946
+ }
3947
+
3948
+ const defaultElement = document.createElement("div");
3949
+ function isFastElement(element) {
3950
+ return element instanceof FASTElement;
3951
+ }
3952
+ class QueuedStyleSheetTarget {
3953
+ setProperty(name, value) {
3954
+ DOM.queueUpdate(() => this.target.setProperty(name, value));
3955
+ }
3956
+ removeProperty(name) {
3957
+ DOM.queueUpdate(() => this.target.removeProperty(name));
3958
+ }
3959
+ }
3960
+ /**
3961
+ * Handles setting properties for a FASTElement using Constructable Stylesheets
3962
+ */
3963
+ class ConstructableStyleSheetTarget extends QueuedStyleSheetTarget {
3964
+ constructor(source) {
3965
+ super();
3966
+ const sheet = new CSSStyleSheet();
3967
+ this.target = sheet.cssRules[sheet.insertRule(":host{}")].style;
3968
+ source.$fastController.addStyles(ElementStyles.create([sheet]));
3969
+ }
3970
+ }
3971
+ class DocumentStyleSheetTarget extends QueuedStyleSheetTarget {
3972
+ constructor() {
3973
+ super();
3974
+ const sheet = new CSSStyleSheet();
3975
+ this.target = sheet.cssRules[sheet.insertRule(":root{}")].style;
3976
+ document.adoptedStyleSheets = [
3977
+ ...document.adoptedStyleSheets,
3978
+ sheet,
3979
+ ];
3980
+ }
3981
+ }
3982
+ class HeadStyleElementStyleSheetTarget extends QueuedStyleSheetTarget {
3983
+ constructor() {
3984
+ super();
3985
+ this.style = document.createElement("style");
3986
+ document.head.appendChild(this.style);
3987
+ const { sheet } = this.style;
3988
+ // Because the HTMLStyleElement has been appended,
3989
+ // there shouldn't exist a case where `sheet` is null,
3990
+ // but if-check it just in case.
3991
+ if (sheet) {
3992
+ // https://github.com/jsdom/jsdom uses https://github.com/NV/CSSOM for it's CSSOM implementation,
3993
+ // which implements the DOM Level 2 spec for CSSStyleSheet where insertRule() requires an index argument.
3994
+ const index = sheet.insertRule(":root{}", sheet.cssRules.length);
3995
+ this.target = sheet.cssRules[index].style;
3996
+ }
3997
+ }
3998
+ }
3999
+ /**
4000
+ * Handles setting properties for a FASTElement using an HTMLStyleElement
4001
+ */
4002
+ class StyleElementStyleSheetTarget {
4003
+ constructor(target) {
4004
+ this.store = new Map();
4005
+ this.target = null;
4006
+ const controller = target.$fastController;
4007
+ this.style = document.createElement("style");
4008
+ controller.addStyles(this.style);
4009
+ Observable.getNotifier(controller).subscribe(this, "isConnected");
4010
+ this.handleChange(controller, "isConnected");
4011
+ }
4012
+ targetChanged() {
4013
+ if (this.target !== null) {
4014
+ for (const [key, value] of this.store.entries()) {
4015
+ this.target.setProperty(key, value);
4016
+ }
4017
+ }
4018
+ }
4019
+ setProperty(name, value) {
4020
+ this.store.set(name, value);
4021
+ DOM.queueUpdate(() => {
4022
+ if (this.target !== null) {
4023
+ this.target.setProperty(name, value);
4024
+ }
4025
+ });
4026
+ }
4027
+ removeProperty(name) {
4028
+ this.store.delete(name);
4029
+ DOM.queueUpdate(() => {
4030
+ if (this.target !== null) {
4031
+ this.target.removeProperty(name);
4032
+ }
4033
+ });
4034
+ }
4035
+ handleChange(source, key) {
4036
+ // HTMLStyleElement.sheet is null if the element isn't connected to the DOM,
4037
+ // so this method reacts to changes in DOM connection for the element hosting
4038
+ // the HTMLStyleElement.
4039
+ //
4040
+ // All rules applied via the CSSOM also get cleared when the element disconnects,
4041
+ // so we need to add a new rule each time and populate it with the stored properties
4042
+ const { sheet } = this.style;
4043
+ if (sheet) {
4044
+ // Safari will throw if we try to use the return result of insertRule()
4045
+ // to index the rule inline, so store as a const prior to indexing.
4046
+ // https://github.com/jsdom/jsdom uses https://github.com/NV/CSSOM for it's CSSOM implementation,
4047
+ // which implements the DOM Level 2 spec for CSSStyleSheet where insertRule() requires an index argument.
4048
+ const index = sheet.insertRule(":host{}", sheet.cssRules.length);
4049
+ this.target = sheet.cssRules[index].style;
4050
+ }
4051
+ else {
4052
+ this.target = null;
4053
+ }
4054
+ }
4055
+ }
4056
+ __decorate([
4057
+ observable
4058
+ ], StyleElementStyleSheetTarget.prototype, "target", void 0);
4059
+ /**
4060
+ * Handles setting properties for a normal HTMLElement
4061
+ */
4062
+ class ElementStyleSheetTarget {
4063
+ constructor(source) {
4064
+ this.target = source.style;
4065
+ }
4066
+ setProperty(name, value) {
4067
+ DOM.queueUpdate(() => this.target.setProperty(name, value));
4068
+ }
4069
+ removeProperty(name) {
4070
+ DOM.queueUpdate(() => this.target.removeProperty(name));
4071
+ }
4072
+ }
4073
+ /**
4074
+ * Controls emission for default values. This control is capable
4075
+ * of emitting to multiple {@link PropertyTarget | PropertyTargets},
4076
+ * and only emits if it has at least one root.
4077
+ *
4078
+ * @internal
4079
+ */
4080
+ class RootStyleSheetTarget {
4081
+ setProperty(name, value) {
4082
+ RootStyleSheetTarget.properties[name] = value;
4083
+ for (const target of RootStyleSheetTarget.roots.values()) {
4084
+ PropertyTargetManager.getOrCreate(RootStyleSheetTarget.normalizeRoot(target)).setProperty(name, value);
4085
+ }
4086
+ }
4087
+ removeProperty(name) {
4088
+ delete RootStyleSheetTarget.properties[name];
4089
+ for (const target of RootStyleSheetTarget.roots.values()) {
4090
+ PropertyTargetManager.getOrCreate(RootStyleSheetTarget.normalizeRoot(target)).removeProperty(name);
4091
+ }
4092
+ }
4093
+ static registerRoot(root) {
4094
+ const { roots } = RootStyleSheetTarget;
4095
+ if (!roots.has(root)) {
4096
+ roots.add(root);
4097
+ const target = PropertyTargetManager.getOrCreate(this.normalizeRoot(root));
4098
+ for (const key in RootStyleSheetTarget.properties) {
4099
+ target.setProperty(key, RootStyleSheetTarget.properties[key]);
4100
+ }
4101
+ }
4102
+ }
4103
+ static unregisterRoot(root) {
4104
+ const { roots } = RootStyleSheetTarget;
4105
+ if (roots.has(root)) {
4106
+ roots.delete(root);
4107
+ const target = PropertyTargetManager.getOrCreate(RootStyleSheetTarget.normalizeRoot(root));
4108
+ for (const key in RootStyleSheetTarget.properties) {
4109
+ target.removeProperty(key);
4110
+ }
4111
+ }
4112
+ }
4113
+ /**
4114
+ * Returns the document when provided the default element,
4115
+ * otherwise is a no-op
4116
+ * @param root - the root to normalize
4117
+ */
4118
+ static normalizeRoot(root) {
4119
+ return root === defaultElement ? document : root;
4120
+ }
4121
+ }
4122
+ RootStyleSheetTarget.roots = new Set();
4123
+ RootStyleSheetTarget.properties = {};
4124
+ // Caches PropertyTarget instances
4125
+ const propertyTargetCache = new WeakMap();
4126
+ // Use Constructable StyleSheets for FAST elements when supported, otherwise use
4127
+ // HTMLStyleElement instances
4128
+ const propertyTargetCtor = DOM.supportsAdoptedStyleSheets
4129
+ ? ConstructableStyleSheetTarget
4130
+ : StyleElementStyleSheetTarget;
4131
+ /**
4132
+ * Manages creation and caching of PropertyTarget instances.
4133
+ *
4134
+ * @internal
4135
+ */
4136
+ const PropertyTargetManager = Object.freeze({
4137
+ getOrCreate(source) {
4138
+ if (propertyTargetCache.has(source)) {
4139
+ /* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */
4140
+ return propertyTargetCache.get(source);
4141
+ }
4142
+ let target;
4143
+ if (source === defaultElement) {
4144
+ target = new RootStyleSheetTarget();
4145
+ }
4146
+ else if (source instanceof Document) {
4147
+ target = DOM.supportsAdoptedStyleSheets
4148
+ ? new DocumentStyleSheetTarget()
4149
+ : new HeadStyleElementStyleSheetTarget();
4150
+ }
4151
+ else if (isFastElement(source)) {
4152
+ target = new propertyTargetCtor(source);
4153
+ }
4154
+ else {
4155
+ target = new ElementStyleSheetTarget(source);
4156
+ }
4157
+ propertyTargetCache.set(source, target);
4158
+ return target;
4159
+ },
4160
+ });
4161
+
4162
+ /**
4163
+ * Implementation of {@link (DesignToken:interface)}
4164
+ */
4165
+ class DesignTokenImpl extends CSSDirective {
4166
+ constructor(configuration) {
4167
+ super();
4168
+ this.subscribers = new WeakMap();
4169
+ this._appliedTo = new Set();
4170
+ this.name = configuration.name;
4171
+ if (configuration.cssCustomPropertyName !== null) {
4172
+ this.cssCustomProperty = `--${configuration.cssCustomPropertyName}`;
4173
+ this.cssVar = `var(${this.cssCustomProperty})`;
4174
+ }
4175
+ this.id = DesignTokenImpl.uniqueId();
4176
+ DesignTokenImpl.tokensById.set(this.id, this);
4177
+ }
4178
+ get appliedTo() {
4179
+ return [...this._appliedTo];
4180
+ }
4181
+ static from(nameOrConfig) {
4182
+ return new DesignTokenImpl({
4183
+ name: typeof nameOrConfig === "string" ? nameOrConfig : nameOrConfig.name,
4184
+ cssCustomPropertyName: typeof nameOrConfig === "string"
4185
+ ? nameOrConfig
4186
+ : nameOrConfig.cssCustomPropertyName === void 0
4187
+ ? nameOrConfig.name
4188
+ : nameOrConfig.cssCustomPropertyName,
4189
+ });
4190
+ }
4191
+ static isCSSDesignToken(token) {
4192
+ return typeof token.cssCustomProperty === "string";
4193
+ }
4194
+ static isDerivedDesignTokenValue(value) {
4195
+ return typeof value === "function";
4196
+ }
4197
+ /**
4198
+ * Gets a token by ID. Returns undefined if the token was not found.
4199
+ * @param id - The ID of the token
4200
+ * @returns
4201
+ */
4202
+ static getTokenById(id) {
4203
+ return DesignTokenImpl.tokensById.get(id);
4204
+ }
4205
+ getOrCreateSubscriberSet(target = this) {
4206
+ return (this.subscribers.get(target) ||
4207
+ (this.subscribers.set(target, new Set()) && this.subscribers.get(target)));
4208
+ }
4209
+ createCSS() {
4210
+ return this.cssVar || "";
4211
+ }
4212
+ getValueFor(element) {
4213
+ const value = DesignTokenNode.getOrCreate(element).get(this);
4214
+ if (value !== undefined) {
4215
+ return value;
4216
+ }
4217
+ throw new Error(`Value could not be retrieved for token named "${this.name}". Ensure the value is set for ${element} or an ancestor of ${element}.`);
4218
+ }
4219
+ setValueFor(element, value) {
4220
+ this._appliedTo.add(element);
4221
+ if (value instanceof DesignTokenImpl) {
4222
+ value = this.alias(value);
4223
+ }
4224
+ DesignTokenNode.getOrCreate(element).set(this, value);
4225
+ return this;
4226
+ }
4227
+ deleteValueFor(element) {
4228
+ this._appliedTo.delete(element);
4229
+ if (DesignTokenNode.existsFor(element)) {
4230
+ DesignTokenNode.getOrCreate(element).delete(this);
4231
+ }
4232
+ return this;
4233
+ }
4234
+ withDefault(value) {
4235
+ this.setValueFor(defaultElement, value);
4236
+ return this;
4237
+ }
4238
+ subscribe(subscriber, target) {
4239
+ const subscriberSet = this.getOrCreateSubscriberSet(target);
4240
+ if (target && !DesignTokenNode.existsFor(target)) {
4241
+ DesignTokenNode.getOrCreate(target);
4242
+ }
4243
+ if (!subscriberSet.has(subscriber)) {
4244
+ subscriberSet.add(subscriber);
4245
+ }
4246
+ }
4247
+ unsubscribe(subscriber, target) {
4248
+ const list = this.subscribers.get(target || this);
4249
+ if (list && list.has(subscriber)) {
4250
+ list.delete(subscriber);
4251
+ }
4252
+ }
4253
+ /**
4254
+ * Notifies subscribers that the value for an element has changed.
4255
+ * @param element - The element to emit a notification for
4256
+ */
4257
+ notify(element) {
4258
+ const record = Object.freeze({ token: this, target: element });
4259
+ if (this.subscribers.has(this)) {
4260
+ this.subscribers.get(this).forEach(sub => sub.handleChange(record));
4261
+ }
4262
+ if (this.subscribers.has(element)) {
4263
+ this.subscribers.get(element).forEach(sub => sub.handleChange(record));
4264
+ }
4265
+ }
4266
+ /**
4267
+ * Alias the token to the provided token.
4268
+ * @param token - the token to alias to
4269
+ */
4270
+ alias(token) {
4271
+ return ((target) => token.getValueFor(target));
4272
+ }
4273
+ }
4274
+ DesignTokenImpl.uniqueId = (() => {
4275
+ let id = 0;
4276
+ return () => {
4277
+ id++;
4278
+ return id.toString(16);
4279
+ };
4280
+ })();
4281
+ /**
4282
+ * Token storage by token ID
4283
+ */
4284
+ DesignTokenImpl.tokensById = new Map();
4285
+ class CustomPropertyReflector {
4286
+ startReflection(token, target) {
4287
+ token.subscribe(this, target);
4288
+ this.handleChange({ token, target });
4289
+ }
4290
+ stopReflection(token, target) {
4291
+ token.unsubscribe(this, target);
4292
+ this.remove(token, target);
4293
+ }
4294
+ handleChange(record) {
4295
+ const { token, target } = record;
4296
+ this.add(token, target);
4297
+ }
4298
+ add(token, target) {
4299
+ PropertyTargetManager.getOrCreate(target).setProperty(token.cssCustomProperty, this.resolveCSSValue(DesignTokenNode.getOrCreate(target).get(token)));
4300
+ }
4301
+ remove(token, target) {
4302
+ PropertyTargetManager.getOrCreate(target).removeProperty(token.cssCustomProperty);
4303
+ }
4304
+ resolveCSSValue(value) {
4305
+ return value && typeof value.createCSS === "function" ? value.createCSS() : value;
4306
+ }
4307
+ }
4308
+ /**
4309
+ * A light wrapper around BindingObserver to handle value caching and
4310
+ * token notification
4311
+ */
4312
+ class DesignTokenBindingObserver {
4313
+ constructor(source, token, node) {
4314
+ this.source = source;
4315
+ this.token = token;
4316
+ this.node = node;
4317
+ this.dependencies = new Set();
4318
+ this.observer = Observable.binding(source, this, false);
4319
+ // This is a little bit hacky because it's using internal APIs of BindingObserverImpl.
4320
+ // BindingObserverImpl queues updates to batch it's notifications which doesn't work for this
4321
+ // scenario because the DesignToken.getValueFor API is not async. Without this, using DesignToken.getValueFor()
4322
+ // after DesignToken.setValueFor() when setting a dependency of the value being retrieved can return a stale
4323
+ // value. Assigning .handleChange to .call forces immediate invocation of this classes handleChange() method,
4324
+ // allowing resolution of values synchronously.
4325
+ // TODO: https://github.com/microsoft/fast/issues/5110
4326
+ this.observer.handleChange = this.observer.call;
4327
+ this.handleChange();
4328
+ }
4329
+ disconnect() {
4330
+ this.observer.disconnect();
4331
+ }
4332
+ /**
4333
+ * @internal
4334
+ */
4335
+ handleChange() {
4336
+ this.node.store.set(this.token, this.observer.observe(this.node.target, defaultExecutionContext));
4337
+ }
4338
+ }
4339
+ /**
4340
+ * Stores resolved token/value pairs and notifies on changes
4341
+ */
4342
+ class Store {
4343
+ constructor() {
4344
+ this.values = new Map();
4345
+ }
4346
+ set(token, value) {
4347
+ if (this.values.get(token) !== value) {
4348
+ this.values.set(token, value);
4349
+ Observable.getNotifier(this).notify(token.id);
4350
+ }
4351
+ }
4352
+ get(token) {
4353
+ Observable.track(this, token.id);
4354
+ return this.values.get(token);
4355
+ }
4356
+ delete(token) {
4357
+ this.values.delete(token);
4358
+ }
4359
+ all() {
4360
+ return this.values.entries();
4361
+ }
4362
+ }
4363
+ const nodeCache = new WeakMap();
4364
+ const childToParent = new WeakMap();
4365
+ /**
4366
+ * A node responsible for setting and getting token values,
4367
+ * emitting values to CSS custom properties, and maintaining
4368
+ * inheritance structures.
4369
+ */
4370
+ class DesignTokenNode {
4371
+ constructor(target) {
4372
+ this.target = target;
4373
+ /**
4374
+ * Stores all resolved token values for a node
4375
+ */
4376
+ this.store = new Store();
4377
+ /**
4378
+ * All children assigned to the node
4379
+ */
4380
+ this.children = [];
4381
+ /**
4382
+ * All values explicitly assigned to the node in their raw form
4383
+ */
4384
+ this.assignedValues = new Map();
4385
+ /**
4386
+ * Tokens currently being reflected to CSS custom properties
4387
+ */
4388
+ this.reflecting = new Set();
4389
+ /**
4390
+ * Binding observers for assigned and inherited derived values.
4391
+ */
4392
+ this.bindingObservers = new Map();
4393
+ /**
4394
+ * Emits notifications to token when token values
4395
+ * change the DesignTokenNode
4396
+ */
4397
+ this.tokenValueChangeHandler = {
4398
+ handleChange: (source, arg) => {
4399
+ const token = DesignTokenImpl.getTokenById(arg);
4400
+ if (token) {
4401
+ // Notify any token subscribers
4402
+ token.notify(this.target);
4403
+ if (DesignTokenImpl.isCSSDesignToken(token)) {
4404
+ const parent = this.parent;
4405
+ const reflecting = this.isReflecting(token);
4406
+ if (parent) {
4407
+ const parentValue = parent.get(token);
4408
+ const sourceValue = source.get(token);
4409
+ if (parentValue !== sourceValue && !reflecting) {
4410
+ this.reflectToCSS(token);
4411
+ }
4412
+ else if (parentValue === sourceValue && reflecting) {
4413
+ this.stopReflectToCSS(token);
4414
+ }
4415
+ }
4416
+ else if (!reflecting) {
4417
+ this.reflectToCSS(token);
4418
+ }
4419
+ }
4420
+ }
4421
+ },
4422
+ };
4423
+ nodeCache.set(target, this);
4424
+ // Map store change notifications to token change notifications
4425
+ Observable.getNotifier(this.store).subscribe(this.tokenValueChangeHandler);
4426
+ if (target instanceof FASTElement) {
4427
+ target.$fastController.addBehaviors([this]);
4428
+ }
4429
+ else if (target.isConnected) {
4430
+ this.bind();
4431
+ }
4432
+ }
4433
+ /**
4434
+ * Returns a DesignTokenNode for an element.
4435
+ * Creates a new instance if one does not already exist for a node,
4436
+ * otherwise returns the cached instance
4437
+ *
4438
+ * @param target - The HTML element to retrieve a DesignTokenNode for
4439
+ */
4440
+ static getOrCreate(target) {
4441
+ return nodeCache.get(target) || new DesignTokenNode(target);
4442
+ }
4443
+ /**
4444
+ * Determines if a DesignTokenNode has been created for a target
4445
+ * @param target - The element to test
4446
+ */
4447
+ static existsFor(target) {
4448
+ return nodeCache.has(target);
4449
+ }
4450
+ /**
4451
+ * Searches for and return the nearest parent DesignTokenNode.
4452
+ * Null is returned if no node is found or the node provided is for a default element.
4453
+ */
4454
+ static findParent(node) {
4455
+ if (!(defaultElement === node.target)) {
4456
+ let parent = composedParent(node.target);
4457
+ while (parent !== null) {
4458
+ if (nodeCache.has(parent)) {
4459
+ return nodeCache.get(parent);
4460
+ }
4461
+ parent = composedParent(parent);
4462
+ }
4463
+ return DesignTokenNode.getOrCreate(defaultElement);
4464
+ }
4465
+ return null;
4466
+ }
4467
+ /**
4468
+ * Finds the closest node with a value explicitly assigned for a token, otherwise null.
4469
+ * @param token - The token to look for
4470
+ * @param start - The node to start looking for value assignment
4471
+ * @returns
4472
+ */
4473
+ static findClosestAssignedNode(token, start) {
4474
+ let current = start;
4475
+ do {
4476
+ if (current.has(token)) {
4477
+ return current;
4478
+ }
4479
+ current = current.parent
4480
+ ? current.parent
4481
+ : current.target !== defaultElement
4482
+ ? DesignTokenNode.getOrCreate(defaultElement)
4483
+ : null;
4484
+ } while (current !== null);
4485
+ return null;
4486
+ }
4487
+ /**
4488
+ * The parent DesignTokenNode, or null.
4489
+ */
4490
+ get parent() {
4491
+ return childToParent.get(this) || null;
4492
+ }
4493
+ /**
4494
+ * Checks if a token has been assigned an explicit value the node.
4495
+ * @param token - the token to check.
4496
+ */
4497
+ has(token) {
4498
+ return this.assignedValues.has(token);
4499
+ }
4500
+ /**
4501
+ * Gets the value of a token for a node
4502
+ * @param token - The token to retrieve the value for
4503
+ * @returns
4504
+ */
4505
+ get(token) {
4506
+ const value = this.store.get(token);
4507
+ if (value !== undefined) {
4508
+ return value;
4509
+ }
4510
+ const raw = this.getRaw(token);
4511
+ if (raw !== undefined) {
4512
+ this.hydrate(token, raw);
4513
+ return this.get(token);
4514
+ }
4515
+ }
4516
+ /**
4517
+ * Retrieves the raw assigned value of a token from the nearest assigned node.
4518
+ * @param token - The token to retrieve a raw value for
4519
+ * @returns
4520
+ */
4521
+ getRaw(token) {
4522
+ var _a;
4523
+ if (this.assignedValues.has(token)) {
4524
+ return this.assignedValues.get(token);
4525
+ }
4526
+ return (_a = DesignTokenNode.findClosestAssignedNode(token, this)) === null || _a === void 0 ? void 0 : _a.getRaw(token);
4527
+ }
4528
+ /**
4529
+ * Sets a token to a value for a node
4530
+ * @param token - The token to set
4531
+ * @param value - The value to set the token to
4532
+ */
4533
+ set(token, value) {
4534
+ if (DesignTokenImpl.isDerivedDesignTokenValue(this.assignedValues.get(token))) {
4535
+ this.tearDownBindingObserver(token);
4536
+ }
4537
+ this.assignedValues.set(token, value);
4538
+ if (DesignTokenImpl.isDerivedDesignTokenValue(value)) {
4539
+ this.setupBindingObserver(token, value);
4540
+ }
4541
+ else {
4542
+ this.store.set(token, value);
4543
+ }
4544
+ }
4545
+ /**
4546
+ * Deletes a token value for the node.
4547
+ * @param token - The token to delete the value for
4548
+ */
4549
+ delete(token) {
4550
+ this.assignedValues.delete(token);
4551
+ this.tearDownBindingObserver(token);
4552
+ const upstream = this.getRaw(token);
4553
+ if (upstream) {
4554
+ this.hydrate(token, upstream);
4555
+ }
4556
+ else {
4557
+ this.store.delete(token);
4558
+ }
4559
+ }
4560
+ /**
4561
+ * Invoked when the DesignTokenNode.target is attached to the document
4562
+ */
4563
+ bind() {
4564
+ const parent = DesignTokenNode.findParent(this);
4565
+ if (parent) {
4566
+ parent.appendChild(this);
4567
+ }
4568
+ for (const key of this.assignedValues.keys()) {
4569
+ key.notify(this.target);
4570
+ }
4571
+ }
4572
+ /**
4573
+ * Invoked when the DesignTokenNode.target is detached from the document
4574
+ */
4575
+ unbind() {
4576
+ if (this.parent) {
4577
+ const parent = childToParent.get(this);
4578
+ parent.removeChild(this);
4579
+ }
4580
+ }
4581
+ /**
4582
+ * Appends a child to a parent DesignTokenNode.
4583
+ * @param child - The child to append to the node
4584
+ */
4585
+ appendChild(child) {
4586
+ if (child.parent) {
4587
+ childToParent.get(child).removeChild(child);
4588
+ }
4589
+ const reParent = this.children.filter(x => child.contains(x));
4590
+ childToParent.set(child, this);
4591
+ this.children.push(child);
4592
+ reParent.forEach(x => child.appendChild(x));
4593
+ Observable.getNotifier(this.store).subscribe(child);
4594
+ // How can we not notify *every* subscriber?
4595
+ for (const [token, value] of this.store.all()) {
4596
+ child.hydrate(token, this.bindingObservers.has(token) ? this.getRaw(token) : value);
4597
+ }
4598
+ }
4599
+ /**
4600
+ * Removes a child from a node.
4601
+ * @param child - The child to remove.
4602
+ */
4603
+ removeChild(child) {
4604
+ const childIndex = this.children.indexOf(child);
4605
+ if (childIndex !== -1) {
4606
+ this.children.splice(childIndex, 1);
4607
+ }
4608
+ Observable.getNotifier(this.store).unsubscribe(child);
4609
+ return child.parent === this ? childToParent.delete(child) : false;
4610
+ }
4611
+ /**
4612
+ * Tests whether a provided node is contained by
4613
+ * the calling node.
4614
+ * @param test - The node to test
4615
+ */
4616
+ contains(test) {
4617
+ return composedContains(this.target, test.target);
4618
+ }
4619
+ /**
4620
+ * Instructs the node to reflect a design token for the provided token.
4621
+ * @param token - The design token to reflect
4622
+ */
4623
+ reflectToCSS(token) {
4624
+ if (!this.isReflecting(token)) {
4625
+ this.reflecting.add(token);
4626
+ DesignTokenNode.cssCustomPropertyReflector.startReflection(token, this.target);
4627
+ }
4628
+ }
4629
+ /**
4630
+ * Stops reflecting a DesignToken to CSS
4631
+ * @param token - The design token to stop reflecting
4632
+ */
4633
+ stopReflectToCSS(token) {
4634
+ if (this.isReflecting(token)) {
4635
+ this.reflecting.delete(token);
4636
+ DesignTokenNode.cssCustomPropertyReflector.stopReflection(token, this.target);
4637
+ }
4638
+ }
4639
+ /**
4640
+ * Determines if a token is being reflected to CSS for a node.
4641
+ * @param token - The token to check for reflection
4642
+ * @returns
4643
+ */
4644
+ isReflecting(token) {
4645
+ return this.reflecting.has(token);
4646
+ }
4647
+ /**
4648
+ * Handle changes to upstream tokens
4649
+ * @param source - The parent DesignTokenNode
4650
+ * @param property - The token ID that changed
4651
+ */
4652
+ handleChange(source, property) {
4653
+ const token = DesignTokenImpl.getTokenById(property);
4654
+ if (!token) {
4655
+ return;
4656
+ }
4657
+ this.hydrate(token, this.getRaw(token));
4658
+ }
4659
+ /**
4660
+ * Hydrates a token with a DesignTokenValue, making retrieval available.
4661
+ * @param token - The token to hydrate
4662
+ * @param value - The value to hydrate
4663
+ */
4664
+ hydrate(token, value) {
4665
+ if (!this.has(token)) {
4666
+ const observer = this.bindingObservers.get(token);
4667
+ if (DesignTokenImpl.isDerivedDesignTokenValue(value)) {
4668
+ if (observer) {
4669
+ // If the binding source doesn't match, we need
4670
+ // to update the binding
4671
+ if (observer.source !== value) {
4672
+ this.tearDownBindingObserver(token);
4673
+ this.setupBindingObserver(token, value);
4674
+ }
4675
+ }
4676
+ else {
4677
+ this.setupBindingObserver(token, value);
4678
+ }
4679
+ }
4680
+ else {
4681
+ if (observer) {
4682
+ this.tearDownBindingObserver(token);
4683
+ }
4684
+ this.store.set(token, value);
4685
+ }
4686
+ }
4687
+ }
4688
+ /**
4689
+ * Sets up a binding observer for a derived token value that notifies token
4690
+ * subscribers on change.
4691
+ *
4692
+ * @param token - The token to notify when the binding updates
4693
+ * @param source - The binding source
4694
+ */
4695
+ setupBindingObserver(token, source) {
4696
+ const binding = new DesignTokenBindingObserver(source, token, this);
4697
+ this.bindingObservers.set(token, binding);
4698
+ return binding;
4699
+ }
4700
+ /**
4701
+ * Tear down a binding observer for a token.
4702
+ */
4703
+ tearDownBindingObserver(token) {
4704
+ if (this.bindingObservers.has(token)) {
4705
+ this.bindingObservers.get(token).disconnect();
4706
+ this.bindingObservers.delete(token);
4707
+ return true;
4708
+ }
4709
+ return false;
4710
+ }
4711
+ }
4712
+ /**
4713
+ * Responsible for reflecting tokens to CSS custom properties
4714
+ */
4715
+ DesignTokenNode.cssCustomPropertyReflector = new CustomPropertyReflector();
4716
+ __decorate([
4717
+ observable
4718
+ ], DesignTokenNode.prototype, "children", void 0);
4719
+ function create(nameOrConfig) {
4720
+ return DesignTokenImpl.from(nameOrConfig);
4721
+ }
4722
+ /* eslint-enable @typescript-eslint/no-unused-vars */
4723
+ /**
4724
+ * Factory object for creating {@link (DesignToken:interface)} instances.
4725
+ * @public
4726
+ */
4727
+ const DesignToken = Object.freeze({
4728
+ create,
4729
+ /**
4730
+ * Informs DesignToken that an HTMLElement for which tokens have
4731
+ * been set has been connected to the document.
4732
+ *
4733
+ * The browser does not provide a reliable mechanism to observe an HTMLElement's connectedness
4734
+ * in all scenarios, so invoking this method manually is necessary when:
4735
+ *
4736
+ * 1. Token values are set for an HTMLElement.
4737
+ * 2. The HTMLElement does not inherit from FASTElement.
4738
+ * 3. The HTMLElement is not connected to the document when token values are set.
4739
+ *
4740
+ * @param element - The element to notify
4741
+ * @returns - true if notification was successful, otherwise false.
4742
+ */
4743
+ notifyConnection(element) {
4744
+ if (!element.isConnected || !DesignTokenNode.existsFor(element)) {
4745
+ return false;
4746
+ }
4747
+ DesignTokenNode.getOrCreate(element).bind();
4748
+ return true;
4749
+ },
4750
+ /**
4751
+ * Informs DesignToken that an HTMLElement for which tokens have
4752
+ * been set has been disconnected to the document.
4753
+ *
4754
+ * The browser does not provide a reliable mechanism to observe an HTMLElement's connectedness
4755
+ * in all scenarios, so invoking this method manually is necessary when:
4756
+ *
4757
+ * 1. Token values are set for an HTMLElement.
4758
+ * 2. The HTMLElement does not inherit from FASTElement.
4759
+ *
4760
+ * @param element - The element to notify
4761
+ * @returns - true if notification was successful, otherwise false.
4762
+ */
4763
+ notifyDisconnection(element) {
4764
+ if (element.isConnected || !DesignTokenNode.existsFor(element)) {
4765
+ return false;
4766
+ }
4767
+ DesignTokenNode.getOrCreate(element).unbind();
4768
+ return true;
4769
+ },
4770
+ /**
4771
+ * Registers and element or document as a DesignToken root.
4772
+ * {@link CSSDesignToken | CSSDesignTokens} with default values assigned via
4773
+ * {@link (DesignToken:interface).withDefault} will emit CSS custom properties to all
4774
+ * registered roots.
4775
+ * @param target - The root to register
4776
+ */
4777
+ registerRoot(target = defaultElement) {
4778
+ RootStyleSheetTarget.registerRoot(target);
4779
+ },
4780
+ /**
4781
+ * Unregister an element or document as a DesignToken root.
4782
+ * @param target - The root to deregister
4783
+ */
4784
+ unregisterRoot(target = defaultElement) {
4785
+ RootStyleSheetTarget.unregisterRoot(target);
4786
+ },
4787
+ });
4788
+ /* eslint-enable @typescript-eslint/no-non-null-assertion */
4789
+
4790
+ /* eslint-disable @typescript-eslint/no-non-null-assertion */
4791
+ /**
4792
+ * Indicates what to do with an ambiguous (duplicate) element.
4793
+ * @public
4794
+ */
4795
+ const ElementDisambiguation = Object.freeze({
4796
+ /**
4797
+ * Skip defining the element but still call the provided callback passed
4798
+ * to DesignSystemRegistrationContext.tryDefineElement
4799
+ */
4800
+ definitionCallbackOnly: null,
4801
+ /**
4802
+ * Ignore the duplicate element entirely.
4803
+ */
4804
+ ignoreDuplicate: Symbol(),
4805
+ });
4806
+ const elementTypesByTag = new Map();
4807
+ const elementTagsByType = new Map();
4808
+ let rootDesignSystem = null;
4809
+ const designSystemKey = DI.createInterface(x => x.cachedCallback(handler => {
4810
+ if (rootDesignSystem === null) {
4811
+ rootDesignSystem = new DefaultDesignSystem(null, handler);
4812
+ }
4813
+ return rootDesignSystem;
4814
+ }));
4815
+ /**
4816
+ * An API gateway to design system features.
4817
+ * @public
4818
+ */
4819
+ const DesignSystem = Object.freeze({
4820
+ /**
4821
+ * Returns the HTML element name that the type is defined as.
4822
+ * @param type - The type to lookup.
4823
+ * @public
4824
+ */
4825
+ tagFor(type) {
4826
+ return elementTagsByType.get(type);
4827
+ },
4828
+ /**
4829
+ * Searches the DOM hierarchy for the design system that is responsible
4830
+ * for the provided element.
4831
+ * @param element - The element to locate the design system for.
4832
+ * @returns The located design system.
4833
+ * @public
4834
+ */
4835
+ responsibleFor(element) {
4836
+ const owned = element.$$designSystem$$;
4837
+ if (owned) {
4838
+ return owned;
4839
+ }
4840
+ const container = DI.findResponsibleContainer(element);
4841
+ return container.get(designSystemKey);
4842
+ },
4843
+ /**
4844
+ * Gets the DesignSystem if one is explicitly defined on the provided element;
4845
+ * otherwise creates a design system defined directly on the element.
4846
+ * @param element - The element to get or create a design system for.
4847
+ * @returns The design system.
4848
+ * @public
4849
+ */
4850
+ getOrCreate(node) {
4851
+ if (!node) {
4852
+ if (rootDesignSystem === null) {
4853
+ rootDesignSystem = DI.getOrCreateDOMContainer().get(designSystemKey);
4854
+ }
4855
+ return rootDesignSystem;
4856
+ }
4857
+ const owned = node.$$designSystem$$;
4858
+ if (owned) {
4859
+ return owned;
4860
+ }
4861
+ const container = DI.getOrCreateDOMContainer(node);
4862
+ if (container.has(designSystemKey, false)) {
4863
+ return container.get(designSystemKey);
4864
+ }
4865
+ else {
4866
+ const system = new DefaultDesignSystem(node, container);
4867
+ container.register(Registration.instance(designSystemKey, system));
4868
+ return system;
4869
+ }
4870
+ },
4871
+ });
4872
+ function extractTryDefineElementParams(params, elementDefinitionType, elementDefinitionCallback) {
4873
+ if (typeof params === "string") {
4874
+ return {
4875
+ name: params,
4876
+ type: elementDefinitionType,
4877
+ callback: elementDefinitionCallback,
4878
+ };
4879
+ }
4880
+ else {
4881
+ return params;
4882
+ }
4883
+ }
4884
+ class DefaultDesignSystem {
4885
+ constructor(owner, container) {
4886
+ this.owner = owner;
4887
+ this.container = container;
4888
+ this.designTokensInitialized = false;
4889
+ this.prefix = "fast";
4890
+ this.shadowRootMode = undefined;
4891
+ this.disambiguate = () => ElementDisambiguation.definitionCallbackOnly;
4892
+ if (owner !== null) {
4893
+ owner.$$designSystem$$ = this;
4894
+ }
4895
+ }
4896
+ withPrefix(prefix) {
4897
+ this.prefix = prefix;
4898
+ return this;
4899
+ }
4900
+ withShadowRootMode(mode) {
4901
+ this.shadowRootMode = mode;
4902
+ return this;
4903
+ }
4904
+ withElementDisambiguation(callback) {
4905
+ this.disambiguate = callback;
4906
+ return this;
4907
+ }
4908
+ withDesignTokenRoot(root) {
4909
+ this.designTokenRoot = root;
4910
+ return this;
4911
+ }
4912
+ register(...registrations) {
4913
+ const container = this.container;
4914
+ const elementDefinitionEntries = [];
4915
+ const disambiguate = this.disambiguate;
4916
+ const shadowRootMode = this.shadowRootMode;
4917
+ const context = {
4918
+ elementPrefix: this.prefix,
4919
+ tryDefineElement(params, elementDefinitionType, elementDefinitionCallback) {
4920
+ const extractedParams = extractTryDefineElementParams(params, elementDefinitionType, elementDefinitionCallback);
4921
+ const { name, callback, baseClass } = extractedParams;
4922
+ let { type } = extractedParams;
4923
+ let elementName = name;
4924
+ let typeFoundByName = elementTypesByTag.get(elementName);
4925
+ let needsDefine = true;
4926
+ while (typeFoundByName) {
4927
+ const result = disambiguate(elementName, type, typeFoundByName);
4928
+ switch (result) {
4929
+ case ElementDisambiguation.ignoreDuplicate:
4930
+ return;
4931
+ case ElementDisambiguation.definitionCallbackOnly:
4932
+ needsDefine = false;
4933
+ typeFoundByName = void 0;
4934
+ break;
4935
+ default:
4936
+ elementName = result;
4937
+ typeFoundByName = elementTypesByTag.get(elementName);
4938
+ break;
4939
+ }
4940
+ }
4941
+ if (needsDefine) {
4942
+ if (elementTagsByType.has(type) || type === FoundationElement) {
4943
+ type = class extends type {
4944
+ };
4945
+ }
4946
+ elementTypesByTag.set(elementName, type);
4947
+ elementTagsByType.set(type, elementName);
4948
+ if (baseClass) {
4949
+ elementTagsByType.set(baseClass, elementName);
4950
+ }
4951
+ }
4952
+ elementDefinitionEntries.push(new ElementDefinitionEntry(container, elementName, type, shadowRootMode, callback, needsDefine));
4953
+ },
4954
+ };
4955
+ if (!this.designTokensInitialized) {
4956
+ this.designTokensInitialized = true;
4957
+ if (this.designTokenRoot !== null) {
4958
+ DesignToken.registerRoot(this.designTokenRoot);
4959
+ }
4960
+ }
4961
+ container.registerWithContext(context, ...registrations);
4962
+ for (const entry of elementDefinitionEntries) {
4963
+ entry.callback(entry);
4964
+ if (entry.willDefine && entry.definition !== null) {
4965
+ entry.definition.define();
4966
+ }
4967
+ }
4968
+ return this;
4969
+ }
4970
+ }
4971
+ class ElementDefinitionEntry {
4972
+ constructor(container, name, type, shadowRootMode, callback, willDefine) {
4973
+ this.container = container;
4974
+ this.name = name;
4975
+ this.type = type;
4976
+ this.shadowRootMode = shadowRootMode;
4977
+ this.callback = callback;
4978
+ this.willDefine = willDefine;
4979
+ this.definition = null;
4980
+ }
4981
+ definePresentation(presentation) {
4982
+ ComponentPresentation.define(this.name, presentation, this.container);
4983
+ }
4984
+ defineElement(definition) {
4985
+ this.definition = new FASTElementDefinition(this.type, Object.assign(Object.assign({}, definition), { name: this.name }));
4986
+ }
4987
+ tagFor(type) {
4988
+ return DesignSystem.tagFor(type);
4989
+ }
4990
+ }
4991
+ /* eslint-enable @typescript-eslint/no-non-null-assertion */
4992
+
4993
+ function provideVividDesignSystem(element) {
4994
+ return DesignSystem.getOrCreate(element).withPrefix('vwc');
4995
+ }
4996
+ const designSystem = provideVividDesignSystem();
4997
+
4998
+ export { AttachedBehaviorHTMLDirective as A, DOM as D, FoundationElement as F, HTMLDirective as H, Observable as O, SubscriberSet as S, __decorate as _, attr as a, __metadata as b, __classPrivateFieldGet as c, designSystem as d, emptyArray as e, HTMLView as f, __classPrivateFieldSet as g, html as h, nullableNumberConverter as n, observable as o, provideVividDesignSystem as p };