lightview 1.8.2 → 2.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 (264) hide show
  1. package/.agent/workflows/daisyui-component-migration.md +155 -0
  2. package/.codacy/cli.sh +149 -0
  3. package/.codacy/codacy.yaml +15 -0
  4. package/.github/instructions/codacy.instructions.md +72 -0
  5. package/.wranglerignore +21 -0
  6. package/README.md +1330 -19
  7. package/_headers +4 -0
  8. package/build.js +70 -0
  9. package/components/actions/button.js +151 -0
  10. package/components/actions/dropdown.js +120 -0
  11. package/components/actions/modal.js +146 -0
  12. package/components/actions/swap.js +118 -0
  13. package/components/daisyui.js +288 -0
  14. package/components/data-display/accordion.js +128 -0
  15. package/components/data-display/alert.js +112 -0
  16. package/components/data-display/avatar.js +170 -0
  17. package/components/data-display/badge.js +82 -0
  18. package/components/data-display/card.js +151 -0
  19. package/components/data-display/carousel.js +94 -0
  20. package/components/data-display/chart.js +220 -0
  21. package/components/data-display/chat.js +128 -0
  22. package/components/data-display/collapse.js +103 -0
  23. package/components/data-display/countdown.js +69 -0
  24. package/components/data-display/diff.js +111 -0
  25. package/components/data-display/kbd.js +65 -0
  26. package/components/data-display/loading.js +75 -0
  27. package/components/data-display/progress.js +79 -0
  28. package/components/data-display/radial-progress.js +88 -0
  29. package/components/data-display/skeleton.js +66 -0
  30. package/components/data-display/stats.js +159 -0
  31. package/components/data-display/table.js +146 -0
  32. package/components/data-display/timeline.js +146 -0
  33. package/components/data-display/toast.js +72 -0
  34. package/components/data-display/tooltip.js +74 -0
  35. package/components/data-input/checkbox.js +253 -0
  36. package/components/data-input/file-input.js +224 -0
  37. package/components/data-input/input.js +264 -0
  38. package/components/data-input/radio.js +338 -0
  39. package/components/data-input/range.js +204 -0
  40. package/components/data-input/rating.js +219 -0
  41. package/components/data-input/select.js +287 -0
  42. package/components/data-input/textarea.js +287 -0
  43. package/components/data-input/toggle.js +201 -0
  44. package/components/index.js +137 -0
  45. package/components/layout/divider.js +72 -0
  46. package/components/layout/drawer.js +142 -0
  47. package/components/layout/footer.js +100 -0
  48. package/components/layout/hero.js +109 -0
  49. package/components/layout/indicator.js +90 -0
  50. package/components/layout/join.js +78 -0
  51. package/components/layout/navbar.js +110 -0
  52. package/components/navigation/breadcrumbs.js +91 -0
  53. package/components/navigation/dock.js +103 -0
  54. package/components/navigation/menu.js +126 -0
  55. package/components/navigation/pagination.js +105 -0
  56. package/components/navigation/steps.js +89 -0
  57. package/components/navigation/tabs.css +177 -0
  58. package/components/navigation/tabs.js +123 -0
  59. package/components/theme/theme-switch.css +65 -0
  60. package/components/theme/theme-switch.js +177 -0
  61. package/docs/about.html +164 -0
  62. package/docs/api/computed.html +184 -0
  63. package/docs/api/effects.html +173 -0
  64. package/docs/api/elements.html +180 -0
  65. package/docs/api/enhance.html +225 -0
  66. package/docs/api/hypermedia.html +165 -0
  67. package/docs/api/index.html +178 -0
  68. package/docs/api/nav.html +18 -0
  69. package/docs/api/signals.html +136 -0
  70. package/docs/api/state.html +217 -0
  71. package/docs/assets/images/logo-favicon.svg +42 -0
  72. package/docs/assets/images/logo-static.svg +40 -0
  73. package/docs/assets/images/logo.svg +66 -0
  74. package/docs/assets/js/examplify.js +395 -0
  75. package/docs/assets/styles/site.css +1102 -0
  76. package/docs/assets/styles/themes.css +236 -0
  77. package/docs/components/accordion.html +439 -0
  78. package/docs/components/alert.html +528 -0
  79. package/docs/components/avatar.html +586 -0
  80. package/docs/components/badge.html +531 -0
  81. package/docs/components/breadcrumbs.html +278 -0
  82. package/docs/components/button.html +579 -0
  83. package/docs/components/card.html +561 -0
  84. package/docs/components/carousel.html +286 -0
  85. package/docs/components/chart-area.html +702 -0
  86. package/docs/components/chart-bar.html +782 -0
  87. package/docs/components/chart-column.html +735 -0
  88. package/docs/components/chart-line.html +794 -0
  89. package/docs/components/chart-pie.html +823 -0
  90. package/docs/components/chart.html +610 -15
  91. package/docs/components/chat.html +547 -0
  92. package/docs/components/checkbox.html +641 -0
  93. package/docs/components/collapse.html +536 -0
  94. package/docs/components/component-nav.html +53 -0
  95. package/docs/components/countdown.html +470 -0
  96. package/docs/components/diff.html +245 -0
  97. package/docs/components/divider.html +240 -0
  98. package/docs/components/dock.html +277 -0
  99. package/docs/components/drawer.html +515 -0
  100. package/docs/components/dropdown.html +479 -0
  101. package/docs/components/file-input.html +591 -0
  102. package/docs/components/footer.html +301 -0
  103. package/docs/components/gallery.html +504 -0
  104. package/docs/components/hero.html +264 -0
  105. package/docs/components/index.css +840 -0
  106. package/docs/components/index.html +735 -0
  107. package/docs/components/indicator.html +342 -0
  108. package/docs/components/input.html +644 -0
  109. package/docs/components/join.html +285 -0
  110. package/docs/components/kbd.html +322 -0
  111. package/docs/components/loading.html +521 -0
  112. package/docs/components/menu.html +461 -0
  113. package/docs/components/modal.html +639 -0
  114. package/docs/components/navbar.html +321 -0
  115. package/docs/components/pagination.html +279 -0
  116. package/docs/components/progress.html +514 -0
  117. package/docs/components/radial-progress.html +434 -0
  118. package/docs/components/radio.html +655 -0
  119. package/docs/components/range.html +611 -0
  120. package/docs/components/rating.html +642 -0
  121. package/docs/components/select.html +696 -0
  122. package/docs/components/sidebar-setup.js +93 -0
  123. package/docs/components/skeleton.html +447 -0
  124. package/docs/components/spinner.html +68 -0
  125. package/docs/components/stats.html +486 -0
  126. package/docs/components/steps.html +356 -0
  127. package/docs/components/swap.html +517 -0
  128. package/docs/components/switch.html +68 -0
  129. package/docs/components/table.html +668 -0
  130. package/docs/components/tabs.html +506 -0
  131. package/docs/components/text-input.html +68 -0
  132. package/docs/components/textarea.html +603 -0
  133. package/docs/components/timeline.html +485 -42
  134. package/docs/components/toast.html +474 -0
  135. package/docs/components/toggle.html +564 -0
  136. package/docs/components/tooltip.html +423 -0
  137. package/docs/examples/getting-started-example.html +40 -0
  138. package/docs/examples/index.html +93 -0
  139. package/docs/getting-started/index.html +739 -0
  140. package/docs/getting-started/reviews.html +23 -0
  141. package/docs/getting-started/reviews.odom +108 -0
  142. package/docs/getting-started/reviews.vdom +84 -0
  143. package/docs/index.html +132 -42
  144. package/docs/playground.html +416 -0
  145. package/docs/router.html +285 -0
  146. package/docs/styles/index.html +190 -0
  147. package/functions/_middleware.js +32 -0
  148. package/index.html +309 -0
  149. package/lightview-router.js +364 -0
  150. package/lightview-x.js +1577 -0
  151. package/lightview.js +659 -1200
  152. package/lightview.js.backup +793 -0
  153. package/middleware/locale.js +25 -0
  154. package/middleware/markdown.js +44 -0
  155. package/middleware/notFound.js +37 -0
  156. package/package.json +27 -41
  157. package/watch.js +92 -0
  158. package/wrangler.toml +12 -0
  159. package/.idea/lightview.iml +0 -12
  160. package/.idea/modules.xml +0 -8
  161. package/.idea/vcs.xml +0 -6
  162. package/LICENSE +0 -21
  163. package/codepen-no-tabs-embed.css +0 -2
  164. package/docs/CNAME +0 -1
  165. package/docs/api.html +0 -674
  166. package/docs/blank.html +0 -10
  167. package/docs/comparedto.html +0 -89
  168. package/docs/components/chart-repl.html +0 -69
  169. package/docs/components/components.js +0 -113
  170. package/docs/components/contents.html +0 -17
  171. package/docs/components/gantt-repl.html +0 -61
  172. package/docs/components/gantt.html +0 -42
  173. package/docs/components/gauge-repl.html +0 -66
  174. package/docs/components/gauge.html +0 -20
  175. package/docs/components/orgchart-repl.html +0 -64
  176. package/docs/components/orgchart.html +0 -41
  177. package/docs/components/repl-as-src.html +0 -17
  178. package/docs/components/repl-repl.html +0 -95
  179. package/docs/components/repl.html +0 -527
  180. package/docs/components/timeline-repl.html +0 -72
  181. package/docs/components.html +0 -14
  182. package/docs/css/highlightjs.min.css +0 -9
  183. package/docs/css/tutorial.css +0 -35
  184. package/docs/examples/anchor.html +0 -11
  185. package/docs/examples/chart.html +0 -34
  186. package/docs/examples/counter.html +0 -26
  187. package/docs/examples/counter.test.mjs +0 -47
  188. package/docs/examples/counter2.html +0 -26
  189. package/docs/examples/directives.html +0 -79
  190. package/docs/examples/foreign.html +0 -50
  191. package/docs/examples/forgeinform.html +0 -98
  192. package/docs/examples/form.html +0 -61
  193. package/docs/examples/gauge.html +0 -18
  194. package/docs/examples/invalid-template-literals.html +0 -44
  195. package/docs/examples/medium/remote.html +0 -60
  196. package/docs/examples/message.html +0 -18
  197. package/docs/examples/nested.html +0 -11
  198. package/docs/examples/object-bound-form.html +0 -34
  199. package/docs/examples/remote-server.js +0 -51
  200. package/docs/examples/remote.html +0 -34
  201. package/docs/examples/remote.json +0 -1
  202. package/docs/examples/scratch.html +0 -69
  203. package/docs/examples/sensors/index.html +0 -44
  204. package/docs/examples/sensors/sensor-server.js +0 -30
  205. package/docs/examples/shared.html +0 -41
  206. package/docs/examples/template.html +0 -33
  207. package/docs/examples/timeline.html +0 -21
  208. package/docs/examples/todo.html +0 -40
  209. package/docs/examples/top.html +0 -10
  210. package/docs/examples/types.html +0 -94
  211. package/docs/examples/xor.html +0 -62
  212. package/docs/examples.html +0 -25
  213. package/docs/javascript/codejar.min.js +0 -8
  214. package/docs/javascript/highlightjs.min.js +0 -1173
  215. package/docs/javascript/isomorphic-git.js +0 -9
  216. package/docs/javascript/json5.min.js +0 -1
  217. package/docs/javascript/lightning-fs.js +0 -1
  218. package/docs/javascript/lightview.js +0 -1285
  219. package/docs/javascript/marked.min.js +0 -6
  220. package/docs/javascript/peerjs.min.js +0 -70
  221. package/docs/javascript/turndown.js +0 -973
  222. package/docs/javascript/types.js +0 -606
  223. package/docs/javascript/utils.js +0 -45
  224. package/docs/lightview.html +0 -63
  225. package/docs/old_index.html +0 -965
  226. package/docs/old_index.md +0 -1132
  227. package/docs/slidein.html +0 -51
  228. package/docs/tutorial/0-getting-started.html +0 -67
  229. package/docs/tutorial/1-intro-to-variables.html +0 -103
  230. package/docs/tutorial/10-template-components.html +0 -80
  231. package/docs/tutorial/11-linked-components.html +0 -76
  232. package/docs/tutorial/12-imported-components.html +0 -67
  233. package/docs/tutorial/13-input-binding.html +0 -94
  234. package/docs/tutorial/14-automatic-variable-creation.html +0 -74
  235. package/docs/tutorial/15-form-binding.html +0 -110
  236. package/docs/tutorial/16-if-directive.html +0 -60
  237. package/docs/tutorial/17-loop-directives.html +0 -83
  238. package/docs/tutorial/18-sanitizing-and-escaping-input.html +0 -79
  239. package/docs/tutorial/2-imported-and-exported-variables.html +0 -80
  240. package/docs/tutorial/3-data-types.html +0 -89
  241. package/docs/tutorial/4-extended-data-types.html +0 -83
  242. package/docs/tutorial/5-extended-functional-types.html +0 -96
  243. package/docs/tutorial/5.1-extended-functional-types.html +0 -79
  244. package/docs/tutorial/5.2-extended-functional-types.html +0 -70
  245. package/docs/tutorial/6-conventional-javascript.html +0 -75
  246. package/docs/tutorial/7-monitoring-with-observers.html +0 -107
  247. package/docs/tutorial/8-event-listeners.html +0 -65
  248. package/docs/tutorial/9-intro-to-components.html +0 -91
  249. package/docs/tutorial/contents.html +0 -32
  250. package/docs/tutorial/my-component.html +0 -29
  251. package/docs/tutorial/remote-value.json +0 -4
  252. package/docs/websiterepl.html +0 -46
  253. package/jest-puppeteer.config.js +0 -5
  254. package/jest.config.json +0 -12
  255. package/lightview.min.js +0 -1
  256. package/lightview_good.js +0 -1267
  257. package/lightview_optimized.js +0 -1274
  258. package/repl_hold.html +0 -320
  259. package/test/basic.html +0 -104
  260. package/test/basic.test.mjs +0 -315
  261. package/test/extended.html +0 -29
  262. package/test/extended.test.mjs +0 -448
  263. package/types.js +0 -607
  264. package/unsplash.key +0 -1
