@schukai/monster 3.51.4 → 3.52.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (451) hide show
  1. package/CHANGELOG.md +706 -0
  2. package/README.md +16 -13
  3. package/example/components/form/button.mjs +10 -0
  4. package/example/components/form/select.mjs +25 -0
  5. package/example/components/form/tree-select.mjs +27 -0
  6. package/example/components/host/host.mjs +0 -0
  7. package/example/components/notify/message.mjs +4 -0
  8. package/example/components/notify/notify.mjs +4 -0
  9. package/example/components/state/log.mjs +0 -0
  10. package/example/components/state/state.mjs +0 -0
  11. package/package.json +6 -2
  12. package/source/components/constants.mjs +132 -0
  13. package/source/components/datatable/columnbar.mjs +310 -0
  14. package/source/components/datatable/constants.mjs +121 -0
  15. package/source/components/datatable/dataset.mjs +219 -0
  16. package/source/components/datatable/datasource/dom.mjs +186 -0
  17. package/source/components/datatable/datasource/namespace.mjs +13 -0
  18. package/source/components/datatable/datasource/rest.mjs +400 -0
  19. package/source/components/datatable/datasource.mjs +102 -0
  20. package/source/components/datatable/datatable/header.mjs +268 -0
  21. package/source/components/datatable/datatable/namespace.mjs +13 -0
  22. package/source/components/datatable/datatable.mjs +789 -0
  23. package/source/components/datatable/embedded-pagination.mjs +113 -0
  24. package/source/components/datatable/filter/abstract-base.mjs +31 -0
  25. package/source/components/datatable/filter/date-range.mjs +1041 -0
  26. package/source/components/datatable/filter/input.mjs +175 -0
  27. package/source/components/datatable/filter/namespace.mjs +13 -0
  28. package/source/components/datatable/filter/range.mjs +671 -0
  29. package/source/components/datatable/filter/select.mjs +65 -0
  30. package/source/components/datatable/filter/settings.mjs +116 -0
  31. package/source/components/datatable/filter-button.mjs +98 -0
  32. package/source/components/datatable/filter.mjs +929 -0
  33. package/source/components/datatable/namespace.mjs +11 -0
  34. package/source/components/datatable/pagination.mjs +456 -0
  35. package/source/components/datatable/style/column-bar.pcss +123 -0
  36. package/source/components/datatable/style/dataset.pcss +13 -0
  37. package/source/components/datatable/style/datasource.pcss +16 -0
  38. package/source/components/datatable/style/datatable.pcss +239 -0
  39. package/source/components/datatable/style/embedded-pagination.pcss +101 -0
  40. package/source/components/datatable/style/filter-button.pcss +22 -0
  41. package/source/components/datatable/style/filter-controls-defaults.pcss +46 -0
  42. package/source/components/datatable/style/filter-date-range.pcss +9 -0
  43. package/source/components/datatable/style/filter-range.pcss +5 -0
  44. package/source/components/datatable/style/filter.pcss +156 -0
  45. package/source/components/datatable/style/pagination.pcss +59 -0
  46. package/source/components/datatable/style/select-filter.pcss +27 -0
  47. package/source/components/datatable/stylesheet/column-bar.mjs +33 -0
  48. package/source/components/datatable/stylesheet/dataset.mjs +33 -0
  49. package/source/components/datatable/stylesheet/datasource.mjs +33 -0
  50. package/source/components/datatable/stylesheet/datatable.mjs +33 -0
  51. package/source/components/datatable/stylesheet/embedded-pagination.mjs +33 -0
  52. package/source/components/datatable/stylesheet/filter-button.mjs +33 -0
  53. package/source/components/datatable/stylesheet/filter-controls-defaults.mjs +33 -0
  54. package/source/components/datatable/stylesheet/filter-date-range.mjs +33 -0
  55. package/source/components/datatable/stylesheet/filter-range.mjs +33 -0
  56. package/source/components/datatable/stylesheet/filter.mjs +33 -0
  57. package/source/components/datatable/stylesheet/namespace.mjs +13 -0
  58. package/source/components/datatable/stylesheet/pagination.mjs +33 -0
  59. package/source/components/datatable/stylesheet/select-filter.mjs +33 -0
  60. package/source/components/datatable/util.mjs +60 -0
  61. package/source/components/form/action-button.mjs +262 -0
  62. package/source/components/form/api-button.mjs +515 -0
  63. package/source/components/form/button-bar.mjs +739 -0
  64. package/source/components/form/button.mjs +350 -0
  65. package/source/components/form/confirm-button.mjs +330 -0
  66. package/source/components/form/constants.mjs +111 -0
  67. package/source/components/form/context-help.mjs +123 -0
  68. package/source/components/form/events.mjs +84 -0
  69. package/source/components/form/form.mjs +601 -0
  70. package/source/components/form/message-state-button.mjs +396 -0
  71. package/source/components/form/namespace.mjs +13 -0
  72. package/source/components/form/popper-button.mjs +435 -0
  73. package/source/components/form/popper.mjs +487 -0
  74. package/source/components/form/reload.mjs +360 -0
  75. package/source/components/form/select.mjs +2314 -0
  76. package/source/components/form/shadow-reload.mjs +137 -0
  77. package/source/components/form/state-button.mjs +182 -0
  78. package/source/components/form/style/action-button.pcss +41 -0
  79. package/source/components/form/style/api-button.pcss +0 -0
  80. package/source/components/form/style/button-bar.pcss +51 -0
  81. package/source/components/form/style/button.pcss +8 -0
  82. package/source/components/form/style/confirm-button.pcss +17 -0
  83. package/source/components/form/style/context-help.pcss +16 -0
  84. package/source/components/form/style/form.pcss +10 -0
  85. package/source/components/form/style/message-state-button.pcss +10 -0
  86. package/source/components/form/style/popper-button.pcss +16 -0
  87. package/source/components/form/style/popper.pcss +8 -0
  88. package/source/components/form/style/select.pcss +265 -0
  89. package/source/components/form/style/state-button.pcss +116 -0
  90. package/source/components/form/style/tabs.pcss +170 -0
  91. package/source/components/form/style/tree-select.pcss +81 -0
  92. package/source/components/form/stylesheet/action-button.mjs +33 -0
  93. package/source/components/form/stylesheet/api-button.mjs +33 -0
  94. package/source/components/form/stylesheet/button-bar.mjs +33 -0
  95. package/source/components/form/stylesheet/button.mjs +33 -0
  96. package/source/components/form/stylesheet/confirm-button.mjs +33 -0
  97. package/source/components/form/stylesheet/context-help.mjs +33 -0
  98. package/source/components/form/stylesheet/form.mjs +33 -0
  99. package/source/components/form/stylesheet/message-state-button.mjs +33 -0
  100. package/source/components/form/stylesheet/namespace.mjs +13 -0
  101. package/source/components/form/stylesheet/popper-button.mjs +33 -0
  102. package/source/components/form/stylesheet/popper.mjs +33 -0
  103. package/source/components/form/stylesheet/select.mjs +33 -0
  104. package/source/components/form/stylesheet/state-button.mjs +33 -0
  105. package/source/components/form/stylesheet/tabs.mjs +33 -0
  106. package/source/components/form/stylesheet/tree-select.mjs +33 -0
  107. package/source/components/form/tabs.mjs +1011 -0
  108. package/source/components/form/template.mjs +373 -0
  109. package/source/components/form/tree-select.mjs +527 -0
  110. package/source/components/form/types/namespace.mjs +13 -0
  111. package/source/components/form/types/state.mjs +93 -0
  112. package/source/components/form/util/fetch.mjs +133 -0
  113. package/source/components/form/util/floating-ui.mjs +245 -0
  114. package/source/components/form/util/namespace.mjs +13 -0
  115. package/source/components/form/util/popper.mjs +49 -0
  116. package/source/components/host/call-button.mjs +236 -0
  117. package/source/components/host/collapse.mjs +526 -0
  118. package/source/components/host/config-manager.mjs +304 -0
  119. package/source/components/host/constants.mjs +18 -0
  120. package/source/components/host/details.mjs +268 -0
  121. package/source/components/host/events.mjs +131 -0
  122. package/source/components/host/host.mjs +420 -0
  123. package/source/components/host/namespace.mjs +13 -0
  124. package/source/components/host/overlay.mjs +339 -0
  125. package/source/components/host/style/call-button.pcss +36 -0
  126. package/source/components/host/style/collapse.pcss +67 -0
  127. package/source/components/host/style/config-manager.pcss +5 -0
  128. package/source/components/host/style/details.pcss +68 -0
  129. package/source/components/host/style/host.pcss +43 -0
  130. package/source/components/host/style/overlay.pcss +73 -0
  131. package/source/components/host/style/toggle-button.pcss +36 -0
  132. package/source/components/host/style/viewer.pcss +13 -0
  133. package/source/components/host/stylesheet/call-button.mjs +33 -0
  134. package/source/components/host/stylesheet/collapse.mjs +33 -0
  135. package/source/components/host/stylesheet/config-manager.mjs +33 -0
  136. package/source/components/host/stylesheet/details.mjs +33 -0
  137. package/source/components/host/stylesheet/host.mjs +33 -0
  138. package/source/components/host/stylesheet/namespace.mjs +13 -0
  139. package/source/components/host/stylesheet/overlay.mjs +33 -0
  140. package/source/components/host/stylesheet/toggle-button.mjs +33 -0
  141. package/source/components/host/stylesheet/viewer.mjs +33 -0
  142. package/source/components/host/toggle-button.mjs +88 -0
  143. package/source/components/host/util.mjs +23 -0
  144. package/source/components/host/viewer.mjs +309 -0
  145. package/source/components/namespace.mjs +14 -0
  146. package/source/components/notify/constants.mjs +15 -0
  147. package/source/components/notify/events.mjs +15 -0
  148. package/source/components/notify/message.mjs +374 -0
  149. package/source/components/notify/namespace.mjs +15 -0
  150. package/source/components/notify/notify.mjs +236 -0
  151. package/source/components/notify/style/message.pcss +57 -0
  152. package/source/components/notify/style/notify.pcss +118 -0
  153. package/source/components/notify/stylesheet/message.mjs +33 -0
  154. package/source/components/notify/stylesheet/namespace.mjs +15 -0
  155. package/source/components/notify/stylesheet/notify.mjs +33 -0
  156. package/source/components/state/log/entry.mjs +126 -0
  157. package/source/components/state/log/namespace.mjs +13 -0
  158. package/source/components/state/log.mjs +275 -0
  159. package/source/components/state/namespace.mjs +13 -0
  160. package/source/components/state/state.mjs +131 -0
  161. package/source/components/state/style/log.pcss +111 -0
  162. package/source/components/state/style/state.pcss +113 -0
  163. package/source/components/state/stylesheet/log.mjs +33 -0
  164. package/source/components/state/stylesheet/state.mjs +33 -0
  165. package/source/components/style/badge.pcss +92 -0
  166. package/source/components/style/border.pcss +77 -0
  167. package/source/components/style/button.pcss +105 -0
  168. package/source/components/style/card.pcss +108 -0
  169. package/source/components/style/color.pcss +257 -0
  170. package/source/components/style/common.pcss +103 -0
  171. package/source/components/style/control.pcss +11 -0
  172. package/source/components/style/data-grid.pcss +43 -0
  173. package/source/components/style/display.pcss +42 -0
  174. package/source/components/style/floating-ui.pcss +33 -0
  175. package/source/components/style/form.pcss +5 -0
  176. package/source/components/style/host.pcss +15 -0
  177. package/source/components/style/link.pcss +63 -0
  178. package/source/components/style/mixin/badge.pcss +18 -0
  179. package/source/components/style/mixin/button.pcss +54 -0
  180. package/source/components/style/mixin/form.pcss +247 -0
  181. package/source/components/style/mixin/hover.pcss +8 -0
  182. package/source/components/style/mixin/media.pcss +107 -0
  183. package/source/components/style/mixin/property.pcss +288 -0
  184. package/source/components/style/mixin/skeleton.pcss +26 -0
  185. package/source/components/style/mixin/spinner.pcss +24 -0
  186. package/source/components/style/mixin/typography.pcss +52 -0
  187. package/source/components/style/normalize.pcss +14 -0
  188. package/source/components/style/popper.pcss +78 -0
  189. package/source/components/style/property.pcss +17 -0
  190. package/source/components/style/ripple.pcss +14 -0
  191. package/source/components/style/skeleton.pcss +28 -0
  192. package/source/components/style/space.pcss +47 -0
  193. package/source/components/style/spinner.pcss +6 -0
  194. package/source/components/style/table.pcss +46 -0
  195. package/source/components/style/theme.pcss +119 -0
  196. package/source/components/style/typography.pcss +131 -0
  197. package/source/components/stylesheet/badge.mjs +33 -0
  198. package/source/components/stylesheet/border.mjs +33 -0
  199. package/source/components/stylesheet/button.mjs +33 -0
  200. package/source/components/stylesheet/card.mjs +33 -0
  201. package/source/components/stylesheet/color.mjs +33 -0
  202. package/source/components/stylesheet/common.mjs +33 -0
  203. package/source/components/stylesheet/control.mjs +33 -0
  204. package/source/components/stylesheet/data-grid.mjs +33 -0
  205. package/source/components/stylesheet/display.mjs +33 -0
  206. package/source/components/stylesheet/floating-ui.mjs +33 -0
  207. package/source/components/stylesheet/form.mjs +33 -0
  208. package/source/components/stylesheet/host.mjs +33 -0
  209. package/source/components/stylesheet/link.mjs +33 -0
  210. package/source/components/stylesheet/namespace.mjs +13 -0
  211. package/source/components/stylesheet/normalize.mjs +33 -0
  212. package/source/components/stylesheet/popper.mjs +33 -0
  213. package/source/components/stylesheet/property.mjs +33 -0
  214. package/source/components/stylesheet/ripple.mjs +33 -0
  215. package/source/components/stylesheet/skeleton.mjs +33 -0
  216. package/source/components/stylesheet/space.mjs +33 -0
  217. package/source/components/stylesheet/spinner.mjs +33 -0
  218. package/source/components/stylesheet/table.mjs +33 -0
  219. package/source/components/stylesheet/theme.mjs +33 -0
  220. package/source/components/stylesheet/tree-menu.mjs +33 -0
  221. package/source/components/stylesheet/typography.mjs +33 -0
  222. package/source/components/tree-menu/namespace.mjs +13 -0
  223. package/source/components/tree-menu/style/tree-menu.pcss +107 -0
  224. package/source/components/tree-menu/stylesheet/namespace.mjs +13 -0
  225. package/source/components/tree-menu/stylesheet/tree-menu.mjs +33 -0
  226. package/source/components/tree-menu/tree-menu.mjs +660 -0
  227. package/source/constraints/abstract.mjs +17 -24
  228. package/source/constraints/abstractoperator.mjs +27 -22
  229. package/source/constraints/andoperator.mjs +20 -17
  230. package/source/constraints/invalid.mjs +17 -17
  231. package/source/constraints/isarray.mjs +20 -20
  232. package/source/constraints/isobject.mjs +20 -20
  233. package/source/constraints/oroperator.mjs +45 -45
  234. package/source/constraints/valid.mjs +17 -17
  235. package/source/data/buildmap.mjs +108 -103
  236. package/source/data/buildtree.mjs +59 -57
  237. package/source/data/datasource/dom.mjs +80 -84
  238. package/source/data/datasource/namespace.mjs +1 -1
  239. package/source/data/datasource/server/restapi/data-fetch-error.mjs +27 -25
  240. package/source/data/datasource/server/restapi/writeerror.mjs +34 -32
  241. package/source/data/datasource/server/restapi.mjs +176 -177
  242. package/source/data/datasource/server/webconnect.mjs +150 -156
  243. package/source/data/datasource/server.mjs +58 -59
  244. package/source/data/datasource/storage/localstorage.mjs +25 -24
  245. package/source/data/datasource/storage/sessionstorage.mjs +28 -25
  246. package/source/data/datasource/storage.mjs +74 -73
  247. package/source/data/datasource.mjs +176 -167
  248. package/source/data/diff.mjs +98 -97
  249. package/source/data/extend.mjs +42 -42
  250. package/source/data/pathfinder.mjs +301 -288
  251. package/source/data/pipe.mjs +36 -36
  252. package/source/data/transformer.mjs +742 -726
  253. package/source/dom/assembler.mjs +44 -44
  254. package/source/dom/attributes.mjs +142 -122
  255. package/source/dom/constants.mjs +62 -58
  256. package/source/dom/customcontrol.mjs +299 -299
  257. package/source/dom/customelement.mjs +843 -806
  258. package/source/dom/dimension.mjs +56 -46
  259. package/source/dom/events.mjs +74 -69
  260. package/source/dom/focusmanager.mjs +175 -175
  261. package/source/dom/locale.mjs +28 -28
  262. package/source/dom/ready.mjs +13 -13
  263. package/source/dom/resource/data.mjs +117 -111
  264. package/source/dom/resource/link/stylesheet.mjs +16 -16
  265. package/source/dom/resource/link.mjs +94 -96
  266. package/source/dom/resource/script.mjs +72 -74
  267. package/source/dom/resource.mjs +174 -172
  268. package/source/dom/resourcemanager.mjs +152 -156
  269. package/source/dom/slotted.mjs +78 -80
  270. package/source/dom/template.mjs +126 -112
  271. package/source/dom/theme.mjs +35 -35
  272. package/source/dom/updater.mjs +673 -651
  273. package/source/dom/util/extract-keys.mjs +34 -22
  274. package/source/dom/util/init-options-from-attributes.mjs +46 -38
  275. package/source/dom/util/namespace.mjs +13 -0
  276. package/source/dom/util/set-option-from-attribute.mjs +35 -29
  277. package/source/dom/util.mjs +112 -81
  278. package/source/dom/worker/factory.mjs +83 -83
  279. package/source/i18n/formatter.mjs +75 -73
  280. package/source/i18n/locale.mjs +146 -144
  281. package/source/i18n/provider.mjs +70 -64
  282. package/source/i18n/providers/embed.mjs +136 -127
  283. package/source/i18n/providers/fetch.mjs +84 -76
  284. package/source/i18n/translations.mjs +205 -195
  285. package/source/logging/handler/console.mjs +36 -36
  286. package/source/logging/handler.mjs +140 -140
  287. package/source/logging/logentry.mjs +25 -25
  288. package/source/logging/logger.mjs +177 -175
  289. package/source/math/random.mjs +63 -59
  290. package/source/monster.mjs +226 -217
  291. package/source/net/webconnect/message.mjs +31 -31
  292. package/source/net/webconnect.mjs +278 -271
  293. package/source/text/bracketed-key-value-hash.mjs +182 -179
  294. package/source/text/formatter.mjs +235 -210
  295. package/source/text/generate-range-comparison-expression.mjs +56 -34
  296. package/source/text/namespace.mjs +1 -1
  297. package/source/types/base.mjs +69 -61
  298. package/source/types/basewithoptions.mjs +46 -46
  299. package/source/types/binary.mjs +20 -20
  300. package/source/types/dataurl.mjs +96 -90
  301. package/source/types/global.mjs +45 -39
  302. package/source/types/id.mjs +25 -25
  303. package/source/types/internal.mjs +115 -114
  304. package/source/types/is.mjs +56 -40
  305. package/source/types/mediatype.mjs +119 -119
  306. package/source/types/namespace.mjs +1 -1
  307. package/source/types/node.mjs +160 -150
  308. package/source/types/nodelist.mjs +94 -96
  309. package/source/types/noderecursiveiterator.mjs +50 -50
  310. package/source/types/observablequeue.mjs +73 -73
  311. package/source/types/observer.mjs +104 -104
  312. package/source/types/observerlist.mjs +66 -66
  313. package/source/types/proxyobserver.mjs +210 -210
  314. package/source/types/queue.mjs +63 -63
  315. package/source/types/randomid.mjs +13 -13
  316. package/source/types/regex.mjs +3 -1
  317. package/source/types/stack.mjs +64 -64
  318. package/source/types/tokenlist.mjs +206 -205
  319. package/source/types/typeof.mjs +12 -10
  320. package/source/types/uniquequeue.mjs +48 -48
  321. package/source/types/uuid.mjs +32 -32
  322. package/source/types/validate.mjs +67 -67
  323. package/source/types/version.mjs +115 -105
  324. package/source/util/clone.mjs +103 -91
  325. package/source/util/comparator.mjs +97 -97
  326. package/source/util/deadmansswitch.mjs +40 -44
  327. package/source/util/freeze.mjs +10 -9
  328. package/source/util/namespace.mjs +1 -1
  329. package/source/util/processing.mjs +104 -105
  330. package/source/util/runtime.mjs +56 -44
  331. package/source/util/trimspaces.mjs +24 -24
  332. package/test/cases/components/form/button.mjs +122 -0
  333. package/test/cases/components/form/confirm-button.mjs +127 -0
  334. package/test/cases/components/form/form.mjs +317 -0
  335. package/test/cases/components/form/reload.mjs +188 -0
  336. package/test/cases/components/form/select.mjs +229 -0
  337. package/test/cases/components/form/state-button.mjs +130 -0
  338. package/test/cases/components/form/tabs.mjs +98 -0
  339. package/test/cases/components/form/template.mjs +189 -0
  340. package/test/cases/components/form/tree-select.mjs +216 -0
  341. package/test/cases/components/host/details.mjs +68 -0
  342. package/test/cases/components/host/host.mjs +70 -0
  343. package/test/cases/components/host/overlay.mjs +60 -0
  344. package/test/cases/components/host/util.mjs +79 -0
  345. package/test/cases/components/notify/message.mjs +39 -0
  346. package/test/cases/components/notify/notify.mjs +89 -0
  347. package/test/cases/constraint/abstractoperator.mjs +2 -2
  348. package/test/cases/constraint/andoperator.mjs +3 -3
  349. package/test/cases/constraint/invalid.mjs +1 -1
  350. package/test/cases/constraint/isarray.mjs +1 -1
  351. package/test/cases/constraint/isobject.mjs +1 -1
  352. package/test/cases/constraint/oroperator.mjs +3 -3
  353. package/test/cases/constraint/valid.mjs +1 -1
  354. package/test/cases/data/buildmap.mjs +1 -1
  355. package/test/cases/data/buildtree.mjs +2 -2
  356. package/test/cases/data/datasource/dom.mjs +1 -1
  357. package/test/cases/data/datasource/server/restapi.mjs +2 -2
  358. package/test/cases/data/datasource/server/websocket.mjs +1 -1
  359. package/test/cases/data/datasource/server.mjs +1 -1
  360. package/test/cases/data/datasource/storage/localstorage.mjs +1 -1
  361. package/test/cases/data/datasource/storage/sessionstorage.mjs +1 -1
  362. package/test/cases/data/datasource.mjs +1 -1
  363. package/test/cases/data/diff.mjs +2 -2
  364. package/test/cases/data/extend.mjs +1 -1
  365. package/test/cases/data/pathfinder.mjs +1 -1
  366. package/test/cases/data/pipe.mjs +2 -2
  367. package/test/cases/data/transformer.mjs +3 -4
  368. package/test/cases/dom/assembler.mjs +1 -1
  369. package/test/cases/dom/attributes.mjs +1 -1
  370. package/test/cases/dom/customcontrol.mjs +8 -7
  371. package/test/cases/dom/customelement-initfromscripthost.mjs +6 -6
  372. package/test/cases/dom/customelement.mjs +7 -7
  373. package/test/cases/dom/dimension.mjs +4 -4
  374. package/test/cases/dom/events.mjs +1 -1
  375. package/test/cases/dom/find.mjs +1 -1
  376. package/test/cases/dom/focusmanager.mjs +1 -1
  377. package/test/cases/dom/locale.mjs +2 -2
  378. package/test/cases/dom/ready.mjs +1 -1
  379. package/test/cases/dom/resource/data.mjs +3 -3
  380. package/test/cases/dom/resource/link/stylesheet.mjs +3 -3
  381. package/test/cases/dom/resource/link.mjs +3 -3
  382. package/test/cases/dom/resource/script.mjs +3 -3
  383. package/test/cases/dom/resource.mjs +1 -1
  384. package/test/cases/dom/resourcemanager.mjs +1 -1
  385. package/test/cases/dom/slotted-nodes.mjs +1 -1
  386. package/test/cases/dom/template.mjs +2 -2
  387. package/test/cases/dom/theme.mjs +2 -2
  388. package/test/cases/dom/updater.mjs +4 -4
  389. package/test/cases/dom/util/extract-keys.mjs +1 -1
  390. package/test/cases/dom/util/init-options-from-attributes.mjs +1 -1
  391. package/test/cases/dom/util.mjs +2 -2
  392. package/test/cases/dom/worker/factory.mjs +2 -2
  393. package/test/cases/i18n/formatter.mjs +2 -2
  394. package/test/cases/i18n/locale.mjs +1 -1
  395. package/test/cases/i18n/provider.mjs +4 -4
  396. package/test/cases/i18n/providers/embed.mjs +3 -3
  397. package/test/cases/i18n/providers/fetch.mjs +3 -3
  398. package/test/cases/i18n/translations.mjs +3 -3
  399. package/test/cases/logging/handler/console.mjs +3 -3
  400. package/test/cases/logging/handler.mjs +3 -3
  401. package/test/cases/logging/logentry.mjs +1 -1
  402. package/test/cases/logging/logger.mjs +1 -1
  403. package/test/cases/math/random.mjs +1 -2
  404. package/test/cases/monster.mjs +2 -2
  405. package/test/cases/net/webconnect/message.mjs +1 -2
  406. package/test/cases/net/webconnect.mjs +3 -3
  407. package/test/cases/text/bracketed-key-value-hash.mjs +1 -1
  408. package/test/cases/text/formatter.mjs +1 -1
  409. package/test/cases/text/util.mjs +1 -1
  410. package/test/cases/types/base.mjs +2 -2
  411. package/test/cases/types/basewithoptions.mjs +1 -1
  412. package/test/cases/types/binary.mjs +1 -1
  413. package/test/cases/types/dataurl.mjs +1 -1
  414. package/test/cases/types/global.mjs +1 -1
  415. package/test/cases/types/id.mjs +1 -1
  416. package/test/cases/types/internal.mjs +2 -2
  417. package/test/cases/types/is.mjs +2 -2
  418. package/test/cases/types/mediatype.mjs +1 -1
  419. package/test/cases/types/node.mjs +4 -4
  420. package/test/cases/types/nodelist.mjs +2 -2
  421. package/test/cases/types/noderecursiveiterator.mjs +3 -3
  422. package/test/cases/types/observablequeue.mjs +2 -2
  423. package/test/cases/types/observer.mjs +1 -1
  424. package/test/cases/types/observerlist.mjs +2 -2
  425. package/test/cases/types/proxyobserver.mjs +4 -4
  426. package/test/cases/types/queue.mjs +1 -1
  427. package/test/cases/types/randomid.mjs +1 -1
  428. package/test/cases/types/regex.mjs +1 -1
  429. package/test/cases/types/stack.mjs +1 -1
  430. package/test/cases/types/tokenlist.mjs +1 -1
  431. package/test/cases/types/typeof.mjs +2 -2
  432. package/test/cases/types/uniquequeue.mjs +1 -1
  433. package/test/cases/types/uuid.mjs +1 -1
  434. package/test/cases/types/validate.mjs +3 -3
  435. package/test/cases/types/version.mjs +1 -1
  436. package/test/cases/util/clone.mjs +1 -1
  437. package/test/cases/util/comparator.mjs +1 -1
  438. package/test/cases/util/deadmansswitch.mjs +1 -1
  439. package/test/cases/util/freeze.mjs +1 -1
  440. package/test/cases/util/processing.mjs +1 -1
  441. package/test/cases/util/trimspaces.mjs +1 -1
  442. package/test/util/chai-dom.mjs +2 -2
  443. package/test/util/intersection-mock.mjs +69 -0
  444. package/test/util/jsdom.mjs +43 -27
  445. package/test/util/localstorage.mjs +1 -0
  446. package/test/util/resize-observer.mjs +29 -0
  447. package/test/util/websocket.mjs +5 -2
  448. package/test/web/import.js +92 -73
  449. package/test/web/test.html +28 -5
  450. package/test/web/tests.js +29430 -15209
  451. package/CHANGELOG +0 -438
