solarite 0.1.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 (63) hide show
  1. package/build/build.bat +3 -0
  2. package/build/build.js +139 -0
  3. package/build/lib/rollup.min.js +11 -0
  4. package/build/lib/source-map.min.js +1 -0
  5. package/build/lib/terser.min.js +1 -0
  6. package/dist/Solarite-debug.js +4143 -0
  7. package/dist/Solarite.js +3740 -0
  8. package/dist/Solarite.min.js +4 -0
  9. package/docs/index.md +423 -0
  10. package/docs/js/Playground.js +184 -0
  11. package/docs/js/codemirror/codemirror6.js +32036 -0
  12. package/docs/js/codemirror/themeSolarIce.js +312 -0
  13. package/docs/js/documentation.js +32 -0
  14. package/docs/js/ui/CodeEditor.js +840 -0
  15. package/docs/js/ui/DarkToggle.js +52 -0
  16. package/docs/js/ui/FlexResizer.js +142 -0
  17. package/docs/js/util/Draggable2.js +151 -0
  18. package/docs/js/util/Errors.js +9 -0
  19. package/docs/js/util/Html.js +147 -0
  20. package/docs/js/util/Icons.js +623 -0
  21. package/docs/js/util/Input.js +253 -0
  22. package/docs/js/util/Util.js +88 -0
  23. package/docs/js/util/delve.js +43 -0
  24. package/docs/media/FiraCode400.woff2 +0 -0
  25. package/docs/media/cabin-latin-700.woff2 +0 -0
  26. package/docs/media/documentation.css +93 -0
  27. package/docs/media/eternium.css +1123 -0
  28. package/docs/media/solarite-machine.webp +0 -0
  29. package/index.html +325 -0
  30. package/package.json +33 -0
  31. package/readme.md +3 -0
  32. package/src/solarite/ExprPath.js +554 -0
  33. package/src/solarite/MultiValueMap.js +65 -0
  34. package/src/solarite/NodeGroup.js +706 -0
  35. package/src/solarite/NodeGroupManager.js +582 -0
  36. package/src/solarite/Shell.js +307 -0
  37. package/src/solarite/Solarite.js +19 -0
  38. package/src/solarite/Template.js +85 -0
  39. package/src/solarite/Util.js +264 -0
  40. package/src/solarite/createSolarite.js +267 -0
  41. package/src/solarite/getArg.js +99 -0
  42. package/src/solarite/hash.js +101 -0
  43. package/src/solarite/r.js +143 -0
  44. package/src/solarite/udomdiff.js +233 -0
  45. package/src/solarite/watch.js +302 -0
  46. package/src/solarite/watch2.js +439 -0
  47. package/src/unused/FastLookupArray.js +54 -0
  48. package/src/unused/Hashes.js +339 -0
  49. package/src/unused/InUse.test.js +92 -0
  50. package/src/unused/InUseMap.js +98 -0
  51. package/src/unused/LinkedList.js +117 -0
  52. package/src/unused/LinkedList.test.js +115 -0
  53. package/src/unused/Perf.js +47 -0
  54. package/src/unused/Template.js +108 -0
  55. package/src/util/Errors.js +9 -0
  56. package/src/util/Util.js +88 -0
  57. package/src/util/delve.js +43 -0
  58. package/tests/Benchmark.test.js +319 -0
  59. package/tests/NodeGroup.test.js +115 -0
  60. package/tests/Shell.test.js +75 -0
  61. package/tests/Solarite.test.js +2896 -0
  62. package/tests/Testimony.js +602 -0
  63. package/tests/index.html +75 -0
