u2ui 1.0.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 (440) hide show
  1. package/.htaccess +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +36 -0
  4. package/attr/behavior/README.md +25 -0
  5. package/attr/behavior/behavior.js +261 -0
  6. package/attr/behavior/manifest.json +43 -0
  7. package/attr/behavior/tests/minimal.html +19 -0
  8. package/attr/behavior/tests/test.html +98 -0
  9. package/attr/confirm/README.md +36 -0
  10. package/attr/confirm/confirm.js +90 -0
  11. package/attr/confirm/manifest.json +43 -0
  12. package/attr/confirm/tests/minimal.html +23 -0
  13. package/attr/confirm/tests/test.html +79 -0
  14. package/attr/draghandle/README.md +41 -0
  15. package/attr/draghandle/draghandle.js +42 -0
  16. package/attr/draghandle/tests/minimal.html +44 -0
  17. package/attr/focusgroup/README.md +49 -0
  18. package/attr/focusgroup/focusgroup.js +100 -0
  19. package/attr/focusgroup/manifest.json +38 -0
  20. package/attr/focusgroup/tests/minimal.html +27 -0
  21. package/attr/focusgroup/tests/test.html +154 -0
  22. package/attr/href/README.md +38 -0
  23. package/attr/href/href.js +42 -0
  24. package/attr/href/manifest.json +43 -0
  25. package/attr/href/tests/minimal.html +17 -0
  26. package/attr/href/tests/test.html +70 -0
  27. package/attr/intersect/README.md +42 -0
  28. package/attr/intersect/intersect.js +99 -0
  29. package/attr/intersect/manifest.json +57 -0
  30. package/attr/intersect/tests/minimal.html +30 -0
  31. package/attr/intersect/tests/test.html +64 -0
  32. package/attr/navigable/README.md +31 -0
  33. package/attr/navigable/TargetObserver.js +91 -0
  34. package/attr/navigable/U2TargetObserver.js +75 -0
  35. package/attr/navigable/manifest.json +42 -0
  36. package/attr/navigable/navigable.js +87 -0
  37. package/attr/navigable/tests/U1TargetObserver.html +56 -0
  38. package/attr/navigable/tests/minimal.html +17 -0
  39. package/attr/navigable/tests/targetObserver.html +106 -0
  40. package/attr/navigable/tests/test.html +84 -0
  41. package/attr/parallax/README.md +48 -0
  42. package/attr/parallax/parallax.js +119 -0
  43. package/attr/parallax/tests/minimal.html +25 -0
  44. package/attr/parallax/tests/performance.html +102 -0
  45. package/attr/parallax/tests/test.html +108 -0
  46. package/attr/skin/README.md +59 -0
  47. package/attr/skin/skin.css +51 -0
  48. package/attr/skin/tests/minimal.html +34 -0
  49. package/attr/skin/tests/test.html +96 -0
  50. package/class/badge/README.md +25 -0
  51. package/class/badge/badge.css +35 -0
  52. package/class/badge/tests/minimal.html +17 -0
  53. package/class/badge/tests/test.html +112 -0
  54. package/class/card1/README.md +45 -0
  55. package/class/card1/card1.css +30 -0
  56. package/class/card1/tests/minimal.html +33 -0
  57. package/class/card1/tests/test.html +78 -0
  58. package/class/flex/README.md +62 -0
  59. package/class/flex/flex.css +25 -0
  60. package/class/flex/tests/minimal.html +31 -0
  61. package/class/flex/tests/test.html +58 -0
  62. package/class/grid/README.md +52 -0
  63. package/class/grid/grid.css +40 -0
  64. package/class/grid/tests/minimal.html +34 -0
  65. package/class/grid/tests/test.html +78 -0
  66. package/class/input/README.md +49 -0
  67. package/class/input/input.css +33 -0
  68. package/class/input/tests/minimal.html +39 -0
  69. package/class/input/tests/test.html +29 -0
  70. package/class/reset/README.md +47 -0
  71. package/class/reset/reset.css +8 -0
  72. package/class/reset/tests/minimal.html +23 -0
  73. package/class/table/README.md +57 -0
  74. package/class/table/table.css +126 -0
  75. package/class/table/tests/minimal.html +40 -0
  76. package/class/table/tests/test.html +226 -0
  77. package/class/unstyle/README.md +32 -0
  78. package/class/unstyle/tests/minimal.html +22 -0
  79. package/class/unstyle/tests/test.html +32 -0
  80. package/class/unstyle/unstyle.css +12 -0
  81. package/class/width/README.md +48 -0
  82. package/class/width/tests/minimal.html +27 -0
  83. package/class/width/tests/test.html +101 -0
  84. package/class/width/width.css +22 -0
  85. package/css/base/README.md +25 -0
  86. package/css/base/base.css +127 -0
  87. package/css/base/beta.css +50 -0
  88. package/css/base/full.css +5 -0
  89. package/css/base/nomotion.css +9 -0
  90. package/css/base/print.css +36 -0
  91. package/css/base/tests/nomotion.html +89 -0
  92. package/css/base/tests/test.html +539 -0
  93. package/css/classes/README.md +17 -0
  94. package/css/classes/classes.css +78 -0
  95. package/css/classes/tests/test.html +63 -0
  96. package/css/classless/README.md +26 -0
  97. package/css/classless/aria.css +64 -0
  98. package/css/classless/classless.css +124 -0
  99. package/css/classless/full.css +11 -0
  100. package/css/classless/more.css +340 -0
  101. package/css/classless/simple.css +103 -0
  102. package/css/classless/snippeds/a/icons.css +12 -0
  103. package/css/classless/snippeds/experiments/conventions.css +41 -0
  104. package/css/classless/snippeds/hr/gradient.css +3 -0
  105. package/css/classless/snippeds/hr/section_sign.css +16 -0
  106. package/css/classless/snippeds/hr/tests.html +50 -0
  107. package/css/classless/tests/aria.html +101 -0
  108. package/css/classless/tests/foreign/classless-almond.css.html +445 -0
  109. package/css/classless/tests/foreign/classless-classless.css.html +831 -0
  110. package/css/classless/tests/foreign/classless-mvp.html +415 -0
  111. package/css/classless/tests/foreign/classless.sakura.html +224 -0
  112. package/css/classless/tests/foreign/stylestage.dev.html +304 -0
  113. package/css/classless/tests/foreign/test-homogenizer.html +433 -0
  114. package/css/classless/tests/foreign/test-html5-elements-tester.html +956 -0
  115. package/css/classless/tests/foreign/test-opinionated_css.html +148 -0
  116. package/css/classless/tests/list-bullet.html +110 -0
  117. package/css/classless/tests/more.html +246 -0
  118. package/css/classless/tests/oklch.experiments.html +280 -0
  119. package/css/classless/tests/test.html +106 -0
  120. package/css/classless/tests/variables.html +109 -0
  121. package/css/classless/variables.css +99 -0
  122. package/css/norm/README.md +37 -0
  123. package/css/norm/beta.css +40 -0
  124. package/css/norm/norm.css +98 -0
  125. package/css/norm/oldies.css +60 -0
  126. package/css/norm/tests/test.html +434 -0
  127. package/css/norm/tests/test.js +103 -0
  128. package/el/accordion/README.md +59 -0
  129. package/el/accordion/accordion.css +7 -0
  130. package/el/accordion/accordion.js +258 -0
  131. package/el/accordion/manifest.json +57 -0
  132. package/el/accordion/tests/minimal.html +44 -0
  133. package/el/accordion/tests/test.html +168 -0
  134. package/el/alert/README.md +67 -0
  135. package/el/alert/alert copy.js +224 -0
  136. package/el/alert/alert.css +73 -0
  137. package/el/alert/alert.js +187 -0
  138. package/el/alert/manifest.json +77 -0
  139. package/el/alert/tests/minimal.html +36 -0
  140. package/el/alert/tests/test.html +105 -0
  141. package/el/buttongroup/README.md +36 -0
  142. package/el/buttongroup/buttongroup.css +30 -0
  143. package/el/buttongroup/buttongroup.js +56 -0
  144. package/el/buttongroup/tests/minimal.html +31 -0
  145. package/el/buttongroup/tests/test.html +83 -0
  146. package/el/bytes/README.md +41 -0
  147. package/el/bytes/bytes.css +6 -0
  148. package/el/bytes/bytes.js +97 -0
  149. package/el/bytes/manifest.json +95 -0
  150. package/el/bytes/tests/minimal.html +19 -0
  151. package/el/bytes/tests/test.html +117 -0
  152. package/el/carousel/README.md +52 -0
  153. package/el/carousel/carousel.css +46 -0
  154. package/el/carousel/carousel.js +371 -0
  155. package/el/carousel/manifest.json +58 -0
  156. package/el/carousel/tests/experiments.html +77 -0
  157. package/el/carousel/tests/minimal.html +31 -0
  158. package/el/carousel/tests/nested.html +54 -0
  159. package/el/carousel/tests/test.html +136 -0
  160. package/el/carousel-nav/README.md +40 -0
  161. package/el/carousel-nav/carousel-nav.js +74 -0
  162. package/el/carousel-nav/tests/minimal.html +32 -0
  163. package/el/carousel-nav/tests/test.html +59 -0
  164. package/el/code/README.md +68 -0
  165. package/el/code/code.css +46 -0
  166. package/el/code/code.js +289 -0
  167. package/el/code/manifest.json +66 -0
  168. package/el/code/tests/minimal.html +35 -0
  169. package/el/code/tests/test.html +162 -0
  170. package/el/copy/README.md +35 -0
  171. package/el/copy/copy.css +3 -0
  172. package/el/copy/copy.js +118 -0
  173. package/el/copy/manifest.json +49 -0
  174. package/el/copy/tests/minimal.html +21 -0
  175. package/el/copy/tests/test.html +75 -0
  176. package/el/counter/README.md +47 -0
  177. package/el/counter/counter.css +8 -0
  178. package/el/counter/counter.js +95 -0
  179. package/el/counter/manifest.json +59 -0
  180. package/el/counter/tests/minimal.html +27 -0
  181. package/el/counter/tests/test.html +106 -0
  182. package/el/ico/README.md +162 -0
  183. package/el/ico/font/Font Awesome.css +22 -0
  184. package/el/ico/font/LigatureSymbols.css +7 -0
  185. package/el/ico/font/Material Icons.css +6 -0
  186. package/el/ico/font/RemixFilled.css +8 -0
  187. package/el/ico/font/RemixOutlined.css +8 -0
  188. package/el/ico/font/old/anicons.css +31 -0
  189. package/el/ico/font/old/devicons.css +210 -0
  190. package/el/ico/font/old/material.all.css +36 -0
  191. package/el/ico/font/old/remix.css +15 -0
  192. package/el/ico/font/old/utf8.css +54 -0
  193. package/el/ico/ico.css +111 -0
  194. package/el/ico/ico.js +189 -0
  195. package/el/ico/manifest.json +86 -0
  196. package/el/ico/tests/combinations.html +86 -0
  197. package/el/ico/tests/emojis.html +213 -0
  198. package/el/ico/tests/fonts.html +110 -0
  199. package/el/ico/tests/ico-directory.html +254 -0
  200. package/el/ico/tests/minimal.html +46 -0
  201. package/el/ico/tests/test.html +210 -0
  202. package/el/ico/tests/util-multi.svg +6 -0
  203. package/el/ico/tests/util.css +2 -0
  204. package/el/ico/tests/util.js +110 -0
  205. package/el/input/README.md +39 -0
  206. package/el/input/input.css +35 -0
  207. package/el/input/input.js +331 -0
  208. package/el/input/tests/formParticipation.html +113 -0
  209. package/el/input/tests/minimal.html +33 -0
  210. package/el/input/tests/test.html +258 -0
  211. package/el/masonry/README.md +51 -0
  212. package/el/masonry/manifest.json +60 -0
  213. package/el/masonry/masonry.css +27 -0
  214. package/el/masonry/masonry.js +92 -0
  215. package/el/masonry/tests/minimal.html +39 -0
  216. package/el/masonry/tests/test.html +42 -0
  217. package/el/number/README.md +47 -0
  218. package/el/number/manifest.json +121 -0
  219. package/el/number/number.css +6 -0
  220. package/el/number/number.js +67 -0
  221. package/el/number/tests/minimal.html +25 -0
  222. package/el/number/tests/test.html +138 -0
  223. package/el/out/README.md +32 -0
  224. package/el/out/manifest.json +38 -0
  225. package/el/out/out.css +2 -0
  226. package/el/out/out.js +59 -0
  227. package/el/out/tests/minimal.html +25 -0
  228. package/el/out/tests/test.html +37 -0
  229. package/el/parallax-bg/README.md +36 -0
  230. package/el/parallax-bg/parallax-bg.css +13 -0
  231. package/el/parallax-bg/parallax-bg.js +186 -0
  232. package/el/parallax-bg/tests/bg.jpg +0 -0
  233. package/el/parallax-bg/tests/bg1.jpg +0 -0
  234. package/el/parallax-bg/tests/bg2.jpg +0 -0
  235. package/el/parallax-bg/tests/demo.html +88 -0
  236. package/el/parallax-bg/tests/minimal.html +30 -0
  237. package/el/parallax-bg/tests/test.html +64 -0
  238. package/el/parallax-bg/tests/visible.html +90 -0
  239. package/el/qrcode/README.md +38 -0
  240. package/el/qrcode/manifest.json +43 -0
  241. package/el/qrcode/package.json +22 -0
  242. package/el/qrcode/qrcode.css +13 -0
  243. package/el/qrcode/qrcode.js +46 -0
  244. package/el/qrcode/tests/minimal.html +26 -0
  245. package/el/qrcode/tests/test.html +31 -0
  246. package/el/rating/README.md +45 -0
  247. package/el/rating/manifest.json +65 -0
  248. package/el/rating/rating.css +11 -0
  249. package/el/rating/rating.js +139 -0
  250. package/el/rating/tests/minimal.html +26 -0
  251. package/el/rating/tests/tests.html +77 -0
  252. package/el/rte/README.md +37 -0
  253. package/el/rte/rte.css +9 -0
  254. package/el/rte/rte.js +56 -0
  255. package/el/rte/tests/minimal.html +25 -0
  256. package/el/rte/tests/test.html +37 -0
  257. package/el/skeleton/README.md +30 -0
  258. package/el/skeleton/manifest.json +51 -0
  259. package/el/skeleton/skeleton.css +61 -0
  260. package/el/skeleton/skeleton.js +72 -0
  261. package/el/skeleton/tests/minimal.html +22 -0
  262. package/el/skeleton/tests/test.html +22 -0
  263. package/el/splitbutton/README.md +39 -0
  264. package/el/splitbutton/splitbutton.css +48 -0
  265. package/el/splitbutton/splitbutton.js +26 -0
  266. package/el/splitbutton/tests/minimal.html +30 -0
  267. package/el/splitbutton/tests/test.html +68 -0
  268. package/el/splitpanel/README.md +39 -0
  269. package/el/splitpanel/manifest.json +49 -0
  270. package/el/splitpanel/splitpanel.css +17 -0
  271. package/el/splitpanel/splitpanel.js +116 -0
  272. package/el/splitpanel/tests/minimal.html +31 -0
  273. package/el/splitpanel/tests/tests.html +121 -0
  274. package/el/table/README.md +68 -0
  275. package/el/table/manifest.json +43 -0
  276. package/el/table/table.css +59 -0
  277. package/el/table/table.js +194 -0
  278. package/el/table/tests/minimal.html +38 -0
  279. package/el/table/tests/test.html +108 -0
  280. package/el/tabs/README.md +50 -0
  281. package/el/tabs/manifest.json +59 -0
  282. package/el/tabs/tabs.css +23 -0
  283. package/el/tabs/tabs.js +210 -0
  284. package/el/tabs/tests/minimal.html +35 -0
  285. package/el/tabs/tests/test.html +180 -0
  286. package/el/textfit/README.md +34 -0
  287. package/el/textfit/manifest.json +45 -0
  288. package/el/textfit/tests/minimal.html +25 -0
  289. package/el/textfit/tests/test.html +26 -0
  290. package/el/textfit/textfit.css +6 -0
  291. package/el/textfit/textfit.js +80 -0
  292. package/el/time/README.md +72 -0
  293. package/el/time/manifest.json +118 -0
  294. package/el/time/tests/minimal.html +19 -0
  295. package/el/time/tests/test.html +160 -0
  296. package/el/time/time copy.js +141 -0
  297. package/el/time/time.js +168 -0
  298. package/el/time/time.old.uhtml.js +129 -0
  299. package/el/tooltip/README.md +48 -0
  300. package/el/tooltip/manifest.json +69 -0
  301. package/el/tooltip/tests/minimal.html +25 -0
  302. package/el/tooltip/tests/test.html +178 -0
  303. package/el/tooltip/tooltip.css +97 -0
  304. package/el/tooltip/tooltip.js +82 -0
  305. package/el/tree1/README.md +111 -0
  306. package/el/tree1/manifest.json +78 -0
  307. package/el/tree1/tests/animated.html +134 -0
  308. package/el/tree1/tests/custom.html +51 -0
  309. package/el/tree1/tests/minimal.html +44 -0
  310. package/el/tree1/tests/test.html +260 -0
  311. package/el/tree1/tree1.css +26 -0
  312. package/el/tree1/tree1.js +265 -0
  313. package/el/typewriter/README.md +62 -0
  314. package/el/typewriter/manifest.json +66 -0
  315. package/el/typewriter/tests/minimal.html +25 -0
  316. package/el/typewriter/tests/test.html +78 -0
  317. package/el/typewriter/typewriter.css +6 -0
  318. package/el/typewriter/typewriter.js +166 -0
  319. package/el/typewriter/typewriter.mp3 +0 -0
  320. package/js/Placer/Placer.js +156 -0
  321. package/js/Placer/README.md +62 -0
  322. package/js/Placer/tests/minimal.html +34 -0
  323. package/js/Placer/tests/test.html +49 -0
  324. package/js/PointerObserver/PointerObserver.js +130 -0
  325. package/js/PointerObserver/README.md +34 -0
  326. package/js/PointerObserver/tests/minimal.html +29 -0
  327. package/js/PointerObserver/tests/test.html +35 -0
  328. package/js/SelectorObserver/README.md +47 -0
  329. package/js/SelectorObserver/SelectorObserver.js +201 -0
  330. package/js/SelectorObserver/tests/minimal.html +21 -0
  331. package/js/SelectorObserver/tests/test.html +57 -0
  332. package/js/SelectorObserver/tests/tests.html +161 -0
  333. package/js/contextmenu/README.md +93 -0
  334. package/js/contextmenu/contextmenu.js +336 -0
  335. package/js/contextmenu/tests/minimal.html +44 -0
  336. package/js/contextmenu/tests/test.html +131 -0
  337. package/js/dialog/README.md +49 -0
  338. package/js/dialog/dialog.js +261 -0
  339. package/js/dialog/notification.mp3 +0 -0
  340. package/js/dialog/tests/minimal.html +29 -0
  341. package/js/dialog/tests/notification.mp3 +0 -0
  342. package/js/dialog/tests/test.html +135 -0
  343. package/js/rte/README.md +44 -0
  344. package/js/rte/old/NodeCleaner.js +315 -0
  345. package/js/rte/old/Rte/Rte.mjs +316 -0
  346. package/js/rte/old/Rte/Rte.ui.items.mjs +543 -0
  347. package/js/rte/old/Rte/Rte.ui.mjs +154 -0
  348. package/js/rte/old/Rte/crossbrowser.mjs +323 -0
  349. package/js/rte/old/Rte/font/tinymce.svg +98 -0
  350. package/js/rte/old/Rte/font/tinymce.woff +0 -0
  351. package/js/rte/old/Rte/helpers.mjs +159 -0
  352. package/js/rte/old/Rte/htmlparser.mjs +178 -0
  353. package/js/rte/old/Rte/index.mjs +5 -0
  354. package/js/rte/old/Rte/main.css +189 -0
  355. package/js/rte/old/old.rte.js +132 -0
  356. package/js/rte/old/range-selection.old.js +394 -0
  357. package/js/rte/rte.js +7 -0
  358. package/js/rte/src/behavior.js +228 -0
  359. package/js/rte/src/events.js +73 -0
  360. package/js/rte/src/fixes.js +251 -0
  361. package/js/rte/src/range.js +472 -0
  362. package/js/rte/src/rte.js +72 -0
  363. package/js/rte/src/ui/items/ai.js +167 -0
  364. package/js/rte/src/ui/items/code.js +93 -0
  365. package/js/rte/src/ui/items/undo.js +183 -0
  366. package/js/rte/src/ui.items.js +571 -0
  367. package/js/rte/src/ui.js +269 -0
  368. package/js/rte/src/util/htmlparser.js +178 -0
  369. package/js/rte/src/util/indentHtml.js +48 -0
  370. package/js/rte/tests/ai.html +81 -0
  371. package/js/rte/tests/behavior.html +88 -0
  372. package/js/rte/tests/events.html +69 -0
  373. package/js/rte/tests/fixes.html +95 -0
  374. package/js/rte/tests/minimal.html +34 -0
  375. package/js/rte/tests/notes.md +6 -0
  376. package/js/rte/tests/range.html +167 -0
  377. package/js/rte/tests/selection-explorer.html +222 -0
  378. package/js/rte/tests/test.html +92 -0
  379. package/js/shortcut/README.md +33 -0
  380. package/js/shortcut/shortcut.js +89 -0
  381. package/js/shortcut/tests/minimal.html +23 -0
  382. package/js/shortcut/tests/test.html +68 -0
  383. package/package.json +12 -0
  384. package/u2/README.md +4 -0
  385. package/u2/auto.js +161 -0
  386. package/u2/auto.ui.js +85 -0
  387. package/u2/experiments/Waiter/test.html +132 -0
  388. package/u2/experiments/getElementByIdPromise/test.html +76 -0
  389. package/u2/experiments/patchInputValue.html +124 -0
  390. package/u2/experiments/radiobutton/test.html +75 -0
  391. package/u2/experiments/tests/test.html +223 -0
  392. package/u2/experiments/u1-responsive/responsive.js +62 -0
  393. package/u2/experiments/u1-responsive/test.html +65 -0
  394. package/u2/experiments/u2Element.js +139 -0
  395. package/u2/experiments/u2Element.test.html +47 -0
  396. package/u2/old-stuff/IterableWeakMap/mod.js +70 -0
  397. package/u2/old-stuff/css/onStyleSheet/mod.js +114 -0
  398. package/u2/old-stuff/css/onStyleSheet/monkeypatches.js +28 -0
  399. package/u2/old-stuff/css/onStyleSheet/test/include.css +19 -0
  400. package/u2/old-stuff/css/onStyleSheet/test/style-has-include.css +6 -0
  401. package/u2/old-stuff/css/onStyleSheet/test/style-no-include.css +3 -0
  402. package/u2/old-stuff/css/onStyleSheet/test/test.html +48 -0
  403. package/u2/old-stuff/css/parser/mod.js +182 -0
  404. package/u2/old-stuff/css/parser/parser_old/mod.js +128 -0
  405. package/u2/old-stuff/css/parser/parser_old/test.html +43 -0
  406. package/u2/old-stuff/css/parser/parser_old/util.js +22 -0
  407. package/u2/old-stuff/css/parser/style.html +52 -0
  408. package/u2/old-stuff/css/parser/test.html +38 -0
  409. package/u2/old-stuff/el/ai-texter/README.md +23 -0
  410. package/u2/old-stuff/el/ai-texter/ai-texter.css +12 -0
  411. package/u2/old-stuff/el/ai-texter/ai-texter.js +153 -0
  412. package/u2/old-stuff/el/ai-texter/tests/minimal.html +47 -0
  413. package/u2/old-stuff/el/ai-texter/tests/test.html +71 -0
  414. package/u2/old-stuff/init.js +38 -0
  415. package/u2/old-stuff/markHashLinks.js +51 -0
  416. package/u2/old-stuff/onElement/mod.js +73 -0
  417. package/u2/old-stuff/test-helpers/mod.js +36 -0
  418. package/u2/old-stuff/test-helpers/test.html +4 -0
  419. package/u2/old-stuff/tests/init.js.html +51 -0
  420. package/u2/old-stuff/viewport.js +64 -0
  421. package/u2/projects.json +468 -0
  422. package/u2/tests/boilerplate.html +46 -0
  423. package/u2/tests/kacheln.html +245 -0
  424. package/u2/tests/showcase.html +270 -0
  425. package/u2/tests/showcase2.html +157 -0
  426. package/u2/tests/test-init.js +35 -0
  427. package/u2/tests/test.html +355 -0
  428. package/u2/tools/baseElement.js +95 -0
  429. package/u2/tools/baseElement.test.html +119 -0
  430. package/u2/tools/ce-inspector.js +308 -0
  431. package/u2/tools/ce-inspector.test.html +66 -0
  432. package/u2/tools/ce-manfest-from-element.js +207 -0
  433. package/u2/tools/dev-iframe.js +213 -0
  434. package/u2/tools/dev-iframe.test.html +75 -0
  435. package/u2/tools/eventsExplorer.js +101 -0
  436. package/u2/tools/logo/u1.svg +9 -0
  437. package/u2/tools/logo/u1ui.svg +6 -0
  438. package/u2/tools/update.repos.json.js +234 -0
  439. package/u2/u2.js +14 -0
  440. package/u2/utils.js +59 -0