@@ -13,37 +13,55 @@ import { Formatter } from "../text/formatter.mjs";
13
13
 
14
14
  import { parseDataURL } from "../types/dataurl.mjs";
15
15
  import { getGlobalObject } from "../types/global.mjs";
16
- import { isArray, isFunction, isIterable, isObject, isString } from "../types/is.mjs";
16
+ import {
17
+ isArray,
18
+ isFunction,
19
+ isIterable,
20
+ isObject,
21
+ isString,
22
+ } from "../types/is.mjs";
17
23
  import { Observer } from "../types/observer.mjs";
18
24
  import { ProxyObserver } from "../types/proxyobserver.mjs";
19
- import { validateFunction, validateInstance, validateObject, validateString } from "../types/validate.mjs";
25
+ import {
26
+ validateFunction,
27
+ validateInstance,
28
+ validateObject,
29
+ validateString,
30
+ } from "../types/validate.mjs";
20
31
  import { clone } from "../util/clone.mjs";
21
- import { addAttributeToken, getLinkedObjects, hasObjectLink } from "./attributes.mjs";
22
32
  import {
23
- ATTRIBUTE_DISABLED,
24
- ATTRIBUTE_ERRORMESSAGE,
25
- ATTRIBUTE_OPTIONS,
26
- ATTRIBUTE_INIT_CALLBACK,
27
- ATTRIBUTE_OPTIONS_SELECTOR,
28
- ATTRIBUTE_SCRIPT_HOST,
29
- customElementUpdaterLinkSymbol,
30
- initControlCallbackName,
33
+ addAttributeToken,
34
+ getLinkedObjects,
35
+ hasObjectLink,
36
+ } from "./attributes.mjs";
37
+ import {
38
+ ATTRIBUTE_DISABLED,
39
+ ATTRIBUTE_ERRORMESSAGE,
40
+ ATTRIBUTE_OPTIONS,
41
+ ATTRIBUTE_INIT_CALLBACK,
42
+ ATTRIBUTE_OPTIONS_SELECTOR,
43
+ ATTRIBUTE_SCRIPT_HOST,
44
+ customElementUpdaterLinkSymbol,
45
+ initControlCallbackName,
31
46
  } from "./constants.mjs";