@@ -0,0 +1,184 @@
1
+ import {r, Solarite} from "../../src/solarite/Solarite.js";
2
+ import "./ui/CodeEditor.js";
3
+ import "./ui/FlexResizer.js";
4
+
5
+
6
+ export default class Playground extends Solarite {
7
+
8
+ /**
9
+ *
10
+ * @param code
11
+ * @param language
12
+ * @param width
13
+ *
14
+ * @param maxHeight {int} If the editor is taller than the preview, and taller than this height, limit it the max of this height and the preview height.
15
+ * */
16
+ constructor({value, language='JavaScript', width=50, prefix='', maxHeight=620}={}) {
17
+ super({scripts: false});
18
+ value = value || (this.code ? this.code.querySelector('script')?.textContent : '');
19
+ this.value = value;
20
+ this.language = language;
21
+ this.width = width;
22
+ this.prefix2 = prefix;
23
+ this.maxHeight = maxHeight
24
+ this.render();
25
+
26
+ this.editor.onChange.push(() => {
27
+ this.run();
28
+ });
29
+
30
+ this.run();
31
+ }
32
+
33
+ run() {
34
+ let html;
35
+ if (this.language === 'javascript')
36
+ html = `<script type="module">${this.editor.getValue()}</script>`;
37
+ else if (this.language === 'html')
38
+ html = this.editor.getValue();
39
+ else {
40
+ this.editor.style.width = '100%';
41
+ this.editor.style.borderRight = 'none';
42
+ this.resizer.style.display = 'none';
43
+ this.preview.style.display = 'none';
44
+ return;
45
+ }
46
+
47
+ // Create a new preview iframe and swap it for the old one once it's loaded.
48
+ let newIframe = r(`<iframe data-id="preview" frameborder="0" style="display: none; height: 0">`);
49
+ newIframe.onload = () => {
50
+
51
+ newIframe.contentWindow.document.open();
52
+ newIframe.contentWindow.onerror = (msg, url, line, col, error) => {
53
+
54
+ setTimeout(() => {
55
+ let message;
56
+ if (error instanceof newIframe.contentWindow.SyntaxError)
57
+ message = `${msg} on line ${line}:${col}`
58
+ else
59
+ message = shortenError(error)
60
+
61
+ let errorDiv = `<div style="color: red; font: 12px sans-serif; position: fixed; left: 0; bottom: 0;
62
+ width: 100%; padding: 5px; max-height: 50%; overflow-y: auto; background: white">${message}</div>`;
63
+ newIframe.contentWindow.document.body.append(r(errorDiv));
64
+ }, 0);
65
+ }
66
+
67
+ newIframe.contentWindow.document.write(this.prefix2 + html);
68
+
69
+ newIframe.contentWindow.document.close();
70
+ newIframe.onload = null;
71
+
72
+ if (document.documentElement.hasAttribute('dark'))
73
+ newIframe.contentWindow.document.documentElement.setAttribute('dark', '');
74
+ // TODO use mutation observer to watch for change.
75
+
76
+
77
+
78
+
79
+
80
+ // TODO: Check to see when all links have a .sheet property with css rules.
81
+ // let dynamic = newIframe.contentWindow.document.querySelectorAll('link');
82
+ // for (let el of dynamic) {
83
+ // console.log(el)
84
+ // dynamic.onload = () => {
85
+ // console.log('loaded')
86
+ // console.log(el)
87
+ // }
88
+ // }
89
+
90
+
91
+
92
+ // Prevent flashing
93
+ //newIframe.contentWindow.document.addEventListener('load', () => {
94
+ setTimeout(() => {
95
+ //newIframe.contentWindow.requestAnimationFrame(() => {
96
+ this.preview.remove();
97
+ newIframe.style.display = '';
98
+ this.preview = newIframe;
99
+
100
+ // Resize iframe to height of content.
101
+ let newPreviewHeight = expandIframe(newIframe);
102
+ setTimeout(() => {
103
+ expandIframe(newIframe);
104
+ }, 500);
105
+
106
+
107
+ if (this.maxHeight) {
108
+
109
+ // Get scroll position.
110
+ let scroller = this.editor.querySelector('.cm-editor > .cm-scroller');
111
+ let scroll = {x: scroller?.scrollLeft || 0, y: scroller?.scrollTop || 0};
112
+
113
+ // Don't let CodeEditor be taller than preview.
114
+ this.editor.style.height = '';
115
+ let editorHeight = this.editor.getBoundingClientRect().height;
116
+ if (editorHeight > newPreviewHeight && editorHeight > this.maxHeight)
117
+ this.editor.style.height = Math.max(newPreviewHeight, this.maxHeight) + 'px';
118
+
119
+ // Restore scroll position.
120
+ if (scroller) {
121
+ scroller.scrollTop = scroll.y;
122
+ scroller.scrollLeft = scroll.x;
123
+ requestAnimationFrame(() => {
124
+ scroller.scrollTop = scroll.y;
125
+ scroller.scrollLeft = scroll.x;
126
+ });
127
+ }
128
+ }
129
+ //})
130
+ }, 10);
131
+ }
132
+
133
+ this.insertBefore(newIframe, this.preview);
134
+ }
135
+
136
+
137
+ render() {
138
+ r(this)`
139
+ <play-ground class="card row pad stretch-v pad-small-tablet col-mobile pad-tiny-mobile">
140
+ <style>
141
+ @media (width < 768px) { /* On mobile, put preview below code */
142
+ :host code-editor { max-height: 300px; border-bottom: var(--border) }
143
+ :host [data-id=preview] { margin: 0; min-width: 0; background: white }
144
+ :host flex-resizer { display: none }
145
+ }
146
+ @media (768px <= width) {
147
+ :host code-editor { width: ${this.width}%; border-right: var(--border) }
148
+ :host [data-id=preview] { width: ${100 - this.width}%; min-width: 0; margin: 0; background: white }
149
+ }
150
+ </style>
151
+ <code-editor data-id="editor" value=${this.value} language=${this.language} options=${{tabSize: 2}}></code-editor>
152
+ <flex-resizer data-id="resizer"></flex-resizer>
153
+ <iframe data-id="preview" frameborder="0"></iframe>
154
+ <slot data-id="code" style="display: none"></slot>
155
+ </play-ground>`
156
+ }
157
+ }
158
+ Playground.define('play-ground');
159
+
160
+ function shortenError(error, br='<br>&nbsp;&nbsp;') {
161
+ if (typeof error === 'string')
162
+ return error;
163
+
164
+ return error.stack.replace(/\r?\n/g, br);
165
+ }
166
+
167
+ function expandIframe(iframe) {
168
+ if (!iframe.contentWindow)
169
+ return;
170
+
171
+ iframe.style.height = '0';
172
+ iframe.style.minHeight = '';
173
+ iframe.style.maxHeight = '0';
174
+
175
+ let previewHeight = iframe.contentWindow.document.documentElement.scrollHeight;
176
+ let newPreviewHeight = Math.ceil(previewHeight);
177
+ if (iframe.contentWindow.document.body.scrollWidth > iframe.clientWidth)
178
+ newPreviewHeight += 24; // If it has a scrollbar.
179
+
180
+ iframe.style.height = '';
181
+ iframe.style.minHeight = newPreviewHeight + 'px';
182
+ iframe.style.maxHeight = '100%';
183
+ return newPreviewHeight;
184
+ }