@@ -1,95 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <title>Lightview:Components:REPL</title>
6
- <link href="../css/tutorial.css" rel="stylesheet">
7
- <link href="../slidein.html" rel="module">
8
- <link href="repl.html" rel="module">
9
- <script src="../javascript/highlightjs.min.js"></script>
10
- <script src="../javascript/marked.min.js"></script>
11
- <script src="../javascript/utils.js"></script>
12
- </head>
13
- <body class="tutorial-body">
14
- <script src="../javascript/lightview.js"></script>
15
- <div class="tutorial-instructions">
16
- <l-slidein src="./contents.html" class="toc"></l-slidein>
17
- <div class="markdown">
18
- ## REPL
19
-
20
- REPL itself is a component, `l-repl`.
21
-
22
- To the right you will see source similar to that used to define the REPL in the tab menu for this website.
23
-
24
- The REPL component has lots of configuration options, so you can use it to just display example code based on
25
- source files if you want or focus users on a specific aspect of the code.
26
-
27
- Try these steps to see the flexibility of `l-repl`:
28
-
29
- 1. Delete the entire slot and its contents starting with `<template slot="src"> ... </template>`. You should now
30
- see a REPL with no content in each of the displayed areas.
31
- 2. Paste `src="./repl-as-src.html"` as one of the attributes of the `l-repl`. You should now see the same code you
32
- saw to start with, except it is loaded from a file.
33
- 3. Paste `readonly` as an attribute to the `l-repl`. Now, none of the code can be edited. also, the `Save` button in the
34
- frames section disappears. (You probably realized this by now, users can save their REPL edits to `IndexedDB` locally. Next time
35
- they visit, the REPL will be in the same state it was left in ... unless it has been more than 10 days on IOS ... Apple
36
- auto clears `IndexedDB for lack of use ;-(.).
37
- 4. Delete `readonly` from the `l-repl` (Ctrl-Z should work) and paste it as an attribute to "bodyhtml" slot. Now the body
38
- can't be edited. You can do this with the other slots also.
39
- 5. Remove `previewpinned` so as not to distract the user with a preview unless it is requested.
40
- 5. Assume you want to focus the user attention of the body and script without editing. Remove the
41
- slots "headhtml" and "css". Add "readonly" to the "script" slot, or the `l-repl`. Remove `previewheight`.
42
- Add `hidetabs` to the `l-repl`.
43
-
44
- One final note, if you want to use multiple script tags, then add `maintainbody` to the `l-repl` and your scripts will be
45
- left alone, otherwise, the `l-repl` assumes you only have one script.
46
-
47
-
48
- </div>
49
- <button class="nav-previous"><a href="gauge-repl.html" target="content">Previous</a></button>
50
- </div>
51
- <div class="repl">
52
- <h2></h2>
53
- <l-repl id="repl" style="min-height:95vh;min-width:600px;" previewpinned path="$location" previewheight="750px" maintainbody>
54
- <div slot="headhtml"></div>
55
- <div slot="bodyhtml"></div>
56
- <div slot="script"></div>
57
- <div slot="css"></div>
58
- <template slot="src">
59
- <l-head>
60
- <link href="./repl.html" rel="module">
61
- <script src="../javascript/lightview.js"></script>
62
- </l-head>
63
- <l-body>
64
- <l-repl id="repl" style="min-height:95vh;min-width:600px;" previewpinned previewheight="250px">
65
- <div slot="headhtml"></div>
66
- <div slot="bodyhtml"></div>
67
- <div slot="script"></div>
68
- <div slot="css"></div>
69
- <template slot="src">
70
- <l-head>
71
- <script src="../javascript/lightview.js?as=x-body"></script>
72
- </l-head>
73
- <l-body>
74
- <div class="message">${message}</div>
75
- </l-body>
76
- <script id="lightview">
77
- currentComponent.mount = function() {
78
- this.variables({message:"string"},{set:"Hello world!"});
79
- }
80
- </script>
81
- <style>
82
- .message { font-size: large }
83
- </style>
84
- </template>
85
- </l-repl>
86
- </l-body>
87
-
88
- </template>
89
- </l-repl>
90
- </div>
91
- <script>
92
- processMarkdown();
93
- </script>
94
- </body>
95
- </html>
@@ -1,527 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <title>Lightview:REPL</title>
6
- <style>
7
- .hljs[slot] { padding: 5px; }
8
- </style>
9
- </head>
10
- <body>
11
- <link rel="stylesheet" href="../css/highlightjs.min.css" export>
12
- <script src="../javascript/lightning-fs.js"></script>
13
- <script src="../javascript/isomorphic-git.js"></script>
14
- <script src="../javascript/highlightjs.min.js"></script>
15
- <script src="../javascript/turndown.js"></script>
16
- <div id="content" style="flex:auto;min-width:500px;border:1px solid;padding:10px;margin-top:1em;margin-bottom:1em; auto;overflow:auto;font-size:smaller">
17
- <div style="display:flex;flex-direction:column;">
18
- <div l-if="${!hidetabs}" id="tabs" style="flex-grow:0;width:100%;border:1px;padding-bottom:5px;text-align:center" hidden>
19
- <span style="padding-right:10px" for="headhtml"><label for="headhtml" l-on:click="${onTabClick}">HTML Head</label><input for="headhtml" value="${headhtmlPinned}" type="checkbox" l-on:click="${onPinClick}"></span>
20
- <span style="padding-right:10px" for="bodyhtml"><label for="bodyhtml" l-on:click="${onTabClick}">HTML Body</label><input for="bodyhtml" value="${bodyhtmlPinned}" type="checkbox" l-on:click="${onPinClick}"></span>
21
- <!--span style="padding-right:10px" for="markdown"><label for="markdown" l-on:click="${onTabClick}">Markdown (Body)</label><input for="markdown" value="${markdownPinned}" type="checkbox" l-on:click="${onPinClick}"></span-->
22
- <span style="padding-right:10px" for="css"><label for="css" l-on:click="${onTabClick}">Style</label><input for="css" value="${cssPinned}" type="checkbox" l-on:click="${onPinClick}"></span>
23
- <span style="padding-right:10px" for="script"><label for="script" l-on:click="${onTabClick}">Script</label><input for="script" value="${scriptPinned}" type="checkbox" l-on:click="${onPinClick}"></span>
24
- <span style="padding-right:10px" for="preview"><label for="preview" l-on:click="${onTabClick}">Preview</label><input for="preview" value="${previewPinned}" type="checkbox" l-on:click="${onPinClick}"></span>
25
- </div>
26
- </div>
27
- <div id="headhtml" style="margin:10px" class="language-html"><slot name="headhtml"></slot></div>
28
- <div id="bodyhtml" style="margin:10px" class="language-html"><slot name="bodyhtml"></slot></div>
29
- <!--textarea id="markdown" style="margin-right:2px;">${markdown}</textarea-->
30
- <div id="css" style="margin:10px" class="language-css"><slot name="css"></slot></div>
31
- <div id="script" style="margin:10px" class="language-javascript"><slot name="script"></slot></div>
32
- <iframe id="preview" style="height:${previewheight||'150px'};max-width:99%;width:99%;" hidden></iframe>
33
- </div>
34
- <div l-if="${editable}" style="width:100%;text-align:center">
35
- <div style="padding:5px">${source}</div>
36
- <button l-on:click="${doSave}">Save</button>&nbsp;&nbsp;
37
- <button l-if="${canReset}" l-on:click="${doReset}">Reset</button>
38
- </div>
39
- <style>
40
- label:hover {
41
- text-decoration: underline
42
- }
43
- slot[name=headhtml]:not([hidden])::before { content: "<head>" }
44
- slot[name=headhtml]:not([hidden])::after { content: "</head>" }
45
- slot[name=bodyhtml]:not([hidden])::before { content: "<body${bodyattributes ? ' ' + bodyattributes : ''}>" }
46
- slot[name=bodyhtml]:not([hidden])::after { content: "</body>" }
47
- slot[name=css]:not([hidden])::before { content: "<style>" }
48
- slot[name=css]:not([hidden])::after { content: "< /style>" }
49
- slot[name=script]:not([hidden])::before { content: "<script ${scriptattributes}>" }
50
- slot[name=script]:not([hidden])::after { content: "</script>" }
51
- </style>
52
- <script id="lightview">
53
- (document.currentComponent||(document.currentComponent=document.body)).mount = async function() {
54
- let CJ
55
- try {
56
- const {CodeJar} = await import(new URL("../javascript/codejar.min.js", this.componentBaseURI).href);
57
- CJ = CodeJar;
58
- } catch {
59
-
60
- }
61
- let turndownService;
62
- try {
63
- turndownService = new TurndownService({
64
- headingStyle: "atx",
65
- codeBlockStyle: "fenced",
66
- emDelimiter: "*"
67
- });
68
- turndownService.keep(() => true);
69
- } catch(e) {
70
-
71
- }
72
-
73
- const {html, css, script} = await import(new URL("../javascript/types.js", this.componentBaseURI).href);
74
- self.variables({
75
- onTabClick: "function",
76
- onPinClick: "function",
77
- doSave: "function",
78
- doReset: "function"
79
- });
80
- self.variables({
81
- wysiwygPinned: "boolean",
82
- headhtmlPinned: "boolean",
83
- headhtml: html,
84
- bodyhtmlPinned: "boolean",
85
- bodyhtml: html,
86
- bodyattributes:"string",
87
- markdownPinned: "boolean",
88
- markdown: "string",
89
- cssPinned: "boolean",
90
- cssText: css,
91
- scriptPinned: "boolean",
92
- scriptText: script,
93
- scriptattributes:"string",
94
- source: "string",
95
- canReset: "boolean",
96
- editable: "boolean"
97
- }, {reactive});
98
- self.variables({
99
- previewPinned: "boolean"
100
- },{imported,reactive});
101
- self.variables({
102
- src: "string",
103
- path: "string",
104
- hidetabs: "boolean",
105
- maintainbody: "boolean",
106
- contentbackground:"string",
107
- readonly: "boolean",
108
- previewheight: "string"
109
- }, {imported});
110
-
111
- bodyhtmlPinned = true;
112
- canReset = false;
113
- bodyattributes = "";
114
- scriptattributes = "";
115
- editable = false;
116
-
117
- const getPath = () => {
118
- if(path==="$location" || path==null) return source = window.location.pathname;
119
- return source = path;
120
- }
121
-
122
- const trimContent = (text) => {
123
- let result = text;
124
- if(result[0]==="\n") result = result.substring(1);
125
- while(result[result.length-1]==="\n") result = result.substring(0,result.length-1);
126
- return result;
127
- }
128
-
129
- const loadFromFile = async () => {
130
- const html = await fs.readFile(url.pathname, {encoding: "utf8"});
131
- source = `IndexedDB://${url.hostname + "_repl"}${url.pathname}`;
132
- return html;
133
- };
134
-
135
- const loadFromServer = async () => {
136
- const response = await fetch(url.href);
137
- const html = await response.text();
138
- source = url.href;
139
- return html;
140
- };
141
-
142
- const loadFromTemplate = () => {
143
- const templateEl = this.querySelector('[slot="src"]');
144
- if(templateEl) {
145
- const template = document.createElement("div");
146
- template.innerHTML = templateEl.innerHTML;
147
- return template;
148
- }
149
- }
150
-
151
- const initFromTemplate = (template) => {
152
- head_el = document.createElement("head");
153
- body_el = document.createElement("body");
154
- if(template) {
155
- const head = template.querySelector("l-head");
156
- if(head) {
157
- headhtml = trimContent(head.innerHTML || "");
158
- [...head.attributes].forEach((attr) => head_el.setAttribute(attr.name,attr.value));
159
- } else {
160
- headhtml = "";
161
- }
162
- style_el = template.querySelector("style");
163
- if(style_el) {
164
- cssText = trimContent(style_el.innerText);
165
- style_el.remove();
166
- } else {
167
- style_el = document.createElement("style");
168
- cssText = "";
169
- }
170
- script_el = template.querySelector('script:not([src*="lightview.js"])');
171
- if(script_el && script_el.parentElement===template) {
172
- scriptText = trimContent(script_el.innerText);
173
- script_el.remove();
174
- } else {
175
- script_el = document.createElement("script");
176
- scriptText = "";
177
- }
178
- const body = template.querySelector("l-body");
179
- if(body) {
180
- bodyhtml = trimContent(body.innerHTML);
181
- [...body.attributes].forEach((attr) => body_el.setAttribute(attr.name,attr.value))
182
- } else {
183
- bodyhtml = "";
184
- }
185
- } else {
186
- script_el = document.createElement("script");
187
- style_el = document.createElement("style");
188
- bodyhtml = "";
189
- headhtml = "";
190
- scriptText = "";
191
- cssText = "";
192
- }
193
- body_el.appendChild(style_el);
194
- body_el.appendChild(script_el);
195
- bodyattributes = "";
196
- [...body_el.attributes].forEach((attr) => bodyattributes = bodyattributes + " " + attr.name + '=\\"' + attr.value + '\\"');
197
- scriptattributes = "";
198
- [...script_el.attributes].forEach((attr) => scriptattributes = scriptattributes + " " + attr.name + '=\\"' + attr.value + '\\"');
199
- }
200
-
201
- let head_el,
202
- body_el,
203
- style_el,
204
- script_el;
205
- const parseFullHTML = (fullHTML) => {
206
- const parser = new DOMParser(),
207
- fragment = parser.parseFromString(fullHTML, "text/html");
208
- head_el = fragment?.head,
209
- body_el = fragment?.body,
210
- style_el = fragment?.body.querySelector("style"),
211
- script_el = fragment?.body.querySelector("script:not([src])");
212
- if(!maintainbody) {
213
- if (style_el) {
214
- cssText = trimContent(style_el?.innerHTML);
215
- style_el.remove();
216
- } else {
217
- cssText = "";
218
- }
219
- if (script_el) {
220
- scriptText = trimContent(script_el?.innerHTML);
221
- script_el.remove();
222
- } else {
223
- scriptText = "";
224
- }
225
- }
226
- headhtml = trimContent(head_el?.innerHTML || "");
227
- bodyhtml = trimContent(body_el?.innerHTML);
228
- if(style_el && body_el) body_el.appendChild(style_el);
229
- if(script_el && body_el) body_el.appendChild(script_el);
230
- };
231
-
232
- let fs,
233
- url;
234
- if (src) {
235
- url = new URL(src,document.baseURI); // , document.baseURI
236
- if(typeof(LightningFS)!=="undefined") {
237
- fs = new LightningFS(url.hostname + "_repl").promises;
238
- }
239
- try {
240
- parseFullHTML(await loadFromFile());
241
- canReset = true;
242
- } catch (e) {
243
- try {
244
- parseFullHTML(await loadFromServer());
245
- } catch (e) {
246
- fullHTML = e.message;
247
- }
248
- }
249
- } else {
250
- url = new URL(getPath(),document.baseURI);
251
- if(typeof(LightningFS)!=="undefined") {
252
- fs = new LightningFS(url.hostname + "_repl").promises;
253
- }
254
- try {
255
- parseFullHTML(await loadFromFile());
256
- canReset = true;
257
- } catch (e) {
258
- initFromTemplate(loadFromTemplate());
259
- }
260
- };
261
-
262
- // initialize variables
263
- markdown = "";
264
-
265
- const tabs = [...self.querySelectorAll("span[for]")]
266
- .map((span) => {
267
- const id = span.getAttribute("for");
268
- if(id==="preview") {
269
- const el = self.getElementById(id);
270
- if(previewPinned) el.removeAttribute("hidden");
271
- return [id, el];
272
- }
273
- const slot = self.querySelector(`[slot="${id}"]`);
274
- if(slot) {
275
- if(slot.hasAttribute("hidden")) self.querySelector(`slot[name="${id}"]`)?.setAttribute("hidden","");
276
- else {
277
- self.varsProxy[`${id}Pinned`] = true;
278
- self.querySelector(`slot[name="${id}"]`)?.setAttribute("checked","");
279
- }
280
- } else {
281
- self.querySelector(`slot[name="${id}"]`)?.setAttribute("hidden","");
282
- span.style.display = "none";
283
- }
284
- return [id, slot];
285
- }).filter(([id, slot]) => slot!=null);
286
-
287
- const showTab = (targetid) => {
288
- tabs.forEach(([id, el, label]) => {
289
- if (id === targetid || self.varsProxy[`${id}Pinned`]) {
290
- el.removeAttribute("hidden");
291
- self.querySelector(`slot[name="${id}"]`)?.removeAttribute("hidden");
292
- } else if (!self.varsProxy[`${id}Pinned`]) {
293
- el.setAttribute("hidden","");
294
- self.querySelector(`slot[name="${id}"]`)?.setAttribute("hidden","");
295
- }
296
- });
297
- };
298
-
299
- const hideTab = (targetid) => {
300
- tabs.forEach(([id, el, label]) => {
301
- if (id === targetid) {
302
- el.setAttribute("hidden","");
303
- self.querySelector(`slot[name="${id}"]`)?.setAttribute("hidden","");
304
- }
305
- });
306
- };
307
-
308
- const replaceEntities = (el) => {
309
- [...el.childNodes].forEach((node) => {
310
- if(node.nodeType===Node.TEXT_NODE) {
311
- if(["&lt;","&gt;","&amp;"].some((entity) => node.data.includes(entity))) {
312
- node.data = node.data.replaceAll(/&lt;/g,"<")
313
- .replaceAll(/&gt;/g,">")
314
- .replaceAll(/&amp;/g,"&");
315
- }
316
- } else if(node.nodeType===Node.ELEMENT_NODE) {
317
- replaceEntities(node);
318
- }
319
- })
320
- };
321
-
322
- onTabClick = (event) => {
323
- showTab(event.target.getAttribute("for"))
324
- }
325
-
326
- onPinClick = (event) => {
327
- const id = event.target.getAttribute("for"),
328
- checked = self.varsProxy[`${id}Pinned`] = event.target.checked;
329
- if (checked) onTabClick(event);
330
- else hideTab(id);
331
- };
332
-
333
- doSave = async () => {
334
- const parts = url.pathname.split("/");
335
- let dir = "";
336
- parts.shift();
337
- parts.pop();
338
- for (const part of parts) {
339
- dir = dir + "/" + part;
340
- try {
341
- await fs.mkdir(dir);
342
- } catch (e) {
343
- if (e.message === "EEXIST") continue;
344
- throw e;
345
- }
346
- }
347
- await fs.writeFile(url.pathname, doPreview(), {encoding: "utf8"}, () => {
348
- });
349
- source = `IndexedDB://${url.hostname + "_repl"}${url.pathname}`;
350
- canReset = true;
351
- };
352
-
353
- doReset = async () => {
354
- originalHTML = null;
355
- try {
356
- await fs.unlink(url.pathname);
357
- } catch (e) {
358
-
359
- }
360
- if (src) {
361
- try {
362
- parseFullHTML(await loadFromServer());
363
- source = url.href;
364
- createEditor();
365
- } catch (e) {
366
- previewEl.innerHTML = fullHTML = e.message;
367
- }
368
- } else {
369
- try {
370
- initFromTemplate(loadFromTemplate());
371
- source = getPath();
372
- createEditor();
373
- } catch (e) {
374
- previewEl.innerHTML = fullHTML = e.message;
375
- }
376
- }
377
- canReset = false;
378
- };
379
-
380
- const content = self.getElementById("content");
381
- let originalHTML;
382
- const doPreview = () => {
383
- head_el.innerHTML = `<base href=\"${document.baseURI}\"></base>` + trimContent(headhtml); //
384
- body_el.innerHTML = trimContent(bodyhtml);
385
- if(!maintainbody) {
386
- style_el.innerText = trimContent(cssText);
387
- script_el.innerHTML = "currentComponent ||= document.body;" + trimContent(scriptText);
388
- body_el.appendChild(style_el);
389
- body_el.appendChild(script_el);
390
- style_el.innerText = style_el.innerText.replaceAll(/<br>/g,"\n");
391
- }
392
- const str = "<html>" + head_el.outerHTML + body_el.outerHTML + "</html>",
393
- blob = new Blob([str], {type : 'text/html'}),
394
- newurl = window.URL.createObjectURL(blob);
395
- if(originalHTML) canReset = originalHTML!=str;
396
- else originalHTML = str;
397
- previewEl.src = newurl;
398
- content.style.minWidth = self.style.minWidth;
399
- content.style.maxWidth = self.style.maxWidth;
400
- //content.style.width = tabs.reduce((min,tab) => Math.max(min,tab[1].clientWidth),0)+"px";
401
- return str;
402
- };
403
-
404
- const tabsEl = self.getElementById("tabs"),
405
- headhtmlEl = self.querySelector('[slot="headhtml"]'),
406
- bodyhtmlEl = self.querySelector('[slot="bodyhtml"]'),
407
- markdownEl = self.getElementById("markdown"),
408
- cssEl = self.querySelector('[slot="css"]'),
409
- scriptEl = self.querySelector('[slot="script"]'),
410
- previewEl = self.getElementById("preview");
411
-
412
- const highlight = (el,...args) => {
413
- hljs.highlightElement(el,...args);
414
- }
415
-
416
- const setCode = (el,code,language) => {
417
- const pre = document.createElement("pre"),
418
- div = document.createElement("div");
419
- pre.style.margin = "5px";
420
- div.className = `language-${language}`;
421
- div.innerText = trimContent(code).replaceAll(/\n/g,"|newline|");
422
- hljs.highlightElement(div);
423
- pre.innerHTML = div.innerHTML.replaceAll(/\|newline\|/g,"\n");
424
- while(el.lastChild) el.lastChild.remove();
425
- replaceEntities(el);
426
- el.append(pre);
427
- }
428
-
429
- if(headhtmlEl) {
430
- headhtmlEl.className = "language-html";
431
- if(headhtmlEl.hasAttribute("readonly") || readonly) {
432
- setCode(headhtmlEl,headhtml,"html");
433
- } else {
434
- editable = true;
435
- const bodyJar = CJ(headhtmlEl, highlight);
436
- bodyJar.updateCode(headhtml);
437
- replaceEntities(headhtmlEl);
438
- bodyJar.onUpdate(code => {
439
- replaceEntities(headhtmlEl);
440
- headhtml = code;
441
- doPreview();
442
- })
443
- }
444
- }
445
-
446
- const createEditor = () => {
447
-
448
- if (bodyhtmlEl) {
449
- bodyhtmlEl.className = "language-html";
450
- if (bodyhtmlEl.hasAttribute("readonly") || readonly) {
451
- setCode(bodyhtmlEl, bodyhtml, "html");
452
- } else {
453
- editable = true;
454
- const bodyJar = CJ(bodyhtmlEl, highlight);
455
- bodyJar.updateCode(bodyhtml);
456
- replaceEntities(bodyhtmlEl);
457
- bodyJar.onUpdate(code => {
458
- replaceEntities(bodyhtmlEl);
459
- bodyhtml = code;
460
- doPreview();
461
- });
462
- }
463
- }
464
-
465
- if (cssEl) {
466
- cssEl.className = "language-css";
467
- if (cssEl.hasAttribute("readonly") || readonly) {
468
- setCode(cssEl, cssText, "css");
469
- //cssEl.innerText = cssText;
470
- } else {
471
- editable = true;
472
- const bodyJar = CJ(cssEl, highlight);
473
- bodyJar.updateCode(cssText);
474
- bodyJar.onUpdate(code => {
475
- cssText = code;
476
- doPreview();
477
- });
478
- }
479
- }
480
-
481
- if (scriptEl) {
482
- scriptEl.className = "language-javascript";
483
- if (scriptEl.hasAttribute("readonly") || readonly) {
484
- setCode(scriptEl, scriptText, "javascript");
485
- //scriptEl.innerText = scriptText;
486
- } else {
487
- editable = true;
488
- const bodyJar = CJ(scriptEl, highlight);
489
- bodyJar.updateCode(scriptText);
490
- replaceEntities(scriptEl);
491
- bodyJar.onUpdate(code => {
492
- replaceEntities(scriptEl);
493
- scriptText = code;
494
- doPreview();
495
- });
496
- }
497
- }
498
-
499
- doPreview();
500
- }
501
-
502
- /*let prevmarkdown; // prevents indirect recursion
503
- observe(() => {
504
- const text = turndownService.turndown(bodyhtml).trim();
505
- if (text && text !== prevtext) {
506
- markdown = markdownEl.innerHTML = prevmarkdown = text;
507
- }
508
- });
509
-
510
- let prevbodyhtml; // prevents indirect recursion
511
- observe(() => {
512
- const html = marked.parse(markdown).trim();
513
- if (html && html !== prevbodyhtml) {
514
- bodyhtml = bodyhtmlEl.innerText = prevbodyhtml = html;
515
- }
516
- });*/
517
-
518
-
519
- self.addEventListener("mounted", () => {
520
- tabsEl.removeAttribute("hidden");
521
- if(contentbackground) content.style.background = contentbackground;
522
- createEditor();
523
- });
524
- }
525
- </script>
526
- </body>
527
- </html>