32
47
  import { findDocumentTemplate, Template } from "./template.mjs";
33
48
  import { addObjectWithUpdaterToElement } from "./updater.mjs";
34
49
  import { instanceSymbol } from "../constants.mjs";
35
- import { getDocumentTranslations, Translations } from "../i18n/translations.mjs";
50
+ import {
51
+ getDocumentTranslations,
52
+ Translations,
53
+ } from "../i18n/translations.mjs";
36
54
  import { getSlottedElements } from "./slotted.mjs";
37
55
  import { initOptionsFromAttributes } from "./util/init-options-from-attributes.mjs";
38
56
  import { setOptionFromAttribute } from "./util/set-option-from-attribute.mjs";
39
57
 
40
58
  export {
41
- CustomElement,
42
- initMethodSymbol,
43
- assembleMethodSymbol,
44
- attributeObserverSymbol,
45
- registerCustomElement,
46
- getSlottedElements,
59
+ CustomElement,
60
+ initMethodSymbol,
61
+ assembleMethodSymbol,
62
+ attributeObserverSymbol,
63
+ registerCustomElement,
64
+ getSlottedElements,
47
65
  };
48
66
 
49
67
  /**
@@ -56,20 +74,26 @@ const initMethodSymbol = Symbol.for("@schukai/monster/dom/@@initMethodSymbol");
56
74
  * @memberOf Monster.DOM
57
75
  * @type {symbol}
58
76
  */
59
- const assembleMethodSymbol = Symbol.for("@schukai/monster/dom/@@assembleMethodSymbol");
77
+ const assembleMethodSymbol = Symbol.for(
78
+ "@schukai/monster/dom/@@assembleMethodSymbol",
79
+ );
60
80
 
61
81
  /**
62
82
  * this symbol holds the attribute observer callbacks. The key is the attribute name.
63
83
  * @memberOf Monster.DOM
64
84
  * @type {symbol}
65
85
  */
66
- const attributeObserverSymbol = Symbol.for("@schukai/monster/dom/@@attributeObserver");
86
+ const attributeObserverSymbol = Symbol.for(
87
+ "@schukai/monster/dom/@@attributeObserver",
88
+ );
67
89
 
68
90
  /**
69
91
  * @private
70
92
  * @type {symbol}
71
93
  */
72
- const attributeMutationObserverSymbol = Symbol("@schukai/monster/dom/@@mutationObserver");
94
+ const attributeMutationObserverSymbol = Symbol(
95
+ "@schukai/monster/dom/@@mutationObserver",
96
+ );
73
97
 
74
98
  /**
75
99
  * @private
@@ -201,458 +225,466 @@ const scriptHostElementSymbol = Symbol("scriptHostElement");
201
225
  * @summary A base class for HTML5 custom controls.
202
226
  */
