lexgui 8.2.5 → 8.3.1

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 (36) hide show
  1. package/build/components/NodeTree.d.ts +51 -51
  2. package/build/components/Tabs.d.ts +1 -0
  3. package/build/core/Namespace.js +1 -1
  4. package/build/core/Namespace.js.map +1 -1
  5. package/build/extensions/AssetView.d.ts +138 -138
  6. package/build/extensions/AssetView.js +1433 -1433
  7. package/build/extensions/CodeEditor.d.ts +467 -363
  8. package/build/extensions/CodeEditor.js +3962 -4628
  9. package/build/extensions/CodeEditor.js.map +1 -1
  10. package/build/extensions/DocMaker.d.ts +28 -28
  11. package/build/extensions/DocMaker.js +363 -363
  12. package/build/extensions/Timeline.d.ts +2 -2
  13. package/build/extensions/Timeline.js +28 -15
  14. package/build/extensions/Timeline.js.map +1 -1
  15. package/build/extensions/VideoEditor.d.ts +1 -1
  16. package/build/extensions/VideoEditor.js +1021 -1014
  17. package/build/extensions/VideoEditor.js.map +1 -1
  18. package/build/extensions/index.js +1 -1
  19. package/build/lexgui.all.js +6379 -6951
  20. package/build/lexgui.all.js.map +1 -1
  21. package/build/lexgui.all.min.js +1 -1
  22. package/build/lexgui.all.module.js +6379 -6952
  23. package/build/lexgui.all.module.js.map +1 -1
  24. package/build/lexgui.all.module.min.js +1 -1
  25. package/build/lexgui.css +7544 -7459
  26. package/build/lexgui.js +4731 -241
  27. package/build/lexgui.js.map +1 -1
  28. package/build/lexgui.min.css +1 -1
  29. package/build/lexgui.min.js +1 -1
  30. package/build/lexgui.module.js +4731 -241
  31. package/build/lexgui.module.js.map +1 -1
  32. package/build/lexgui.module.min.js +1 -1
  33. package/changelog.md +43 -1
  34. package/demo.js +3 -2
  35. package/examples/code-editor.html +97 -16
  36. package/package.json +1 -1
