juxscript 1.1.342 → 1.1.343
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.
- package/package.json +1 -1
- package/dist/components/blocks/menu.d.ts +0 -62
- package/dist/components/blocks/menu.d.ts.map +0 -1
- package/dist/components/blocks/menu.js +0 -149
- package/dist/components/blocks/menu.js.map +0 -1
- package/dist/components/blocks/sidebar.d.ts +0 -61
- package/dist/components/blocks/sidebar.d.ts.map +0 -1
- package/dist/components/blocks/sidebar.js +0 -148
- package/dist/components/blocks/sidebar.js.map +0 -1
- package/dist/lib/components/blocks/menu.d.ts +0 -40
- package/dist/lib/components/blocks/menu.d.ts.map +0 -1
- package/dist/lib/components/blocks/menu.js +0 -136
- package/dist/lib/components/button.d.ts +0 -33
- package/dist/lib/components/button.d.ts.map +0 -1
- package/dist/lib/components/button.js +0 -107
- package/dist/lib/components/checkbox.d.ts +0 -62
- package/dist/lib/components/checkbox.d.ts.map +0 -1
- package/dist/lib/components/checkbox.js +0 -178
- package/dist/lib/components/container.d.ts +0 -58
- package/dist/lib/components/container.d.ts.map +0 -1
- package/dist/lib/components/container.js +0 -151
- package/dist/lib/components/data.d.ts +0 -58
- package/dist/lib/components/data.d.ts.map +0 -1
- package/dist/lib/components/data.js +0 -130
- package/dist/lib/components/grid.d.ts +0 -58
- package/dist/lib/components/grid.d.ts.map +0 -1
- package/dist/lib/components/grid.js +0 -127
- package/dist/lib/components/include.d.ts +0 -86
- package/dist/lib/components/include.d.ts.map +0 -1
- package/dist/lib/components/include.js +0 -238
- package/dist/lib/components/input.d.ts +0 -58
- package/dist/lib/components/input.d.ts.map +0 -1
- package/dist/lib/components/input.js +0 -161
- package/dist/lib/components/link.d.ts +0 -35
- package/dist/lib/components/link.d.ts.map +0 -1
- package/dist/lib/components/link.js +0 -135
- package/dist/lib/components/list.d.ts +0 -48
- package/dist/lib/components/list.d.ts.map +0 -1
- package/dist/lib/components/list.js +0 -178
- package/dist/lib/components/nav.d.ts +0 -46
- package/dist/lib/components/nav.d.ts.map +0 -1
- package/dist/lib/components/nav.js +0 -189
- package/dist/lib/components/radio.d.ts +0 -40
- package/dist/lib/components/radio.d.ts.map +0 -1
- package/dist/lib/components/radio.js +0 -112
- package/dist/lib/components/select.d.ts +0 -41
- package/dist/lib/components/select.d.ts.map +0 -1
- package/dist/lib/components/select.js +0 -111
- package/dist/lib/components/store.d.ts +0 -78
- package/dist/lib/components/store.d.ts.map +0 -1
- package/dist/lib/components/store.js +0 -248
- package/dist/lib/components/style.d.ts +0 -27
- package/dist/lib/components/style.d.ts.map +0 -1
- package/dist/lib/components/style.js +0 -52
- package/dist/lib/components/table.d.ts +0 -56
- package/dist/lib/components/table.d.ts.map +0 -1
- package/dist/lib/components/table.js +0 -199
- package/dist/lib/components/tabs.d.ts +0 -52
- package/dist/lib/components/tabs.d.ts.map +0 -1
- package/dist/lib/components/tabs.js +0 -206
- package/dist/lib/components/tag.d.ts +0 -41
- package/dist/lib/components/tag.d.ts.map +0 -1
- package/dist/lib/components/tag.js +0 -103
- package/dist/lib/devtools/devtools.d.ts +0 -3
- package/dist/lib/devtools/devtools.d.ts.map +0 -1
- package/dist/lib/devtools/devtools.js +0 -181
- package/dist/lib/index.d.ts +0 -70
- package/dist/lib/index.d.ts.map +0 -1
- package/dist/lib/index.js +0 -65
- package/dist/lib/state/pageState.d.ts +0 -19
- package/dist/lib/state/pageState.d.ts.map +0 -1
- package/dist/lib/state/pageState.js +0 -360
- package/dist/lib/utils/codeHighlight.d.ts +0 -7
- package/dist/lib/utils/codeHighlight.d.ts.map +0 -1
- package/dist/lib/utils/codeHighlight.js +0 -105
- package/dist/lib/utils/codeparser.d.ts +0 -29
- package/dist/lib/utils/codeparser.d.ts.map +0 -1
- package/dist/lib/utils/codeparser.js +0 -384
- package/dist/lib/utils/fetch.d.ts +0 -176
- package/dist/lib/utils/fetch.d.ts.map +0 -1
- package/dist/lib/utils/fetch.js +0 -427
- package/dist/lib/utils/formatId.d.ts +0 -16
- package/dist/lib/utils/formatId.d.ts.map +0 -1
- package/dist/lib/utils/formatId.js +0 -27
- package/dist/lib/utils/idgen.d.ts +0 -2
- package/dist/lib/utils/idgen.d.ts.map +0 -1
- package/dist/lib/utils/idgen.js +0 -4
- package/dist/lib/utils/niceName.d.ts +0 -14
- package/dist/lib/utils/niceName.d.ts.map +0 -1
- package/dist/lib/utils/niceName.js +0 -22
|
@@ -1,360 +0,0 @@
|
|
|
1
|
-
// Tracks which reactive block is currently running so we can record dependencies
|
|
2
|
-
let activeReaction = null;
|
|
3
|
-
const reactionDeps = new Map();
|
|
4
|
-
let notifyQueue = [];
|
|
5
|
-
let isNotifying = false;
|
|
6
|
-
class PageState {
|
|
7
|
-
constructor() {
|
|
8
|
-
this._registry = new Map();
|
|
9
|
-
this._nullProxy = new Proxy({}, {
|
|
10
|
-
get: (_, prop) => {
|
|
11
|
-
if (typeof prop === 'symbol')
|
|
12
|
-
return undefined;
|
|
13
|
-
return undefined;
|
|
14
|
-
},
|
|
15
|
-
set: () => true
|
|
16
|
-
});
|
|
17
|
-
this._proxy = new Proxy({}, {
|
|
18
|
-
get: (_, id) => {
|
|
19
|
-
if (typeof id === 'symbol')
|
|
20
|
-
return undefined;
|
|
21
|
-
if (id === '__register')
|
|
22
|
-
return this._register.bind(this);
|
|
23
|
-
if (id === '__watch')
|
|
24
|
-
return this._watch.bind(this);
|
|
25
|
-
if (id === '__unregister')
|
|
26
|
-
return this._unregister.bind(this);
|
|
27
|
-
if (id === '__notify')
|
|
28
|
-
return this._notify.bind(this);
|
|
29
|
-
if (id === '__keys')
|
|
30
|
-
return () => Array.from(this._registry.keys());
|
|
31
|
-
const entry = this._registry.get(id);
|
|
32
|
-
if (!entry)
|
|
33
|
-
return this._nullProxy;
|
|
34
|
-
return this._createComponentProxy(id, entry);
|
|
35
|
-
},
|
|
36
|
-
set: (_, id, value) => {
|
|
37
|
-
if (typeof id === 'symbol')
|
|
38
|
-
return false;
|
|
39
|
-
if (value && typeof value === 'object' && value.id) {
|
|
40
|
-
this._register(value);
|
|
41
|
-
return true;
|
|
42
|
-
}
|
|
43
|
-
return false;
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
_createComponentProxy(id, entry) {
|
|
48
|
-
return new Proxy({}, {
|
|
49
|
-
get: (_, prop) => {
|
|
50
|
-
if (typeof prop === 'symbol')
|
|
51
|
-
return undefined;
|
|
52
|
-
const depKey = `${id}.${prop}`;
|
|
53
|
-
if (activeReaction) {
|
|
54
|
-
if (!reactionDeps.has(activeReaction)) {
|
|
55
|
-
reactionDeps.set(activeReaction, new Set());
|
|
56
|
-
}
|
|
57
|
-
reactionDeps.get(activeReaction).add(depKey);
|
|
58
|
-
}
|
|
59
|
-
// Event flags
|
|
60
|
-
if (prop in entry.events) {
|
|
61
|
-
return entry.events[prop];
|
|
62
|
-
}
|
|
63
|
-
// Component props
|
|
64
|
-
if (prop in entry.props) {
|
|
65
|
-
return entry.props[prop];
|
|
66
|
-
}
|
|
67
|
-
// Special: files for file inputs
|
|
68
|
-
if (prop === 'files') {
|
|
69
|
-
const comp = entry.component;
|
|
70
|
-
if (typeof comp.getFiles === 'function') {
|
|
71
|
-
return comp.getFiles();
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
// Component methods
|
|
75
|
-
const comp = entry.component;
|
|
76
|
-
if (typeof comp[prop] === 'function') {
|
|
77
|
-
return comp[prop].bind(comp);
|
|
78
|
-
}
|
|
79
|
-
// Getter pattern
|
|
80
|
-
const getterName = `get${prop.charAt(0).toUpperCase()}${prop.slice(1)}`;
|
|
81
|
-
if (typeof comp[getterName] === 'function') {
|
|
82
|
-
return comp[getterName]();
|
|
83
|
-
}
|
|
84
|
-
if (prop in comp) {
|
|
85
|
-
return comp[prop];
|
|
86
|
-
}
|
|
87
|
-
return undefined;
|
|
88
|
-
},
|
|
89
|
-
set: (_, prop, value) => {
|
|
90
|
-
if (typeof prop === 'symbol')
|
|
91
|
-
return false;
|
|
92
|
-
const depKey = `${id}.${prop}`;
|
|
93
|
-
const comp = entry.component;
|
|
94
|
-
// Try setXxx first (e.g. setValue, setContent, setClass)
|
|
95
|
-
const setterName = `set${prop.charAt(0).toUpperCase()}${prop.slice(1)}`;
|
|
96
|
-
if (typeof comp[setterName] === 'function') {
|
|
97
|
-
comp[setterName](value);
|
|
98
|
-
}
|
|
99
|
-
// Fallback: direct DOM manipulation for known props
|
|
100
|
-
else if (prop === 'value') {
|
|
101
|
-
if (typeof comp.setValue === 'function') {
|
|
102
|
-
comp.setValue(value);
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
const el = this._findElement(comp);
|
|
106
|
-
if (el && 'value' in el) {
|
|
107
|
-
el.value = value;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
else if (prop === 'content') {
|
|
112
|
-
if (typeof comp.setContent === 'function') {
|
|
113
|
-
comp.setContent(value);
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
// Direct DOM update for elements that don't have setContent
|
|
117
|
-
const el = this._findElement(comp);
|
|
118
|
-
if (el) {
|
|
119
|
-
el.textContent = value;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
else if (prop === 'innerHTML') {
|
|
124
|
-
if (typeof comp.setInnerHTML === 'function') {
|
|
125
|
-
comp.setInnerHTML(value);
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
const el = this._findElement(comp);
|
|
129
|
-
if (el) {
|
|
130
|
-
el.innerHTML = value;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
else if (prop === 'visible') {
|
|
135
|
-
// Prefer wrapper (hides label + input together), fall back to element
|
|
136
|
-
let target = null;
|
|
137
|
-
if (comp._wrapper instanceof HTMLElement) {
|
|
138
|
-
target = comp._wrapper;
|
|
139
|
-
}
|
|
140
|
-
else {
|
|
141
|
-
target = this._findElement(comp);
|
|
142
|
-
}
|
|
143
|
-
if (target) {
|
|
144
|
-
target.style.display = value ? '' : 'none';
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
// Update tracked props
|
|
148
|
-
entry.props[prop] = value;
|
|
149
|
-
// Notify listeners
|
|
150
|
-
this._notify(depKey);
|
|
151
|
-
return true;
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
_register(component) {
|
|
156
|
-
const id = component.id;
|
|
157
|
-
if (!id)
|
|
158
|
-
return;
|
|
159
|
-
// Check if already registered — preserve event listeners
|
|
160
|
-
const existing = this._registry.get(id);
|
|
161
|
-
if (existing) {
|
|
162
|
-
// Update component reference and re-seed props
|
|
163
|
-
existing.component = component;
|
|
164
|
-
if (component.getValue)
|
|
165
|
-
existing.props.value = component.getValue();
|
|
166
|
-
if (component.getContent)
|
|
167
|
-
existing.props.content = component.getContent();
|
|
168
|
-
if (component.getValues)
|
|
169
|
-
existing.props.values = component.getValues();
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
const entry = {
|
|
173
|
-
component,
|
|
174
|
-
props: {},
|
|
175
|
-
events: {},
|
|
176
|
-
listeners: new Map()
|
|
177
|
-
};
|
|
178
|
-
// Seed initial props
|
|
179
|
-
if (component.getValue)
|
|
180
|
-
entry.props.value = component.getValue();
|
|
181
|
-
if (component.getContent)
|
|
182
|
-
entry.props.content = component.getContent();
|
|
183
|
-
if (component.getValues)
|
|
184
|
-
entry.props.values = component.getValues();
|
|
185
|
-
// Seed visibility — default true
|
|
186
|
-
entry.props.visible = true;
|
|
187
|
-
if (component.opts || component.options) {
|
|
188
|
-
const opts = component.opts || component.options;
|
|
189
|
-
if ('disabled' in opts)
|
|
190
|
-
entry.props.disabled = opts.disabled;
|
|
191
|
-
if ('required' in opts)
|
|
192
|
-
entry.props.required = opts.required;
|
|
193
|
-
if ('type' in opts)
|
|
194
|
-
entry.props.type = opts.type;
|
|
195
|
-
}
|
|
196
|
-
entry.props.id = id;
|
|
197
|
-
this._registry.set(id, entry);
|
|
198
|
-
// Wire onChange — use internal callback pattern, don't replace
|
|
199
|
-
if (typeof component.onChange === 'function') {
|
|
200
|
-
component.onChange((val, e) => {
|
|
201
|
-
if (Array.isArray(val)) {
|
|
202
|
-
entry.props.values = val;
|
|
203
|
-
this._notify(`${id}.values`);
|
|
204
|
-
}
|
|
205
|
-
else if (typeof val === 'boolean') {
|
|
206
|
-
entry.props.checked = val;
|
|
207
|
-
this._notify(`${id}.checked`);
|
|
208
|
-
}
|
|
209
|
-
else {
|
|
210
|
-
entry.props.value = val;
|
|
211
|
-
this._notify(`${id}.value`);
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
// Wire DOM events
|
|
216
|
-
for (const eventName of PageState.WIRE_EVENTS) {
|
|
217
|
-
this._wireEvent(id, entry, eventName);
|
|
218
|
-
}
|
|
219
|
-
// Wire composite state flags: hover, active, focused
|
|
220
|
-
this._wireStateFlag(id, entry, 'hover', 'mouseenter', 'mouseleave');
|
|
221
|
-
this._wireStateFlag(id, entry, 'active', 'mousedown', 'mouseup');
|
|
222
|
-
this._wireStateFlag(id, entry, 'focused', 'focus', 'blur');
|
|
223
|
-
}
|
|
224
|
-
_wireEvent(id, entry, eventName) {
|
|
225
|
-
entry.events[eventName] = false;
|
|
226
|
-
const el = this._findElement(entry.component);
|
|
227
|
-
if (!el)
|
|
228
|
-
return;
|
|
229
|
-
el.addEventListener(eventName, (e) => {
|
|
230
|
-
entry.events[eventName] = true;
|
|
231
|
-
if ((eventName === 'input' || eventName === 'change') && el instanceof HTMLInputElement) {
|
|
232
|
-
entry.props.value = el.value;
|
|
233
|
-
}
|
|
234
|
-
if ((eventName === 'input' || eventName === 'change') && el instanceof HTMLSelectElement) {
|
|
235
|
-
entry.props.value = el.value;
|
|
236
|
-
}
|
|
237
|
-
// For non-input elements (e.g. Store's hidden div), sync value from component
|
|
238
|
-
if (eventName === 'change' && !(el instanceof HTMLInputElement) && !(el instanceof HTMLSelectElement)) {
|
|
239
|
-
const comp = entry.component;
|
|
240
|
-
if (typeof comp.getValue === 'function') {
|
|
241
|
-
entry.props.value = comp.getValue();
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
this._notify(`${id}.${eventName}`);
|
|
245
|
-
queueMicrotask(() => {
|
|
246
|
-
entry.events[eventName] = false;
|
|
247
|
-
});
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
_findElement(component) {
|
|
251
|
-
if (component._element instanceof HTMLElement)
|
|
252
|
-
return component._element;
|
|
253
|
-
if (typeof component.getElement === 'function') {
|
|
254
|
-
const el = component.getElement();
|
|
255
|
-
if (el instanceof HTMLElement)
|
|
256
|
-
return el;
|
|
257
|
-
}
|
|
258
|
-
if (component._wrapper instanceof HTMLElement) {
|
|
259
|
-
const input = component._wrapper.querySelector('input, select, textarea, button');
|
|
260
|
-
if (input)
|
|
261
|
-
return input;
|
|
262
|
-
return component._wrapper;
|
|
263
|
-
}
|
|
264
|
-
if (component.id && typeof document !== 'undefined') {
|
|
265
|
-
const el = document.getElementById(component.id);
|
|
266
|
-
if (el)
|
|
267
|
-
return el;
|
|
268
|
-
}
|
|
269
|
-
return null;
|
|
270
|
-
}
|
|
271
|
-
_wireStateFlag(id, entry, flagName, onEvent, offEvent) {
|
|
272
|
-
entry.events[flagName] = false;
|
|
273
|
-
const el = this._findElement(entry.component);
|
|
274
|
-
if (!el)
|
|
275
|
-
return;
|
|
276
|
-
el.addEventListener(onEvent, () => {
|
|
277
|
-
entry.events[flagName] = true;
|
|
278
|
-
this._notify(`${id}.${flagName}`);
|
|
279
|
-
});
|
|
280
|
-
el.addEventListener(offEvent, () => {
|
|
281
|
-
entry.events[flagName] = false;
|
|
282
|
-
this._notify(`${id}.${flagName}`);
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
_unregister(id) {
|
|
286
|
-
this._registry.delete(id);
|
|
287
|
-
}
|
|
288
|
-
_notify(depKey) {
|
|
289
|
-
notifyQueue.push(depKey);
|
|
290
|
-
// Prevent re-entrant notification loops
|
|
291
|
-
if (isNotifying)
|
|
292
|
-
return;
|
|
293
|
-
isNotifying = true;
|
|
294
|
-
const eventKeysToReset = [];
|
|
295
|
-
try {
|
|
296
|
-
while (notifyQueue.length > 0) {
|
|
297
|
-
const key = notifyQueue.shift();
|
|
298
|
-
// For event-style keys, set the flag before firing reactions
|
|
299
|
-
const dotIdx = key.indexOf('.');
|
|
300
|
-
if (dotIdx > -1) {
|
|
301
|
-
const id = key.substring(0, dotIdx);
|
|
302
|
-
const prop = key.substring(dotIdx + 1);
|
|
303
|
-
const entry = this._registry.get(id);
|
|
304
|
-
if (entry && prop in entry.events) {
|
|
305
|
-
entry.events[prop] = true;
|
|
306
|
-
eventKeysToReset.push({ entry, prop });
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
for (const [reaction, deps] of reactionDeps.entries()) {
|
|
310
|
-
if (deps.has(key)) {
|
|
311
|
-
reaction();
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
finally {
|
|
317
|
-
isNotifying = false;
|
|
318
|
-
// Reset all event flags after all reactions have run
|
|
319
|
-
for (const { entry, prop } of eventKeysToReset) {
|
|
320
|
-
queueMicrotask(() => {
|
|
321
|
-
entry.events[prop] = false;
|
|
322
|
-
});
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
_watch(fn) {
|
|
327
|
-
const reaction = () => {
|
|
328
|
-
reactionDeps.set(reaction, new Set());
|
|
329
|
-
activeReaction = reaction;
|
|
330
|
-
try {
|
|
331
|
-
const result = fn();
|
|
332
|
-
if (result && typeof result.catch === 'function') {
|
|
333
|
-
result.catch((err) => {
|
|
334
|
-
console.error('[pageState] async watch error:', err);
|
|
335
|
-
});
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
finally {
|
|
339
|
-
activeReaction = null;
|
|
340
|
-
}
|
|
341
|
-
};
|
|
342
|
-
reaction();
|
|
343
|
-
}
|
|
344
|
-
getProxy() {
|
|
345
|
-
return this._proxy;
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
PageState.WIRE_EVENTS = [
|
|
349
|
-
'blur', 'focus',
|
|
350
|
-
'click', 'dblclick',
|
|
351
|
-
'change', 'input',
|
|
352
|
-
'keydown', 'keyup', 'keypress',
|
|
353
|
-
'mouseenter', 'mouseleave',
|
|
354
|
-
'mousedown', 'mouseup',
|
|
355
|
-
'submit'
|
|
356
|
-
];
|
|
357
|
-
// Singleton
|
|
358
|
-
const _instance = new PageState();
|
|
359
|
-
export const pageState = _instance.getProxy();
|
|
360
|
-
export { PageState };
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Lightweight syntax highlighter for JS/TS code blocks.
|
|
3
|
-
* Returns HTML string with <span class="jux-hl-xxx"> wrappers.
|
|
4
|
-
*/
|
|
5
|
-
export declare function highlightCode(code: string): string;
|
|
6
|
-
export default highlightCode;
|
|
7
|
-
//# sourceMappingURL=codeHighlight.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"codeHighlight.d.ts","sourceRoot":"","sources":["../../../lib/utils/codeHighlight.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAcH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAmFlD;AAED,eAAe,aAAa,CAAC"}
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Lightweight syntax highlighter for JS/TS code blocks.
|
|
3
|
-
* Returns HTML string with <span class="jux-hl-xxx"> wrappers.
|
|
4
|
-
*/
|
|
5
|
-
const KEYWORDS = new Set([
|
|
6
|
-
'const', 'let', 'var', 'function', 'return', 'if', 'else', 'for', 'while', 'do',
|
|
7
|
-
'switch', 'case', 'break', 'continue', 'new', 'delete', 'typeof', 'instanceof',
|
|
8
|
-
'import', 'export', 'from', 'default', 'class', 'extends', 'super', 'this',
|
|
9
|
-
'try', 'catch', 'finally', 'throw', 'async', 'await', 'yield',
|
|
10
|
-
'true', 'false', 'null', 'undefined', 'void', 'of', 'in'
|
|
11
|
-
]);
|
|
12
|
-
function escapeHtml(str) {
|
|
13
|
-
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
14
|
-
}
|
|
15
|
-
export function highlightCode(code) {
|
|
16
|
-
const out = [];
|
|
17
|
-
let i = 0;
|
|
18
|
-
const len = code.length;
|
|
19
|
-
while (i < len) {
|
|
20
|
-
const ch = code[i];
|
|
21
|
-
// Single-line comment
|
|
22
|
-
if (ch === '/' && code[i + 1] === '/') {
|
|
23
|
-
let end = code.indexOf('\n', i);
|
|
24
|
-
if (end === -1)
|
|
25
|
-
end = len;
|
|
26
|
-
out.push(`<span class="jux-hl-comment">${escapeHtml(code.slice(i, end))}</span>`);
|
|
27
|
-
i = end;
|
|
28
|
-
continue;
|
|
29
|
-
}
|
|
30
|
-
// Multi-line comment
|
|
31
|
-
if (ch === '/' && code[i + 1] === '*') {
|
|
32
|
-
let end = code.indexOf('*/', i + 2);
|
|
33
|
-
if (end === -1)
|
|
34
|
-
end = len;
|
|
35
|
-
else
|
|
36
|
-
end += 2;
|
|
37
|
-
out.push(`<span class="jux-hl-comment">${escapeHtml(code.slice(i, end))}</span>`);
|
|
38
|
-
i = end;
|
|
39
|
-
continue;
|
|
40
|
-
}
|
|
41
|
-
// Strings (single, double, backtick)
|
|
42
|
-
if (ch === '"' || ch === "'" || ch === '`') {
|
|
43
|
-
const quote = ch;
|
|
44
|
-
let j = i + 1;
|
|
45
|
-
while (j < len) {
|
|
46
|
-
if (code[j] === '\\') {
|
|
47
|
-
j += 2;
|
|
48
|
-
continue;
|
|
49
|
-
}
|
|
50
|
-
if (code[j] === quote) {
|
|
51
|
-
j++;
|
|
52
|
-
break;
|
|
53
|
-
}
|
|
54
|
-
j++;
|
|
55
|
-
}
|
|
56
|
-
out.push(`<span class="jux-hl-string">${escapeHtml(code.slice(i, j))}</span>`);
|
|
57
|
-
i = j;
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
// Numbers
|
|
61
|
-
if (/[0-9]/.test(ch) && (i === 0 || !/[a-zA-Z_$]/.test(code[i - 1]))) {
|
|
62
|
-
let j = i;
|
|
63
|
-
while (j < len && /[0-9a-fA-FxXoObB._]/.test(code[j]))
|
|
64
|
-
j++;
|
|
65
|
-
out.push(`<span class="jux-hl-number">${escapeHtml(code.slice(i, j))}</span>`);
|
|
66
|
-
i = j;
|
|
67
|
-
continue;
|
|
68
|
-
}
|
|
69
|
-
// Identifiers / keywords
|
|
70
|
-
if (/[a-zA-Z_$]/.test(ch)) {
|
|
71
|
-
let j = i;
|
|
72
|
-
while (j < len && /[a-zA-Z0-9_$]/.test(code[j]))
|
|
73
|
-
j++;
|
|
74
|
-
const word = code.slice(i, j);
|
|
75
|
-
if (KEYWORDS.has(word)) {
|
|
76
|
-
out.push(`<span class="jux-hl-keyword">${escapeHtml(word)}</span>`);
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
// Check if it's a function call
|
|
80
|
-
let k = j;
|
|
81
|
-
while (k < len && code[k] === ' ')
|
|
82
|
-
k++;
|
|
83
|
-
if (code[k] === '(') {
|
|
84
|
-
out.push(`<span class="jux-hl-fn">${escapeHtml(word)}</span>`);
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
out.push(`<span class="jux-hl-ident">${escapeHtml(word)}</span>`);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
i = j;
|
|
91
|
-
continue;
|
|
92
|
-
}
|
|
93
|
-
// Punctuation / operators
|
|
94
|
-
if (/[{}()\[\];,.:?!<>=+\-*/%&|^~@#]/.test(ch)) {
|
|
95
|
-
out.push(`<span class="jux-hl-punct">${escapeHtml(ch)}</span>`);
|
|
96
|
-
i++;
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
99
|
-
// Whitespace & everything else
|
|
100
|
-
out.push(escapeHtml(ch));
|
|
101
|
-
i++;
|
|
102
|
-
}
|
|
103
|
-
return out.join('');
|
|
104
|
-
}
|
|
105
|
-
export default highlightCode;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
export interface ParsedLine {
|
|
2
|
-
lineNumber: number;
|
|
3
|
-
html: string;
|
|
4
|
-
raw: string;
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* Escape HTML entities
|
|
8
|
-
*/
|
|
9
|
-
declare function escapeHtml(text: string): string;
|
|
10
|
-
/**
|
|
11
|
-
* Parse code into lines - CHARACTER-BY-CHARACTER TOKENIZATION
|
|
12
|
-
*/
|
|
13
|
-
export declare function parseCode(code: string, language?: string): ParsedLine[];
|
|
14
|
-
/**
|
|
15
|
-
* Render a parsed line
|
|
16
|
-
*/
|
|
17
|
-
export declare function renderLineWithTokens(parsedLine: ParsedLine): string;
|
|
18
|
-
/**
|
|
19
|
-
* Generate CSS for syntax highlighting
|
|
20
|
-
*/
|
|
21
|
-
export declare function getSyntaxHighlightCSS(): string;
|
|
22
|
-
declare const _default: {
|
|
23
|
-
parse: typeof parseCode;
|
|
24
|
-
renderLine: typeof renderLineWithTokens;
|
|
25
|
-
getCSS: typeof getSyntaxHighlightCSS;
|
|
26
|
-
escapeHtml: typeof escapeHtml;
|
|
27
|
-
};
|
|
28
|
-
export default _default;
|
|
29
|
-
//# sourceMappingURL=codeparser.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"codeparser.d.ts","sourceRoot":"","sources":["../../../lib/utils/codeparser.ts"],"names":[],"mappings":"AA2DA,MAAM,WAAW,UAAU;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,iBAAS,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOxC;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAqB,GAAG,UAAU,EAAE,CAQrF;AAuPD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAEnE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAyD9C;;;;;;;AAED,wBAKE"}
|