@codady/coax 0.0.3 → 0.0.5
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/LICENSE +1 -1
- package/README.md +331 -166
- package/dist/coax.cjs.js +88 -75
- package/dist/coax.cjs.min.js +4 -4
- package/dist/coax.esm.js +88 -75
- package/dist/coax.esm.min.js +4 -4
- package/dist/coax.umd.js +259 -247
- package/dist/coax.umd.min.js +4 -4
- package/examples/color-selector.html +3 -4
- package/examples/deepseek-highlight.html +19 -10
- package/examples/js-highlight.html +3 -9
- package/package.json +2 -2
- package/script-note.js +2 -2
- package/src/Coax.js +2 -3
- package/src/Coax.ts +2 -3
- package/src/components/{CoaxElem.js → Coax.js} +159 -90
- package/src/components/{CoaxElem.ts → Coax.ts} +169 -103
- package/src/modules.js +3 -3
- package/src/modules.ts +3 -3
- package/examples/.htaccess +0 -0
- package/examples/nginx.htaccess +0 -0
package/dist/coax.esm.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
|
|
2
2
|
/*!
|
|
3
|
-
* @since Last modified: 2026-1-12
|
|
3
|
+
* @since Last modified: 2026-1-12 15:14:48
|
|
4
4
|
* @name Coax event management system.
|
|
5
|
-
* @version 0.0.
|
|
5
|
+
* @version 0.0.5
|
|
6
6
|
* @author AXUI development team <3217728223@qq.com>
|
|
7
|
-
* @description Coax is a
|
|
7
|
+
* @description Coax is a lightweight web component for elegant code display with syntax highlighting, typewriter effects, and theme switching. Supports JavaScript, HTML, CSS, TypeScript, and Markdown with copy tools and customization.
|
|
8
8
|
* @see {@link https://coax.axui.cn|Official website}
|
|
9
9
|
* @see {@link https://github.com/codady/coax/issues|github issues}
|
|
10
10
|
* @see {@link https://gitee.com/codady/coax/issues|Gitee issues}
|
|
@@ -266,36 +266,35 @@ const createTools = (data) => {
|
|
|
266
266
|
return toolsEl;
|
|
267
267
|
};
|
|
268
268
|
|
|
269
|
-
class
|
|
269
|
+
class Coax extends HTMLElement {
|
|
270
270
|
// A static Map to hold the configuration for different languages
|
|
271
271
|
static languages = new Map();
|
|
272
|
+
// A static array to hold the tools registered with the component
|
|
272
273
|
static tools = [];
|
|
273
|
-
source;
|
|
274
|
-
_renderQueued = false;
|
|
275
|
-
baseStylesEl;
|
|
276
|
-
themeStylesEl;
|
|
277
|
-
dynamicStylesEl;
|
|
278
|
-
|
|
279
|
-
headerEl;
|
|
280
|
-
codeNameEl;
|
|
281
|
-
codeToolsEl;
|
|
282
|
-
codeBodyEl;
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
274
|
+
source; // Source code content to be highlighted
|
|
275
|
+
_renderQueued = false; // Flag to prevent multiple render requests
|
|
276
|
+
baseStylesEl; // Element for base styles
|
|
277
|
+
themeStylesEl; // Element for theme styles
|
|
278
|
+
dynamicStylesEl; // Element for dynamic styles
|
|
279
|
+
highlightEl; // Element that holds the highlighted code
|
|
280
|
+
headerEl; // Header element (for code name, tools, etc.)
|
|
281
|
+
codeNameEl; // Code name element (shows language or alias)
|
|
282
|
+
codeToolsEl; // Code tools element (for interactive tools like copy)
|
|
283
|
+
codeBodyEl; // Code body element (the container for the code)
|
|
284
|
+
lang = 'plain'; // Language of the code (default is plain text)
|
|
285
|
+
alias = 'Plain Text'; // Alias name for the language (default is 'Plain Text')
|
|
286
|
+
lineString = ''; // The current line's string being typed
|
|
287
|
+
lastLineString = ''; // The last line's string
|
|
288
|
+
speed = 5; // Speed of the typing effect (higher is slower)
|
|
289
|
+
autoScroll = true; // Flag to enable/disable auto-scrolling
|
|
290
|
+
canListen = true; // Flag to enable/disable auto-scrolling
|
|
287
291
|
constructor() {
|
|
288
292
|
super();
|
|
289
293
|
// Attach a Shadow DOM to the custom element
|
|
290
294
|
this.attachShadow({ mode: 'open' });
|
|
291
295
|
// Remove leading/trailing whitespace from the raw code content
|
|
292
296
|
this.source = this.textContent?.replace(/^\s*\n|\n\s*$/g, '') || '';
|
|
293
|
-
|
|
294
|
-
this.alias = 'Plain Text';
|
|
295
|
-
this.lineString = '';
|
|
296
|
-
this.speed = 5;
|
|
297
|
-
this.autoScroll = true;
|
|
298
|
-
// 1. 初始化基础骨架
|
|
297
|
+
// Initialize the basic structure of the component
|
|
299
298
|
this.shadowRoot.innerHTML = `
|
|
300
299
|
<style id="base-styles">
|
|
301
300
|
:host {
|
|
@@ -425,10 +424,10 @@ class CoaxElem extends HTMLElement {
|
|
|
425
424
|
<style id="theme-styles"></style>
|
|
426
425
|
<div id="code-header"><span id="code-name">${this.alias}</span><div id="code-tools"></div></div>
|
|
427
426
|
<div id="code-body">
|
|
428
|
-
<pre><code id="highlight
|
|
427
|
+
<pre><code id="highlight"></code></pre>
|
|
429
428
|
</div>
|
|
430
429
|
`;
|
|
431
|
-
//
|
|
430
|
+
// Cache references to various elements
|
|
432
431
|
this.baseStylesEl = getEl('#base-styles', this.shadowRoot);
|
|
433
432
|
this.themeStylesEl = getEl('#theme-styles', this.shadowRoot);
|
|
434
433
|
this.dynamicStylesEl = getEl('#dynamic-styles', this.shadowRoot);
|
|
@@ -436,10 +435,10 @@ class CoaxElem extends HTMLElement {
|
|
|
436
435
|
this.codeNameEl = getEl('#code-name', this.shadowRoot);
|
|
437
436
|
this.codeToolsEl = getEl('#code-tools', this.shadowRoot);
|
|
438
437
|
this.codeBodyEl = getEl('#code-body', this.shadowRoot);
|
|
439
|
-
this.
|
|
438
|
+
this.highlightEl = getEl('#highlight', this.shadowRoot);
|
|
440
439
|
this.codeBodyEl.addEventListener('scroll', () => {
|
|
441
440
|
let flag = this.codeBodyEl.scrollTop + this.codeBodyEl.clientHeight < this.codeBodyEl.scrollHeight;
|
|
442
|
-
//
|
|
441
|
+
// Check if the user manually scrolled
|
|
443
442
|
this.autoScroll = !flag;
|
|
444
443
|
});
|
|
445
444
|
}
|
|
@@ -448,11 +447,11 @@ class CoaxElem extends HTMLElement {
|
|
|
448
447
|
// Store the language configuration in the static map
|
|
449
448
|
this.languages.set(name, { ...config });
|
|
450
449
|
}
|
|
451
|
-
|
|
450
|
+
|
|
452
451
|
static addTools(items) {
|
|
453
|
-
|
|
452
|
+
Coax.tools = items;
|
|
454
453
|
}
|
|
455
|
-
|
|
454
|
+
|
|
456
455
|
mountTools(toolItems) {
|
|
457
456
|
requestAnimationFrame(() => {
|
|
458
457
|
this.codeToolsEl.innerHTML = '';
|
|
@@ -463,31 +462,32 @@ class CoaxElem extends HTMLElement {
|
|
|
463
462
|
this.codeToolsEl.appendChild(createTools(items));
|
|
464
463
|
});
|
|
465
464
|
}
|
|
466
|
-
|
|
465
|
+
|
|
467
466
|
connectedCallback() {
|
|
468
467
|
this.render();
|
|
469
468
|
}
|
|
470
|
-
|
|
469
|
+
|
|
471
470
|
static get observedAttributes() { return ['lang', 'height', 'max-height', 'tools', 'speed']; }
|
|
472
471
|
|
|
473
472
|
attributeChangedCallback(name, oldVal, newVal) {
|
|
474
|
-
if (oldVal === newVal)
|
|
473
|
+
if (oldVal === newVal || !this.canListen)
|
|
475
474
|
return;
|
|
476
475
|
if (name === 'height' || name === 'max-height') {
|
|
477
476
|
this.updateStyleByRegExp(name, newVal);
|
|
478
477
|
}
|
|
479
478
|
if (name === 'speed') {
|
|
479
|
+
// Convert to integer (0 or 1)
|
|
480
480
|
this.speed = ~~(!!newVal);
|
|
481
481
|
}
|
|
482
482
|
if (name === 'lang') {
|
|
483
|
-
|
|
483
|
+
// Update the language and re-render
|
|
484
484
|
this.lang = newVal;
|
|
485
485
|
this.render();
|
|
486
486
|
}
|
|
487
487
|
if (name === 'tools') {
|
|
488
488
|
if (!newVal)
|
|
489
489
|
this.codeToolsEl.innerHTML = '';
|
|
490
|
-
const tools = parseClasses$1(newVal), toolItems =
|
|
490
|
+
const tools = parseClasses$1(newVal), toolItems = Coax.tools.filter(k => tools.includes(k.name));
|
|
491
491
|
if (!toolItems.length)
|
|
492
492
|
return;
|
|
493
493
|
this.mountTools(toolItems);
|
|
@@ -501,11 +501,13 @@ class CoaxElem extends HTMLElement {
|
|
|
501
501
|
// 替换为新的属性值
|
|
502
502
|
this.baseStylesEl.textContent = this.baseStylesEl.textContent.replace(regex, `;\n${prop}: ${value};`);
|
|
503
503
|
}
|
|
504
|
+
|
|
504
505
|
getCssPrefix(config) {
|
|
505
506
|
return (config?.cssPrefix || this.lang).replace(/[^a-zA-Z0-9_-]/g, '\\$&');
|
|
506
507
|
}
|
|
508
|
+
|
|
507
509
|
getHighLightString(string, config) {
|
|
508
|
-
config = config ||
|
|
510
|
+
config = config || Coax.languages.get(this.lang);
|
|
509
511
|
if (!config)
|
|
510
512
|
return string;
|
|
511
513
|
// 如果找到了配置,则进行高亮处理
|
|
@@ -517,19 +519,21 @@ class CoaxElem extends HTMLElement {
|
|
|
517
519
|
return i !== -1 && config.rules[i] ? `<span class="${NAMESPACE}-${cssPrefix}-${config.rules[i].token}">${match}</span>` : match;
|
|
518
520
|
});
|
|
519
521
|
}
|
|
522
|
+
|
|
520
523
|
createLineWrap(index, startIndex) {
|
|
521
524
|
let dataIndex = 0;
|
|
522
525
|
if (index == null && startIndex == null) {
|
|
523
|
-
dataIndex = this.
|
|
526
|
+
dataIndex = this.highlightEl.children.length;
|
|
524
527
|
}
|
|
525
528
|
else {
|
|
526
|
-
const start = startIndex || this.
|
|
529
|
+
const start = startIndex || this.highlightEl.children.length;
|
|
527
530
|
dataIndex = start + index;
|
|
528
531
|
}
|
|
529
532
|
return createEl('div', { 'data-index': dataIndex }, '<div></div>');
|
|
530
533
|
}
|
|
534
|
+
|
|
531
535
|
getLineToFill(codeWrap, line, config) {
|
|
532
|
-
config = config ||
|
|
536
|
+
config = config || Coax.languages.get(this.lang);
|
|
533
537
|
let highlightedLine = this.getHighLightString(line, config);
|
|
534
538
|
// 将高亮后的内容填充到 div 中
|
|
535
539
|
codeWrap.innerHTML = highlightedLine;
|
|
@@ -537,7 +541,7 @@ class CoaxElem extends HTMLElement {
|
|
|
537
541
|
;
|
|
538
542
|
|
|
539
543
|
async highlight(newCode) {
|
|
540
|
-
const config =
|
|
544
|
+
const config = Coax.languages.get(this.lang), startIndex = this.highlightEl.children.length,
|
|
541
545
|
// 将新源码按行分割
|
|
542
546
|
newCodeLines = newCode ? newCode.split('\n') : [];
|
|
543
547
|
//更新别名
|
|
@@ -552,9 +556,9 @@ class CoaxElem extends HTMLElement {
|
|
|
552
556
|
// 创建一个 div 包裹每一行
|
|
553
557
|
const lineWrap = this.createLineWrap(index, startIndex), codeWrap = lineWrap.lastElementChild;
|
|
554
558
|
//标记完成
|
|
555
|
-
|
|
559
|
+
lineWrap.completed = true;
|
|
556
560
|
if (this.hasAttribute('speed')) {
|
|
557
|
-
this.
|
|
561
|
+
this.highlightEl.appendChild(lineWrap);
|
|
558
562
|
//流式打字
|
|
559
563
|
await typeWriter(lineString, {
|
|
560
564
|
speed: this.speed,
|
|
@@ -568,20 +572,22 @@ class CoaxElem extends HTMLElement {
|
|
|
568
572
|
//直接打出
|
|
569
573
|
this.getLineToFill(codeWrap, lineString, config);
|
|
570
574
|
//
|
|
571
|
-
this.
|
|
575
|
+
this.highlightEl.appendChild(lineWrap);
|
|
572
576
|
}
|
|
573
577
|
}
|
|
574
578
|
//滚动到最底部
|
|
575
579
|
this.autoScrollCode();
|
|
576
580
|
return true;
|
|
577
581
|
}
|
|
582
|
+
|
|
578
583
|
autoScrollCode() {
|
|
579
584
|
if (this.autoScroll) {
|
|
580
585
|
this.codeBodyEl.scrollTop = this.codeBodyEl.scrollHeight;
|
|
581
586
|
}
|
|
582
587
|
}
|
|
588
|
+
|
|
583
589
|
injectThemeStyles() {
|
|
584
|
-
const config =
|
|
590
|
+
const config = Coax.languages.get(this.lang);
|
|
585
591
|
if (!config)
|
|
586
592
|
return;
|
|
587
593
|
// Get language name, fallback to 'js' if not provided
|
|
@@ -603,13 +609,13 @@ class CoaxElem extends HTMLElement {
|
|
|
603
609
|
.${NAMESPACE}-${cssPrefix}-${rule.token} { color: var(--${NAMESPACE}-${cssPrefix}-${rule.token},${rule.dark}); }` : ``} `).join('\n');
|
|
604
610
|
schemeStyles += `}`;
|
|
605
611
|
// Set the inner HTML of the shadow root, including styles and highlighted code
|
|
606
|
-
// 2. 精确更新 DOM 节点而非重写 ShadowRoot
|
|
607
612
|
this.dynamicStylesEl.textContent = lightStyles + darkStyles + schemeStyles;
|
|
608
613
|
//附加主题样式
|
|
609
614
|
if (config?.themeStyles) {
|
|
610
615
|
this.themeStylesEl.textContent = config.themeStyles;
|
|
611
616
|
}
|
|
612
617
|
}
|
|
618
|
+
|
|
613
619
|
updateName(config) {
|
|
614
620
|
if (this.hasAttribute('unnamed'))
|
|
615
621
|
return;
|
|
@@ -625,21 +631,18 @@ class CoaxElem extends HTMLElement {
|
|
|
625
631
|
|
|
626
632
|
render(code = this.source) {
|
|
627
633
|
//同时多次改变属性,只执行一次
|
|
628
|
-
// 如果已经在队列中,则直接返回
|
|
629
634
|
if (this._renderQueued)
|
|
630
635
|
return;
|
|
631
636
|
this._renderQueued = true;
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
await this.highlight(code);
|
|
638
|
-
this._renderQueued = false;
|
|
639
|
-
});
|
|
637
|
+
this.clear();
|
|
638
|
+
this.injectThemeStyles();
|
|
639
|
+
//一次性渲染
|
|
640
|
+
this.highlight(code);
|
|
641
|
+
this._renderQueued = false;
|
|
640
642
|
}
|
|
643
|
+
|
|
641
644
|
clear() {
|
|
642
|
-
this.
|
|
645
|
+
this.highlightEl.innerHTML = this.source = this.lineString = '';
|
|
643
646
|
}
|
|
644
647
|
|
|
645
648
|
async replace(newCode) {
|
|
@@ -653,36 +656,46 @@ class CoaxElem extends HTMLElement {
|
|
|
653
656
|
// 高亮新的部分
|
|
654
657
|
await this.highlight(newCode);
|
|
655
658
|
}
|
|
656
|
-
|
|
657
|
-
|
|
659
|
+
|
|
660
|
+
getLastLine() {
|
|
661
|
+
const lastChild = this.highlightEl.lastElementChild, lastLine = !lastChild || this.highlightEl.lastElementChild?.completed ?
|
|
658
662
|
this.createLineWrap() : lastChild;
|
|
659
663
|
return {
|
|
660
664
|
lineWrap: lastLine,
|
|
661
665
|
codeWrap: lastLine.lastElementChild
|
|
662
666
|
};
|
|
663
667
|
}
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
668
|
+
|
|
669
|
+
close() {
|
|
670
|
+
const lineWrap = this.highlightEl.lastElementChild;
|
|
671
|
+
if (!lineWrap)
|
|
672
|
+
return;
|
|
673
|
+
lineWrap.completed = true;
|
|
674
|
+
//行结束前保存
|
|
675
|
+
this.lastLineString = this.lineString;
|
|
676
|
+
this.getLineToFill(lineWrap?.lastElementChild, this.lineString);
|
|
677
|
+
//一行结束,清空临时行文本
|
|
678
|
+
this.lineString = '';
|
|
667
679
|
}
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
680
|
+
|
|
681
|
+
open() {
|
|
682
|
+
const lineWrap = this.highlightEl.lastElementChild;
|
|
683
|
+
if (!lineWrap)
|
|
684
|
+
return;
|
|
685
|
+
lineWrap.completed = false;
|
|
686
|
+
//恢复最后一行字符串
|
|
687
|
+
(lineWrap?.lastElementChild).textContent = this.lineString = this.lastLineString;
|
|
671
688
|
}
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
this.
|
|
689
|
+
|
|
690
|
+
stream(str, forceClose = false) {
|
|
691
|
+
const { lineWrap, codeWrap } = this.getLastLine();
|
|
692
|
+
this.highlightEl.appendChild(lineWrap);
|
|
675
693
|
//汇集
|
|
676
694
|
this.source += str;
|
|
677
695
|
//如果没有遇到换行符号,也可以强制结束
|
|
678
|
-
|
|
679
|
-
if (str.startsWith('\n') || str.startsWith('\r')) {
|
|
696
|
+
if (forceClose || (str.startsWith('\n') || str.endsWith('\n'))) {
|
|
680
697
|
//标记完成
|
|
681
|
-
this.
|
|
682
|
-
//渲染
|
|
683
|
-
this.getLineToFill(codeWrap, this.lineString);
|
|
684
|
-
//一行结束,清空临时行文本
|
|
685
|
-
this.lineString = '';
|
|
698
|
+
this.close();
|
|
686
699
|
}
|
|
687
700
|
else {
|
|
688
701
|
//插入文本
|
|
@@ -859,4 +872,4 @@ const copy = {
|
|
|
859
872
|
}
|
|
860
873
|
};
|
|
861
874
|
|
|
862
|
-
export {
|
|
875
|
+
export { Coax, copy, css, html, javascript, markdown, typescript };
|
package/dist/coax.esm.min.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @since Last modified: 2026-1-12
|
|
2
|
+
* @since Last modified: 2026-1-12 15:14:48
|
|
3
3
|
* @name Coax event management system.
|
|
4
|
-
* @version 0.0.
|
|
4
|
+
* @version 0.0.5
|
|
5
5
|
* @author AXUI development team <3217728223@qq.com>
|
|
6
|
-
* @description Coax is a
|
|
6
|
+
* @description Coax is a lightweight web component for elegant code display with syntax highlighting, typewriter effects, and theme switching. Supports JavaScript, HTML, CSS, TypeScript, and Markdown with copy tools and customization.
|
|
7
7
|
* @see {@link https://coax.axui.cn|Official website}
|
|
8
8
|
* @see {@link https://github.com/codady/coax/issues|github issues}
|
|
9
9
|
* @see {@link https://gitee.com/codady/coax/issues|Gitee issues}
|
|
@@ -12,4 +12,4 @@
|
|
|
12
12
|
* @copyright This software supports the MIT License, allowing free learning and commercial use, but please retain the terms 'coax', 'Coax' and 'COAX' within the software.
|
|
13
13
|
* @license MIT license
|
|
14
14
|
*/
|
|
15
|
-
const typeWriter=(e,t)=>{const n=t.speed||100;return new Promise(r=>{t?.onBeforeType?.(e);let i=0;const a=setInterval(()=>{if(i<e.length){const n=e.charAt(i),r=e.substring(0,i+1);t?.onDuringType?.(n,r),i++}else clearInterval(a),r(e),t?.onAfterType?.(e)},n)})},COMMA$1=",",SPACE$1=" ",trim$1=(e,t="compress")=>{if("string"!=typeof e)return"";switch(t){case"start":return e.trimStart();case"end":return e.trimEnd();case"both":return e.trim();case"global":return e.replace(/[\s\r\n]+/g,"");default:return e.trim().replace(/[\s\r\n]+/g," ")}},parseClasses$1=e=>{let t,n=[];return Array.isArray(e)?n=e.filter(e=>e&&"string"==typeof e):(t=(e=trim$1(e)).includes(",")?",":" ",n=e.split(t)),n.map(e=>trim$1(e,"global")).filter(Boolean)},NAMESPACE="ax",getDataType=e=>{let t,n=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===n&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===n&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":n,t},getEl=(e,t=document.body)=>{let n=getDataType(e),r=getDataType(t),i=r.includes("HTML")||"ShadowRoot"===r?t:document.querySelector(t),a=i&&i instanceof HTMLTemplateElement?i.content:i,o=null;if(e)if(n.includes("HTML"))o=e;else if("String"===n)try{o=(a||document).querySelector(e.trim())}catch{o=null}return o},createEl=(e,t,n)=>{let r=(e=e||"div").toUpperCase().trim(),i=document.createElement(r),a=getDataType(t);if(t&&"Object"===a)for(let e in t)t.hasOwnProperty(e)&&i.setAttribute(e,"string"==typeof t[e]?t[e]:JSON.stringify(t[e]));return((e,t)=>{if(""===t||null==t)return!1;let n=getDataType(t);if("TEMPLATE"===r)e.innerHTML=t.toString();else if("Array"===n&&t.length>0)for(let n of t){if(getDataType(n).includes("HTML"))e.appendChild(n);else{let t=createEl(n.name,n.attrs,n.content);t&&e.appendChild(t)}}else if(n.includes("HTML"))e.appendChild(t);else if("String"===n&&t.trim().startsWith("#")&&t.trim().length>1){let n=getEl(t);if(!n)return;"TEMPLATE"===n.nodeName?e.appendChild(n.content.cloneNode(!0)):e.insertAdjacentHTML("beforeEnd",n.innerHTML)}else e.insertAdjacentHTML("beforeEnd",t)})(i,n),i},isEmpty=e=>{let t,n=getDataType(e);return t=!e||("Object"===n?0===Object.keys(e).length:"Array"===n?""===e.join(""):"Function"===n?"{}"===e.toString().replace(/\s+/g,"").match(/{.*}/g)[0]:"Symbol"===n?"()"===e.toString().replace(/\s+/g,"").match(/\(.*\)/g)[0]:"Set"===n||"Map"===n?0===e.size:"Date"===n?isNaN(e.getTime()):"RegExp"===n?""===e.source:"ArrayBuffer"===n?0===e.byteLength:"NodeList"===n||"HTMLCollection"===n||"length"in e&&"number"==typeof e.length?0===e.length:"size"in e&&"number"==typeof e.size?0===e.size:"Error"===n||e instanceof Error?""===e.message:!(!n.includes("Array")||!["Uint8Array","Int8Array","Uint16Array","Int16Array","Uint32Array","Int32Array","Float32Array","Float64Array"].includes(n))&&0===e.length),t},ALIAS="rep",addClasses=(e,t,n)=>{const r=getEl(e),i=parseClasses$1(t);r&&0!==i.length&&i.forEach(e=>{r.classList.add(e)})},createTools=e=>{const t=createEl("span",{class:"ax-box-tools"}),renderFn=e=>{const t={},n=e.extendable?'<i rep="arrow"></i>':"",r=(e.icon?`<i rep="icon">${e.icon}</i>`:"")+(e.disk?`<i rep="disk"><img src="${e.disk}"/></i>`:"")+(e.cube?`<i rep="cube"><img src="${e.cube}"/></i>`:"")+(e.image?`<i rep="image"><img src="${e.image}"/></i>`:"")+(e.label?`<i rep="label">${e.label}</i>`:"")+n;e.title&&(t.title=e.title),e.focusable&&(t.tabindex=1),e.wrapEl=createEl(e.nodeName||"span",Object.assign(t,e.attrs),r),e.iconEl=e.wrapEl.querySelector('[rep="icon"]'),e.cubeEl=e.wrapEl.querySelector('[rep="cube"]'),e.diskEl=e.wrapEl.querySelector('[rep="disk"]'),e.imageEl=e.wrapEl.querySelector('[rep="image"]'),e.labelEl=e.wrapEl.querySelector('[rep="label"]'),!isEmpty(e.classes)&&addClasses(e.wrapEl,e.classes),!isEmpty(e.styles)&&(e.wrapEl.style.cssText+=e.styles)};for(let n of e)renderFn(n),t.appendChild(n.wrapEl),n?.action?.(n);return t};class CoaxElem extends HTMLElement{static languages=new Map;static tools=[];source;_renderQueued=!1;baseStylesEl;themeStylesEl;dynamicStylesEl;highlightedCodeEl;headerEl;codeNameEl;codeToolsEl;codeBodyEl;alias;lineString;speed;autoScroll;constructor(){super(),this.attachShadow({mode:"open"}),this.source=this.textContent?.replace(/^\s*\n|\n\s*$/g,"")||"",this.lang="plain",this.alias="Plain Text",this.lineString="",this.speed=5,this.autoScroll=!0,this.shadowRoot.innerHTML=`\n <style id="base-styles">\n :host { \n --border-width:1px;\n --border-style:solid;\n --radius:9px;\n --height:auto;\n --max-height:500px;\n --radius:9px;\n --padding:1em;\n --font-size:16px;\n --line-height:1.8;\n --background:rgb(247, 247, 247);\n --border-color:rgb(224, 224, 224);\n --color-code:rgb(51, 51, 51);\n --color-index:rgb(153, 153, 153);\n --color-stripe:rgba(0,0,0,0.04);\n --color-hover:rgba(0,0,0,0.06);\n } \n :host([scheme="dark"]){\n --background: #282c34;\n --border-color: transparent;\n --color-code: #abb2bf;\n --color-index:rgb(153, 153, 153);\n --color-stripe:rgba(255,255,255,0.04);\n --color-hover:rgba(255,255,255,0.06);\n }\n @media (prefers-color-scheme: dark) {\n :host{\n --background: #282c34;\n --border-color: transparent;\n --color-code: #abb2bf;\n --color-index:rgb(153, 153, 153);\n --color-stripe:rgba(255,255,255,0.04);\n --color-hover:rgba(255,255,255,0.06);\n }\n }\n :host {\n font-size: var(--ax-code-font-size,var(--font-size));\n display: block; \n box-sizing:border-box;\n background:var(--ax-code-background-color,var(--background));\n color:var(--ax-code-color,var(--color-code));\n border:var(--ax-code-border-width,var(--border-width)) var(--ax-code-border-style,var(--border-style)) var(--ax-code-border-color,var(--border-color));\n transition: border-color 0.3s ease,color 0.3s ease; \n border-radius: var(--ax-code-radius,var(--radius));\n }\n #code-header{\n line-height:calc(var(--ax-code-line-height,var(--line-height))*1.5);\n padding-inline-start:var(--ax-code-padding,var(--padding));\n display:flex;\n \n >:first-child{\n flex:auto;\n }\n }\n #code-body{\n padding: var(--ax-code-padding,var(--padding)) 0;\n height:var(--ax-code-height,var(--height));\n max-height:var(--ax-code-max-height,var(--max-height));\n overflow:auto;\n }\n pre,code{\n font-family:"Consolas", "Monaco", "Andale Mono", "Ubuntu Mono", "monospace";\n margin:0; padding:0;\n }\n code>div{\n display:flex;\n padding:0 var(--ax-code-padding,var(--padding));\n line-height: var(--ax-code-line-height,var(--line-height));\n box-sizing:border-box;\n \n >div{\n flex:auto;\n }\n }\n code>div>div:empty:before{\n content:' ';\n }\n :host([indexed]) code>div:before{\n display:inline-flex;\n color:var(--color-index);\n content: attr(data-index);\n min-width:var(--ax-code-index-width,2em);\n margin-inline-end:var(--ax-code-padding,8px);\n }\n :host([striped]) code>div:nth-child(odd){\n background-color:var(--color-stripe);\n }\n :host([hoverable]) code>div:hover{\n background-color:var(--color-hover);\n }\n :host([wrapped]) code>div>div{\n white-space: pre-wrap;\n }\n :host([unnamed]) #code-name{\n display:none;\n }\n .ax-box-tools{\n >*{\n font-size:14px;\n display:inline-flex;\n align-items:center;\n justify-content:center;\n height:2em;\n line-height:2em;\n aspect-ratio:1/1;\n margin-inline-end:8px;\n transition:all 200ms ease;\n border-radius:6px;\n &:hover{\n cursor:pointer;\n background-color:rgba(0,0,0,.04);\n }\n }\n [rep=icon]{\n display:inline-flex;\n align-items:center;\n justify-content:center;\n }\n }\n [disabled]{\n pointer-event:none;\n }\n </style>\n <style id="dynamic-styles"></style>\n <style id="theme-styles"></style>\n <div id="code-header"><span id="code-name">${this.alias}</span><div id="code-tools"></div></div>\n <div id="code-body">\n <pre><code id="highlight-code"></code></pre>\n </div>\n `,this.baseStylesEl=getEl("#base-styles",this.shadowRoot),this.themeStylesEl=getEl("#theme-styles",this.shadowRoot),this.dynamicStylesEl=getEl("#dynamic-styles",this.shadowRoot),this.headerEl=getEl("#code-header",this.shadowRoot),this.codeNameEl=getEl("#code-name",this.shadowRoot),this.codeToolsEl=getEl("#code-tools",this.shadowRoot),this.codeBodyEl=getEl("#code-body",this.shadowRoot),this.highlightedCodeEl=getEl("#highlight-code",this.shadowRoot),this.codeBodyEl.addEventListener("scroll",()=>{let e=this.codeBodyEl.scrollTop+this.codeBodyEl.clientHeight<this.codeBodyEl.scrollHeight;this.autoScroll=!e})}static register(e,t){this.languages.set(e,{...t})}static addTools(e){CoaxElem.tools=e}mountTools(e){requestAnimationFrame(()=>{this.codeToolsEl.innerHTML="";let t=e.map(e=>(e.action=e.action.bind(this),e));this.codeToolsEl.appendChild(createTools(t))})}connectedCallback(){this.render()}static get observedAttributes(){return["lang","height","max-height","tools","speed"]}attributeChangedCallback(e,t,n){if(t!==n&&("height"!==e&&"max-height"!==e||this.updateStyleByRegExp(e,n),"speed"===e&&(this.speed=~~!!n),"lang"===e&&(this.lang=n,this.render()),"tools"===e)){n||(this.codeToolsEl.innerHTML="");const e=parseClasses$1(n),t=CoaxElem.tools.filter(t=>e.includes(t.name));if(!t.length)return;this.mountTools(t)}}updateStyleByRegExp(e,t){const n=new RegExp(`;\\n\\s*${e}:\\s*[^;]+;`,"g");this.baseStylesEl.textContent=this.baseStylesEl.textContent.replace(n,`;\n${e}: ${t};`)}getCssPrefix(e){return(e?.cssPrefix||this.lang).replace(/[^a-zA-Z0-9_-]/g,"\\$&")}getHighLightString(e,t){if(!(t=t||CoaxElem.languages.get(this.lang)))return e;const n=this.getCssPrefix(t),r=new RegExp(t.rules.map(e=>`(${e.pattern.source})`).join("|"),"g");return e.replace(r,(e,...r)=>{const i=r.findIndex(e=>void 0!==e);return-1!==i&&t.rules[i]?`<span class="ax-${n}-${t.rules[i].token}">${e}</span>`:e})}createLineWrap(e,t){let n=0;if(null==e&&null==t)n=this.highlightedCodeEl.children.length;else{n=(t||this.highlightedCodeEl.children.length)+e}return createEl("div",{"data-index":n},"<div></div>")}getLineToFill(e,t,n){n=n||CoaxElem.languages.get(this.lang);let r=this.getHighLightString(t,n);e.innerHTML=r}async highlight(e){const t=CoaxElem.languages.get(this.lang),n=this.highlightedCodeEl.children.length,r=e?e.split("\n"):[];if(this.updateName(t),!r.length)return!0;for(let[e,i]of r.entries()){if(!i.trim()&&this.hasAttribute("sanitized"))continue;const r=this.createLineWrap(e,n),a=r.lastElementChild;this.closeLine(r),this.hasAttribute("speed")?(this.highlightedCodeEl.appendChild(r),await typeWriter(i,{speed:this.speed,onDuringType:(e,t)=>{a.innerHTML=t}}),this.getLineToFill(a,i,t)):(this.getLineToFill(a,i,t),this.highlightedCodeEl.appendChild(r))}return this.autoScrollCode(),!0}autoScrollCode(){this.autoScroll&&(this.codeBodyEl.scrollTop=this.codeBodyEl.scrollHeight)}injectThemeStyles(){const e=CoaxElem.languages.get(this.lang);if(!e)return;let t=this.getCssPrefix(e),n=e.rules.map(e=>`\n .ax-${t}-${e.token} { color: var(--ax-${t}-${e.token}${e.light?","+e.light:""});}`).join("\n"),r="",i="";r+=':host([scheme="dark"]){',r+=e.rules.map(e=>"\n "+(e.light?`\n .ax-${t}-${e.token} {color: var(--ax-${t}-${e.token},${e.dark});}`:"")).join("\n"),r+="}",i="@media (prefers-color-scheme: dark){\n :host{\n ",i+=e.rules.map(e=>`\n ${e.light?`\n .ax-${t}-${e.token} { color: var(--ax-${t}-${e.token},${e.dark}); }`:""} `).join("\n"),i+="}",this.dynamicStylesEl.textContent=n+r+i,e?.themeStyles&&(this.themeStylesEl.textContent=e.themeStyles)}updateName(e){this.hasAttribute("unnamed")||(e?(this.alias=e.alias||this.lang,this.codeNameEl.innerHTML=this.alias):this.codeNameEl.innerHTML="Plain Text")}render(e=this.source){this._renderQueued||(this._renderQueued=!0,requestAnimationFrame(async()=>{this.clear(),this.injectThemeStyles(),await this.highlight(e),this._renderQueued=!1}))}clear(){this.highlightedCodeEl.innerHTML=this.source=this.lineString=""}async replace(e){this.clear(),await this.highlight(e)}async append(e){this.source+=`\n${e}`,await this.highlight(e)}getActiveCodeWrap(){const e=this.highlightedCodeEl.lastElementChild,t=!e||this.highlightedCodeEl.lastElementChild?.completed?this.createLineWrap():e;return{lineWrap:t,codeWrap:t.lastElementChild}}closeLine(e){(e=e||this.highlightedCodeEl.lastElementChild)&&(e.completed=!0)}openLine(e){(e=e||this.highlightedCodeEl.lastElementChild)&&(e.completed=!1)}stream(e,t=!1){const{lineWrap:n,codeWrap:r}=this.getActiveCodeWrap();this.highlightedCodeEl.appendChild(n),this.source+=e,t&&this.closeLine(n),e.startsWith("\n")||e.startsWith("\r")?(this.closeLine(n),this.getLineToFill(r,this.lineString),this.lineString=""):(r.innerHTML+=e,this.lineString+=e),this.autoScrollCode()}}const css=[{token:"comment",pattern:/\/\*[\s\S]*?\*\//,light:"#6a737d",dark:"#8b949e"},{token:"value",pattern:/(?:'|")(?:\\.|[^\\'"\b])*?(?:'|")/,light:"#032f62",dark:"#a5d6ff"},{token:"func",pattern:/[a-z-]+\(?=/,light:"#e36209",dark:"#ffa657"},{token:"property",pattern:/[a-z-]+(?=\s*:)/,light:"#005cc5",dark:"#79c0ff"},{token:"selector",pattern:/[.#a-z0-9, \n\t>:+()_-]+(?=\s*\{)/i,light:"#22863a",dark:"#7ee787"},{token:"unit",pattern:/(?<=\d)(px|em|rem|%|vh|vw|ms|s|deg)/,light:"#d73a49",dark:"#ff7b72"},{token:"number",pattern:/\b\d+(\.\d+)?\b/,light:"#005cc5",dark:"#79c0ff"},{token:"punct",pattern:/[{}();:]/,light:"#24292e",dark:"#c9d1d9"}],html=[{token:"comment",pattern:/<!--[\s\S]*?-->/,light:"#999999",dark:"#6e7681"},{token:"doctype",pattern:/<!DOCTYPE[\s\S]*?>/i,light:"#6a737d",dark:"#8b949e"},{token:"tag",pattern:/<\/?[a-zA-Z0-9]+/,light:"#22863a",dark:"#7ee787"},{token:"attr",pattern:/[a-zA-Z-]+(?=\s*=\s*)/,light:"#6f42c1",dark:"#d2a8ff"},{token:"string",pattern:/(['"])(?:\\.|[^\\])*?\1/,light:"#032f62",dark:"#a5d6ff"},{token:"bracket",pattern:/\/?>/,light:"#24292e",dark:"#c9d1d9"}],javascript=[{token:"comment",pattern:/\/\/[^\n]*|\/\*[\s\S]*?\*\//,light:"#6a737d",dark:"#8b949e"},{token:"string",pattern:/(?:'|"|`)(?:\\.|[^\\'"\b])*?(?:'|"|`)/,light:"#032f62",dark:"#98c379"},{token:"keyword",pattern:/\b(async|await|break|case|catch|class|const|continue|default|delete|do|else|export|extends|finally|for|function|if|import|in|instanceof|new|return|super|switch|this|throw|try|typeof|var|while|with|yield|let|static)\b/,light:"#d73a49",dark:"#ff7b72"},{token:"builtin",pattern:/\b(console|window|document|Math|JSON|true|false|null|undefined|Object|Array|Promise|Number|String|Boolean)\b/,light:"#e36209",dark:"#ffa657"},{token:"number",pattern:/\b(0x[\da-fA-F]+|0b[01]+|\d+(\.\d+)?)\b/,light:"#005cc5",dark:"#79c0ff"},{token:"func",pattern:/\b[a-zA-Z_]\w*(?=\s*\()/,light:"#6f42c1",dark:"#d2a8ff"},{token:"op",pattern:/[+\-*/%=<>!&|^~]+/,light:"#069598",dark:"#56b6c2"}],markdown=[{token:"comment",pattern:/<!--[\s\S]*?-->/,light:"#6a737d",dark:"#8b949e"},{token:"heading",pattern:/(^|\n)(#{1,6})\s*(.+)/,light:"#e36209",dark:"#ffa657"},{token:"bold",pattern:/\*\*([^*]+)\*\*|__([^_]+)__/g,light:"#d73a49",dark:"#ff7b72"},{token:"italic",pattern:/\*([^*]+)\*|_([^_]+)_/g,light:"#032f62",dark:"#a5d6ff"},{token:"link",pattern:/\[([^\]]+)\]\(([^)]+)\)/g,light:"#0288d1",dark:"#80c0ff"},{token:"inline-code",pattern:/`([^`]+)`/g,light:"#032f62",dark:"#98c379"},{token:"code-block",pattern:/```([^\n]+)\n([\s\S]*?)```/g,light:"#24292e",dark:"#c9d1d9"},{token:"list-item",pattern:/(^|\n)([-*])\s+(.+)/g,light:"#5c6e7c",dark:"#8b949e"},{token:"quote",pattern:/(^|\n)>[ \t]*(.+)/g,light:"#6f42c1",dark:"#d2a8ff"},{token:"image",pattern:/!\[([^\]]+)\]\(([^)]+)\)/g,light:"#d73a49",dark:"#ff7b72"},{token:"hr",pattern:/^(---|___|\*\*\*)\s*$/gm,light:"#24292e",dark:"#c9d1d9"},{token:"strikethrough",pattern:/~~([^~]+)~~/g,light:"#e36209",dark:"#ffa657"},{token:"table",pattern:/\|([^\|]+)\|([^\|]+)\|/g,light:"#5c6e7c",dark:"#8b949e"}],typescript=[{token:"comment",pattern:/\/\/[^\n]*|\/\*[\s\S]*?\*\//,light:"#6a737d",dark:"#8b949e"},{token:"string",pattern:/(?:'|"|`)(?:\\.|[^\\'"\b])*?(?:'|"|`)/,light:"#032f62",dark:"#98c379"},{token:"decorator",pattern:/@[a-zA-Z_]\w*/,light:"#953800",dark:"#ffa657"},{token:"keyword",pattern:/\b(abstract|as|async|await|break|case|catch|class|const|continue|debugger|declare|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|is|keyof|let|module|namespace|new|package|private|protected|public|readonly|return|set|static|super|switch|this|throw|try|type|typeof|var|while|with|yield)\b/,light:"#d73a49",dark:"#ff7b72"},{token:"builtin",pattern:/\b(any|boolean|never|number|string|symbol|unknown|void|undefined|null|true|false|console|window|document)\b/,light:"#e36209",dark:"#ffa657"},{token:"type",pattern:/\b[A-Z]\w*\b/,light:"#005cc5",dark:"#79c0ff"},{token:"number",pattern:/\b(0x[\da-fA-F]+|0b[01]+|\d+(\.\d+)?)\b/,light:"#005cc5",dark:"#79c0ff"},{token:"func",pattern:/\b[a-zA-Z_]\w*(?=\s*\()/,light:"#6f42c1",dark:"#d2a8ff"},{token:"op",pattern:/(\?\.|![:\.]|[+\-*/%=<>!&|^~]+)/,light:"#089ba6",dark:"#79c0ff"}],COMMA=",",SPACE=" ",trim=(e,t="")=>{if("string"!=typeof e)return"";switch(t){case"start":return e.trimStart();case"end":return e.trimEnd();case"both":return e.trim();case"global":return e.replace(/[\s\r\n]+/g,"");default:return e.trim().replace(/[\s\r\n]+/g," ")}},parseClasses=e=>{let t,n=[];return Array.isArray(e)?n=e.filter(e=>e&&"string"==typeof e):(t=(e=trim(e)).includes(",")?",":" ",n=e.split(t)),n.map(e=>trim(e,"global")).filter(Boolean)},rtlStyle=(e="")=>`\n <style>\n :where([dir="rtl"]) .icax-${e},\n :where(:dir(rtl)) .icax-${e} {\n transform: scaleX(-1);\n transform-origin: center;\n }\n </style>\n`,wrap=(e,t,n=!1,r)=>{const i=r?.size||"1em",a=r?.color||"currentColor",o=r?.thickness||2,l=r?.classes?parseClasses(r.classes).join(" "):"",s=t.name.replace(/([A-Z])/g,"-$1").toLowerCase();return`<svg xmlns="http://www.w3.org/2000/svg" width="${i}" height="${i}" viewBox="0 0 24 24" fill="none" stroke="${a}"\n stroke-width="${o}" stroke-linecap="round" stroke-linejoin="round" class="${s} ${l}">\n ${n?rtlStyle(s.split("-")[1]):""}\n ${e}\n </svg>`},icaxCheck=e=>wrap('<polyline points="20 6 9 17 4 12"></polyline>',icaxCheck,!1,e),icaxCopy=e=>wrap('<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>',icaxCopy,!1,e),copy={name:"copy",icon:icaxCopy(),action:function(e){e.wrapEl.onclick=()=>{navigator.clipboard.writeText(this.source).then(()=>{e.iconEl.innerHTML=icaxCheck(),e.iconEl.toggleAttribute("disabled",!0),setTimeout(()=>{e.iconEl.removeAttribute("disabled"),e.iconEl.innerHTML=icaxCopy()},2e3)}).catch(e=>{})}}};export{CoaxElem,copy,css,html,javascript,markdown,typescript};
|
|
15
|
+
const typeWriter=(e,t)=>{const n=t.speed||100;return new Promise(r=>{t?.onBeforeType?.(e);let i=0;const a=setInterval(()=>{if(i<e.length){const n=e.charAt(i),r=e.substring(0,i+1);t?.onDuringType?.(n,r),i++}else clearInterval(a),r(e),t?.onAfterType?.(e)},n)})},COMMA$1=",",SPACE$1=" ",trim$1=(e,t="compress")=>{if("string"!=typeof e)return"";switch(t){case"start":return e.trimStart();case"end":return e.trimEnd();case"both":return e.trim();case"global":return e.replace(/[\s\r\n]+/g,"");default:return e.trim().replace(/[\s\r\n]+/g," ")}},parseClasses$1=e=>{let t,n=[];return Array.isArray(e)?n=e.filter(e=>e&&"string"==typeof e):(t=(e=trim$1(e)).includes(",")?",":" ",n=e.split(t)),n.map(e=>trim$1(e,"global")).filter(Boolean)},NAMESPACE="ax",getDataType=e=>{let t,n=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===n&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===n&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":n,t},getEl=(e,t=document.body)=>{let n=getDataType(e),r=getDataType(t),i=r.includes("HTML")||"ShadowRoot"===r?t:document.querySelector(t),a=i&&i instanceof HTMLTemplateElement?i.content:i,o=null;if(e)if(n.includes("HTML"))o=e;else if("String"===n)try{o=(a||document).querySelector(e.trim())}catch{o=null}return o},createEl=(e,t,n)=>{let r=(e=e||"div").toUpperCase().trim(),i=document.createElement(r),a=getDataType(t);if(t&&"Object"===a)for(let e in t)t.hasOwnProperty(e)&&i.setAttribute(e,"string"==typeof t[e]?t[e]:JSON.stringify(t[e]));return((e,t)=>{if(""===t||null==t)return!1;let n=getDataType(t);if("TEMPLATE"===r)e.innerHTML=t.toString();else if("Array"===n&&t.length>0)for(let n of t){if(getDataType(n).includes("HTML"))e.appendChild(n);else{let t=createEl(n.name,n.attrs,n.content);t&&e.appendChild(t)}}else if(n.includes("HTML"))e.appendChild(t);else if("String"===n&&t.trim().startsWith("#")&&t.trim().length>1){let n=getEl(t);if(!n)return;"TEMPLATE"===n.nodeName?e.appendChild(n.content.cloneNode(!0)):e.insertAdjacentHTML("beforeEnd",n.innerHTML)}else e.insertAdjacentHTML("beforeEnd",t)})(i,n),i},isEmpty=e=>{let t,n=getDataType(e);return t=!e||("Object"===n?0===Object.keys(e).length:"Array"===n?""===e.join(""):"Function"===n?"{}"===e.toString().replace(/\s+/g,"").match(/{.*}/g)[0]:"Symbol"===n?"()"===e.toString().replace(/\s+/g,"").match(/\(.*\)/g)[0]:"Set"===n||"Map"===n?0===e.size:"Date"===n?isNaN(e.getTime()):"RegExp"===n?""===e.source:"ArrayBuffer"===n?0===e.byteLength:"NodeList"===n||"HTMLCollection"===n||"length"in e&&"number"==typeof e.length?0===e.length:"size"in e&&"number"==typeof e.size?0===e.size:"Error"===n||e instanceof Error?""===e.message:!(!n.includes("Array")||!["Uint8Array","Int8Array","Uint16Array","Int16Array","Uint32Array","Int32Array","Float32Array","Float64Array"].includes(n))&&0===e.length),t},ALIAS="rep",addClasses=(e,t,n)=>{const r=getEl(e),i=parseClasses$1(t);r&&0!==i.length&&i.forEach(e=>{r.classList.add(e)})},createTools=e=>{const t=createEl("span",{class:"ax-box-tools"}),renderFn=e=>{const t={},n=e.extendable?'<i rep="arrow"></i>':"",r=(e.icon?`<i rep="icon">${e.icon}</i>`:"")+(e.disk?`<i rep="disk"><img src="${e.disk}"/></i>`:"")+(e.cube?`<i rep="cube"><img src="${e.cube}"/></i>`:"")+(e.image?`<i rep="image"><img src="${e.image}"/></i>`:"")+(e.label?`<i rep="label">${e.label}</i>`:"")+n;e.title&&(t.title=e.title),e.focusable&&(t.tabindex=1),e.wrapEl=createEl(e.nodeName||"span",Object.assign(t,e.attrs),r),e.iconEl=e.wrapEl.querySelector('[rep="icon"]'),e.cubeEl=e.wrapEl.querySelector('[rep="cube"]'),e.diskEl=e.wrapEl.querySelector('[rep="disk"]'),e.imageEl=e.wrapEl.querySelector('[rep="image"]'),e.labelEl=e.wrapEl.querySelector('[rep="label"]'),!isEmpty(e.classes)&&addClasses(e.wrapEl,e.classes),!isEmpty(e.styles)&&(e.wrapEl.style.cssText+=e.styles)};for(let n of e)renderFn(n),t.appendChild(n.wrapEl),n?.action?.(n);return t};class Coax extends HTMLElement{static languages=new Map;static tools=[];source;_renderQueued=!1;baseStylesEl;themeStylesEl;dynamicStylesEl;highlightEl;headerEl;codeNameEl;codeToolsEl;codeBodyEl;lang="plain";alias="Plain Text";lineString="";lastLineString="";speed=5;autoScroll=!0;canListen=!0;constructor(){super(),this.attachShadow({mode:"open"}),this.source=this.textContent?.replace(/^\s*\n|\n\s*$/g,"")||"",this.shadowRoot.innerHTML=`\n <style id="base-styles">\n :host { \n --border-width:1px;\n --border-style:solid;\n --radius:9px;\n --height:auto;\n --max-height:500px;\n --radius:9px;\n --padding:1em;\n --font-size:16px;\n --line-height:1.8;\n --background:rgb(247, 247, 247);\n --border-color:rgb(224, 224, 224);\n --color-code:rgb(51, 51, 51);\n --color-index:rgb(153, 153, 153);\n --color-stripe:rgba(0,0,0,0.04);\n --color-hover:rgba(0,0,0,0.06);\n } \n :host([scheme="dark"]){\n --background: #282c34;\n --border-color: transparent;\n --color-code: #abb2bf;\n --color-index:rgb(153, 153, 153);\n --color-stripe:rgba(255,255,255,0.04);\n --color-hover:rgba(255,255,255,0.06);\n }\n @media (prefers-color-scheme: dark) {\n :host{\n --background: #282c34;\n --border-color: transparent;\n --color-code: #abb2bf;\n --color-index:rgb(153, 153, 153);\n --color-stripe:rgba(255,255,255,0.04);\n --color-hover:rgba(255,255,255,0.06);\n }\n }\n :host {\n font-size: var(--ax-code-font-size,var(--font-size));\n display: block; \n box-sizing:border-box;\n background:var(--ax-code-background-color,var(--background));\n color:var(--ax-code-color,var(--color-code));\n border:var(--ax-code-border-width,var(--border-width)) var(--ax-code-border-style,var(--border-style)) var(--ax-code-border-color,var(--border-color));\n transition: border-color 0.3s ease,color 0.3s ease; \n border-radius: var(--ax-code-radius,var(--radius));\n }\n #code-header{\n line-height:calc(var(--ax-code-line-height,var(--line-height))*1.5);\n padding-inline-start:var(--ax-code-padding,var(--padding));\n display:flex;\n \n >:first-child{\n flex:auto;\n }\n }\n #code-body{\n padding: var(--ax-code-padding,var(--padding)) 0;\n height:var(--ax-code-height,var(--height));\n max-height:var(--ax-code-max-height,var(--max-height));\n overflow:auto;\n }\n pre,code{\n font-family:"Consolas", "Monaco", "Andale Mono", "Ubuntu Mono", "monospace";\n margin:0; padding:0;\n }\n code>div{\n display:flex;\n padding:0 var(--ax-code-padding,var(--padding));\n line-height: var(--ax-code-line-height,var(--line-height));\n box-sizing:border-box;\n \n >div{\n flex:auto;\n }\n }\n code>div>div:empty:before{\n content:' ';\n }\n :host([indexed]) code>div:before{\n display:inline-flex;\n color:var(--color-index);\n content: attr(data-index);\n min-width:var(--ax-code-index-width,2em);\n margin-inline-end:var(--ax-code-padding,8px);\n }\n :host([striped]) code>div:nth-child(odd){\n background-color:var(--color-stripe);\n }\n :host([hoverable]) code>div:hover{\n background-color:var(--color-hover);\n }\n :host([wrapped]) code>div>div{\n white-space: pre-wrap;\n }\n :host([unnamed]) #code-name{\n display:none;\n }\n .ax-box-tools{\n >*{\n font-size:14px;\n display:inline-flex;\n align-items:center;\n justify-content:center;\n height:2em;\n line-height:2em;\n aspect-ratio:1/1;\n margin-inline-end:8px;\n transition:all 200ms ease;\n border-radius:6px;\n &:hover{\n cursor:pointer;\n background-color:rgba(0,0,0,.04);\n }\n }\n [rep=icon]{\n display:inline-flex;\n align-items:center;\n justify-content:center;\n }\n }\n [disabled]{\n pointer-event:none;\n }\n </style>\n <style id="dynamic-styles"></style>\n <style id="theme-styles"></style>\n <div id="code-header"><span id="code-name">${this.alias}</span><div id="code-tools"></div></div>\n <div id="code-body">\n <pre><code id="highlight"></code></pre>\n </div>\n `,this.baseStylesEl=getEl("#base-styles",this.shadowRoot),this.themeStylesEl=getEl("#theme-styles",this.shadowRoot),this.dynamicStylesEl=getEl("#dynamic-styles",this.shadowRoot),this.headerEl=getEl("#code-header",this.shadowRoot),this.codeNameEl=getEl("#code-name",this.shadowRoot),this.codeToolsEl=getEl("#code-tools",this.shadowRoot),this.codeBodyEl=getEl("#code-body",this.shadowRoot),this.highlightEl=getEl("#highlight",this.shadowRoot),this.codeBodyEl.addEventListener("scroll",()=>{let e=this.codeBodyEl.scrollTop+this.codeBodyEl.clientHeight<this.codeBodyEl.scrollHeight;this.autoScroll=!e})}static register(e,t){this.languages.set(e,{...t})}static addTools(e){Coax.tools=e}mountTools(e){requestAnimationFrame(()=>{this.codeToolsEl.innerHTML="";let t=e.map(e=>(e.action=e.action.bind(this),e));this.codeToolsEl.appendChild(createTools(t))})}connectedCallback(){this.render()}static get observedAttributes(){return["lang","height","max-height","tools","speed"]}attributeChangedCallback(e,t,n){if(t!==n&&this.canListen&&("height"!==e&&"max-height"!==e||this.updateStyleByRegExp(e,n),"speed"===e&&(this.speed=~~!!n),"lang"===e&&(this.lang=n,this.render()),"tools"===e)){n||(this.codeToolsEl.innerHTML="");const e=parseClasses$1(n),t=Coax.tools.filter(t=>e.includes(t.name));if(!t.length)return;this.mountTools(t)}}updateStyleByRegExp(e,t){const n=new RegExp(`;\\n\\s*${e}:\\s*[^;]+;`,"g");this.baseStylesEl.textContent=this.baseStylesEl.textContent.replace(n,`;\n${e}: ${t};`)}getCssPrefix(e){return(e?.cssPrefix||this.lang).replace(/[^a-zA-Z0-9_-]/g,"\\$&")}getHighLightString(e,t){if(!(t=t||Coax.languages.get(this.lang)))return e;const n=this.getCssPrefix(t),r=new RegExp(t.rules.map(e=>`(${e.pattern.source})`).join("|"),"g");return e.replace(r,(e,...r)=>{const i=r.findIndex(e=>void 0!==e);return-1!==i&&t.rules[i]?`<span class="ax-${n}-${t.rules[i].token}">${e}</span>`:e})}createLineWrap(e,t){let n=0;if(null==e&&null==t)n=this.highlightEl.children.length;else{n=(t||this.highlightEl.children.length)+e}return createEl("div",{"data-index":n},"<div></div>")}getLineToFill(e,t,n){n=n||Coax.languages.get(this.lang);let r=this.getHighLightString(t,n);e.innerHTML=r}async highlight(e){const t=Coax.languages.get(this.lang),n=this.highlightEl.children.length,r=e?e.split("\n"):[];if(this.updateName(t),!r.length)return!0;for(let[e,i]of r.entries()){if(!i.trim()&&this.hasAttribute("sanitized"))continue;const r=this.createLineWrap(e,n),a=r.lastElementChild;r.completed=!0,this.hasAttribute("speed")?(this.highlightEl.appendChild(r),await typeWriter(i,{speed:this.speed,onDuringType:(e,t)=>{a.innerHTML=t}}),this.getLineToFill(a,i,t)):(this.getLineToFill(a,i,t),this.highlightEl.appendChild(r))}return this.autoScrollCode(),!0}autoScrollCode(){this.autoScroll&&(this.codeBodyEl.scrollTop=this.codeBodyEl.scrollHeight)}injectThemeStyles(){const e=Coax.languages.get(this.lang);if(!e)return;let t=this.getCssPrefix(e),n=e.rules.map(e=>`\n .ax-${t}-${e.token} { color: var(--ax-${t}-${e.token}${e.light?","+e.light:""});}`).join("\n"),r="",i="";r+=':host([scheme="dark"]){',r+=e.rules.map(e=>"\n "+(e.light?`\n .ax-${t}-${e.token} {color: var(--ax-${t}-${e.token},${e.dark});}`:"")).join("\n"),r+="}",i="@media (prefers-color-scheme: dark){\n :host{\n ",i+=e.rules.map(e=>`\n ${e.light?`\n .ax-${t}-${e.token} { color: var(--ax-${t}-${e.token},${e.dark}); }`:""} `).join("\n"),i+="}",this.dynamicStylesEl.textContent=n+r+i,e?.themeStyles&&(this.themeStylesEl.textContent=e.themeStyles)}updateName(e){this.hasAttribute("unnamed")||(e?(this.alias=e.alias||this.lang,this.codeNameEl.innerHTML=this.alias):this.codeNameEl.innerHTML="Plain Text")}render(e=this.source){this._renderQueued||(this._renderQueued=!0,this.clear(),this.injectThemeStyles(),this.highlight(e),this._renderQueued=!1)}clear(){this.highlightEl.innerHTML=this.source=this.lineString=""}async replace(e){this.clear(),await this.highlight(e)}async append(e){this.source+=`\n${e}`,await this.highlight(e)}getLastLine(){const e=this.highlightEl.lastElementChild,t=!e||this.highlightEl.lastElementChild?.completed?this.createLineWrap():e;return{lineWrap:t,codeWrap:t.lastElementChild}}close(){const e=this.highlightEl.lastElementChild;e&&(e.completed=!0,this.lastLineString=this.lineString,this.getLineToFill(e?.lastElementChild,this.lineString),this.lineString="")}open(){const e=this.highlightEl.lastElementChild;e&&(e.completed=!1,(e?.lastElementChild).textContent=this.lineString=this.lastLineString)}stream(e,t=!1){const{lineWrap:n,codeWrap:r}=this.getLastLine();this.highlightEl.appendChild(n),this.source+=e,t||e.startsWith("\n")||e.endsWith("\n")?this.close():(r.innerHTML+=e,this.lineString+=e),this.autoScrollCode()}}const css=[{token:"comment",pattern:/\/\*[\s\S]*?\*\//,light:"#6a737d",dark:"#8b949e"},{token:"value",pattern:/(?:'|")(?:\\.|[^\\'"\b])*?(?:'|")/,light:"#032f62",dark:"#a5d6ff"},{token:"func",pattern:/[a-z-]+\(?=/,light:"#e36209",dark:"#ffa657"},{token:"property",pattern:/[a-z-]+(?=\s*:)/,light:"#005cc5",dark:"#79c0ff"},{token:"selector",pattern:/[.#a-z0-9, \n\t>:+()_-]+(?=\s*\{)/i,light:"#22863a",dark:"#7ee787"},{token:"unit",pattern:/(?<=\d)(px|em|rem|%|vh|vw|ms|s|deg)/,light:"#d73a49",dark:"#ff7b72"},{token:"number",pattern:/\b\d+(\.\d+)?\b/,light:"#005cc5",dark:"#79c0ff"},{token:"punct",pattern:/[{}();:]/,light:"#24292e",dark:"#c9d1d9"}],html=[{token:"comment",pattern:/<!--[\s\S]*?-->/,light:"#999999",dark:"#6e7681"},{token:"doctype",pattern:/<!DOCTYPE[\s\S]*?>/i,light:"#6a737d",dark:"#8b949e"},{token:"tag",pattern:/<\/?[a-zA-Z0-9]+/,light:"#22863a",dark:"#7ee787"},{token:"attr",pattern:/[a-zA-Z-]+(?=\s*=\s*)/,light:"#6f42c1",dark:"#d2a8ff"},{token:"string",pattern:/(['"])(?:\\.|[^\\])*?\1/,light:"#032f62",dark:"#a5d6ff"},{token:"bracket",pattern:/\/?>/,light:"#24292e",dark:"#c9d1d9"}],javascript=[{token:"comment",pattern:/\/\/[^\n]*|\/\*[\s\S]*?\*\//,light:"#6a737d",dark:"#8b949e"},{token:"string",pattern:/(?:'|"|`)(?:\\.|[^\\'"\b])*?(?:'|"|`)/,light:"#032f62",dark:"#98c379"},{token:"keyword",pattern:/\b(async|await|break|case|catch|class|const|continue|default|delete|do|else|export|extends|finally|for|function|if|import|in|instanceof|new|return|super|switch|this|throw|try|typeof|var|while|with|yield|let|static)\b/,light:"#d73a49",dark:"#ff7b72"},{token:"builtin",pattern:/\b(console|window|document|Math|JSON|true|false|null|undefined|Object|Array|Promise|Number|String|Boolean)\b/,light:"#e36209",dark:"#ffa657"},{token:"number",pattern:/\b(0x[\da-fA-F]+|0b[01]+|\d+(\.\d+)?)\b/,light:"#005cc5",dark:"#79c0ff"},{token:"func",pattern:/\b[a-zA-Z_]\w*(?=\s*\()/,light:"#6f42c1",dark:"#d2a8ff"},{token:"op",pattern:/[+\-*/%=<>!&|^~]+/,light:"#069598",dark:"#56b6c2"}],markdown=[{token:"comment",pattern:/<!--[\s\S]*?-->/,light:"#6a737d",dark:"#8b949e"},{token:"heading",pattern:/(^|\n)(#{1,6})\s*(.+)/,light:"#e36209",dark:"#ffa657"},{token:"bold",pattern:/\*\*([^*]+)\*\*|__([^_]+)__/g,light:"#d73a49",dark:"#ff7b72"},{token:"italic",pattern:/\*([^*]+)\*|_([^_]+)_/g,light:"#032f62",dark:"#a5d6ff"},{token:"link",pattern:/\[([^\]]+)\]\(([^)]+)\)/g,light:"#0288d1",dark:"#80c0ff"},{token:"inline-code",pattern:/`([^`]+)`/g,light:"#032f62",dark:"#98c379"},{token:"code-block",pattern:/```([^\n]+)\n([\s\S]*?)```/g,light:"#24292e",dark:"#c9d1d9"},{token:"list-item",pattern:/(^|\n)([-*])\s+(.+)/g,light:"#5c6e7c",dark:"#8b949e"},{token:"quote",pattern:/(^|\n)>[ \t]*(.+)/g,light:"#6f42c1",dark:"#d2a8ff"},{token:"image",pattern:/!\[([^\]]+)\]\(([^)]+)\)/g,light:"#d73a49",dark:"#ff7b72"},{token:"hr",pattern:/^(---|___|\*\*\*)\s*$/gm,light:"#24292e",dark:"#c9d1d9"},{token:"strikethrough",pattern:/~~([^~]+)~~/g,light:"#e36209",dark:"#ffa657"},{token:"table",pattern:/\|([^\|]+)\|([^\|]+)\|/g,light:"#5c6e7c",dark:"#8b949e"}],typescript=[{token:"comment",pattern:/\/\/[^\n]*|\/\*[\s\S]*?\*\//,light:"#6a737d",dark:"#8b949e"},{token:"string",pattern:/(?:'|"|`)(?:\\.|[^\\'"\b])*?(?:'|"|`)/,light:"#032f62",dark:"#98c379"},{token:"decorator",pattern:/@[a-zA-Z_]\w*/,light:"#953800",dark:"#ffa657"},{token:"keyword",pattern:/\b(abstract|as|async|await|break|case|catch|class|const|continue|debugger|declare|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|is|keyof|let|module|namespace|new|package|private|protected|public|readonly|return|set|static|super|switch|this|throw|try|type|typeof|var|while|with|yield)\b/,light:"#d73a49",dark:"#ff7b72"},{token:"builtin",pattern:/\b(any|boolean|never|number|string|symbol|unknown|void|undefined|null|true|false|console|window|document)\b/,light:"#e36209",dark:"#ffa657"},{token:"type",pattern:/\b[A-Z]\w*\b/,light:"#005cc5",dark:"#79c0ff"},{token:"number",pattern:/\b(0x[\da-fA-F]+|0b[01]+|\d+(\.\d+)?)\b/,light:"#005cc5",dark:"#79c0ff"},{token:"func",pattern:/\b[a-zA-Z_]\w*(?=\s*\()/,light:"#6f42c1",dark:"#d2a8ff"},{token:"op",pattern:/(\?\.|![:\.]|[+\-*/%=<>!&|^~]+)/,light:"#089ba6",dark:"#79c0ff"}],COMMA=",",SPACE=" ",trim=(e,t="")=>{if("string"!=typeof e)return"";switch(t){case"start":return e.trimStart();case"end":return e.trimEnd();case"both":return e.trim();case"global":return e.replace(/[\s\r\n]+/g,"");default:return e.trim().replace(/[\s\r\n]+/g," ")}},parseClasses=e=>{let t,n=[];return Array.isArray(e)?n=e.filter(e=>e&&"string"==typeof e):(t=(e=trim(e)).includes(",")?",":" ",n=e.split(t)),n.map(e=>trim(e,"global")).filter(Boolean)},rtlStyle=(e="")=>`\n <style>\n :where([dir="rtl"]) .icax-${e},\n :where(:dir(rtl)) .icax-${e} {\n transform: scaleX(-1);\n transform-origin: center;\n }\n </style>\n`,wrap=(e,t,n=!1,r)=>{const i=r?.size||"1em",a=r?.color||"currentColor",o=r?.thickness||2,l=r?.classes?parseClasses(r.classes).join(" "):"",s=t.name.replace(/([A-Z])/g,"-$1").toLowerCase();return`<svg xmlns="http://www.w3.org/2000/svg" width="${i}" height="${i}" viewBox="0 0 24 24" fill="none" stroke="${a}"\n stroke-width="${o}" stroke-linecap="round" stroke-linejoin="round" class="${s} ${l}">\n ${n?rtlStyle(s.split("-")[1]):""}\n ${e}\n </svg>`},icaxCheck=e=>wrap('<polyline points="20 6 9 17 4 12"></polyline>',icaxCheck,!1,e),icaxCopy=e=>wrap('<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>',icaxCopy,!1,e),copy={name:"copy",icon:icaxCopy(),action:function(e){e.wrapEl.onclick=()=>{navigator.clipboard.writeText(this.source).then(()=>{e.iconEl.innerHTML=icaxCheck(),e.iconEl.toggleAttribute("disabled",!0),setTimeout(()=>{e.iconEl.removeAttribute("disabled"),e.iconEl.innerHTML=icaxCopy()},2e3)}).catch(e=>{})}}};export{Coax,copy,css,html,javascript,markdown,typescript};
|