203
227
  class CustomElement extends HTMLElement {
204
- /**
205
- * A new object is created. First the `initOptions` method is called. Here the
206
- * options can be defined in derived classes. Subsequently, the shadowRoot is initialized.
207
- *
208
- * IMPORTANT: CustomControls instances are not created via the constructor, but either via a tag in the HTML or via <code>document.createElement()</code>.
209
- *
210
- * @throws {Error} the options attribute does not contain a valid json definition.
211
- * @since 1.7.0
212
- */
213
- constructor() {
214
- super();
215
-
216
- this[attributeObserverSymbol] = {};
217
- this[internalSymbol] = new ProxyObserver({
218
- options: initOptionsFromAttributes(this, extend({}, this.defaults)),
219
- });
220
- this[initMethodSymbol]();
221
- initOptionObserver.call(this);
222
- this[scriptHostElementSymbol] = [];
223
- }
224
-
225
- /**
226
- * This method is called by the `instanceof` operator.
227
- * @returns {symbol}
228
- * @since 2.1.0
229
- */
230
- static get [instanceSymbol]() {
231
- return Symbol.for("@schukai/monster/dom/custom-element@@instance");
232
- }
233
-
234
- /**
235
- * This method determines which attributes are to be
236
- * monitored by `attributeChangedCallback()`. Unfortunately, this method is static.
237
- * Therefore, the `observedAttributes` property cannot be changed during runtime.
238
- *
239
- * @return {string[]}
240
- * @since 1.15.0
241
- */
242
- static get observedAttributes() {
243
- return [];
244
- }
245
-
246
- /**
247
- *
248
- * @param attribute
249
- * @param callback
250
- * @returns {Monster.DOM.CustomElement}
251
- */
252
- addAttributeObserver(attribute, callback) {
253
- validateFunction(callback);
254
- this[attributeObserverSymbol][attribute] = callback;
255
- return this;
256
- }
257
-
258
- /**
259
- *
260
- * @param attribute
261
- * @returns {Monster.DOM.CustomElement}
262
- */
263
- removeAttributeObserver(attribute) {
264
- delete this[attributeObserverSymbol][attribute];
265
- return this;
266
- }
267
-
268
- /**
269
- * The `defaults` property defines the default values for a control. If you want to override these,
270
- * you can use various methods, which are described in the documentation available at
271
- * {@link https://monsterjs.orgendocconfigurate-a-monster-control}.
272
- *
273
- * The individual configuration values are listed below:
274
- *
275
- * More information about the shadowRoot can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow),
276
- * in the [HTML Standard](https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements) or in the [WHATWG Wiki](https://wiki.whatwg.org/wiki/Custom_Elements).
277
- *
278
- * More information about the template element can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template).
279
- *
280
- * More information about the slot element can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot).
281
- *
282
- * @property {boolean} disabled=false Specifies whether the control is disabled. When present, it makes the element non-mutable, non-focusable, and non-submittable with the form.
283
- * @property {string} shadowMode=open Specifies the mode of the shadow root. When set to `open`, elements in the shadow root are accessible from JavaScript outside the root, while setting it to `closed` denies access to the root's nodes from JavaScript outside it.
284
- * @property {Boolean} delegatesFocus=true Specifies the behavior of the control with respect to focusability. When set to `true`, it mitigates custom element issues around focusability. When a non-focusable part of the shadow DOM is clicked, the first focusable part is given focus, and the shadow host is given any available :focus styling.
285
- * @property {Object} templates Specifies the templates used by the control.
286
- * @property {string} templates.main=undefined Specifies the main template used by the control.
287
- * @property {Object} templateMapping Specifies the mapping of templates.
288
- * @since 1.8.0
289
- */
290
- get defaults() {
291
- return {
292
- disabled: false,
293
- shadowMode: "open",
294
- delegatesFocus: true,
295
- templates: {
296
- main: undefined,
297
- },
298
- templateMapping: {},
299
- };
300
- }
301
-
302
- /**
303
- * This method updates the labels of the element.
304
- * The labels are defined in the options object.
305
- * The key of the label is used to retrieve the translation from the document.
306
- * If the translation is different from the label, the label is updated.
307
- *
308
- * Before you can use this method, you must have loaded the translations.
309
- *
310
- * @returns {Monster.DOM.CustomElement}
311
- * @throws {Error} Cannot find element with translations. Add a translations object to the document.
312
- */
313
- updateI18n() {
314
- const translations = getDocumentTranslations();
315
- if (!translations) {
316
- return this;
317
- }
318
-
319
- let labels = this.getOption("labels");
320
- if (!(isObject(labels) || isIterable(labels))) {
321
- return this;
322
- }
323
-
324
- for (const key in labels) {
325
- const def = labels[key];
326
-
327
- if (isString(def)) {
328
- const text = translations.getText(key, def);
329
- if (text !== def) {
330
- this.setOption(`labels.${key}`, text);
331
- }
332
- continue;
333
- } else if (isObject(def)) {
334
- for (const k in def) {
335
- const d = def[k];
336
-
337
- const text = translations.getPluralRuleText(key, k, d);
338
- if (!isString(text)) {
339
- throw new Error("Invalid labels definition");
340
- }
341
- if (text !== d) {
342
- this.setOption(`labels.${key}.${k}`, text);
343
- }
344
- }
345
- continue;
346
- }
347
-
348
- throw new Error("Invalid labels definition");
349
- }
350
- return this;
351
- }
352
-
353
- /**
354
- * The `getTag()` method returns the tag name associated with the custom element. This method should be overwritten
355
- * by the derived class.
356
- *
357
- * Note that there is no check on the name of the tag in this class. It is the responsibility of
358
- * the developer to assign an appropriate tag name. If the name is not valid, the
359
- * `registerCustomElement()` method will issue an error.
360
- *
361
- * @see https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name
362
- * @throws {Error} This method must be overridden by the derived class.
363
- * @return {string} The tag name associated with the custom element.
364
- * @since 1.7.0
365
- */
366
- static getTag() {
367
- throw new Error("The method `getTag()` must be overridden by the derived class.");
368
- }
369
-
370
- /**
371
- * The `getCSSStyleSheet()` method returns a `CSSStyleSheet` object that defines the styles for the custom element.
372
- * If the environment does not support the `CSSStyleSheet` constructor, then an object can be built using the provided detour.
373
- *
374
- * If `undefined` is returned, then the shadow root does not receive a stylesheet.
375
- *
376
- * Example usage:
377
- *
378
- * ```js
379
- * static getCSSStyleSheet() {
380
- * const sheet = new CSSStyleSheet();
381
- * sheet.replaceSync("p { color: red; }");
382
- * return sheet;
383
- * }
384
- * ```
385
- *
386
- * If the environment does not support the `CSSStyleSheet` constructor,
387
- * you can use the following workaround to create the stylesheet:
388
- *
389
- * ```js
390
- * const doc = document.implementation.createHTMLDocument('title');
391
- * let style = doc.createElement("style");
392
- * style.innerHTML = "p { color: red; }";
393
- * style.appendChild(document.createTextNode(""));
394
- * doc.head.appendChild(style);
395
- * return doc.styleSheets[0];
396
- * ```
397
- *
398
- * @return {CSSStyleSheet|CSSStyleSheet[]|string|undefined} A `CSSStyleSheet` object or an array of such objects that define the styles for the custom element, or `undefined` if no stylesheet should be applied.
399
- */
400
- static getCSSStyleSheet() {
401
- return undefined;
402
- }
403
-
404
- /**
405
- * attach a new observer
406
- *
407
- * @param {Observer} observer
408
- * @returns {CustomElement}
409
- */
410
- attachObserver(observer) {
411
- this[internalSymbol].attachObserver(observer);
412
- return this;
413
- }
414
-
415
- /**
416
- * detach a observer
417
- *
418
- * @param {Observer} observer
419
- * @returns {CustomElement}
420
- */
421
- detachObserver(observer) {
422
- this[internalSymbol].detachObserver(observer);
423
- return this;
424
- }
425
-
426
- /**
427
- * @param {Observer} observer
428
- * @returns {ProxyObserver}
429
- */
430
- containsObserver(observer) {
431
- return this[internalSymbol].containsObserver(observer);
432
- }
433
-
434
- /**
435
- * nested options can be specified by path `a.b.c`
436
- *
437
- * @param {string} path
438
- * @param {*} defaultValue
439
- * @return {*}
440
- * @since 1.10.0
441
- */
442
- getOption(path, defaultValue) {
443
- let value;
444
-
445
- try {
446
- value = new Pathfinder(this[internalSymbol].getRealSubject()["options"]).getVia(path);
447
- } catch (e) {}
448
-
449
- if (value === undefined) return defaultValue;
450
- return value;
451
- }
452
-
453
- /**
454
- * Set option and inform elements
455
- *
456
- * @param {string} path
457
- * @param {*} value
458
- * @return {CustomElement}
459
- * @since 1.14.0
460
- */
461
- setOption(path, value) {
462
- new Pathfinder(this[internalSymbol].getSubject()["options"]).setVia(path, value);
463
- return this;
464
- }
465
-
466
- /**
467
- * @since 1.15.0
468
- * @param {string|object} options
469
- * @return {CustomElement}
470
- */
471
- setOptions(options) {
472
- if (isString(options)) {
473
- options = parseOptionsJSON.call(this, options);
474
- }
475
-
476
- const self = this;
477
- extend(self[internalSymbol].getSubject()["options"], self.defaults, options);
478
-
479
- return self;
480
- }
481
-
482
- /**
483
- * Is called once via the constructor
484
- *
485
- * @return {CustomElement}
486
- * @since 1.8.0
487
- */
488
- [initMethodSymbol]() {
489
- return this;
490
- }
491
-
492
- /**
493
- * This method is called once when the object is included in the DOM for the first time. It performs the following actions:
494
- * 1. Extracts the options from the attributes and the script tag of the element and sets them.
495
- * 2. Initializes the shadow root and its CSS stylesheet (if specified).
496
- * 3. Initializes the HTML content of the element.
497
- * 4. Initializes the custom elements inside the shadow root and the slotted elements.
498
- * 5. Attaches a mutation observer to observe changes to the attributes of the element.
499
- *
500
- * @return {CustomElement} - The updated custom element.
501
- * @since 1.8.0
502
- */
503
- [assembleMethodSymbol]() {
504
- const self = this;
505
- let elements;
506
- let nodeList;
507
-
508
- // Extract options from attributes and set them
509
- const AttributeOptions = getOptionsFromAttributes.call(self);
510
- if (isObject(AttributeOptions) && Object.keys(AttributeOptions).length > 0) {
511
- self.setOptions(AttributeOptions);
512
- }
513
-
514
- // Extract options from script tag and set them
515
- const ScriptOptions = getOptionsFromScriptTag.call(self);
516
- if (isObject(ScriptOptions) && Object.keys(ScriptOptions).length > 0) {
517
- self.setOptions(ScriptOptions);
518
- }
519
-
520
- // Initialize the shadow root and its CSS stylesheet
521
- if (self.getOption("shadowMode", false) !== false) {
522
- try {
523
- initShadowRoot.call(self);
524
- elements = self.shadowRoot.childNodes;
525
- } catch (e) {
526
- addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.toString());
527
- }
528
-
529
- try {
530
- initCSSStylesheet.call(this);
531
- } catch (e) {
532
- addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.toString());
533
- }
534
- }
535
-
536
- // If the elements are not found inside the shadow root, initialize the HTML content of the element
537
- if (!(elements instanceof NodeList)) {
538
- initHtmlContent.call(this);
539
- elements = this.childNodes;
540
- }
541
-
542
- // Initialize the custom elements inside the shadow root and the slotted elements
543
- initFromCallbackHost.call(this);
544
- try {
545
- nodeList = new Set([...elements, ...getSlottedElements.call(self)]);
546
- } catch (e) {
547
- nodeList = elements;
548
- }
549
- addObjectWithUpdaterToElement.call(
550
- self,
551
- nodeList,
552
- customElementUpdaterLinkSymbol,
553
- clone(self[internalSymbol].getRealSubject()["options"]),
554
- );
555
-
556
- // Attach a mutation observer to observe changes to the attributes of the element
557
- attachAttributeChangeMutationObserver.call(this);
558
-
559
- return self;
560
- }
561
-
562
- /**
563
- * This method is called every time the element is inserted into the DOM. It checks if the custom element
564
- * has already been initialized and if not, calls the assembleMethod to initialize it.
565
- *
566
- * @return {void}
567
- * @since 1.7.0
568
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/connectedCallback
569
- */
570
- connectedCallback() {
571
- const self = this;
572
-
573
- // Check if the object has already been initialized
574
- if (!hasObjectLink(self, customElementUpdaterLinkSymbol)) {
575
- // If not, call the assembleMethod to initialize the object
576
- self[assembleMethodSymbol]();
577
- }
578
- }
579
-
580
- /**
581
- * Called every time the element is removed from the DOM. Useful for running clean up code.
582
- *
583
- * @return {void}
584
- * @since 1.7.0
585
- */
586
- disconnectedCallback() {}
587
-
588
- /**
589
- * The custom element has been moved into a new document (e.g. someone called document.adoptNode(el)).
590
- *
591
- * @return {void}
592
- * @since 1.7.0
593
- */
594
- adoptedCallback() {}
595
-
596
- /**
597
- * Called when an observed attribute has been added, removed, updated, or replaced. Also called for initial
598
- * values when an element is created by the parser, or upgraded. Note: only attributes listed in the observedAttributes
599
- * property will receive this callback.
600
- *
601
- * @param {string} attrName
602
- * @param {string} oldVal
603
- * @param {string} newVal
604
- * @return {void}
605
- * @since 1.15.0
606
- */
607
- attributeChangedCallback(attrName, oldVal, newVal) {
608
- const self = this;
609
-
610
- if (attrName.startsWith("data-monster-option-")) {
611
- setOptionFromAttribute(self, attrName, this[internalSymbol].getSubject()["options"]);
612
- }
613
-
614
- const callback = self[attributeObserverSymbol]?.[attrName];
615
- if (isFunction(callback)) {
616
- try {
617
- callback.call(self, newVal, oldVal);
618
- } catch (e) {
619
- addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.toString());
620
- }
621
- }
622
- }
623
-
624
- /**
625
- *
626
- * @param {Node} node
627
- * @return {boolean}
628
- * @throws {TypeError} value is not an instance of
629
- * @since 1.19.0
630
- */
631
- hasNode(node) {
632
- const self = this;
633
-
634
- if (containChildNode.call(self, validateInstance(node, Node))) {
635
- return true;
636
- }
637
-
638
- if (!(self.shadowRoot instanceof ShadowRoot)) {
639
- return false;
640
- }
641
-
642
- return containChildNode.call(self.shadowRoot, node);
643
- }
644
-
645
- /**
646
- * Calls a callback function if it exists.
647
- *
648
- * @param {string} name
649
- * @param {*} args
650
- * @returns {*}
651
- */
652
- callCallback(name, args) {
653
- const self = this;
654
- return callControlCallback.call(self, name, ...args);
655
- }
228
+ /**
229
+ * A new object is created. First the `initOptions` method is called. Here the
230
+ * options can be defined in derived classes. Subsequently, the shadowRoot is initialized.
231
+ *
232
+ * IMPORTANT: CustomControls instances are not created via the constructor, but either via a tag in the HTML or via <code>document.createElement()</code>.
233
+ *
234
+ * @throws {Error} the options attribute does not contain a valid json definition.
235
+ * @since 1.7.0
236
+ */
237
+ constructor() {
238
+ super();
239
+
240
+ this[attributeObserverSymbol] = {};
241
+ this[internalSymbol] = new ProxyObserver({
242
+ options: initOptionsFromAttributes(this, extend({}, this.defaults)),
243
+ });
244
+ this[initMethodSymbol]();
245
+ initOptionObserver.call(this);
246
+ this[scriptHostElementSymbol] = [];
247
+ }
248
+
249
+ /**
250
+ * This method is called by the `instanceof` operator.
251
+ * @returns {symbol}
252
+ * @since 2.1.0
253
+ */
254
+ static get [instanceSymbol]() {
255
+ return Symbol.for("@schukai/monster/dom/custom-element@@instance");
256
+ }
257
+
258
+ /**
259
+ * This method determines which attributes are to be
260
+ * monitored by `attributeChangedCallback()`. Unfortunately, this method is static.
261
+ * Therefore, the `observedAttributes` property cannot be changed during runtime.
262
+ *
263
+ * @return {string[]}
264
+ * @since 1.15.0
265
+ */
266
+ static get observedAttributes() {
267
+ return [];
268
+ }
269
+
270
+ /**
271
+ *
272
+ * @param attribute
273
+ * @param callback
274
+ * @returns {Monster.DOM.CustomElement}
275
+ */
276
+ addAttributeObserver(attribute, callback) {
277
+ validateFunction(callback);
278
+ this[attributeObserverSymbol][attribute] = callback;
279
+ return this;
280
+ }
281
+
282
+ /**
283
+ *
284
+ * @param attribute
285
+ * @returns {Monster.DOM.CustomElement}
286
+ */
287
+ removeAttributeObserver(attribute) {
288
+ delete this[attributeObserverSymbol][attribute];
289
+ return this;
290
+ }
291
+
292
+ /**
293
+ * The `defaults` property defines the default values for a control. If you want to override these,
294
+ * you can use various methods, which are described in the documentation available at
295
+ * {@link https://monsterjs.orgendocconfigurate-a-monster-control}.
296
+ *
297
+ * The individual configuration values are listed below:
298
+ *
299
+ * More information about the shadowRoot can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow),
300
+ * in the [HTML Standard](https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements) or in the [WHATWG Wiki](https://wiki.whatwg.org/wiki/Custom_Elements).
301
+ *
302
+ * More information about the template element can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template).
303
+ *
304
+ * More information about the slot element can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot).
305
+ *
306
+ * @property {boolean} disabled=false Specifies whether the control is disabled. When present, it makes the element non-mutable, non-focusable, and non-submittable with the form.
307
+ * @property {string} shadowMode=open Specifies the mode of the shadow root. When set to `open`, elements in the shadow root are accessible from JavaScript outside the root, while setting it to `closed` denies access to the root's nodes from JavaScript outside it.
308
+ * @property {Boolean} delegatesFocus=true Specifies the behavior of the control with respect to focusability. When set to `true`, it mitigates custom element issues around focusability. When a non-focusable part of the shadow DOM is clicked, the first focusable part is given focus, and the shadow host is given any available :focus styling.
309
+ * @property {Object} templates Specifies the templates used by the control.
310
+ * @property {string} templates.main=undefined Specifies the main template used by the control.
311
+ * @property {Object} templateMapping Specifies the mapping of templates.
312
+ * @since 1.8.0
313
+ */
314
+ get defaults() {
315
+ return {
316
+ disabled: false,
317
+ shadowMode: "open",
318
+ delegatesFocus: true,
319
+ templates: {
320
+ main: undefined,
321
+ },
322
+ templateMapping: {},
323
+ };
324
+ }
325
+
326
+ /**
327
+ * This method updates the labels of the element.
328
+ * The labels are defined in the options object.
329
+ * The key of the label is used to retrieve the translation from the document.
330
+ * If the translation is different from the label, the label is updated.
331
+ *
332
+ * Before you can use this method, you must have loaded the translations.
333
+ *
334
+ * @returns {Monster.DOM.CustomElement}
335
+ * @throws {Error} Cannot find element with translations. Add a translations object to the document.
336
+ */
337
+ updateI18n() {
338
+ const translations = getDocumentTranslations();
339
+ if (!translations) {
340
+ return this;
341
+ }
342
+
343
+ const labels = this.getOption("labels");
344
+ if (!(isObject(labels) || isIterable(labels))) {
345
+ return this;
346
+ }
347
+
348
+ for (const key in labels) {
349
+ const def = labels[key];
350
+
351
+ if (isString(def)) {
352
+ const text = translations.getText(key, def);
353
+ if (text !== def) {
354
+ this.setOption(`labels.${key}`, text);
355
+ }
356
+ continue;
357
+ } else if (isObject(def)) {
358
+ for (const k in def) {
359
+ const d = def[k];
360
+
361
+ const text = translations.getPluralRuleText(key, k, d);
362
+ if (!isString(text)) {
363
+ throw new Error("Invalid labels definition");
364
+ }
365
+ if (text !== d) {
366
+ this.setOption(`labels.${key}.${k}`, text);
367
+ }
368
+ }
369
+ continue;
370
+ }
371
+
372
+ throw new Error("Invalid labels definition");
373
+ }
374
+ return this;
375
+ }
376
+
377
+ /**
378
+ * The `getTag()` method returns the tag name associated with the custom element. This method should be overwritten
379
+ * by the derived class.
380
+ *
381
+ * Note that there is no check on the name of the tag in this class. It is the responsibility of
382
+ * the developer to assign an appropriate tag name. If the name is not valid, the
383
+ * `registerCustomElement()` method will issue an error.
384
+ *
385
+ * @see https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name
386
+ * @throws {Error} This method must be overridden by the derived class.
387
+ * @return {string} The tag name associated with the custom element.
388
+ * @since 1.7.0
389
+ */
390
+ static getTag() {
391
+ throw new Error(
392
+ "The method `getTag()` must be overridden by the derived class.",
393
+ );
394
+ }
395
+
396
+ /**
397
+ * The `getCSSStyleSheet()` method returns a `CSSStyleSheet` object that defines the styles for the custom element.
398
+ * If the environment does not support the `CSSStyleSheet` constructor, then an object can be built using the provided detour.
399
+ *
400
+ * If `undefined` is returned, then the shadow root does not receive a stylesheet.
401
+ *
402
+ * Example usage:
403
+ *
404
+ * ```js
405
+ * static getCSSStyleSheet() {
406
+ * const sheet = new CSSStyleSheet();
407
+ * sheet.replaceSync("p { color: red; }");
408
+ * return sheet;
409
+ * }
410
+ * ```
411
+ *
412
+ * If the environment does not support the `CSSStyleSheet` constructor,
413
+ * you can use the following workaround to create the stylesheet:
414
+ *
415
+ * ```js
416
+ * const doc = document.implementation.createHTMLDocument('title');
417
+ * let style = doc.createElement("style");
418
+ * style.innerHTML = "p { color: red; }";
419
+ * style.appendChild(document.createTextNode(""));
420
+ * doc.head.appendChild(style);
421
+ * return doc.styleSheets[0];
422
+ * ```
423
+ *
424
+ * @return {CSSStyleSheet|CSSStyleSheet[]|string|undefined} A `CSSStyleSheet` object or an array of such objects that define the styles for the custom element, or `undefined` if no stylesheet should be applied.
425
+ */
426
+ static getCSSStyleSheet() {
427
+ return undefined;
428
+ }
429
+
430
+ /**
431
+ * attach a new observer
432
+ *
433
+ * @param {Observer} observer
434
+ * @returns {CustomElement}
435
+ */
436
+ attachObserver(observer) {
437
+ this[internalSymbol].attachObserver(observer);
438
+ return this;
439
+ }
440
+
441
+ /**
442
+ * detach a observer
443
+ *
444
+ * @param {Observer} observer
445
+ * @returns {CustomElement}
446
+ */
447
+ detachObserver(observer) {
448
+ this[internalSymbol].detachObserver(observer);
449
+ return this;
450
+ }
451
+
452
+ /**
453
+ * @param {Observer} observer
454
+ * @returns {ProxyObserver}
455
+ */
456
+ containsObserver(observer) {
457
+ return this[internalSymbol].containsObserver(observer);
458
+ }
459
+
460
+ /**
461
+ * nested options can be specified by path `a.b.c`
462
+ *
463
+ * @param {string} path
464
+ * @param {*} defaultValue
465
+ * @return {*}
466
+ * @since 1.10.0
467
+ */
468
+ getOption(path, defaultValue) {
469
+ let value;
470
+
471
+ try {
472
+ value = new Pathfinder(
473
+ this[internalSymbol].getRealSubject()["options"],
474
+ ).getVia(path);
475
+ } catch (e) {}
476
+
477
+ if (value === undefined) return defaultValue;
478
+ return value;
479
+ }
480
+
481
+ /**
482
+ * Set option and inform elements
483
+ *
484
+ * @param {string} path
485
+ * @param {*} value
486
+ * @return {CustomElement}
487
+ * @since 1.14.0
488
+ */
489
+ setOption(path, value) {
490
+ new Pathfinder(this[internalSymbol].getSubject()["options"]).setVia(
491
+ path,
492
+ value,
493
+ );
494
+ return this;
495
+ }
496
+
497
+ /**
498
+ * @since 1.15.0
499
+ * @param {string|object} options
500
+ * @return {CustomElement}
501
+ */
502
+ setOptions(options) {
503
+ if (isString(options)) {
504
+ options = parseOptionsJSON.call(this, options);
505
+ }
506
+ extend(
507
+ this[internalSymbol].getSubject()["options"],
508
+ this.defaults,
509
+ options,
510
+ );
511
+
512
+ return this;
513
+ }
514
+
515
+ /**
516
+ * Is called once via the constructor
517
+ *
518
+ * @return {CustomElement}
519
+ * @since 1.8.0
520
+ */
521
+ [initMethodSymbol]() {
522
+ return this;
523
+ }
524
+
525
+ /**
526
+ * This method is called once when the object is included in the DOM for the first time. It performs the following actions:
527
+ * 1. Extracts the options from the attributes and the script tag of the element and sets them.
528
+ * 2. Initializes the shadow root and its CSS stylesheet (if specified).
529
+ * 3. Initializes the HTML content of the element.
530
+ * 4. Initializes the custom elements inside the shadow root and the slotted elements.
531
+ * 5. Attaches a mutation observer to observe changes to the attributes of the element.
532
+ *
533
+ * @return {CustomElement} - The updated custom element.
534
+ * @since 1.8.0
535
+ */
536
+ [assembleMethodSymbol]() {
537
+ let elements;
538
+ let nodeList;
539
+
540
+ // Extract options from attributes and set them
541
+ const AttributeOptions = getOptionsFromAttributes.call(this);
542
+ if (
543
+ isObject(AttributeOptions) &&
544
+ Object.keys(AttributeOptions).length > 0
545
+ ) {
546
+ this.setOptions(AttributeOptions);
547
+ }
548
+
549
+ // Extract options from script tag and set them
550
+ const ScriptOptions = getOptionsFromScriptTag.call(this);
551
+ if (isObject(ScriptOptions) && Object.keys(ScriptOptions).length > 0) {
552
+ this.setOptions(ScriptOptions);
553
+ }
554
+
555
+ // Initialize the shadow root and its CSS stylesheet
556
+ if (this.getOption("shadowMode", false) !== false) {
557
+ try {
558
+ initShadowRoot.call(this);
559
+ elements = this.shadowRoot.childNodes;
560
+ } catch (e) {
561
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.toString());
562
+ }
563
+
564
+ try {
565
+ initCSSStylesheet.call(this);
566
+ } catch (e) {
567
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.toString());
568
+ }
569
+ }
570
+
571
+ // If the elements are not found inside the shadow root, initialize the HTML content of the element
572
+ if (!(elements instanceof NodeList)) {
573
+ initHtmlContent.call(this);
574
+ elements = this.childNodes;
575
+ }
576
+
577
+ // Initialize the custom elements inside the shadow root and the slotted elements
578
+ initFromCallbackHost.call(this);
579
+ try {
580
+ nodeList = new Set([...elements, ...getSlottedElements.call(this)]);
581
+ } catch (e) {
582
+ nodeList = elements;
583
+ }
584
+ addObjectWithUpdaterToElement.call(
585
+ this,
586
+ nodeList,
587
+ customElementUpdaterLinkSymbol,
588
+ clone(this[internalSymbol].getRealSubject()["options"]),
589
+ );
590
+
591
+ // Attach a mutation observer to observe changes to the attributes of the element
592
+ attachAttributeChangeMutationObserver.call(this);
593
+
594
+ return this;
595
+ }
596
+
597
+ /**
598
+ * This method is called every time the element is inserted into the DOM. It checks if the custom element
599
+ * has already been initialized and if not, calls the assembleMethod to initialize it.
600
+ *
601
+ * @return {void}
602
+ * @since 1.7.0
603
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/connectedCallback
604
+ */
605
+ connectedCallback() {
606
+ // Check if the object has already been initialized
607
+ if (!hasObjectLink(this, customElementUpdaterLinkSymbol)) {
608
+ // If not, call the assembleMethod to initialize the object
609
+ this[assembleMethodSymbol]();
610
+ }
611
+ }
612
+
613
+ /**
614
+ * Called every time the element is removed from the DOM. Useful for running clean up code.
615
+ *
616
+ * @return {void}
617
+ * @since 1.7.0
618
+ */
619
+ disconnectedCallback() {}
620
+
621
+ /**
622
+ * The custom element has been moved into a new document (e.g. someone called document.adoptNode(el)).
623
+ *
624
+ * @return {void}
625
+ * @since 1.7.0
626
+ */
627
+ adoptedCallback() {}
628
+
629
+ /**
630
+ * Called when an observed attribute has been added, removed, updated, or replaced. Also called for initial
631
+ * values when an element is created by the parser, or upgraded. Note: only attributes listed in the observedAttributes
632
+ * property will receive this callback.
633
+ *
634
+ * @param {string} attrName
635
+ * @param {string} oldVal
636
+ * @param {string} newVal
637
+ * @return {void}
638
+ * @since 1.15.0
639
+ */
640
+ attributeChangedCallback(attrName, oldVal, newVal) {
641
+ if (attrName.startsWith("data-monster-option-")) {
642
+ setOptionFromAttribute(
643
+ this,
644
+ attrName,
645
+ this[internalSymbol].getSubject()["options"],
646
+ );
647
+ }
648
+
649
+ const callback = this[attributeObserverSymbol]?.[attrName];
650
+ if (isFunction(callback)) {
651
+ try {
652
+ callback.call(this, newVal, oldVal);
653
+ } catch (e) {
654
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.toString());
655
+ }
656
+ }
657
+ }
658
+
659
+ /**
660
+ *
661
+ * @param {Node} node
662
+ * @return {boolean}
663
+ * @throws {TypeError} value is not an instance of
664
+ * @since 1.19.0
665
+ */
666
+ hasNode(node) {
667
+ if (containChildNode.call(this, validateInstance(node, Node))) {
668
+ return true;
669
+ }
670
+
671
+ if (!(this.shadowRoot instanceof ShadowRoot)) {
672
+ return false;
673
+ }
674
+
675
+ return containChildNode.call(this.shadowRoot, node);
676
+ }
677
+
678
+ /**
679
+ * Calls a callback function if it exists.
680
+ *
681
+ * @param {string} name
682
+ * @param {*} args
683
+ * @returns {*}
684
+ */
685
+ callCallback(name, args) {
686
+ return callControlCallback.call(this, name, ...args);
687
+ }
656
688
  }
