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,131 @@
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
+ <script src="../../../u2/auto.js" type=module async></script>
8
+
9
+ <link rel=stylesheet href="../../../css/classless/full.css">
10
+ <link rel=stylesheet href="../../../css/classless/aria.css">
11
+ <link rel=stylesheet href="../../../css/classless/simple.css">
12
+
13
+
14
+
15
+ <script src="../contextmenu.js" type=module async></script>
16
+
17
+ </head>
18
+
19
+ <body>
20
+
21
+ <script type=module>
22
+ import {contextMenu} from '../contextmenu.js';
23
+
24
+ contextMenu.addItem('Icon as SVG',{
25
+ action: () => alert('Eine Section'),
26
+ icon: '<svg viewBox="0 0 24 24"><path d="M15.5 14h-.79l-.28-.27A6.47 6.47 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0a4.5 4.5 0 1 1-.01-8.99A4.5 4.5 0 0 1 9.5 14z"/></svg>',
27
+ });
28
+
29
+ contextMenu.addItem('Shortcut',{
30
+ action: (e) => alert('triggered by: '+e.originalEvent.type),
31
+ icon: 'article_shortcut',
32
+ shortcut: 'Ctrl + M + K',
33
+ });
34
+
35
+ const more = contextMenu.addItem('Mehr', {icon: 'add_circle'});
36
+ more.addItem('This item has a label with very long text, is it truncated?',{
37
+ action: () => alert('should be truncated'),
38
+ });
39
+ more.addItem('Label with <b style="color:green">html</b> in it',{
40
+ action: () => alert('look at the source code'),
41
+ });
42
+
43
+ contextMenu.addSeparator();
44
+
45
+
46
+ contextMenu.add({
47
+ 'multi on menu': e=>console.log(e),
48
+ 'multi on menu second': e=>console.log(e),
49
+ });
50
+
51
+
52
+ const addItems = contextMenu.addItem('multi on item').add({
53
+ 'obj index 1': e=>console.log(e),
54
+ 'obj index 2': {
55
+ 'small': e=>alert('should have a min width'),
56
+ 'ok?': e=>alert('should have a max width'),
57
+ },
58
+ 'obj index 3': [
59
+ {label: 'array item 1',action: e=>console.log(e)},
60
+ '-',
61
+ {label: 'array item 2',action: e=>console.log(e), children: [
62
+ {label: 'array item 2.1', action: e=>console.log(e)},
63
+ {label: 'array item 2.2', action: e=>console.log(e)}
64
+ ],
65
+ }],
66
+ });
67
+
68
+ contextMenu.addItem('custom html',{
69
+ html: `
70
+ <div class=-item style="justify-content:center">
71
+ <button role=menuitem>left</button>
72
+ <button role=menuitem>center</button>
73
+ <button role=menuitem>right</button>
74
+ </div>`,
75
+ selector: 'section'
76
+ });
77
+ contextMenu.addItem('checkbox (html)',{
78
+ html: `
79
+ <label class=-item>
80
+ <span class=-icon><input type=checkbox></span>
81
+ <span class=-label>Checkbox</span>
82
+ </label>`
83
+ });
84
+ contextMenu.addItem('input',{
85
+ html: `
86
+ <label class=-item>
87
+ <span class=-label><input placeholder="value"></span>
88
+ </label>`,
89
+ selector: 'input, textarea',
90
+ onparse(e) {
91
+ const inp = this.el.querySelector('input');
92
+ inp.value = e.target.value;
93
+ inp.oninput = () => e.target.value = inp.value;
94
+ }
95
+ });
96
+
97
+
98
+ </script>
99
+
100
+
101
+ <section tabindex="0">
102
+ Dies ist eine section
103
+
104
+ <br>
105
+ <label>
106
+ <input type=text value=Hallo><br>
107
+ </label>
108
+ <label>
109
+ <input type=text value=World><br>
110
+ </label>
111
+
112
+ </section>
113
+
114
+
115
+ <u2-code trim editable>
116
+ <style style="display:block" contenteditable>
117
+ html {
118
+ --color: #88c4ff;
119
+ --color-bg: #eef7ff;
120
+ --color-text: #001040;
121
+ }
122
+ #u2ContextMenuContainer::part(menu) {
123
+ border-radius: .8em;
124
+ padding: .5em;
125
+ }
126
+ #u2ContextMenuContainer::part(item) {
127
+ border-radius: .5em;
128
+ overflow: hidden;
129
+ }
130
+ </style>
131
+ </u2-code>
@@ -0,0 +1,49 @@
1
+ # dialog.js
2
+ alert, prompt, confirm but async
3
+
4
+ ## Features
5
+
6
+ - alert(), prompt() and confirm() are API-compatible but async.
7
+ - Uses native Dialog-Element (polyfill here: https://github.com/nuxodin/dialog-polyfill)
8
+ - Unstyled, style it yourself!
9
+ - Lightweight
10
+
11
+ ## Usage
12
+
13
+ ```html
14
+ <button onclick="module.prompt('Just a test').then(console.log)">run</button>
15
+ ```
16
+
17
+ ```css
18
+ dialog:where(.\:modal, :modal) {
19
+ box-shadow: 0 0 1rem #0008;
20
+ border: 0;
21
+ border-radius: .3rem;
22
+ }
23
+ ```
24
+
25
+ ## Install
26
+
27
+ ```js
28
+ import * as module from "https://cdn.jsdelivr.net/gh/u2ui/u2@x.x.x/js/dialog/dialog.min.js"
29
+ ```
30
+
31
+ ## Demos
32
+
33
+ [minimal.html](http://gcdn.li/u2ui/u2@main/js/dialog/tests/minimal.html)
34
+ [test.html](http://gcdn.li/u2ui/u2@main/js/dialog/tests/test.html)
35
+
36
+ ## Pro-Tip
37
+
38
+ To get sure your lib works even if the script does not load, you can fallback to the native confirm/alert/prompt function.
39
+
40
+ ```js
41
+ const {confirm} = await import('../fails/dialog.js').catch(e=>window);
42
+ await confirm('test');
43
+ ```
44
+
45
+ ## About
46
+
47
+ - MIT License, Copyright (c) 2022 <u2> (like all repositories in this organization) <br>
48
+ - Suggestions, ideas, finding bugs and making pull requests make us very happy. ♥
49
+
@@ -0,0 +1,261 @@
1
+ // TODO:
2
+ // - should we move the dom inside shadowDom to avoid style conflicts?
3
+ // or should we add an option to use shadowDom or just to define the container for the dialog-element?
4
+ // - rename to modal.js? see <iframe sandbox="allow-modals">
5
+
6
+ class Dialog {
7
+ constructor(options) {
8
+
9
+ const element = this.element = d.createElement('dialog');
10
+ element.classList.add('u2x-modal');
11
+ //element.setAttribute('role','alertdialog'); // todo: internals.role = 'alertdialog'; ?
12
+ element.innerHTML =
13
+ `<form method=dialog>
14
+ ${options.body}
15
+ ${options.buttons?'<div class=-buttons u2-focusgroup></div>':''}
16
+ </form>`;
17
+
18
+ const btnCont = element.querySelector('.-buttons');
19
+ if (options.buttons) {
20
+
21
+ import('../../attr/focusgroup/focusgroup.js');
22
+
23
+ options.buttons.forEach((btn, i)=>{
24
+ const el = d.createElement('button');
25
+ el.innerHTML = btn.title;
26
+ el.value = btn.value;
27
+ el.type = btn.type || 'submit';
28
+ el.addEventListener('click', e=>{
29
+ btn.then && btn.then.call(this,e);
30
+ });
31
+ btnCont.appendChild(el);
32
+ if (i === 0) setTimeout(()=>el.focus());
33
+ });
34
+ }
35
+ this.options = options;
36
+ options.init && options.init(this.element);
37
+ }
38
+ show(){
39
+ const element = this.element;
40
+ d.body.appendChild(element);
41
+ element.showModal();
42
+ element.classList.add(':modal'); // fallback for browsers that don't support :modal
43
+ if (this.options.audio) {
44
+ const url = this.options.audio === true ? import.meta.url + '/../notification.mp3' : this.options.audio;
45
+ const audio = new Audio();
46
+ audio.volume = 0.2;
47
+ audio.src = url;
48
+ audio.play();
49
+ }
50
+
51
+ return new Promise((resolve, reject)=>{
52
+ element.addEventListener('close',()=>{
53
+ resolve(this.value);
54
+ element.remove();
55
+ });
56
+ });
57
+
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Creates and shows a dialog with an alert message.
63
+ * @param {string} text - The text to be displayed in the alert dialog.
64
+ * @returns {Promise<undefined>} A Promise that resolves to undefined when the dialog is closed.
65
+ * @example
66
+ * await alert('This is an alert message');
67
+ */
68
+ export function alert(text) {
69
+ const options = toOptions(text);
70
+ options.buttons = [{title:'OK'}];
71
+ return new Dialog(options).show();
72
+ };
73
+
74
+ /**
75
+ * Creates and shows a dialog with a confirmation message.
76
+ * @param {string} text - The text to be displayed in the confirmation dialog.
77
+ * @returns {Promise<boolean>} A Promise that resolves to true if the user clicks the OK button, and false if the user clicks the Cancel button.
78
+ * @example
79
+ * if (await confirm('Do you want to delete this item?')) {
80
+ * deleteItem();
81
+ * }
82
+ */
83
+ export function confirm(text) {
84
+ const options = toOptions(text);
85
+ options.buttons = [
86
+ {title: 'OK',then(){ dialog.value = true; } },
87
+ {title: translate(options.lang, 'Cancel')}
88
+ ];
89
+ const dialog = new Dialog(options);
90
+ dialog.value = false;
91
+ return dialog.show();
92
+ };
93
+
94
+ /**
95
+ * Creates and shows a dialog with a prompt message.
96
+ * @param {string} text - The text to be displayed in the prompt dialog.
97
+ * @param {string} [initial] - The initial value of the input field.
98
+ * @returns {Promise<string>} A Promise that resolves to the value entered by the user, or null if the user clicks the Cancel button.
99
+ * @example
100
+ * const name = await prompt('Enter your name:');
101
+ */
102
+ export function prompt(text, initial) {
103
+ const options = toOptions(text);
104
+ options.body = '<label>'+options.body+'<input style="width:100%;display:block;margin-top:.5rem"></label>';
105
+ options.buttons = [
106
+ {title: 'OK', then(){ dialog.value = input.value; } },
107
+ {title: translate(options.lang, 'Cancel')}
108
+ ];
109
+ const dialog = new Dialog(options);
110
+ const input = dialog.element.querySelector('input');
111
+ input.value = initial ?? '';
112
+ setTimeout(()=>input.focus());
113
+ dialog.value = null;
114
+ return dialog.show();
115
+ };
116
+
117
+ /* */
118
+ export function form(html){
119
+ if (typeof html === 'string') html = { body: html };
120
+ const options = toOptions(html);
121
+ options.buttons =
122
+ [{title:'OK',then(){ // TODO: triggers by click but would be better by form.submit?
123
+ const form = dialog.element.querySelector('form');
124
+ if (!form.checkValidity()) dialog.value = null;
125
+ else {
126
+ const data = Object.fromEntries(new FormData(form).entries());
127
+ dialog.value = data;
128
+ }
129
+ }},{title: translate(lang(), 'Cancel'), type:'button', then(){
130
+ dialog.element.close();
131
+ }}];
132
+
133
+ const dialog = new Dialog(options);
134
+ return dialog.show();
135
+ }
136
+ /* */
137
+
138
+
139
+ /* init */
140
+ const d = document;
141
+
142
+ d.head.insertAdjacentHTML(
143
+ 'afterbegin',
144
+ '<style>'+
145
+ '.u2x-modal .-buttons {'+
146
+ 'display:flex;'+
147
+ 'flex-wrap:wrap;'+
148
+ 'justify-content:flex-end;'+
149
+ 'gap:.5rem;'+
150
+ 'margin-top:1rem;'+
151
+ '}'+
152
+ '</style>'
153
+ );
154
+
155
+
156
+
157
+ // close dialog on backdrop-click if it has the backdropClose-class
158
+ addEventListener('click', event=>{
159
+ const el = event.target;
160
+ if (el.tagName !== 'DIALOG') return;
161
+ if (!el.classList.contains('backdropClose')) return;
162
+ const rect = el.getBoundingClientRect();
163
+ let isInDialog = (rect.top <= event.clientY && event.clientY <= rect.top + rect.height && rect.left <= event.clientX && event.clientX <= rect.left + rect.width);
164
+ if (isInDialog) return;
165
+ el.close();
166
+ //hideAnimated(el, ()=>el.close());
167
+ });
168
+
169
+
170
+
171
+ // helper functions
172
+
173
+ function toOptions(options) {
174
+ if (typeof options === 'string') {
175
+ options = { body: htmlEntities(options) };
176
+ }
177
+ options.lang ??= lang();
178
+ return options;
179
+ }
180
+
181
+
182
+ function htmlEntities(str) {
183
+ return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
184
+ }
185
+ function translate(lang, v) {
186
+ return text[v][lang] || v;
187
+ }
188
+ function lang() {
189
+ return navigator.language.substring(0,2);
190
+ }
191
+ const text = {
192
+ 'Cancel':{
193
+ 'de':'Abbrechen',
194
+ 'fr':'Annuler',
195
+ 'es':'Cancelar',
196
+ 'it':'Annulla',
197
+ 'pt':'Cancelar',
198
+ 'ua':'Скасувати',
199
+ 'ru':'Отмена',
200
+ 'ja':'キャンセル',
201
+ 'ko':'취소',
202
+ 'zh':'取消',
203
+ 'nl':'Annuleren',
204
+ }
205
+ }
206
+
207
+
208
+ /*
209
+
210
+ Works! Waiting for demand
211
+ There are standards on the way that allow animations (@starting-style, transition-behavior: allow-discrete;)
212
+
213
+ needs css:
214
+ dialog.animated[hidden] {
215
+ display:block !important;
216
+ pointer-events:none !important;
217
+ }
218
+
219
+ function hideAnimated(el, then) {
220
+ if (!el.classList.contains('animated')) {
221
+ then();
222
+ return;
223
+ }
224
+ el.style.animation = 'none'; // animation can be the same in reverse, so remove it first to avoid it not triggering
225
+ setTimeout(()=>{
226
+ el.style.animation = '';
227
+ const end = e=>{
228
+ if (e && e.type && e.target !== el) return;
229
+ el.hidden = false;
230
+ then && then();
231
+ el.removeEventListener('animationend',end);
232
+ el.removeEventListener('transitionend',end);
233
+ clearTimeout(timeout);
234
+ return;
235
+ }
236
+ el.addEventListener('animationend',end);
237
+ el.addEventListener('transitionend',end);
238
+ const timeout = setTimeout(end,2000);
239
+ el.hidden = true;
240
+ });
241
+
242
+ };
243
+ addEventListener('cancel', e=>{
244
+ if (e.defaultPrevented) return;
245
+ const el = e.target;
246
+ if (el.hidden) return;
247
+ if (!el.classList.contains('animated')) return;
248
+ e.preventDefault();
249
+ hideAnimated(el, ()=>el.close());
250
+ }, true)
251
+ addEventListener('submit', e=>{
252
+ if (e.defaultPrevented) return;
253
+ const form = e.target;
254
+ if (form.method!=='dialog') return;
255
+ const el = el.closest('.dialog');
256
+ if (el.hidden) return;
257
+ if (!el.classList.contains('animated')) return;
258
+ e.preventDefault();
259
+ hideAnimated(el, ()=>form.submit());
260
+ }, true)
261
+ /* */
Binary file
@@ -0,0 +1,29 @@
1
+ <!DOCTYPE HTML>
2
+ <html lang=en>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name=viewport content="width=device-width">
6
+ <title>dialog.js minimal.html | U2 design-system</title>
7
+ <script src="../../../u2/tests/test-init.js" type=module async></script>
8
+ <link rel=stylesheet href="../../../css/classless/full.css">
9
+ <link rel=stylesheet href="../../../css/classless/simple.css">
10
+
11
+ <script type=module>
12
+ import * as module from '../dialog.js';
13
+ window.module = module;
14
+ </script>
15
+
16
+ <body>
17
+
18
+
19
+ <section class="main">
20
+ <button onclick="module.prompt('Just a test').then(console.log)">run</button>
21
+ </section>
22
+
23
+ <style class="main">
24
+ dialog:where(.\:modal, :modal) {
25
+ box-shadow: 0 0 1rem #0008;
26
+ border: 0;
27
+ border-radius: .3rem;
28
+ }
29
+ </style>
Binary file
@@ -0,0 +1,135 @@
1
+ <!DOCTYPE HTML>
2
+ <html lang=en>
3
+
4
+ <head>
5
+ <meta charset="utf-8">
6
+ <meta name=viewport content="width=device-width">
7
+ <script src="../../../u2/tests/test-init.js" type=module async></script>
8
+ <title>dialog.js test.html | U2 design-system</title>
9
+
10
+ <link rel=stylesheet href="../../../css/classless/full.css">
11
+ <link rel=stylesheet href="../../../css/classless/simple.css">
12
+ <link rel=stylesheet href="../../../class/table/table.css">
13
+
14
+ <script src="../../../el/code/code.js" type=module async></script>
15
+ <link rel=stylesheet href="../../../el/code/code.css">
16
+
17
+ </head>
18
+
19
+ <body>
20
+
21
+ <script type=module>
22
+ import * as dialog from '../dialog.js';
23
+ window.dialog = dialog;
24
+ </script>
25
+
26
+
27
+ <section>
28
+ <h2>alert, confirm, prompt</h2>
29
+
30
+ <button onclick="dialog.alert('Just a test').then(console.log)">alert</button>
31
+ <button onclick="console.log(alert('Just a test'))">native</button>
32
+ <br><br>
33
+ <button onclick="dialog.confirm('Really?').then(console.log)">confirm</button>
34
+ <button onclick="console.log(confirm('Really?'))">native</button>
35
+ <br><br>
36
+ <button onclick="dialog.prompt('value:','100').then(console.log)">prompt</button>
37
+ <button onclick="console.log(prompt('value:','100'))">native</button>
38
+
39
+ <h2>Tests</h2>
40
+
41
+ <button onclick="dialog.alert('Html content: <b>bold</b>')">Html content not parsed </button>
42
+ <br><br>
43
+ <button onclick="dialog.alert({body:'Html content: <b>bold</b>'})">Html parsed </button>
44
+ <br><br>
45
+ <button onclick="dialog.prompt({body:'Annuler?', lang:'fr'}, '👍')">option "lang" </button>
46
+ <br><br>
47
+ <button onclick="dialog.alert({body:'click on the backdrop',init:el=>el.classList.add('backdropClose')}).then(console.log)">backdropClose class</button>
48
+ <br><br>
49
+ <button onclick="dialog.alert({audio:true, body:'Please inform the developer if the standard sound needs to be improved'})">default notification sound</button>
50
+
51
+ <button onclick="dialog.alert({audio:'./notification.mp3', body:'sound'})">custom notification sound</button>
52
+ <br><br>
53
+
54
+ <button id=formTestHtml>form(html) beta</button>
55
+ <script>
56
+ formTestHtml.addEventListener('click',async e=>{
57
+ const result = await dialog.form(`
58
+ <h2>Fill the form</h2>
59
+ <div>
60
+ Gender: &nbsp;
61
+ <label><input type=radio name=gender value=female required> Female </label>
62
+ <label><input type=radio name=gender value=male> Male </label>
63
+ </div>
64
+ <label>
65
+ Firstname:
66
+ <input name=firstname required style="width:100%">
67
+ </label>
68
+ <label>
69
+ Lastname:
70
+ <input name=lastname style="width:100%">
71
+ </label>
72
+ <label>
73
+ Accept AGB:
74
+ <input type=checkbox name=agb value=1 required>
75
+ </label>
76
+ `);
77
+ result && dialog.alert('Thank you '+result.firstname+'!');
78
+ console.log(result)
79
+ });
80
+ </script>
81
+
82
+ </section>
83
+
84
+ <style> u2-code { font-size:14px; border:1px solid var(--color-line); padding:1rem; } </style>
85
+
86
+ <u2-code editable trim>
87
+ <style>
88
+
89
+ dialog { transition: opacity 1s ease; opacity:0; }
90
+ dialog[open] { opacity:1 }
91
+
92
+ dialog:is(.\:modal, :modal) {
93
+ width: 18rem;
94
+ box-shadow: 0 0 1rem #0008;
95
+ border: 0;
96
+ border-radius: .3rem;
97
+ opacity:1;
98
+ }
99
+ /* dialog:where(.\:modal, :modal)[hidden] { opacity:0; transition-duration:1s; } close animation, still commented out in code */
100
+ </style>
101
+ </u2-code>
102
+
103
+
104
+ <!-- /* new variant using @starting-style and transition-behavior: allow-discrete; (chromium for now) */
105
+ dialog[open] {
106
+ opacity: 1;
107
+ transform: translateY(0);
108
+ }
109
+ @starting-style {
110
+ dialog[open] {
111
+ opacity: 0;
112
+ transform: translateY(-80vh);
113
+ }
114
+ }
115
+ dialog {
116
+ opacity: 0;
117
+ transform: translateY(-80vh);
118
+ transition: 0.4s ease-in-out;
119
+ transition-behavior: allow-discrete;
120
+ }
121
+
122
+ dialog::backdrop {
123
+ background-color: rgb(0 0 0 / 0%);
124
+ transition: 0.4s ease-in-out;
125
+ transition-behavior: allow-discrete;
126
+ }
127
+ dialog[open]::backdrop {
128
+ background-color: rgb(0 0 0 / 25%);
129
+ }
130
+ @starting-style {
131
+ dialog[open]::backdrop {
132
+ background-color: rgb(0 0 0 / 0%);
133
+ }
134
+ }
135
+ -->
@@ -0,0 +1,44 @@
1
+ # SelectorObserver.js
2
+ Easily Make Elements Editable with Intuitive Controls
3
+
4
+ ## Usage
5
+
6
+ ```js
7
+ import "../rte.js";
8
+ ```
9
+
10
+ ```html
11
+ <div contenteditable id="myEditor">
12
+ Start <strong>typing</strong> here...
13
+ </div>
14
+ ```
15
+
16
+ ```css
17
+ #myEditor {
18
+ --u2-rte:true;
19
+ --u2-rte-toolbar:Bold Italic Code;
20
+ }
21
+ ```
22
+
23
+ ## Install
24
+
25
+ ```js
26
+ import * as module from "https://cdn.jsdelivr.net/gh/u2ui/u2@x.x.x/js/rte/rte.min.js"
27
+ ```
28
+
29
+ ## Demos
30
+
31
+ [ai.html](http://gcdn.li/u2ui/u2@main/js/rte/tests/ai.html)
32
+ [behavior.html](http://gcdn.li/u2ui/u2@main/js/rte/tests/behavior.html)
33
+ [events.html](http://gcdn.li/u2ui/u2@main/js/rte/tests/events.html)
34
+ [fixes.html](http://gcdn.li/u2ui/u2@main/js/rte/tests/fixes.html)
35
+ [minimal.html](http://gcdn.li/u2ui/u2@main/js/rte/tests/minimal.html)
36
+ [range.html](http://gcdn.li/u2ui/u2@main/js/rte/tests/range.html)
37
+ [selection-explorer.html](http://gcdn.li/u2ui/u2@main/js/rte/tests/selection-explorer.html)
38
+ [test.html](http://gcdn.li/u2ui/u2@main/js/rte/tests/test.html)
39
+
40
+ ## About
41
+
42
+ - MIT License, Copyright (c) 2022 <u2> (like all repositories in this organization) <br>
43
+ - Suggestions, ideas, finding bugs and making pull requests make us very happy. ♥
44
+