@@ -1,363 +1,363 @@
1
- // This is a generated file. Do not edit.
2
- import { LX } from '../core/Namespace.js';
3
-
4
- // DocMaker.ts @jxarco
5
- if (!LX) {
6
- throw ('Missing LX namespace!');
7
- }
8
- LX.extensions.push('DocMaker');
9
- const CLASS_WORDS = ['uint32_t', 'uint64_t', 'uint8_t'];
10
- const CPP_KEY_WORDS = ['int', 'float', 'double', 'bool', 'char', 'wchar_t', 'const', 'static_cast', 'dynamic_cast', 'new', 'delete', 'void', 'true',
11
- 'false', 'auto', 'struct', 'typedef', 'nullptr', 'NULL', 'unsigned', 'namespace', 'auto'];
12
- const JS_KEY_WORDS = ['var', 'let', 'const', 'static', 'function', 'null', 'undefined', 'new', 'delete', 'true', 'false', 'NaN', 'this'];
13
- const WGSL_KEY_WORDS = ['var', 'let', 'const', 'override', 'fn', 'struct', 'alias', 'true', 'false', 'bool', 'f16', 'f32', 'i32', 'u32', 'vec2',
14
- 'vec3', 'vec4', 'mat2x2', 'mat2x3', 'mat2x4', 'mat3x2', 'mat3x3', 'mat3x4', 'mat4x2', 'mat4x3', 'mat4x4' // 'atomic', 'array', 'ptr', 'sampler', 'sampler_comparison', 'texture_1d', 'texture_2d', 'texture_2d_array', 'texture_3d', 'texture_cube', 'texture_cube_array',
15
- // 'texture_multisampled_2d', 'texture_external', 'texture_storage_1d', 'texture_storage_2d', 'texture_storage_2d_array', 'texture_storage_3d', 'texture_depth_2d',
16
- // 'texture_depth_2d_array', 'texture_depth_cube', 'texture_depth_cube_array', 'texture_depth_multisampled_2d', 'function', 'private', 'workgroup', 'uniform',
17
- // 'storage', 'read', 'write', 'read_write', 'binding', 'builtin', 'group', 'id', 'interpolate', 'invariant', 'location', 'size', 'align', 'stride', 'vertex', 'fragment', 'compute', 'workgroup_size',
18
- ];
19
- const STATEMENT_WORDS = ['for', 'if', 'else', 'return', 'continue', 'break', 'case', 'switch', 'while', 'import', 'from', 'await'];
20
- const HTML_ATTRIBUTES = ['html', 'charset', 'rel', 'src', 'href', 'crossorigin', 'type', 'lang'];
21
- const HTML_TAGS = ['DOCTYPE', 'html', 'head', 'body', 'title', 'base', 'link', 'meta', 'style', 'main', 'section', 'nav', 'article', 'aside',
22
- 'header', 'footer', 'address', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'hr', 'pre', 'blockquote', 'ol', 'ul', 'li', 'dl', 'dt', 'dd', 'figure',
23
- 'figcaption', 'div', 'a', 'abbr', 'b', 'bdi', 'bdo', 'br', 'cite', 'code', 'data', 'dfn', 'em', 'i', 'kbd', 'mark', 'q', 'rp', 'rt', 'ruby', 's',
24
- 'samp', 'small', 'span', 'strong', 'sub', 'sup', 'time', 'u', 'var', 'wbr', 'img', 'audio', 'video', 'source', 'track', 'picture', 'map', 'area',
25
- 'canvas', 'iframe', 'embed', 'object', 'param', 'form', 'label', 'input', 'button', 'select', 'datalist', 'optgroup', 'option', 'textarea',
26
- 'output', 'progress', 'meter', 'fieldset', 'legend', 'table', 'caption', 'colgroup', 'col', 'tbody', 'thead', 'tfoot', 'tr', 'td', 'th',
27
- 'details', 'summary', 'dialog', 'script', 'noscript', 'template'];
28
- class DocMaker {
29
- root;
30
- _listQueued = undefined;
31
- _lastDomTarget = undefined;
32
- constructor(element) {
33
- this.root = element ?? document.body;
34
- }
35
- setDomTarget(element) {
36
- this.root = element;
37
- }
38
- lineBreak(target) {
39
- target = target ?? this.root;
40
- target.appendChild(document.createElement('br'));
41
- }
42
- header(string, type, id, options = {}) {
43
- console.assert(string !== undefined && type !== undefined);
44
- if (options.collapsable) {
45
- const collapsible = LX.makeElement('div', LX.mergeClass('my-4 px-6 cursor-pointer', options.className), `<${type} id="${id ?? ''}">${string}</${type}>`, this.root);
46
- const collapsibleContent = LX.makeContainer(['100%', 'auto'], 'px-4', '', this.root);
47
- LX.listen(collapsible, 'click', () => collapsible.querySelector('a.collapser').click());
48
- this._lastDomTarget = this.root;
49
- this.setDomTarget(collapsibleContent);
50
- if (options.collapsableContentCallback) {
51
- options.collapsableContentCallback();
52
- }
53
- LX.makeCollapsible(collapsible, collapsibleContent, null, { collapsed: options.collapsed ?? false });
54
- this.setDomTarget(this._lastDomTarget);
55
- delete this._lastDomTarget;
56
- return collapsible;
57
- }
58
- const header = document.createElement(type);
59
- header.className = options.className ?? '';
60
- header.innerHTML = string;
61
- if (id)
62
- header.id = id;
63
- this.root.appendChild(header);
64
- return header;
65
- }
66
- paragraph(string, sup = false, className = '') {
67
- console.assert(string !== undefined);
68
- let paragraph = document.createElement(sup ? 'sup' : 'p');
69
- paragraph.className = LX.mergeClass('leading-relaxed', className);
70
- paragraph.innerHTML = string;
71
- this.root.appendChild(paragraph);
72
- return paragraph;
73
- }
74
- code(text, language = 'js') {
75
- console.assert(text !== undefined);
76
- text.replaceAll('<', '&lt;');
77
- text.replaceAll('>', '&gt;');
78
- let highlight = '';
79
- let content = '';
80
- const getHTML = (h, c) => {
81
- return `<span class="${h}">${c}</span>`;
82
- };
83
- for (let i = 0; i < text.length; ++i) {
84
- const char = text[i];
85
- const string = text.substring(i);
86
- const endLineIdx = string.indexOf('\n');
87
- const line = string.substring(0, endLineIdx > -1 ? endLineIdx : undefined);
88
- if (char == '@') {
89
- const str = line.substring(1);
90
- if (!(str.indexOf('@') > -1) && !(str.indexOf('[') > -1)) {
91
- continue;
92
- }
93
- let html = null;
94
- const tagIndex = str.indexOf('@');
95
- const skipTag = str[tagIndex - 1] == '|';
96
- // Highlight is specified
97
- if (text[i + 1] == '[') {
98
- highlight = str.substring(1, 4);
99
- content = str.substring(5, tagIndex);
100
- if (skipTag) {
101
- const newString = str.substring(6 + content.length);
102
- const preContent = content;
103
- const postContent = newString.substring(0, newString.indexOf('@'));
104
- const finalContent = preContent.substring(0, preContent.length - 1) + '@' + postContent;
105
- html = getHTML(highlight, finalContent);
106
- const ogContent = preContent + '@' + postContent;
107
- text = text.replace(`@[${highlight}]${ogContent}@`, html);
108
- }
109
- else {
110
- html = getHTML(highlight, content);
111
- text = text.replace(`@[${highlight}]${content}@`, html);
112
- }
113
- }
114
- else {
115
- content = str.substring(0, tagIndex);
116
- if (skipTag) {
117
- const preContent = str.substring(0, str.indexOf('@') - 1);
118
- content = str.substring(preContent.length + 1);
119
- content = preContent + content.substring(0, content.substring(1).indexOf('@') + 1);
120
- text = text.substr(0, i) + '@' + content + '@' + text.substr(i + content.length + 3);
121
- }
122
- if (language == 'cpp' && CPP_KEY_WORDS.includes(content)) {
123
- highlight = 'kwd';
124
- }
125
- else if (language == 'js' && JS_KEY_WORDS.includes(content)) {
126
- highlight = 'kwd';
127
- }
128
- else if (language == 'wgsl' && WGSL_KEY_WORDS.includes(content)) {
129
- highlight = 'kwd';
130
- }
131
- else if (CLASS_WORDS.includes(content)) {
132
- highlight = 'cls';
133
- }
134
- else if (STATEMENT_WORDS.includes(content)) {
135
- highlight = 'lit';
136
- }
137
- else if (HTML_TAGS.includes(content)) {
138
- highlight = 'tag';
139
- }
140
- else if (HTML_ATTRIBUTES.includes(content)) {
141
- highlight = 'atn';
142
- }
143
- else if ((content[0] == '"' && content[content.length - 1] == '"')
144
- || (content[0] == "'" && content[content.length - 1] == "'")
145
- || (content[0] == '`' && content[content.length - 1] == '`')) {
146
- highlight = 'str';
147
- }
148
- else if (!Number.isNaN(parseFloat(content))) {
149
- highlight = 'dec';
150
- }
151
- else {
152
- highlight = '';
153
- console.error('WARNING[Code Parsing]: Unknown highlight type: ' + content);
154
- }
155
- html = getHTML(highlight, content);
156
- text = text.replace(`@${content}@`, html);
157
- }
158
- i += html.length - 1;
159
- }
160
- }
161
- let container = document.createElement('div');
162
- container.className = 'code-container';
163
- let pre = document.createElement('pre');
164
- let code = document.createElement('code');
165
- code.innerHTML = text;
166
- let button = document.createElement('button');
167
- button.title = 'Copy code sample';
168
- button.appendChild(LX.makeIcon('Copy'));
169
- button.addEventListener('click', this._copySnippet.bind(this, button));
170
- container.appendChild(button);
171
- pre.appendChild(code);
172
- container.appendChild(pre);
173
- this.root.appendChild(container);
174
- return container;
175
- }
176
- list(list, type, target, className = '') {
177
- const validTypes = ['bullet', 'numbered'];
178
- console.assert(list && list.length > 0 && validTypes.includes(type), 'Invalid list type or empty list' + type);
179
- const typeString = type == 'bullet' ? 'ul' : 'ol';
180
- let ul = document.createElement(typeString);
181
- ul.className = className;
182
- target = target ?? this.root;
183
- target.appendChild(ul);
184
- for (var el of list) {
185
- if (el.constructor === Array) {
186
- this.list(el, type, ul);
187
- return;
188
- }
189
- let li = document.createElement('li');
190
- li.className = 'leading-loose';
191
- li.innerHTML = el;
192
- ul.appendChild(li);
193
- }
194
- return ul;
195
- }
196
- bulletList(list) {
197
- return this.list(list, 'bullet');
198
- }
199
- numberedList(list) {
200
- return this.list(list, 'numbered');
201
- }
202
- startCodeBulletList() {
203
- let ul = document.createElement('ul');
204
- this._listQueued = ul;
205
- return ul;
206
- }
207
- endCodeBulletList() {
208
- if (this._listQueued === undefined)
209
- return;
210
- console.assert(this._listQueued !== undefined);
211
- this.root.appendChild(this._listQueued);
212
- this._listQueued = undefined;
213
- }
214
- codeListItem(item, target) {
215
- target = target ?? this._listQueued;
216
- let split = item.constructor === Array;
217
- if (split && item[0].constructor === Array) {
218
- this.codeBulletList(item, target);
219
- return;
220
- }
221
- let li = document.createElement('li');
222
- li.className = 'leading-loose';
223
- li.innerHTML = split
224
- ? (item.length == 2
225
- ? this.iCode(item[0]) + ': ' + item[1]
226
- : this.iCode(item[0] + " <span class='desc'>(" + item[1] + ')</span>') + ': ' + item[2])
227
- : this.iCode(item);
228
- target?.appendChild(li);
229
- }
230
- codeBulletList(list, target) {
231
- console.assert(list !== undefined && list.length > 0);
232
- let ul = document.createElement('ul');
233
- for (var el of list) {
234
- this.codeListItem(el, ul);
235
- }
236
- if (target) {
237
- target.appendChild(ul);
238
- }
239
- else {
240
- this.root.appendChild(ul);
241
- }
242
- return ul;
243
- }
244
- image(src, caption = '', parent, className = '') {
245
- let img = document.createElement('img');
246
- img.src = src;
247
- img.alt = caption;
248
- img.className = LX.mergeClass('my-1', className);
249
- parent = parent ?? this.root;
250
- parent.appendChild(img);
251
- return img;
252
- }
253
- images(sources, captions = [], width, height) {
254
- const mobile = navigator && /Android|iPhone/i.test(navigator.userAgent);
255
- const div = document.createElement('div');
256
- if (!mobile) {
257
- div.style.width = width ?? 'auto';
258
- div.style.height = height ?? '256px';
259
- div.className = 'flex flex-row justify-center';
260
- }
261
- for (let i = 0; i < sources.length; ++i) {
262
- this.image(sources[i], captions[i], div);
263
- }
264
- this.root.appendChild(div);
265
- return div;
266
- }
267
- video(src, caption = '', controls = true, autoplay = false, className = '') {
268
- let video = document.createElement('video');
269
- video.className = className;
270
- video.src = src;
271
- video.controls = controls;
272
- video.autoplay = autoplay;
273
- if (autoplay) {
274
- video.muted = true;
275
- }
276
- video.loop = true;
277
- video.alt = caption;
278
- this.root.appendChild(video);
279
- return video;
280
- }
281
- note(text, warning = false, title, icon, className = '') {
282
- console.assert(text !== undefined);
283
- const note = LX.makeContainer([], LX.mergeClass('border-color rounded-xl overflow-hidden text-sm text-secondary-foreground my-6', className), '', this.root);
284
- const header = document.createElement('div');
285
- header.className = 'flex bg-muted font-semibold px-3 py-2 gap-2 text-secondary-foreground';
286
- header.appendChild(LX.makeIcon(icon ?? (warning ? 'MessageSquareWarning' : 'NotepadText')));
287
- header.innerHTML += title ?? (warning ? 'Important' : 'Note');
288
- note.appendChild(header);
289
- // Node body
290
- return LX.makeContainer([], 'leading-6 p-3', text, note);
291
- }
292
- classCtor(name, params, language = 'js') {
293
- let paramsHTML = '';
294
- for (var p of params) {
295
- const str1 = p[0]; // cpp: param js: name
296
- const str2 = p[1]; // cpp: defaultValue js: type
297
- if (language == 'cpp') {
298
- paramsHTML += str1 + (str2 ? " = <span class='desc'>" + str2 + '</span>' : '')
299
- + (params.indexOf(p) != (params.length - 1) ? ', ' : '');
300
- }
301
- else if (language == 'js') {
302
- paramsHTML += str1 + ": <span class='desc'>" + str2 + '</span>'
303
- + (params.indexOf(p) != (params.length - 1) ? ', ' : '');
304
- }
305
- }
306
- let pr = document.createElement('p');
307
- pr.innerHTML = this.iCode("<span class='constructor'>" + name + '(' + paramsHTML + ')' + '</span>');
308
- this.root.appendChild(pr);
309
- return pr;
310
- }
311
- classMethod(name, desc, params, ret) {
312
- this.startCodeBulletList();
313
- let paramsHTML = '';
314
- for (var p of params) {
315
- const name = p[0];
316
- const type = p[1];
317
- paramsHTML += name + ": <span class='desc'>" + type + '</span>'
318
- + (params.indexOf(p) != (params.length - 1) ? ', ' : '');
319
- }
320
- let li = document.createElement('li');
321
- li.innerHTML = this.iCode("<span class='method'>" + name + ' (' + paramsHTML + ')' + (ret ? (': ' + ret) : '') + '</span>');
322
- this._listQueued?.appendChild(li);
323
- this.endCodeBulletList();
324
- this.paragraph(desc);
325
- return li.parentElement;
326
- }
327
- iLink(text, href) {
328
- console.assert(text !== undefined && href !== undefined);
329
- return `<a class="font-semibold underline-offset-4 hover:underline" href="${href}">${text}</a>`;
330
- }
331
- iPage(text, page) {
332
- console.assert(text !== undefined && page !== undefined);
333
- const startPage = page.replace('.html', '');
334
- const g = globalThis;
335
- if (g.setPath && g.loadPage) {
336
- const tabName = g.setPath(startPage);
337
- return `<a onclick="loadPage('${page}', true, '${tabName}')">${text}</a>`;
338
- }
339
- else {
340
- console.warn('[DocMaker] Create globalThis.setPath and globalThis.loadPage to use inline pages!');
341
- }
342
- }
343
- iCode(text, codeClass) {
344
- console.assert(text !== undefined);
345
- return `<code class="inline ${codeClass ?? ''}">${text}</code>`;
346
- }
347
- _copySnippet(b) {
348
- b.innerHTML = '';
349
- b.appendChild(LX.makeIcon('Check'));
350
- b.classList.add('copied');
351
- setTimeout(() => {
352
- b.innerHTML = '';
353
- b.appendChild(LX.makeIcon('Copy'));
354
- b.classList.remove('copied');
355
- }, 2000);
356
- navigator.clipboard.writeText(b.dataset['snippet'] ?? b.parentElement.innerText);
357
- console.log('Copied!');
358
- }
359
- }
360
- LX.DocMaker = DocMaker;
361
-
362
- export { DocMaker };
363
- //# sourceMappingURL=DocMaker.js.map
1
+ // This is a generated file. Do not edit.
2
+ import { LX } from '../core/Namespace.js';
3
+
4
+ // DocMaker.ts @jxarco
5
+ if (!LX) {
6
+ throw ('Missing LX namespace!');
7
+ }
8
+ LX.extensions.push('DocMaker');
9
+ const CLASS_WORDS = ['uint32_t', 'uint64_t', 'uint8_t'];
10
+ const CPP_KEY_WORDS = ['int', 'float', 'double', 'bool', 'char', 'wchar_t', 'const', 'static_cast', 'dynamic_cast', 'new', 'delete', 'void', 'true',
11
+ 'false', 'auto', 'struct', 'typedef', 'nullptr', 'NULL', 'unsigned', 'namespace', 'auto'];
12
+ const JS_KEY_WORDS = ['var', 'let', 'const', 'static', 'function', 'null', 'undefined', 'new', 'delete', 'true', 'false', 'NaN', 'this'];
13
+ const WGSL_KEY_WORDS = ['var', 'let', 'const', 'override', 'fn', 'struct', 'alias', 'true', 'false', 'bool', 'f16', 'f32', 'i32', 'u32', 'vec2',
14
+ 'vec3', 'vec4', 'mat2x2', 'mat2x3', 'mat2x4', 'mat3x2', 'mat3x3', 'mat3x4', 'mat4x2', 'mat4x3', 'mat4x4' // 'atomic', 'array', 'ptr', 'sampler', 'sampler_comparison', 'texture_1d', 'texture_2d', 'texture_2d_array', 'texture_3d', 'texture_cube', 'texture_cube_array',
15
+ // 'texture_multisampled_2d', 'texture_external', 'texture_storage_1d', 'texture_storage_2d', 'texture_storage_2d_array', 'texture_storage_3d', 'texture_depth_2d',
16
+ // 'texture_depth_2d_array', 'texture_depth_cube', 'texture_depth_cube_array', 'texture_depth_multisampled_2d', 'function', 'private', 'workgroup', 'uniform',
17
+ // 'storage', 'read', 'write', 'read_write', 'binding', 'builtin', 'group', 'id', 'interpolate', 'invariant', 'location', 'size', 'align', 'stride', 'vertex', 'fragment', 'compute', 'workgroup_size',
18
+ ];
19
+ const STATEMENT_WORDS = ['for', 'if', 'else', 'return', 'continue', 'break', 'case', 'switch', 'while', 'import', 'from', 'await'];
20
+ const HTML_ATTRIBUTES = ['html', 'charset', 'rel', 'src', 'href', 'crossorigin', 'type', 'lang'];
21
+ const HTML_TAGS = ['DOCTYPE', 'html', 'head', 'body', 'title', 'base', 'link', 'meta', 'style', 'main', 'section', 'nav', 'article', 'aside',
22
+ 'header', 'footer', 'address', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'hr', 'pre', 'blockquote', 'ol', 'ul', 'li', 'dl', 'dt', 'dd', 'figure',
23
+ 'figcaption', 'div', 'a', 'abbr', 'b', 'bdi', 'bdo', 'br', 'cite', 'code', 'data', 'dfn', 'em', 'i', 'kbd', 'mark', 'q', 'rp', 'rt', 'ruby', 's',
24
+ 'samp', 'small', 'span', 'strong', 'sub', 'sup', 'time', 'u', 'var', 'wbr', 'img', 'audio', 'video', 'source', 'track', 'picture', 'map', 'area',
25
+ 'canvas', 'iframe', 'embed', 'object', 'param', 'form', 'label', 'input', 'button', 'select', 'datalist', 'optgroup', 'option', 'textarea',
26
+ 'output', 'progress', 'meter', 'fieldset', 'legend', 'table', 'caption', 'colgroup', 'col', 'tbody', 'thead', 'tfoot', 'tr', 'td', 'th',
27
+ 'details', 'summary', 'dialog', 'script', 'noscript', 'template'];
28
+ class DocMaker {
29
+ root;
30
+ _listQueued = undefined;
31
+ _lastDomTarget = undefined;
32
+ constructor(element) {
33
+ this.root = element ?? document.body;
34
+ }
35
+ setDomTarget(element) {
36
+ this.root = element;
37
+ }
38
+ lineBreak(target) {
39
+ target = target ?? this.root;
40
+ target.appendChild(document.createElement('br'));
41
+ }
42
+ header(string, type, id, options = {}) {
43
+ console.assert(string !== undefined && type !== undefined);
44
+ if (options.collapsable) {
45
+ const collapsible = LX.makeElement('div', LX.mergeClass('my-4 px-6 cursor-pointer', options.className), `<${type} id="${id ?? ''}">${string}</${type}>`, this.root);
46
+ const collapsibleContent = LX.makeContainer(['100%', 'auto'], 'px-4', '', this.root);
47
+ LX.listen(collapsible, 'click', () => collapsible.querySelector('a.collapser').click());
48
+ this._lastDomTarget = this.root;
49
+ this.setDomTarget(collapsibleContent);
50
+ if (options.collapsableContentCallback) {
51
+ options.collapsableContentCallback();
52
+ }
53
+ LX.makeCollapsible(collapsible, collapsibleContent, null, { collapsed: options.collapsed ?? false });
54
+ this.setDomTarget(this._lastDomTarget);
55
+ delete this._lastDomTarget;
56
+ return collapsible;
57
+ }
58
+ const header = document.createElement(type);
59
+ header.className = options.className ?? '';
60
+ header.innerHTML = string;
61
+ if (id)
62
+ header.id = id;
63
+ this.root.appendChild(header);
64
+ return header;
65
+ }
66
+ paragraph(string, sup = false, className = '') {
67
+ console.assert(string !== undefined);
68
+ let paragraph = document.createElement(sup ? 'sup' : 'p');
69
+ paragraph.className = LX.mergeClass('leading-relaxed', className);
70
+ paragraph.innerHTML = string;
71
+ this.root.appendChild(paragraph);
72
+ return paragraph;
73
+ }
74
+ code(text, language = 'js') {
75
+ console.assert(text !== undefined);
76
+ text.replaceAll('<', '&lt;');
77
+ text.replaceAll('>', '&gt;');
78
+ let highlight = '';
79
+ let content = '';
80
+ const getHTML = (h, c) => {
81
+ return `<span class="${h}">${c}</span>`;
82
+ };
83
+ for (let i = 0; i < text.length; ++i) {
84
+ const char = text[i];
85
+ const string = text.substring(i);
86
+ const endLineIdx = string.indexOf('\n');
87
+ const line = string.substring(0, endLineIdx > -1 ? endLineIdx : undefined);
88
+ if (char == '@') {
89
+ const str = line.substring(1);
90
+ if (!(str.indexOf('@') > -1) && !(str.indexOf('[') > -1)) {
91
+ continue;
92
+ }
93
+ let html = null;
94
+ const tagIndex = str.indexOf('@');
95
+ const skipTag = str[tagIndex - 1] == '|';
96
+ // Highlight is specified
97
+ if (text[i + 1] == '[') {
98
+ highlight = str.substring(1, 4);
99
+ content = str.substring(5, tagIndex);
100
+ if (skipTag) {
101
+ const newString = str.substring(6 + content.length);
102
+ const preContent = content;
103
+ const postContent = newString.substring(0, newString.indexOf('@'));
104
+ const finalContent = preContent.substring(0, preContent.length - 1) + '@' + postContent;
105
+ html = getHTML(highlight, finalContent);
106
+ const ogContent = preContent + '@' + postContent;
107
+ text = text.replace(`@[${highlight}]${ogContent}@`, html);
108
+ }
109
+ else {
110
+ html = getHTML(highlight, content);
111
+ text = text.replace(`@[${highlight}]${content}@`, html);
112
+ }
113
+ }
114
+ else {
115
+ content = str.substring(0, tagIndex);
116
+ if (skipTag) {
117
+ const preContent = str.substring(0, str.indexOf('@') - 1);
118
+ content = str.substring(preContent.length + 1);
119
+ content = preContent + content.substring(0, content.substring(1).indexOf('@') + 1);
120
+ text = text.substr(0, i) + '@' + content + '@' + text.substr(i + content.length + 3);
121
+ }
122
+ if (language == 'cpp' && CPP_KEY_WORDS.includes(content)) {
123
+ highlight = 'kwd';
124
+ }
125
+ else if (language == 'js' && JS_KEY_WORDS.includes(content)) {
126
+ highlight = 'kwd';
127
+ }
128
+ else if (language == 'wgsl' && WGSL_KEY_WORDS.includes(content)) {
129
+ highlight = 'kwd';
130
+ }
131
+ else if (CLASS_WORDS.includes(content)) {
132
+ highlight = 'cls';
133
+ }
134
+ else if (STATEMENT_WORDS.includes(content)) {
135
+ highlight = 'lit';
136
+ }
137
+ else if (HTML_TAGS.includes(content)) {
138
+ highlight = 'tag';
139
+ }
140
+ else if (HTML_ATTRIBUTES.includes(content)) {
141
+ highlight = 'atn';
142
+ }
143
+ else if ((content[0] == '"' && content[content.length - 1] == '"')
144
+ || (content[0] == "'" && content[content.length - 1] == "'")
145
+ || (content[0] == '`' && content[content.length - 1] == '`')) {
146
+ highlight = 'str';
147
+ }
148
+ else if (!Number.isNaN(parseFloat(content))) {
149
+ highlight = 'dec';
150
+ }
151
+ else {
152
+ highlight = '';
153
+ console.error('WARNING[Code Parsing]: Unknown highlight type: ' + content);
154
+ }
155
+ html = getHTML(highlight, content);
156
+ text = text.replace(`@${content}@`, html);
157
+ }
158
+ i += html.length - 1;
159
+ }
160
+ }
161
+ let container = document.createElement('div');
162
+ container.className = 'code-container';
163
+ let pre = document.createElement('pre');
164
+ let code = document.createElement('code');
165
+ code.innerHTML = text;
166
+ let button = document.createElement('button');
167
+ button.title = 'Copy code sample';
168
+ button.appendChild(LX.makeIcon('Copy'));
169
+ button.addEventListener('click', this._copySnippet.bind(this, button));
170
+ container.appendChild(button);
171
+ pre.appendChild(code);
172
+ container.appendChild(pre);
173
+ this.root.appendChild(container);
174
+ return container;
175
+ }
176
+ list(list, type, target, className = '') {
177
+ const validTypes = ['bullet', 'numbered'];
178
+ console.assert(list && list.length > 0 && validTypes.includes(type), 'Invalid list type or empty list' + type);
179
+ const typeString = type == 'bullet' ? 'ul' : 'ol';
180
+ let ul = document.createElement(typeString);
181
+ ul.className = className;
182
+ target = target ?? this.root;
183
+ target.appendChild(ul);
184
+ for (var el of list) {
185
+ if (el.constructor === Array) {
186
+ this.list(el, type, ul);
187
+ return;
188
+ }
189
+ let li = document.createElement('li');
190
+ li.className = 'leading-loose';
191
+ li.innerHTML = el;
192
+ ul.appendChild(li);
193
+ }
194
+ return ul;
195
+ }
196
+ bulletList(list) {
197
+ return this.list(list, 'bullet');
198
+ }
199
+ numberedList(list) {
200
+ return this.list(list, 'numbered');
201
+ }
202
+ startCodeBulletList() {
203
+ let ul = document.createElement('ul');
204
+ this._listQueued = ul;
205
+ return ul;
206
+ }
207
+ endCodeBulletList() {
208
+ if (this._listQueued === undefined)
209
+ return;
210
+ console.assert(this._listQueued !== undefined);
211
+ this.root.appendChild(this._listQueued);
212
+ this._listQueued = undefined;
213
+ }
214
+ codeListItem(item, target) {
215
+ target = target ?? this._listQueued;
216
+ let split = item.constructor === Array;
217
+ if (split && item[0].constructor === Array) {
218
+ this.codeBulletList(item, target);
219
+ return;
220
+ }
221
+ let li = document.createElement('li');
222
+ li.className = 'leading-loose';
223
+ li.innerHTML = split
224
+ ? (item.length == 2
225
+ ? this.iCode(item[0]) + ': ' + item[1]
226
+ : this.iCode(item[0] + " <span class='desc'>(" + item[1] + ')</span>') + ': ' + item[2])
227
+ : this.iCode(item);
228
+ target?.appendChild(li);
229
+ }
230
+ codeBulletList(list, target) {
231
+ console.assert(list !== undefined && list.length > 0);
232
+ let ul = document.createElement('ul');
233
+ for (var el of list) {
234
+ this.codeListItem(el, ul);
235
+ }
236
+ if (target) {
237
+ target.appendChild(ul);
238
+ }
239
+ else {
240
+ this.root.appendChild(ul);
241
+ }
242
+ return ul;
243
+ }
244
+ image(src, caption = '', parent, className = '') {
245
+ let img = document.createElement('img');
246
+ img.src = src;
247
+ img.alt = caption;
248
+ img.className = LX.mergeClass('my-1', className);
249
+ parent = parent ?? this.root;
250
+ parent.appendChild(img);
251
+ return img;
252
+ }
253
+ images(sources, captions = [], width, height) {
254
+ const mobile = navigator && /Android|iPhone/i.test(navigator.userAgent);
255
+ const div = document.createElement('div');
256
+ if (!mobile) {
257
+ div.style.width = width ?? 'auto';
258
+ div.style.height = height ?? '256px';
259
+ div.className = 'flex flex-row justify-center';
260
+ }
261
+ for (let i = 0; i < sources.length; ++i) {
262
+ this.image(sources[i], captions[i], div);
263
+ }
264
+ this.root.appendChild(div);
265
+ return div;
266
+ }
267
+ video(src, caption = '', controls = true, autoplay = false, className = '') {
268
+ let video = document.createElement('video');
269
+ video.className = className;
270
+ video.src = src;
271
+ video.controls = controls;
272
+ video.autoplay = autoplay;
273
+ if (autoplay) {
274
+ video.muted = true;
275
+ }
276
+ video.loop = true;
277
+ video.alt = caption;
278
+ this.root.appendChild(video);
279
+ return video;
280
+ }
281
+ note(text, warning = false, title, icon, className = '') {
282
+ console.assert(text !== undefined);
283
+ const note = LX.makeContainer([], LX.mergeClass('border-color rounded-xl overflow-hidden text-sm text-secondary-foreground my-6', className), '', this.root);
284
+ const header = document.createElement('div');
285
+ header.className = 'flex bg-muted font-semibold px-3 py-2 gap-2 text-secondary-foreground';
286
+ header.appendChild(LX.makeIcon(icon ?? (warning ? 'MessageSquareWarning' : 'NotepadText')));
287
+ header.innerHTML += title ?? (warning ? 'Important' : 'Note');
288
+ note.appendChild(header);
289
+ // Node body
290
+ return LX.makeContainer([], 'leading-6 p-3', text, note);
291
+ }
292
+ classCtor(name, params, language = 'js') {
293
+ let paramsHTML = '';
294
+ for (var p of params) {
295
+ const str1 = p[0]; // cpp: param js: name
296
+ const str2 = p[1]; // cpp: defaultValue js: type
297
+ if (language == 'cpp') {
298
+ paramsHTML += str1 + (str2 ? " = <span class='desc'>" + str2 + '</span>' : '')
299
+ + (params.indexOf(p) != (params.length - 1) ? ', ' : '');
300
+ }
301
+ else if (language == 'js') {
302
+ paramsHTML += str1 + ": <span class='desc'>" + str2 + '</span>'
303
+ + (params.indexOf(p) != (params.length - 1) ? ', ' : '');
304
+ }
305
+ }
306
+ let pr = document.createElement('p');
307
+ pr.innerHTML = this.iCode("<span class='constructor'>" + name + '(' + paramsHTML + ')' + '</span>');
308
+ this.root.appendChild(pr);
309
+ return pr;
310
+ }
311
+ classMethod(name, desc, params, ret) {
312
+ this.startCodeBulletList();
313
+ let paramsHTML = '';
314
+ for (var p of params) {
315
+ const name = p[0];
316
+ const type = p[1];
317
+ paramsHTML += name + ": <span class='desc'>" + type + '</span>'
318
+ + (params.indexOf(p) != (params.length - 1) ? ', ' : '');
319
+ }
320
+ let li = document.createElement('li');
321
+ li.innerHTML = this.iCode("<span class='method'>" + name + ' (' + paramsHTML + ')' + (ret ? (': ' + ret) : '') + '</span>');
322
+ this._listQueued?.appendChild(li);
323
+ this.endCodeBulletList();
324
+ this.paragraph(desc);
325
+ return li.parentElement;
326
+ }
327
+ iLink(text, href) {
328
+ console.assert(text !== undefined && href !== undefined);
329
+ return `<a class="font-semibold underline-offset-4 hover:underline" href="${href}">${text}</a>`;
330
+ }
331
+ iPage(text, page) {
332
+ console.assert(text !== undefined && page !== undefined);
333
+ const startPage = page.replace('.html', '');
334
+ const g = globalThis;
335
+ if (g.setPath && g.loadPage) {
336
+ const tabName = g.setPath(startPage);
337
+ return `<a onclick="loadPage('${page}', true, '${tabName}')">${text}</a>`;
338
+ }
339
+ else {
340
+ console.warn('[DocMaker] Create globalThis.setPath and globalThis.loadPage to use inline pages!');
341
+ }
342
+ }
343
+ iCode(text, codeClass) {
344
+ console.assert(text !== undefined);
345
+ return `<code class="inline ${codeClass ?? ''}">${text}</code>`;
346
+ }
347
+ _copySnippet(b) {
348
+ b.innerHTML = '';
349
+ b.appendChild(LX.makeIcon('Check'));
350
+ b.classList.add('copied');
351
+ setTimeout(() => {
352
+ b.innerHTML = '';
353
+ b.appendChild(LX.makeIcon('Copy'));
354
+ b.classList.remove('copied');
355
+ }, 2000);
356
+ navigator.clipboard.writeText(b.dataset['snippet'] ?? b.parentElement.innerText);
357
+ console.log('Copied!');
358
+ }
359
+ }
360
+ LX.DocMaker = DocMaker;
361
+
362
+ export { DocMaker };
363
+ //# sourceMappingURL=DocMaker.js.map