657
689
 
658
690
  /**
@@ -661,48 +693,50 @@ class CustomElement extends HTMLElement {
661
693
  * @return {any}
662
694
  */
663
695
  function callControlCallback(callBackFunctionName, ...args) {
664
- const self = this;
665
-
666
- if (!isString(callBackFunctionName) || callBackFunctionName === "") {
667
- return;
668
- }
669
-
670
- if (callBackFunctionName in self) {
671
- return self[callBackFunctionName](self, ...args);
672
- }
673
-
674
- if (!self.hasAttribute(ATTRIBUTE_SCRIPT_HOST)) {
675
- return;
676
- }
677
-
678
- if (self[scriptHostElementSymbol].length === 0) {
679
- const targetId = self.getAttribute(ATTRIBUTE_SCRIPT_HOST);
680
- if (!targetId) {
681
- return;
682
- }
683
-
684
- const list = targetId.split(",");
685
- for (const id of list) {
686
- const host = findElementWithIdUpwards(self, targetId);
687
- if (!(host instanceof HTMLElement)) {
688
- continue;
689
- }
690
-
691
- self[scriptHostElementSymbol].push(host);
692
- }
693
- }
694
-
695
- for (const host of self[scriptHostElementSymbol]) {
696
- if (callBackFunctionName in host) {
697
- try {
698
- return host[callBackFunctionName](self, ...args);
699
- } catch (e) {
700
- addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.toString());
701
- }
702
- }
703
- }
704
-
705
- addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, `callback ${callBackFunctionName} not found`);
696
+ if (!isString(callBackFunctionName) || callBackFunctionName === "") {
697
+ return;
698
+ }
699
+
700
+ if (callBackFunctionName in this) {
701
+ return this[callBackFunctionName](this, ...args);
702
+ }
703
+
704
+ if (!this.hasAttribute(ATTRIBUTE_SCRIPT_HOST)) {
705
+ return;
706
+ }
707
+
708
+ if (this[scriptHostElementSymbol].length === 0) {
709
+ const targetId = this.getAttribute(ATTRIBUTE_SCRIPT_HOST);
710
+ if (!targetId) {
711
+ return;
712
+ }
713
+
714
+ const list = targetId.split(",");
715
+ for (const id of list) {
716
+ const host = findElementWithIdUpwards(this, targetId);
717
+ if (!(host instanceof HTMLElement)) {
718
+ continue;
719
+ }
720
+
721
+ this[scriptHostElementSymbol].push(host);
722
+ }
723
+ }
724
+
725
+ for (const host of this[scriptHostElementSymbol]) {
726
+ if (callBackFunctionName in host) {
727
+ try {
728
+ return host[callBackFunctionName](this, ...args);
729
+ } catch (e) {
730
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.toString());
731
+ }
732
+ }
733
+ }
734
+
735
+ addAttributeToken(
736
+ this,
737
+ ATTRIBUTE_ERRORMESSAGE,
738
+ `callback ${callBackFunctionName} not found`,
739
+ );
706
740
  }