@@ -0,0 +1,42 @@
1
+ /* Copyright (c) 2016 Tobias Buschor https://goo.gl/gl0mbf | MIT License https://goo.gl/HgajeK */
2
+
3
+ document.addEventListener('click', e => {
4
+ if (e.button !== 0) return; // only left-click
5
+ if (e.defaultPrevented) return; // not if prevented
6
+ const sel = getSelection();
7
+ if (!sel.isCollapsed) { // only if the selection is collapsed.
8
+ const textSelected = sel.anchorNode.nodeType === 3 || sel.focusNode.nodeType === 3;
9
+ const shadowElSelected = sel.focusNode.nodeType === 11; // svg-use-element, firefox
10
+ if (textSelected && !shadowElSelected) return;
11
+ }
12
+ if (!e.target.closest) return; // some targets have no closest method?
13
+ const A = e.target.closest('[u2-href]');
14
+ if (!A) return;
15
+ if (e.target.closest('a,input,textarea,select,button,label')) return;
16
+ //if (e.target.closest('[onclick]')) return; //
17
+ //if (e.target.closest(c1.href.ignoreSelector)) return;
18
+ if (e.target.isContentEditable) return; // not if contenteditable
19
+ const href = A.getAttribute('u2-href'); // get the url
20
+ if (!href) return;
21
+
22
+ const url = new URL(href, location.href); // security check, as its not a standard attribute, puryfiers will probably not remove it
23
+ if (url.protocol === 'javascript:') return;
24
+
25
+ let target = A.getAttribute('u2-href-target'); // get the target
26
+ if (e.ctrlKey) target = '_blank'; // better random-string?
27
+ // var event = new CustomEvent('u2-href-navigate', { // trigger custom event with the ability to prevent Navigation
28
+ // cancelable: true,
29
+ // detail: {
30
+ // url: href,
31
+ // target: target,
32
+ // }
33
+ // });
34
+ // window.dispatchEvent(event);
35
+ // if (event.defaultPrevented) return;
36
+ if (target) {
37
+ window.open(href, target, 'noopener'); //!e.ctrlKey && win.focus(); // not needed in chrome, not working in ff
38
+ } else {
39
+ location.href = href;
40
+ }
41
+ });
42
+ document.head.insertAdjacentHTML('afterbegin', '<style>:where([u2-href]){cursor:pointer}</style>');
@@ -0,0 +1,43 @@
1
+ {
2
+ "schemaVersion": "1.0.0",
3
+ "readme": "README.md",
4
+ "modules": [
5
+ {
6
+ "kind": "javascript-module",
7
+ "path": "href.js",
8
+ "declarations": [
9
+ {
10
+ "summary": "Turn every element in a link",
11
+ "description": "This attribute allows you to turn any element into a link by simply adding the `u2-href` attribute to it.\n`Ctrl + click` will open the link in a new tab.\nClicks on interactive elements inside the pseudo-link element prevent the link from being opened.\nXSS attacks are prevented by disallowing the `javascript:` protocol.",
12
+ "name": "u2-href",
13
+ "members": [],
14
+ "events": [],
15
+ "attributes": [
16
+ {
17
+ "name": "u2-href",
18
+ "description": "The URL that the hyperlink points to.",
19
+ "u2Examples": ["", "https://www.google.com", "./test.html", "#section1"]
20
+ },{
21
+ "name": "u2-href-target",
22
+ "description": "The target attribute specifies where to open the linked document.",
23
+ "u2Examples": ["_blank", "myFrame"]
24
+ }
25
+ ],
26
+ "cssProperties": [],
27
+ "attributeName": "u2-href"
28
+ }
29
+ ],
30
+ "exports": [
31
+ {
32
+ "kind": "custom-attribute-definition",
33
+ "name": "u2-href",
34
+ "declaration": {
35
+ "name": "u2-href",
36
+ "module": "href.js"
37
+ }
38
+ }
39
+ ]
40
+ }
41
+ ]
42
+ }
43
+
@@ -0,0 +1,17 @@
1
+ <!DOCTYPE html>
2
+ <html lang=en>
3
+ <head>
4
+ <meta charset=utf-8>
5
+ <meta name=viewport content="width=device-width">
6
+ <script src="../../../u2/tests/test-init.js" type=module async></script>
7
+
8
+ <script src="../href.js" type=module async></script>
9
+
10
+ <body>
11
+
12
+ <section class=main>
13
+ <div u2-href="http://schwups.ch" u2-href-target=_blank>
14
+ Pseudo link
15
+ </div>
16
+ </section>
17
+
@@ -0,0 +1,70 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width">
6
+ <script src="../../../u2/tests/test-init.js" type=module async></script>
7
+ <title>Attribute u2-href tests</title>
8
+
9
+ <link rel=stylesheet href="../../../css/classless/full.css">
10
+ <link rel=stylesheet href="../../../css/classless/simple.css">
11
+
12
+ <script src="../href.js"></script>
13
+
14
+ <body>
15
+
16
+ <div u2-href="https://github.com/u2ui" class=pseudoLink>
17
+ <h1>I am a DIV and i act like a link</h1>
18
+ <ul>
19
+ <li>Elements using the u2-href-attribute have a cursor:pointer</li>
20
+ <li>Try <mark>ctrl-click</mark>, the link shoul open in a new tab</li>
21
+ <li>Try <mark>right or middle mouse button</mark> the link does not work</li>
22
+ <li>If you <mark>Select some text</mark> the link does not work</li>
23
+ <li>
24
+ <button> if you click the button, the u2-href does not work</button>
25
+ </li>
26
+ <li>
27
+ <label>
28
+ Label
29
+ <input value="and inputs also prevents navigation" style="width:200px">
30
+ </label>
31
+ </li>
32
+ <li contenteditable>
33
+ I am contenteditable, h1-href does not navigate
34
+ </li>
35
+ <li onclick="event.preventDefault()">I am a li that prevents the click-default, it also prevents c1-href from navigate (<code>onclick="event.preventDefault()"</code>)</li>
36
+ </ul>
37
+ </div>
38
+
39
+ <div u2-href="https://github.com/u2ui" u2-href-target=_blank class=pseudoLink>
40
+ A u2-href link with the attribute <code>u2-href-target="_blank"</code><br>
41
+ Opens in a new window
42
+ </div>
43
+
44
+
45
+ <div u2-href="https://github.com/u2ui" class=pseudoLink tabindex="0">
46
+ This u2-href link is keyboard-accessible through it has "tabindex"-attribute<br>
47
+ It will not trigger navigation if it is focused and you press enter, should it?<br>
48
+ If you have usecase, please let me know.
49
+ </div>
50
+
51
+
52
+ <div u2-href="./" class=pseudoLink>
53
+ relative links "./"
54
+ </div>
55
+
56
+ <div u2-href=" &#14; jAvascript:alert('xss')" class=pseudoLink>
57
+ security, should not execute u2-href=" &amp;#14; jAvascript:alert('xss')"
58
+ </div>
59
+
60
+ <style>
61
+ li {
62
+ padding:1rem;
63
+ }
64
+ .pseudoLink {
65
+ margin:1rem;
66
+ border:1px solid red;
67
+ background:#ffe;
68
+ padding:1rem;
69
+ }
70
+ </style>
@@ -0,0 +1,42 @@
1
+ # [u2-intersect] - attribute
2
+ declarativ intersection-observer
3
+
4
+ ## Usage
5
+
6
+ ```html
7
+ <div u2-intersect>intersect</div>
8
+ <div u2-intersect>item 2</div>
9
+ <div u2-intersect>item 3</div>
10
+ ```
11
+
12
+ ```css
13
+ [u2-intersect] {
14
+ --u2-intersect-margin:-10%;
15
+ --u2-intersect-threshold:1;
16
+ background:#fbb;
17
+ }
18
+ [u2-intersect].u2-intersected { background:#bfb; }
19
+ [u2-intersect]::after {
20
+ display:block;
21
+ content:'below';
22
+ }
23
+ [u2-intersect].u2-intersected::after { content:'intersected'; }
24
+ [u2-intersect~="above"]::after { content:'above' }
25
+ ```
26
+
27
+ ## Install
28
+
29
+ ```html
30
+ <script src="https://cdn.jsdelivr.net/gh/u2ui/u2@x.x.x/attr/intersect/intersect.min.js" type=module async></script>
31
+ ```
32
+
33
+ ## Demos
34
+
35
+ [minimal.html](http://gcdn.li/u2ui/u2@main/attr/intersect/tests/minimal.html)
36
+ [test.html](http://gcdn.li/u2ui/u2@main/attr/intersect/tests/test.html)
37
+
38
+ ## About
39
+
40
+ - MIT License, Copyright (c) 2022 <u2> (like all repositories in this organization) <br>
41
+ - Suggestions, ideas, finding bugs and making pull requests make us very happy. ♥
42
+
@@ -0,0 +1,99 @@
1
+ /* Copyright (c) 2016 Tobias Buschor https://goo.gl/gl0mbf | MIT License https://goo.gl/HgajeK */
2
+
3
+ import {SelectorObserver} from '../../js/SelectorObserver/SelectorObserver.js'
4
+
5
+ new SelectorObserver({
6
+ on: (el) => {
7
+ //const el = this.element;
8
+ const style = getComputedStyle(el);
9
+ const threshold = parseFloat(style.getPropertyValue('--u2-intersect-threshold').trim()) || 0;
10
+ const margin = style.getPropertyValue('--u2-intersect-margin') || '0px';
11
+
12
+ const thresholds = new Set([threshold, 0, 1, 0.5]);
13
+
14
+ el.u2IntersectionObserver = new IntersectionObserver(entries=>{
15
+ let attrValue = '';
16
+ const entry = entries[0];
17
+ let ratio = entry.intersectionRatio;
18
+ let onTarget = false;
19
+ if (entry.isIntersecting) {
20
+ for (const val of thresholds) {
21
+ if (ratio >= val) attrValue += ' '+val;
22
+ }
23
+ if (ratio >= threshold) onTarget = true;
24
+ }
25
+
26
+
27
+ if (entry.boundingClientRect.top + entry.boundingClientRect.height / 2 < innerHeight / 2) {
28
+ attrValue += ' above';
29
+ }
30
+
31
+ attrValue = attrValue.trim();
32
+ el.setAttribute('u2-intersect', attrValue);
33
+ el.classList[onTarget?'add':'remove']('u2-intersected');
34
+
35
+ const event = new CustomEvent('u2-intersect.'+(onTarget?'enter':'leave'), {bubbles:true} );
36
+ el.dispatchEvent(event);
37
+ }, {
38
+ //root: document.scrollingElement,
39
+ rootMargin: margin,
40
+ threshold: thresholds,
41
+ });
42
+ el.u2IntersectionObserver.observe(el);
43
+
44
+ },
45
+ off: (el) => {
46
+ if (el.u2IntersectionObserver) el.u2IntersectionObserver.unobserve(el);
47
+ }
48
+ }).observe('[u2-intersect]');
49
+
50
+ /*
51
+ old code:
52
+ import 'https://cdn.jsdelivr.net/npm/wicked-elements@3.1.2/min.js';
53
+ wickedElements.define(
54
+ '[u2-intersect]', {
55
+ init() {},
56
+ connected() {
57
+ const el = this.element;
58
+ const style = getComputedStyle(el);
59
+ const threshold = parseFloat(style.getPropertyValue('--u2-intersect-threshold').trim()) || 0;
60
+ const margin = style.getPropertyValue('--u2-intersect-margin') || '0px';
61
+
62
+ const thresholds = new Set([threshold, 0, 1, 0.5]);
63
+
64
+ this.u2IntersectionObserver = new IntersectionObserver(entries=>{
65
+ let attrValue = '';
66
+ const entry = entries[0];
67
+ let ratio = entry.intersectionRatio;
68
+ let onTarget = false;
69
+ if (entry.isIntersecting) {
70
+ for (const val of thresholds) {
71
+ if (ratio >= val) attrValue += ' '+val;
72
+ }
73
+ if (ratio >= threshold) onTarget = true;
74
+ }
75
+
76
+
77
+ if (entry.boundingClientRect.top + entry.boundingClientRect.height / 2 < innerHeight / 2) {
78
+ attrValue += ' above';
79
+ }
80
+
81
+ attrValue = attrValue.trim();
82
+ el.setAttribute('u2-intersect', attrValue);
83
+ el.classList[onTarget?'add':'remove']('u2-intersected');
84
+
85
+ //var event = new CustomEvent('u2-intersected-'+(onTarget?'in':'out'), /*{bubbles:true}* / );
86
+ //el.dispatchEvent(event);
87
+ }, {
88
+ //root: document.scrollingElement,
89
+ rootMargin: margin,
90
+ threshold: thresholds,
91
+ });
92
+ this.u2IntersectionObserver.observe(el);
93
+ },
94
+ disconnected() {
95
+ this.u2IntersectionObserver.unobserve(el);
96
+ },
97
+ }
98
+ );
99
+ */
@@ -0,0 +1,57 @@
1
+ {
2
+ "schemaVersion": "1.0.0",
3
+ "readme": "README.md",
4
+ "modules": [
5
+ {
6
+ "kind": "javascript-module",
7
+ "path": "intersect.js",
8
+ "declarations": [
9
+ {
10
+ "summary": "Declarativ intersection-observer",
11
+ "description": "This attribute allows you to turn any element into a link by simply adding the `u2-intersect` attribute to it.\n`Ctrl + click` will open the link in a new tab.\nClicks on interactive elements inside the pseudo-link element prevent the link from being opened.\nXSS attacks are prevented by disallowing the `javascript:` protocol.",
12
+ "name": "u2-intersect",
13
+ "members": [],
14
+ "events": [
15
+ {
16
+ "name": "u2-intersect.enter",
17
+ "description": "Fired when the element intersects with the viewport."
18
+ },{
19
+ "name": "u2-intersect.leave",
20
+ "description": "Fired when the element leaves the viewport."
21
+ }
22
+ ],
23
+ "attributes": [
24
+ {
25
+ "name": "u2-intersect",
26
+ "description": "Enables the intersection observer on the element.",
27
+ "u2Examples": ["", "https://www.google.com", "./test.html", "#section1"]
28
+ }
29
+ ],
30
+ "cssProperties": [
31
+ {
32
+ "name": "--u2-intersect-margin",
33
+ "description": "The margin around the element that will trigger the intersection observer.",
34
+ "syntax": "<length>"
35
+ },{
36
+ "name": "--u2-intersect-threshold",
37
+ "description": "The threshold at which the intersection observer will trigger.",
38
+ "syntax": "<number>"
39
+ }
40
+ ],
41
+ "attributeName": "u2-intersect"
42
+ }
43
+ ],
44
+ "exports": [
45
+ {
46
+ "kind": "custom-attribute-definition",
47
+ "name": "u2-intersect",
48
+ "declaration": {
49
+ "name": "u2-intersect",
50
+ "module": "intersect.js"
51
+ }
52
+ }
53
+ ]
54
+ }
55
+ ]
56
+ }
57
+
@@ -0,0 +1,30 @@
1
+ <!DOCTYPE html>
2
+ <html lang=en>
3
+ <head>
4
+ <meta charset=utf-8>
5
+ <meta name=viewport content="width=device-width">
6
+
7
+ <script src="../intersect.js" type=module async></script>
8
+
9
+ <body>
10
+
11
+ <section class="main">
12
+ <div u2-intersect>intersect</div>
13
+ <div u2-intersect>item 2</div>
14
+ <div u2-intersect>item 3</div>
15
+ </section>
16
+
17
+ <style class="main">
18
+ [u2-intersect] {
19
+ --u2-intersect-margin:-10%;
20
+ --u2-intersect-threshold:1;
21
+ background:#fbb;
22
+ }
23
+ [u2-intersect].u2-intersected { background:#bfb; }
24
+ [u2-intersect]::after {
25
+ display:block;
26
+ content:'below';
27
+ }
28
+ [u2-intersect].u2-intersected::after { content:'intersected'; }
29
+ [u2-intersect~="above"]::after { content:'above' }
30
+ </style>
@@ -0,0 +1,64 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width">
6
+ <title>Attribute u2-href tests</title>
7
+
8
+ <link rel=stylesheet href="../../../css/classless/full.css">
9
+ <!--link rel=stylesheet href="../../../css/classless/simple.css"-->
10
+
11
+ <script src="../intersect.js" type=module async></script>
12
+
13
+ <body>
14
+
15
+ <style>
16
+ [u2-intersect] {
17
+ border:2px solid;
18
+ padding:2rem;
19
+ margin:5rem auto;
20
+ background:red;
21
+ width:50%;
22
+ }
23
+ [u2-intersect].u2-intersected {
24
+ background:green;
25
+ }
26
+ [u2-intersect~="above"] {
27
+ background:orange;
28
+ }
29
+
30
+ </style>
31
+
32
+
33
+ <div style="position:fixed; top:0; left:0; right:0; bottom:0; opacity:0.2; z-index:-1; border:20vh solid #A49CE1; border-width:20vh 20vw"></div>
34
+
35
+ <div>
36
+ <div u2-intersect style="height:20vh; --u2-intersect-margin:0%; --u2-intersect-threshold:0;" >
37
+ --u2-intersect-margin:0;<br>
38
+ --u2-intersect-threshold:0;
39
+ </div>
40
+ <div u2-intersect style="height:20vh; --u2-intersect-margin:-20%; --u2-intersect-threshold:0;" >
41
+ --u2-intersect-margin:-20%;<br>
42
+ --u2-intersect-threshold:0;
43
+ </div>
44
+ <div u2-intersect style="height:20vh; --u2-intersect-margin:-20%; --u2-intersect-threshold:1;" >
45
+ --u2-intersect-margin:-20%;<br>
46
+ --u2-intersect-threshold:1;
47
+ </div>
48
+ <div u2-intersect style="height:20vh; --u2-intersect-margin:-20%; --u2-intersect-threshold:0.25;" >
49
+ --u2-intersect-margin:-20%;<br>
50
+ --u2-intersect-threshold:0.25;
51
+ </div>
52
+ <div u2-intersect style="height:20vh;" class=selector1>
53
+ <style style="display:block; font-size:.9rem">
54
+ .selector1:not([u2-intersect~="0.5"]) {
55
+ background:red;
56
+ }
57
+ .selector1:not([u2-intersect~="0.5"])[u2-intersect~="above"] {
58
+ background:orange;
59
+ }
60
+ </style>
61
+ </div>
62
+
63
+ <div style="height:100vh"></div>
64
+ </div>
@@ -0,0 +1,31 @@
1
+ # [u2-navigable] - attribute
2
+ Make elements navigatable
3
+
4
+ ## Usage
5
+
6
+ ```html
7
+ Link to navigable dialog:<br>
8
+ <a href="#navigable">open</a>
9
+ <dialog u2-navigable id=navigable>
10
+ go back using esc or your browser's back button
11
+ </dialog>
12
+ ```
13
+
14
+ ## Install
15
+
16
+ ```html
17
+ <script src="https://cdn.jsdelivr.net/gh/u2ui/u2@x.x.x/attr/navigable/navigable.min.js" type=module async></script>
18
+ ```
19
+
20
+ ## Demos
21
+
22
+ [minimal.html](http://gcdn.li/u2ui/u2@main/attr/navigable/tests/minimal.html)
23
+ [targetObserver.html](http://gcdn.li/u2ui/u2@main/attr/navigable/tests/targetObserver.html)
24
+ [test.html](http://gcdn.li/u2ui/u2@main/attr/navigable/tests/test.html)
25
+ [U1TargetObserver.html](http://gcdn.li/u2ui/u2@main/attr/navigable/tests/U1TargetObserver.html)
26
+
27
+ ## About
28
+
29
+ - MIT License, Copyright (c) 2022 <u2> (like all repositories in this organization) <br>
30
+ - Suggestions, ideas, finding bugs and making pull requests make us very happy. ♥
31
+
@@ -0,0 +1,91 @@
1
+ // checks for hashchange and element matches
2
+
3
+ const observers = new Set();
4
+
5
+ export class TargetObserver {
6
+
7
+ /**
8
+ * @param {Object} opts
9
+ * @param {Function} opts.on - called when a element is the target
10
+ * @param {Function} opts.off - called when a element lost the target
11
+ * @param {Function} opts.in - called when a element or a descendant is the target
12
+ * @param {Function} opts.out - called when a element lost the target including descendants
13
+ * @param {String} opts.matches - CSS selector for elements we listen to
14
+ */
15
+ constructor(opts) {
16
+ this.opts = opts;
17
+ observers.add(this);
18
+ this.parentTargets = new Set();
19
+ this._testOn(active);
20
+ }
21
+
22
+ /**
23
+ * @description stops listening
24
+ */
25
+ disconnect() {
26
+ observers.delete(this);
27
+ }
28
+
29
+ /**
30
+ * @param {Element} el
31
+ * @private
32
+ */
33
+ _matches(el){
34
+ if (!el) return false;
35
+ return this.opts.matches==null || el.matches(this.opts.matches);
36
+ }
37
+
38
+ /**
39
+ * @param {Element} el
40
+ * @private
41
+ */
42
+ _testOn(el){
43
+ this.opts.on && this._matches(el) && this.opts.on(el);
44
+ if (this.opts.in && el) { // todo: && this.opts.matches ??
45
+ let closest = el.closest(this.opts.matches);
46
+ while (closest) {
47
+ this.opts.in(closest);
48
+ this.parentTargets.add(closest);
49
+ closest = closest.parentNode.closest(this.opts.matches);
50
+ }
51
+ }
52
+ for (const pTarget of this.parentTargets) {
53
+ if (el && pTarget.contains(el)) continue;
54
+ this.opts?.out(pTarget);
55
+ this.parentTargets.delete(pTarget);
56
+ }
57
+ }
58
+
59
+ /**
60
+ * @param {Element} el
61
+ * @private
62
+ */
63
+ _testOff(el){
64
+ this.opts.off && this._matches(el) && this.opts.off(el);
65
+ this.opts.out && this._matches(el) && this.opts.out(el);
66
+ }
67
+ }
68
+
69
+ let active = null;
70
+
71
+ function checkTarget(e) {
72
+ const target = location.hash ? document.getElementById(location.hash.substring(1)) : false;
73
+ const changed = e ? e.oldURL !== e.newURL : target !== active; // test url vs old-url because it can have lost a trigger when changed using replaceState
74
+ if (!changed) return;
75
+ for (const observer of observers) {
76
+ observer._testOff(active);
77
+ observer._testOn(target);
78
+ }
79
+ active = target;
80
+ }
81
+ checkTarget();
82
+ addEventListener('hashchange', checkTarget);
83
+
84
+
85
+ // Usage:
86
+ // const observer = new TargetObserver({
87
+ // in: (target) => console.log(target),
88
+ // out: (target) => console.log(target),
89
+ // matches: '.element', // optional
90
+ // })
91
+ // observer.disconnect();
@@ -0,0 +1,75 @@
1
+ // checks for the "u2-target" query parameter and calls the on/off functions
2
+ // e.g. ?u2-target=details1+checkbox3+dialog1
3
+
4
+ const observers = new Set();
5
+
6
+ export class U2TargetObserver {
7
+ constructor(opts) {
8
+ this.opts = opts;
9
+ observers.add(this);
10
+
11
+ this._testOns(actives);
12
+ }
13
+ disconnect() {
14
+ observers.delete(this);
15
+ }
16
+ _matches(el){
17
+ if (!el) return false;
18
+ return el!==false && this.opts.matches==null || el.matches(this.opts.matches);
19
+ }
20
+ _testOn(el){
21
+ this.opts.on && this._matches(el) && this.opts.on(el);
22
+ }
23
+ _testOff(el){
24
+ this.opts.off && this._matches(el) && this.opts.off(el);
25
+ }
26
+ _testOns(els){
27
+ for (const el of els) this._testOn(el);
28
+ }
29
+ _testOffs(els){
30
+ for (const el of els) this._testOff(el);
31
+ }
32
+ }
33
+
34
+ let actives = new Set();
35
+
36
+ function checkTargets(){
37
+ const newest = new Set();
38
+ const param = new URL(location).searchParams.get('u2-target');
39
+ if (param) {
40
+ for (const item of param.split(' ')) {
41
+ const el = item && document.getElementById(item);
42
+ el && newest.add(el);
43
+ }
44
+ }
45
+
46
+ const added = new Set();
47
+ const removed = new Set();
48
+ for (let item of actives) if (!newest.has(item)) removed.add(item);
49
+ for (let item of newest) if (!actives.has(item)) added.add(item);
50
+ for (const obs of observers) {
51
+ obs._testOffs(removed);
52
+ obs._testOns(added);
53
+ }
54
+ actives = newest;
55
+ }
56
+ addEventListener('popstate', checkTargets);
57
+ checkTargets();
58
+
59
+
60
+ // Possible improvement:
61
+ // Initial TargetObserver tiggers if in url, then toggle-event triggers, resulting in toggleParam without a need.
62
+ // Can we solve this?
63
+
64
+ // togglelParam
65
+ export function toggleParam(id, force, replace){
66
+ const url = new URL(location);
67
+ const targets = new Set((url.searchParams.get('u2-target')||'').split(' '));
68
+ const isPresent = targets.has(id);
69
+ const shouldAdd = force ?? !isPresent;
70
+ if (shouldAdd === isPresent) return;
71
+ shouldAdd ? targets.add(id) : targets.delete(id);
72
+ url.searchParams.set('u2-target', [...targets].join(' '));
73
+ history[replace?'replaceState':'pushState'](null, '', url.href);
74
+ checkTargets();
75
+ }