707
741
 
708
742
  /**
@@ -719,18 +753,16 @@ function callControlCallback(callBackFunctionName, ...args) {
719
753
  * @since 1.8.0
720
754
  */
721
755
  function initFromCallbackHost() {
722
- const self = this;
756
+ // Set the default callback function name
757
+ let callBackFunctionName = initControlCallbackName;
723
758
 
724
- // Set the default callback function name
725
- let callBackFunctionName = initControlCallbackName;
759
+ // If the `data-monster-option-callback` attribute is set, use its value as the callback function name
760
+ if (this.hasAttribute(ATTRIBUTE_INIT_CALLBACK)) {
761
+ callBackFunctionName = this.getAttribute(ATTRIBUTE_INIT_CALLBACK);
762
+ }
726
763
 
727
- // If the `data-monster-option-callback` attribute is set, use its value as the callback function name
728
- if (self.hasAttribute(ATTRIBUTE_INIT_CALLBACK)) {
729
- callBackFunctionName = self.getAttribute(ATTRIBUTE_INIT_CALLBACK);
730
- }
731
-
732
- // Call the callback function with the element as a parameter if it exists
733
- callControlCallback.call(self, callBackFunctionName);
764
+ // Call the callback function with the element as a parameter if it exists
765
+ callControlCallback.call(this, callBackFunctionName);
734
766
  }
735
767
 
736
768
  /**
@@ -740,32 +772,35 @@ function initFromCallbackHost() {
740
772
  * @this CustomElement
741
773
  */
742
774
  function attachAttributeChangeMutationObserver() {
743
- const self = this;
744
-
745
- if (typeof self[attributeMutationObserverSymbol] !== "undefined") {
746
- return;
747
- }
748
-
749
- self[attributeMutationObserverSymbol] = new MutationObserver(function (mutations, observer) {
750
- for (const mutation of mutations) {
751
- if (mutation.type === "attributes") {
752
- self.attributeChangedCallback(
753
- mutation.attributeName,
754
- mutation.oldValue,
755
- mutation.target.getAttribute(mutation.attributeName),
756
- );
757
- }
758
- }
759
- });
760
-
761
- try {
762
- self[attributeMutationObserverSymbol].observe(self, {
763
- attributes: true,
764
- attributeOldValue: true,
765
- });
766
- } catch (e) {
767
- addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.toString());
768
- }
775
+ const self = this;
776
+
777
+ if (typeof self[attributeMutationObserverSymbol] !== "undefined") {
778
+ return;
779
+ }
780
+
781
+ self[attributeMutationObserverSymbol] = new MutationObserver(function (
782
+ mutations,
783
+ observer,
784
+ ) {
785
+ for (const mutation of mutations) {
786
+ if (mutation.type === "attributes") {
787
+ self.attributeChangedCallback(
788
+ mutation.attributeName,
789
+ mutation.oldValue,
790
+ mutation.target.getAttribute(mutation.attributeName),
791
+ );
792
+ }
793
+ }
794
+ });
795
+
796
+ try {
797
+ self[attributeMutationObserverSymbol].observe(self, {
798
+ attributes: true,
799
+ attributeOldValue: true,
800
+ });
801
+ } catch (e) {
802
+ addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.toString());
803
+ }
769
804
  }
770
805
 
771
806
  /**
@@ -775,21 +810,19 @@ function attachAttributeChangeMutationObserver() {
775
810
  * @return {boolean}
776
811
  */
777
812
  function containChildNode(node) {
778
- const self = this;
779
-
780
- if (self.contains(node)) {
781
- return true;
782
- }
813
+ if (this.contains(node)) {
814
+ return true;
815
+ }
783
816
 
784
- for (const [, e] of Object.entries(self.childNodes)) {
785
- if (e.contains(node)) {
786
- return true;
787
- }
817
+ for (const [, e] of Object.entries(this.childNodes)) {
818
+ if (e.contains(node)) {
819
+ return true;
820
+ }
788
821
 
789
- containChildNode.call(e, node);
790
- }
822
+ containChildNode.call(e, node);
823
+ }
791
824
 
792
- return false;
825
+ return false;
793
826
  }
794
827
 
795
828
  /**
@@ -799,86 +832,89 @@ function containChildNode(node) {
799
832
  * @this CustomElement
800
833
  */
801
834
  function initOptionObserver() {
802
- const self = this;
803
-
804
- let lastDisabledValue = undefined;
805
- self.attachObserver(
806
- new Observer(function () {
807
- const flag = self.getOption("disabled");
808
-
809
- if (flag === lastDisabledValue) {
810
- return;
811
- }
812
-
813
- lastDisabledValue = flag;
814
-
815
- if (!(self.shadowRoot instanceof ShadowRoot)) {
816
- return;
817
- }
818
-
819
- const query =
820
- "button, command, fieldset, keygen, optgroup, option, select, textarea, input, [data-monster-objectlink]";
821
- const elements = self.shadowRoot.querySelectorAll(query);
822
-
823
- let nodeList;
824
- try {
825
- nodeList = new Set([...elements, ...getSlottedElements.call(self, query)]);
826
- } catch (e) {
827
- nodeList = elements;
828
- }
829
-
830
- for (const element of [...nodeList]) {
831
- if (flag === true) {
832
- element.setAttribute(ATTRIBUTE_DISABLED, "");
833
- } else {
834
- element.removeAttribute(ATTRIBUTE_DISABLED);
835
- }
836
- }
837
- }),
838
- );
839
-
840
- self.attachObserver(
841
- new Observer(function () {
842
- // not initialised
843
- if (!hasObjectLink(self, customElementUpdaterLinkSymbol)) {
844
- return;
845
- }
846
- // inform every element
847
- const updaters = getLinkedObjects(self, customElementUpdaterLinkSymbol);
848
-
849
- for (const list of updaters) {
850
- for (const updater of list) {
851
- let d = clone(self[internalSymbol].getRealSubject()["options"]);
852
- Object.assign(updater.getSubject(), d);
853
- }
854
- }
855
- }),
856
- );
857
-
858
- // disabled
859
- self[attributeObserverSymbol][ATTRIBUTE_DISABLED] = () => {
860
- if (self.hasAttribute(ATTRIBUTE_DISABLED)) {
861
- self.setOption(ATTRIBUTE_DISABLED, true);
862
- } else {
863
- self.setOption(ATTRIBUTE_DISABLED, undefined);
864
- }
865
- };
866
-
867
- // data-monster-options
868
- self[attributeObserverSymbol][ATTRIBUTE_OPTIONS] = () => {
869
- const options = getOptionsFromAttributes.call(self);
870
- if (isObject(options) && Object.keys(options).length > 0) {
871
- self.setOptions(options);
872
- }
873
- };
874
-
875
- // data-monster-options-selector
876
- self[attributeObserverSymbol][ATTRIBUTE_OPTIONS_SELECTOR] = () => {
877
- const options = getOptionsFromScriptTag.call(self);
878
- if (isObject(options) && Object.keys(options).length > 0) {
879
- self.setOptions(options);
880
- }
881
- };
835
+ const self = this;
836
+
837
+ let lastDisabledValue = undefined;
838
+ self.attachObserver(
839
+ new Observer(function () {
840
+ const flag = self.getOption("disabled");
841
+
842
+ if (flag === lastDisabledValue) {
843
+ return;
844
+ }
845
+
846
+ lastDisabledValue = flag;
847
+
848
+ if (!(self.shadowRoot instanceof ShadowRoot)) {
849
+ return;
850
+ }
851
+
852
+ const query =
853
+ "button, command, fieldset, keygen, optgroup, option, select, textarea, input, [data-monster-objectlink]";
854
+ const elements = self.shadowRoot.querySelectorAll(query);
855
+
856
+ let nodeList;
857
+ try {
858
+ nodeList = new Set([
859
+ ...elements,
860
+ ...getSlottedElements.call(self, query),
861
+ ]);
862
+ } catch (e) {
863
+ nodeList = elements;
864
+ }
865
+
866
+ for (const element of [...nodeList]) {
867
+ if (flag === true) {
868
+ element.setAttribute(ATTRIBUTE_DISABLED, "");
869
+ } else {
870
+ element.removeAttribute(ATTRIBUTE_DISABLED);
871
+ }
872
+ }
873
+ }),
874
+ );
875
+
876
+ self.attachObserver(
877
+ new Observer(function () {
878
+ // not initialised
879
+ if (!hasObjectLink(self, customElementUpdaterLinkSymbol)) {
880
+ return;
881
+ }
882
+ // inform every element
883
+ const updaters = getLinkedObjects(self, customElementUpdaterLinkSymbol);
884
+
885
+ for (const list of updaters) {
886
+ for (const updater of list) {
887
+ const d = clone(self[internalSymbol].getRealSubject()["options"]);
888
+ Object.assign(updater.getSubject(), d);
889
+ }
890
+ }
891
+ }),
892
+ );
893
+
894
+ // disabled
895
+ self[attributeObserverSymbol][ATTRIBUTE_DISABLED] = () => {
896
+ if (self.hasAttribute(ATTRIBUTE_DISABLED)) {
897
+ self.setOption(ATTRIBUTE_DISABLED, true);
898
+ } else {
899
+ self.setOption(ATTRIBUTE_DISABLED, undefined);
900
+ }
901
+ };
902
+
903
+ // data-monster-options
904
+ self[attributeObserverSymbol][ATTRIBUTE_OPTIONS] = () => {
905
+ const options = getOptionsFromAttributes.call(self);
906
+ if (isObject(options) && Object.keys(options).length > 0) {
907
+ self.setOptions(options);
908
+ }
909
+ };
910
+
911
+ // data-monster-options-selector
912
+ self[attributeObserverSymbol][ATTRIBUTE_OPTIONS_SELECTOR] = () => {
913
+ const options = getOptionsFromScriptTag.call(self);
914
+ if (isObject(options) && Object.keys(options).length > 0) {
915
+ self.setOptions(options);
916
+ }
917
+ };
882
918
  }
883
919
 
884
920
  /**
@@ -887,37 +923,37 @@ function initOptionObserver() {
887
923
  * @throws {TypeError} value is not a object
888
924
  */
889
925
  function getOptionsFromScriptTag() {
890
- const self = this;
891
-
892
- if (!self.hasAttribute(ATTRIBUTE_OPTIONS_SELECTOR)) {
893
- return {};
894
- }
895
-
896
- const node = document.querySelector(self.getAttribute(ATTRIBUTE_OPTIONS_SELECTOR));
897
- if (!(node instanceof HTMLScriptElement)) {
898
- addAttributeToken(
899
- self,
900
- ATTRIBUTE_ERRORMESSAGE,
901
- `the selector ${ATTRIBUTE_OPTIONS_SELECTOR} for options was specified (${self.getAttribute(
902
- ATTRIBUTE_OPTIONS_SELECTOR,
903
- )}) but not found.`,
904
- );
905
- return {};
906
- }
907
-
908
- let obj = {};
909
-
910
- try {
911
- obj = parseOptionsJSON.call(this, node.textContent.trim());
912
- } catch (e) {
913
- addAttributeToken(
914
- self,
915
- ATTRIBUTE_ERRORMESSAGE,
916
- `when analyzing the configuration from the script tag there was an error. ${e}`,
917
- );
918
- }
919
-
920
- return obj;
926
+ if (!this.hasAttribute(ATTRIBUTE_OPTIONS_SELECTOR)) {
927
+ return {};
928
+ }
929
+
930
+ const node = document.querySelector(
931
+ this.getAttribute(ATTRIBUTE_OPTIONS_SELECTOR),
932
+ );
933
+ if (!(node instanceof HTMLScriptElement)) {
934
+ addAttributeToken(
935
+ this,
936
+ ATTRIBUTE_ERRORMESSAGE,
937
+ `the selector ${ATTRIBUTE_OPTIONS_SELECTOR} for options was specified (${this.getAttribute(
938
+ ATTRIBUTE_OPTIONS_SELECTOR,
939
+ )}) but not found.`,
940
+ );
941
+ return {};
942
+ }
943
+
944
+ let obj = {};
945
+
946
+ try {
947
+ obj = parseOptionsJSON.call(this, node.textContent.trim());
948
+ } catch (e) {
949
+ addAttributeToken(
950
+ this,
951
+ ATTRIBUTE_ERRORMESSAGE,
952
+ `when analyzing the configuration from the script tag there was an error. ${e}`,
953
+ );
954
+ }
955
+
956
+ return obj;
921
957
  }
922
958
 
923
959
  /**
@@ -925,23 +961,21 @@ function getOptionsFromScriptTag() {
925
961
  * @return {object}
926
962
  */
927
963
  function getOptionsFromAttributes() {
928
- const self = this;
929
-
930
- if (this.hasAttribute(ATTRIBUTE_OPTIONS)) {
931
- try {
932
- return parseOptionsJSON.call(self, this.getAttribute(ATTRIBUTE_OPTIONS));
933
- } catch (e) {
934
- addAttributeToken(
935
- self,
936
- ATTRIBUTE_ERRORMESSAGE,
937
- `the options attribute ${ATTRIBUTE_OPTIONS} does not contain a valid json definition (actual: ${this.getAttribute(
938
- ATTRIBUTE_OPTIONS,
939
- )}).${e}`,
940
- );
941
- }
942
- }
943
-
944
- return {};
964
+ if (this.hasAttribute(ATTRIBUTE_OPTIONS)) {
965
+ try {
966
+ return parseOptionsJSON.call(this, this.getAttribute(ATTRIBUTE_OPTIONS));
967
+ } catch (e) {
968
+ addAttributeToken(
969
+ this,
970
+ ATTRIBUTE_ERRORMESSAGE,
971
+ `the options attribute ${ATTRIBUTE_OPTIONS} does not contain a valid json definition (actual: ${this.getAttribute(
972
+ ATTRIBUTE_OPTIONS,
973
+ )}).${e}`,
974
+ );
975
+ }
976
+ }
977
+
978
+ return {};
945
979
  }
946
980
 
947
981
  /**
@@ -950,25 +984,25 @@ function getOptionsFromAttributes() {
950
984
  * @return {Object}
951
985
  */
952
986
  function parseOptionsJSON(data) {
953
- let obj = {};
987
+ let obj = {};
954
988
 
955
- if (!isString(data)) {
956
- return obj;
957
- }
989
+ if (!isString(data)) {
990
+ return obj;
991
+ }
958
992
 
959
- // the configuration can be specified as a data url.
960
- try {
961
- let dataUrl = parseDataURL(data);
962
- data = dataUrl.content;
963
- } catch (e) {}
993
+ // the configuration can be specified as a data url.
994
+ try {
995
+ const dataUrl = parseDataURL(data);
996
+ data = dataUrl.content;
997
+ } catch (e) {}
964
998
 
965
- try {
966
- obj = JSON.parse(data);
967
- } catch (e) {
968
- throw e;
969
- }
999
+ try {
1000
+ obj = JSON.parse(data);
1001
+ } catch (e) {
1002
+ throw e;
1003
+ }
970
1004
 
971
- return validateObject(obj);
1005
+ return validateObject(obj);
972
1006
  }
973
1007
 
974
1008
  /**
@@ -976,21 +1010,21 @@ function parseOptionsJSON(data) {
976
1010
  * @return {initHtmlContent}
977
1011
  */
978
1012
  function initHtmlContent() {
979
- try {
980
- let template = findDocumentTemplate(this.constructor.getTag());
981
- this.appendChild(template.createDocumentFragment());
982
- } catch (e) {
983
- let html = this.getOption("templates.main", "");
984
- if (isString(html) && html.length > 0) {
985
- const mapping = this.getOption("templateMapping", {});
986
- if (isObject(mapping)) {
987
- html = new Formatter(mapping).format(html);
988
- }
989
- this.innerHTML = html;
990
- }
991
- }
992
-
993
- return this;
1013
+ try {
1014
+ const template = findDocumentTemplate(this.constructor.getTag());
1015
+ this.appendChild(template.createDocumentFragment());
1016
+ } catch (e) {
1017
+ let html = this.getOption("templates.main", "");
1018
+ if (isString(html) && html.length > 0) {
1019
+ const mapping = this.getOption("templateMapping", {});
1020
+ if (isObject(mapping)) {
1021
+ html = new Formatter(mapping).format(html);
1022
+ }
1023
+ this.innerHTML = html;
1024
+ }
1025
+ }
1026
+
1027
+ return this;
994
1028
  }
995
1029
 
996
1030
  /**
@@ -1003,51 +1037,49 @@ function initHtmlContent() {
1003
1037
  * @throws {TypeError} value is not an instance of
1004
1038
  */
1005
1039
  function initCSSStylesheet() {
1006
- const self = this;
1007
-
1008
- if (!(this.shadowRoot instanceof ShadowRoot)) {
1009
- return self;
1010
- }
1011
-
1012
- const styleSheet = this.constructor.getCSSStyleSheet();
1013
-
1014
- if (styleSheet instanceof CSSStyleSheet) {
1015
- if (styleSheet.cssRules.length > 0) {
1016
- this.shadowRoot.adoptedStyleSheets = [styleSheet];
1017
- }
1018
- } else if (isArray(styleSheet)) {
1019
- const assign = [];
1020
- for (let s of styleSheet) {
1021
- if (isString(s)) {
1022
- let trimedStyleSheet = s.trim();
1023
- if (trimedStyleSheet !== "") {
1024
- const style = document.createElement("style");
1025
- style.innerHTML = trimedStyleSheet;
1026
- self.shadowRoot.prepend(style);
1027
- }
1028
- continue;
1029
- }
1030
-
1031
- validateInstance(s, CSSStyleSheet);
1032
-
1033
- if (s.cssRules.length > 0) {
1034
- assign.push(s);
1035
- }
1036
- }
1037
-
1038
- if (assign.length > 0) {
1039
- this.shadowRoot.adoptedStyleSheets = assign;
1040
- }
1041
- } else if (isString(styleSheet)) {
1042
- let trimedStyleSheet = styleSheet.trim();
1043
- if (trimedStyleSheet !== "") {
1044
- const style = document.createElement("style");
1045
- style.innerHTML = styleSheet;
1046
- self.shadowRoot.prepend(style);
1047
- }
1048
- }
1049
-
1050
- return self;
1040
+ if (!(this.shadowRoot instanceof ShadowRoot)) {
1041
+ return this;
1042
+ }
1043
+
1044
+ const styleSheet = this.constructor.getCSSStyleSheet();
1045
+
1046
+ if (styleSheet instanceof CSSStyleSheet) {
1047
+ if (styleSheet.cssRules.length > 0) {
1048
+ this.shadowRoot.adoptedStyleSheets = [styleSheet];
1049
+ }
1050
+ } else if (isArray(styleSheet)) {
1051
+ const assign = [];
1052
+ for (const s of styleSheet) {
1053
+ if (isString(s)) {
1054
+ const trimedStyleSheet = s.trim();
1055
+ if (trimedStyleSheet !== "") {
1056
+ const style = document.createElement("style");
1057
+ style.innerHTML = trimedStyleSheet;
1058
+ this.shadowRoot.prepend(style);
1059
+ }
1060
+ continue;
1061
+ }
1062
+
1063
+ validateInstance(s, CSSStyleSheet);
1064
+
1065
+ if (s.cssRules.length > 0) {
1066
+ assign.push(s);
1067
+ }
1068
+ }
1069
+
1070
+ if (assign.length > 0) {
1071
+ this.shadowRoot.adoptedStyleSheets = assign;
1072
+ }
1073
+ } else if (isString(styleSheet)) {
1074
+ const trimedStyleSheet = styleSheet.trim();
1075
+ if (trimedStyleSheet !== "") {
1076
+ const style = document.createElement("style");
1077
+ style.innerHTML = styleSheet;
1078
+ this.shadowRoot.prepend(style);
1079
+ }
1080
+ }
1081
+
1082
+ return this;
1051
1083
  }
1052
1084
 
1053
1085
  /**
@@ -1060,35 +1092,35 @@ function initCSSStylesheet() {
1060
1092
  * @since 1.8.0
1061
1093
  */
1062
1094
  function initShadowRoot() {
1063
- let template;
1064
- let html;
1065
-
1066
- try {
1067
- template = findDocumentTemplate(this.constructor.getTag());
1068
- } catch (e) {
1069
- html = this.getOption("templates.main", "");
1070
- if (!isString(html) || html === undefined || html === "") {
1071
- throw new Error("html is not set.");
1072
- }
1073
- }
1074
-
1075
- this.attachShadow({
1076
- mode: this.getOption("shadowMode", "open"),
1077
- delegatesFocus: this.getOption("delegatesFocus", true),
1078
- });
1079
-
1080
- if (template instanceof Template) {
1081
- this.shadowRoot.appendChild(template.createDocumentFragment());
1082
- return this;
1083
- }
1084
-
1085
- const mapping = this.getOption("templateMapping", {});
1086
- if (isObject(mapping)) {
1087
- html = new Formatter(mapping).format(html);
1088
- }
1089
-
1090
- this.shadowRoot.innerHTML = html;
1091
- return this;
1095
+ let template;
1096
+ let html;
1097
+
1098
+ try {
1099
+ template = findDocumentTemplate(this.constructor.getTag());
1100
+ } catch (e) {
1101
+ html = this.getOption("templates.main", "");
1102
+ if (!isString(html) || html === undefined || html === "") {
1103
+ throw new Error("html is not set.");
1104
+ }
1105
+ }
1106
+
1107
+ this.attachShadow({
1108
+ mode: this.getOption("shadowMode", "open"),
1109
+ delegatesFocus: this.getOption("delegatesFocus", true),
1110
+ });
1111
+
1112
+ if (template instanceof Template) {
1113
+ this.shadowRoot.appendChild(template.createDocumentFragment());
1114
+ return this;
1115
+ }
1116
+
1117
+ const mapping = this.getOption("templateMapping", {});
1118
+ if (isObject(mapping)) {
1119
+ html = new Formatter(mapping).format(html);
1120
+ }
1121
+
1122
+ this.shadowRoot.innerHTML = html;
1123
+ return this;
1092
1124
  }
1093
1125
 
1094
1126
  /**
@@ -1103,15 +1135,20 @@ function initShadowRoot() {
1103
1135
  * @throws {DOMException} Failed to execute 'define' on 'CustomElementRegistry': is not a valid custom element name
1104
1136
  */
1105
1137
  function registerCustomElement(element) {
1106
- validateFunction(element);
1107
- const customElements = getGlobalObject("customElements");
1108
- if (customElements === undefined) {
1109
- throw new Error("customElements is not supported.");
1110
- }
1111
-
1112
- if (customElements.get(element.getTag()) !== undefined) {
1113
- return;
1114
- }
1115
-
1116
- customElements.define(element.getTag(), element);
1138
+ validateFunction(element);
1139
+ const customElements = getGlobalObject("customElements");
1140
+ if (customElements === undefined) {
1141
+ throw new Error("customElements is not supported.");
1142
+ }
1143
+
1144
+ const tag = element?.getTag();
1145
+ if (!isString(tag) || tag === "") {
1146
+ throw new Error("tag is not set.");
1147
+ }
1148
+
1149
+ if (customElements.get(tag) !== undefined) {
1150
+ return;
1151
+ }
1152
+
1153
+ customElements.define(tag, element);
1117
1154
  }