@codady/coax 0.0.4 → 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/dist/coax.cjs.js CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
2
  /*!
3
- * @since Last modified: 2026-1-12 14:46:3
3
+ * @since Last modified: 2026-1-12 15:14:48
4
4
  * @name Coax event management system.
5
- * @version 0.0.4
5
+ * @version 0.0.5
6
6
  * @author AXUI development team <3217728223@qq.com>
7
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}
@@ -278,7 +278,7 @@ class Coax extends HTMLElement {
278
278
  baseStylesEl; // Element for base styles
279
279
  themeStylesEl; // Element for theme styles
280
280
  dynamicStylesEl; // Element for dynamic styles
281
- highlightedCodeEl; // Element that holds the highlighted code
281
+ highlightEl; // Element that holds the highlighted code
282
282
  headerEl; // Header element (for code name, tools, etc.)
283
283
  codeNameEl; // Code name element (shows language or alias)
284
284
  codeToolsEl; // Code tools element (for interactive tools like copy)
@@ -289,6 +289,7 @@ class Coax extends HTMLElement {
289
289
  lastLineString = ''; // The last line's string
290
290
  speed = 5; // Speed of the typing effect (higher is slower)
291
291
  autoScroll = true; // Flag to enable/disable auto-scrolling
292
+ canListen = true; // Flag to enable/disable auto-scrolling
292
293
  constructor() {
293
294
  super();
294
295
  // Attach a Shadow DOM to the custom element
@@ -425,7 +426,7 @@ class Coax extends HTMLElement {
425
426
  <style id="theme-styles"></style>
426
427
  <div id="code-header"><span id="code-name">${this.alias}</span><div id="code-tools"></div></div>
427
428
  <div id="code-body">
428
- <pre><code id="highlight-code"></code></pre>
429
+ <pre><code id="highlight"></code></pre>
429
430
  </div>
430
431
  `;
431
432
  // Cache references to various elements
@@ -436,7 +437,7 @@ class Coax extends HTMLElement {
436
437
  this.codeNameEl = getEl('#code-name', this.shadowRoot);
437
438
  this.codeToolsEl = getEl('#code-tools', this.shadowRoot);
438
439
  this.codeBodyEl = getEl('#code-body', this.shadowRoot);
439
- this.highlightedCodeEl = getEl('#highlight-code', this.shadowRoot);
440
+ this.highlightEl = getEl('#highlight', this.shadowRoot);
440
441
  this.codeBodyEl.addEventListener('scroll', () => {
441
442
  let flag = this.codeBodyEl.scrollTop + this.codeBodyEl.clientHeight < this.codeBodyEl.scrollHeight;
442
443
  // Check if the user manually scrolled
@@ -471,7 +472,7 @@ class Coax extends HTMLElement {
471
472
  static get observedAttributes() { return ['lang', 'height', 'max-height', 'tools', 'speed']; }
472
473
 
473
474
  attributeChangedCallback(name, oldVal, newVal) {
474
- if (oldVal === newVal)
475
+ if (oldVal === newVal || !this.canListen)
475
476
  return;
476
477
  if (name === 'height' || name === 'max-height') {
477
478
  this.updateStyleByRegExp(name, newVal);
@@ -524,10 +525,10 @@ class Coax extends HTMLElement {
524
525
  createLineWrap(index, startIndex) {
525
526
  let dataIndex = 0;
526
527
  if (index == null && startIndex == null) {
527
- dataIndex = this.highlightedCodeEl.children.length;
528
+ dataIndex = this.highlightEl.children.length;
528
529
  }
529
530
  else {
530
- const start = startIndex || this.highlightedCodeEl.children.length;
531
+ const start = startIndex || this.highlightEl.children.length;
531
532
  dataIndex = start + index;
532
533
  }
533
534
  return createEl('div', { 'data-index': dataIndex }, '<div></div>');
@@ -542,7 +543,7 @@ class Coax extends HTMLElement {
542
543
  ;
543
544
 
544
545
  async highlight(newCode) {
545
- const config = Coax.languages.get(this.lang), startIndex = this.highlightedCodeEl.children.length,
546
+ const config = Coax.languages.get(this.lang), startIndex = this.highlightEl.children.length,
546
547
  // 将新源码按行分割
547
548
  newCodeLines = newCode ? newCode.split('\n') : [];
548
549
  //更新别名
@@ -559,7 +560,7 @@ class Coax extends HTMLElement {
559
560
  //标记完成
560
561
  lineWrap.completed = true;
561
562
  if (this.hasAttribute('speed')) {
562
- this.highlightedCodeEl.appendChild(lineWrap);
563
+ this.highlightEl.appendChild(lineWrap);
563
564
  //流式打字
564
565
  await typeWriter(lineString, {
565
566
  speed: this.speed,
@@ -573,7 +574,7 @@ class Coax extends HTMLElement {
573
574
  //直接打出
574
575
  this.getLineToFill(codeWrap, lineString, config);
575
576
  //
576
- this.highlightedCodeEl.appendChild(lineWrap);
577
+ this.highlightEl.appendChild(lineWrap);
577
578
  }
578
579
  }
579
580
  //滚动到最底部
@@ -635,18 +636,15 @@ class Coax extends HTMLElement {
635
636
  if (this._renderQueued)
636
637
  return;
637
638
  this._renderQueued = true;
638
- // 使用 requestAnimationFrame 将渲染推迟到下一帧
639
- requestAnimationFrame(async () => {
640
- this.clear();
641
- this.injectThemeStyles();
642
- //一次性渲染
643
- await this.highlight(code);
644
- this._renderQueued = false;
645
- });
639
+ this.clear();
640
+ this.injectThemeStyles();
641
+ //一次性渲染
642
+ this.highlight(code);
643
+ this._renderQueued = false;
646
644
  }
647
645
 
648
646
  clear() {
649
- this.highlightedCodeEl.innerHTML = this.source = this.lineString = '';
647
+ this.highlightEl.innerHTML = this.source = this.lineString = '';
650
648
  }
651
649
 
652
650
  async replace(newCode) {
@@ -662,7 +660,7 @@ class Coax extends HTMLElement {
662
660
  }
663
661
 
664
662
  getLastLine() {
665
- const lastChild = this.highlightedCodeEl.lastElementChild, lastLine = !lastChild || this.highlightedCodeEl.lastElementChild?.completed ?
663
+ const lastChild = this.highlightEl.lastElementChild, lastLine = !lastChild || this.highlightEl.lastElementChild?.completed ?
666
664
  this.createLineWrap() : lastChild;
667
665
  return {
668
666
  lineWrap: lastLine,
@@ -671,7 +669,7 @@ class Coax extends HTMLElement {
671
669
  }
672
670
 
673
671
  close() {
674
- const lineWrap = this.highlightedCodeEl.lastElementChild;
672
+ const lineWrap = this.highlightEl.lastElementChild;
675
673
  if (!lineWrap)
676
674
  return;
677
675
  lineWrap.completed = true;
@@ -683,7 +681,7 @@ class Coax extends HTMLElement {
683
681
  }
684
682
 
685
683
  open() {
686
- const lineWrap = this.highlightedCodeEl.lastElementChild;
684
+ const lineWrap = this.highlightEl.lastElementChild;
687
685
  if (!lineWrap)
688
686
  return;
689
687
  lineWrap.completed = false;
@@ -693,7 +691,7 @@ class Coax extends HTMLElement {
693
691
 
694
692
  stream(str, forceClose = false) {
695
693
  const { lineWrap, codeWrap } = this.getLastLine();
696
- this.highlightedCodeEl.appendChild(lineWrap);
694
+ this.highlightEl.appendChild(lineWrap);
697
695
  //汇集
698
696
  this.source += str;
699
697
  //如果没有遇到换行符号,也可以强制结束
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * @since Last modified: 2026-1-12 14:46:3
2
+ * @since Last modified: 2026-1-12 15:14:48
3
3
  * @name Coax event management system.
4
- * @version 0.0.4
4
+ * @version 0.0.5
5
5
  * @author AXUI development team <3217728223@qq.com>
6
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}
@@ -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
- "use strict";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;highlightedCodeEl;headerEl;codeNameEl;codeToolsEl;codeBodyEl;lang="plain";alias="Plain Text";lineString="";lastLineString="";speed=5;autoScroll=!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"></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){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&&("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.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||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.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;r.completed=!0,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=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,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)}getLastLine(){const e=this.highlightedCodeEl.lastElementChild,t=!e||this.highlightedCodeEl.lastElementChild?.completed?this.createLineWrap():e;return{lineWrap:t,codeWrap:t.lastElementChild}}close(){const e=this.highlightedCodeEl.lastElementChild;e&&(e.completed=!0,this.lastLineString=this.lineString,this.getLineToFill(e?.lastElementChild,this.lineString),this.lineString="")}open(){const e=this.highlightedCodeEl.lastElementChild;e&&(e.completed=!1,(e?.lastElementChild).textContent=this.lineString=this.lastLineString)}stream(e,t=!1){const{lineWrap:n,codeWrap:r}=this.getLastLine();this.highlightedCodeEl.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:/&lt;!--[\s\S]*?--&gt;/,light:"#999999",dark:"#6e7681"},{token:"doctype",pattern:/&lt;!DOCTYPE[\s\S]*?&gt;/i,light:"#6a737d",dark:"#8b949e"},{token:"tag",pattern:/&lt;\/?[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:/\/?&gt;/,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=>{})}}};exports.Coax=Coax,exports.copy=copy,exports.css=css,exports.html=html,exports.javascript=javascript,exports.markdown=markdown,exports.typescript=typescript;
15
+ "use strict";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:/&lt;!--[\s\S]*?--&gt;/,light:"#999999",dark:"#6e7681"},{token:"doctype",pattern:/&lt;!DOCTYPE[\s\S]*?&gt;/i,light:"#6a737d",dark:"#8b949e"},{token:"tag",pattern:/&lt;\/?[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:/\/?&gt;/,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=>{})}}};exports.Coax=Coax,exports.copy=copy,exports.css=css,exports.html=html,exports.javascript=javascript,exports.markdown=markdown,exports.typescript=typescript;
package/dist/coax.esm.js CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
2
  /*!
3
- * @since Last modified: 2026-1-12 14:46:3
3
+ * @since Last modified: 2026-1-12 15:14:48
4
4
  * @name Coax event management system.
5
- * @version 0.0.4
5
+ * @version 0.0.5
6
6
  * @author AXUI development team <3217728223@qq.com>
7
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}
@@ -276,7 +276,7 @@ class Coax extends HTMLElement {
276
276
  baseStylesEl; // Element for base styles
277
277
  themeStylesEl; // Element for theme styles
278
278
  dynamicStylesEl; // Element for dynamic styles
279
- highlightedCodeEl; // Element that holds the highlighted code
279
+ highlightEl; // Element that holds the highlighted code
280
280
  headerEl; // Header element (for code name, tools, etc.)
281
281
  codeNameEl; // Code name element (shows language or alias)
282
282
  codeToolsEl; // Code tools element (for interactive tools like copy)
@@ -287,6 +287,7 @@ class Coax extends HTMLElement {
287
287
  lastLineString = ''; // The last line's string
288
288
  speed = 5; // Speed of the typing effect (higher is slower)
289
289
  autoScroll = true; // Flag to enable/disable auto-scrolling
290
+ canListen = true; // Flag to enable/disable auto-scrolling
290
291
  constructor() {
291
292
  super();
292
293
  // Attach a Shadow DOM to the custom element
@@ -423,7 +424,7 @@ class Coax extends HTMLElement {
423
424
  <style id="theme-styles"></style>
424
425
  <div id="code-header"><span id="code-name">${this.alias}</span><div id="code-tools"></div></div>
425
426
  <div id="code-body">
426
- <pre><code id="highlight-code"></code></pre>
427
+ <pre><code id="highlight"></code></pre>
427
428
  </div>
428
429
  `;
429
430
  // Cache references to various elements
@@ -434,7 +435,7 @@ class Coax extends HTMLElement {
434
435
  this.codeNameEl = getEl('#code-name', this.shadowRoot);
435
436
  this.codeToolsEl = getEl('#code-tools', this.shadowRoot);
436
437
  this.codeBodyEl = getEl('#code-body', this.shadowRoot);
437
- this.highlightedCodeEl = getEl('#highlight-code', this.shadowRoot);
438
+ this.highlightEl = getEl('#highlight', this.shadowRoot);
438
439
  this.codeBodyEl.addEventListener('scroll', () => {
439
440
  let flag = this.codeBodyEl.scrollTop + this.codeBodyEl.clientHeight < this.codeBodyEl.scrollHeight;
440
441
  // Check if the user manually scrolled
@@ -469,7 +470,7 @@ class Coax extends HTMLElement {
469
470
  static get observedAttributes() { return ['lang', 'height', 'max-height', 'tools', 'speed']; }
470
471
 
471
472
  attributeChangedCallback(name, oldVal, newVal) {
472
- if (oldVal === newVal)
473
+ if (oldVal === newVal || !this.canListen)
473
474
  return;
474
475
  if (name === 'height' || name === 'max-height') {
475
476
  this.updateStyleByRegExp(name, newVal);
@@ -522,10 +523,10 @@ class Coax extends HTMLElement {
522
523
  createLineWrap(index, startIndex) {
523
524
  let dataIndex = 0;
524
525
  if (index == null && startIndex == null) {
525
- dataIndex = this.highlightedCodeEl.children.length;
526
+ dataIndex = this.highlightEl.children.length;
526
527
  }
527
528
  else {
528
- const start = startIndex || this.highlightedCodeEl.children.length;
529
+ const start = startIndex || this.highlightEl.children.length;
529
530
  dataIndex = start + index;
530
531
  }
531
532
  return createEl('div', { 'data-index': dataIndex }, '<div></div>');
@@ -540,7 +541,7 @@ class Coax extends HTMLElement {
540
541
  ;
541
542
 
542
543
  async highlight(newCode) {
543
- const config = Coax.languages.get(this.lang), startIndex = this.highlightedCodeEl.children.length,
544
+ const config = Coax.languages.get(this.lang), startIndex = this.highlightEl.children.length,
544
545
  // 将新源码按行分割
545
546
  newCodeLines = newCode ? newCode.split('\n') : [];
546
547
  //更新别名
@@ -557,7 +558,7 @@ class Coax extends HTMLElement {
557
558
  //标记完成
558
559
  lineWrap.completed = true;
559
560
  if (this.hasAttribute('speed')) {
560
- this.highlightedCodeEl.appendChild(lineWrap);
561
+ this.highlightEl.appendChild(lineWrap);
561
562
  //流式打字
562
563
  await typeWriter(lineString, {
563
564
  speed: this.speed,
@@ -571,7 +572,7 @@ class Coax extends HTMLElement {
571
572
  //直接打出
572
573
  this.getLineToFill(codeWrap, lineString, config);
573
574
  //
574
- this.highlightedCodeEl.appendChild(lineWrap);
575
+ this.highlightEl.appendChild(lineWrap);
575
576
  }
576
577
  }
577
578
  //滚动到最底部
@@ -633,18 +634,15 @@ class Coax extends HTMLElement {
633
634
  if (this._renderQueued)
634
635
  return;
635
636
  this._renderQueued = true;
636
- // 使用 requestAnimationFrame 将渲染推迟到下一帧
637
- requestAnimationFrame(async () => {
638
- this.clear();
639
- this.injectThemeStyles();
640
- //一次性渲染
641
- await this.highlight(code);
642
- this._renderQueued = false;
643
- });
637
+ this.clear();
638
+ this.injectThemeStyles();
639
+ //一次性渲染
640
+ this.highlight(code);
641
+ this._renderQueued = false;
644
642
  }
645
643
 
646
644
  clear() {
647
- this.highlightedCodeEl.innerHTML = this.source = this.lineString = '';
645
+ this.highlightEl.innerHTML = this.source = this.lineString = '';
648
646
  }
649
647
 
650
648
  async replace(newCode) {
@@ -660,7 +658,7 @@ class Coax extends HTMLElement {
660
658
  }
661
659
 
662
660
  getLastLine() {
663
- const lastChild = this.highlightedCodeEl.lastElementChild, lastLine = !lastChild || this.highlightedCodeEl.lastElementChild?.completed ?
661
+ const lastChild = this.highlightEl.lastElementChild, lastLine = !lastChild || this.highlightEl.lastElementChild?.completed ?
664
662
  this.createLineWrap() : lastChild;
665
663
  return {
666
664
  lineWrap: lastLine,
@@ -669,7 +667,7 @@ class Coax extends HTMLElement {
669
667
  }
670
668
 
671
669
  close() {
672
- const lineWrap = this.highlightedCodeEl.lastElementChild;
670
+ const lineWrap = this.highlightEl.lastElementChild;
673
671
  if (!lineWrap)
674
672
  return;
675
673
  lineWrap.completed = true;
@@ -681,7 +679,7 @@ class Coax extends HTMLElement {
681
679
  }
682
680
 
683
681
  open() {
684
- const lineWrap = this.highlightedCodeEl.lastElementChild;
682
+ const lineWrap = this.highlightEl.lastElementChild;
685
683
  if (!lineWrap)
686
684
  return;
687
685
  lineWrap.completed = false;
@@ -691,7 +689,7 @@ class Coax extends HTMLElement {
691
689
 
692
690
  stream(str, forceClose = false) {
693
691
  const { lineWrap, codeWrap } = this.getLastLine();
694
- this.highlightedCodeEl.appendChild(lineWrap);
692
+ this.highlightEl.appendChild(lineWrap);
695
693
  //汇集
696
694
  this.source += str;
697
695
  //如果没有遇到换行符号,也可以强制结束
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * @since Last modified: 2026-1-12 14:46:3
2
+ * @since Last modified: 2026-1-12 15:14:48
3
3
  * @name Coax event management system.
4
- * @version 0.0.4
4
+ * @version 0.0.5
5
5
  * @author AXUI development team <3217728223@qq.com>
6
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}
@@ -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 Coax extends HTMLElement{static languages=new Map;static tools=[];source;_renderQueued=!1;baseStylesEl;themeStylesEl;dynamicStylesEl;highlightedCodeEl;headerEl;codeNameEl;codeToolsEl;codeBodyEl;lang="plain";alias="Plain Text";lineString="";lastLineString="";speed=5;autoScroll=!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"></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){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&&("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.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||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.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;r.completed=!0,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=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,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)}getLastLine(){const e=this.highlightedCodeEl.lastElementChild,t=!e||this.highlightedCodeEl.lastElementChild?.completed?this.createLineWrap():e;return{lineWrap:t,codeWrap:t.lastElementChild}}close(){const e=this.highlightedCodeEl.lastElementChild;e&&(e.completed=!0,this.lastLineString=this.lineString,this.getLineToFill(e?.lastElementChild,this.lineString),this.lineString="")}open(){const e=this.highlightedCodeEl.lastElementChild;e&&(e.completed=!1,(e?.lastElementChild).textContent=this.lineString=this.lastLineString)}stream(e,t=!1){const{lineWrap:n,codeWrap:r}=this.getLastLine();this.highlightedCodeEl.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:/&lt;!--[\s\S]*?--&gt;/,light:"#999999",dark:"#6e7681"},{token:"doctype",pattern:/&lt;!DOCTYPE[\s\S]*?&gt;/i,light:"#6a737d",dark:"#8b949e"},{token:"tag",pattern:/&lt;\/?[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:/\/?&gt;/,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};
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:/&lt;!--[\s\S]*?--&gt;/,light:"#999999",dark:"#6e7681"},{token:"doctype",pattern:/&lt;!DOCTYPE[\s\S]*?&gt;/i,light:"#6a737d",dark:"#8b949e"},{token:"tag",pattern:/&lt;\/?[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:/\/?&gt;/,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};
package/dist/coax.umd.js CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
2
  /*!
3
- * @since Last modified: 2026-1-12 14:46:3
3
+ * @since Last modified: 2026-1-12 15:14:48
4
4
  * @name Coax event management system.
5
- * @version 0.0.4
5
+ * @version 0.0.5
6
6
  * @author AXUI development team <3217728223@qq.com>
7
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}
@@ -446,7 +446,7 @@
446
446
  baseStylesEl; // Element for base styles
447
447
  themeStylesEl; // Element for theme styles
448
448
  dynamicStylesEl; // Element for dynamic styles
449
- highlightedCodeEl; // Element that holds the highlighted code
449
+ highlightEl; // Element that holds the highlighted code
450
450
  headerEl; // Header element (for code name, tools, etc.)
451
451
  codeNameEl; // Code name element (shows language or alias)
452
452
  codeToolsEl; // Code tools element (for interactive tools like copy)
@@ -457,6 +457,7 @@
457
457
  lastLineString = ''; // The last line's string
458
458
  speed = 5; // Speed of the typing effect (higher is slower)
459
459
  autoScroll = true; // Flag to enable/disable auto-scrolling
460
+ canListen = true; // Flag to enable/disable auto-scrolling
460
461
  constructor() {
461
462
  super();
462
463
  // Attach a Shadow DOM to the custom element
@@ -593,7 +594,7 @@
593
594
  <style id="theme-styles"></style>
594
595
  <div id="code-header"><span id="code-name">${this.alias}</span><div id="code-tools"></div></div>
595
596
  <div id="code-body">
596
- <pre><code id="highlight-code"></code></pre>
597
+ <pre><code id="highlight"></code></pre>
597
598
  </div>
598
599
  `;
599
600
  // Cache references to various elements
@@ -604,7 +605,7 @@
604
605
  this.codeNameEl = getEl('#code-name', this.shadowRoot);
605
606
  this.codeToolsEl = getEl('#code-tools', this.shadowRoot);
606
607
  this.codeBodyEl = getEl('#code-body', this.shadowRoot);
607
- this.highlightedCodeEl = getEl('#highlight-code', this.shadowRoot);
608
+ this.highlightEl = getEl('#highlight', this.shadowRoot);
608
609
  this.codeBodyEl.addEventListener('scroll', () => {
609
610
  let flag = this.codeBodyEl.scrollTop + this.codeBodyEl.clientHeight < this.codeBodyEl.scrollHeight;
610
611
  // Check if the user manually scrolled
@@ -639,7 +640,7 @@
639
640
  static get observedAttributes() { return ['lang', 'height', 'max-height', 'tools', 'speed']; }
640
641
 
641
642
  attributeChangedCallback(name, oldVal, newVal) {
642
- if (oldVal === newVal)
643
+ if (oldVal === newVal || !this.canListen)
643
644
  return;
644
645
  if (name === 'height' || name === 'max-height') {
645
646
  this.updateStyleByRegExp(name, newVal);
@@ -692,10 +693,10 @@
692
693
  createLineWrap(index, startIndex) {
693
694
  let dataIndex = 0;
694
695
  if (index == null && startIndex == null) {
695
- dataIndex = this.highlightedCodeEl.children.length;
696
+ dataIndex = this.highlightEl.children.length;
696
697
  }
697
698
  else {
698
- const start = startIndex || this.highlightedCodeEl.children.length;
699
+ const start = startIndex || this.highlightEl.children.length;
699
700
  dataIndex = start + index;
700
701
  }
701
702
  return createEl('div', { 'data-index': dataIndex }, '<div></div>');
@@ -710,7 +711,7 @@
710
711
  ;
711
712
 
712
713
  async highlight(newCode) {
713
- const config = Coax.languages.get(this.lang), startIndex = this.highlightedCodeEl.children.length,
714
+ const config = Coax.languages.get(this.lang), startIndex = this.highlightEl.children.length,
714
715
  // 将新源码按行分割
715
716
  newCodeLines = newCode ? newCode.split('\n') : [];
716
717
  //更新别名
@@ -727,7 +728,7 @@
727
728
  //标记完成
728
729
  lineWrap.completed = true;
729
730
  if (this.hasAttribute('speed')) {
730
- this.highlightedCodeEl.appendChild(lineWrap);
731
+ this.highlightEl.appendChild(lineWrap);
731
732
  //流式打字
732
733
  await typeWriter(lineString, {
733
734
  speed: this.speed,
@@ -741,7 +742,7 @@
741
742
  //直接打出
742
743
  this.getLineToFill(codeWrap, lineString, config);
743
744
  //
744
- this.highlightedCodeEl.appendChild(lineWrap);
745
+ this.highlightEl.appendChild(lineWrap);
745
746
  }
746
747
  }
747
748
  //滚动到最底部
@@ -803,18 +804,15 @@
803
804
  if (this._renderQueued)
804
805
  return;
805
806
  this._renderQueued = true;
806
- // 使用 requestAnimationFrame 将渲染推迟到下一帧
807
- requestAnimationFrame(async () => {
808
- this.clear();
809
- this.injectThemeStyles();
810
- //一次性渲染
811
- await this.highlight(code);
812
- this._renderQueued = false;
813
- });
807
+ this.clear();
808
+ this.injectThemeStyles();
809
+ //一次性渲染
810
+ this.highlight(code);
811
+ this._renderQueued = false;
814
812
  }
815
813
 
816
814
  clear() {
817
- this.highlightedCodeEl.innerHTML = this.source = this.lineString = '';
815
+ this.highlightEl.innerHTML = this.source = this.lineString = '';
818
816
  }
819
817
 
820
818
  async replace(newCode) {
@@ -830,7 +828,7 @@
830
828
  }
831
829
 
832
830
  getLastLine() {
833
- const lastChild = this.highlightedCodeEl.lastElementChild, lastLine = !lastChild || this.highlightedCodeEl.lastElementChild?.completed ?
831
+ const lastChild = this.highlightEl.lastElementChild, lastLine = !lastChild || this.highlightEl.lastElementChild?.completed ?
834
832
  this.createLineWrap() : lastChild;
835
833
  return {
836
834
  lineWrap: lastLine,
@@ -839,7 +837,7 @@
839
837
  }
840
838
 
841
839
  close() {
842
- const lineWrap = this.highlightedCodeEl.lastElementChild;
840
+ const lineWrap = this.highlightEl.lastElementChild;
843
841
  if (!lineWrap)
844
842
  return;
845
843
  lineWrap.completed = true;
@@ -851,7 +849,7 @@
851
849
  }
852
850
 
853
851
  open() {
854
- const lineWrap = this.highlightedCodeEl.lastElementChild;
852
+ const lineWrap = this.highlightEl.lastElementChild;
855
853
  if (!lineWrap)
856
854
  return;
857
855
  lineWrap.completed = false;
@@ -861,7 +859,7 @@
861
859
 
862
860
  stream(str, forceClose = false) {
863
861
  const { lineWrap, codeWrap } = this.getLastLine();
864
- this.highlightedCodeEl.appendChild(lineWrap);
862
+ this.highlightEl.appendChild(lineWrap);
865
863
  //汇集
866
864
  this.source += str;
867
865
  //如果没有遇到换行符号,也可以强制结束
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * @since Last modified: 2026-1-12 14:46:3
2
+ * @since Last modified: 2026-1-12 15:14:48
3
3
  * @name Coax event management system.
4
- * @version 0.0.4
4
+ * @version 0.0.5
5
5
  * @author AXUI development team <3217728223@qq.com>
6
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}
@@ -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
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).coax=t()}(this,function(){"use strict";const e="ax",trim$1=(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," ")}},wrap=(e,t,n=!1,i)=>{const r=i?.size||"1em",o=i?.color||"currentColor",a=i?.thickness||2,l=i?.classes?(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)})(i.classes).join(" "):"",s=t.name.replace(/([A-Z])/g,"-$1").toLowerCase();return`<svg xmlns="http://www.w3.org/2000/svg" width="${r}" height="${r}" viewBox="0 0 24 24" fill="none" stroke="${o}"\n stroke-width="${a}" stroke-linecap="round" stroke-linejoin="round" class="${s} ${l}">\n ${n?((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`)(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),t={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=>{})}}},typeWriter=(e,t)=>{const n=t.speed||100;return new Promise(i=>{t?.onBeforeType?.(e);let r=0;const o=setInterval(()=>{if(r<e.length){const n=e.charAt(r),i=e.substring(0,r+1);t?.onDuringType?.(n,i),r++}else clearInterval(o),i(e),t?.onAfterType?.(e)},n)})},trim=(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=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)},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),i=getDataType(t),r=i.includes("HTML")||"ShadowRoot"===i?t:document.querySelector(t),o=r&&r instanceof HTMLTemplateElement?r.content:r,a=null;if(e)if(n.includes("HTML"))a=e;else if("String"===n)try{a=(o||document).querySelector(e.trim())}catch{a=null}return a},createEl=(e,t,n)=>{let i=(e=e||"div").toUpperCase().trim(),r=document.createElement(i),o=getDataType(t);if(t&&"Object"===o)for(let e in t)t.hasOwnProperty(e)&&r.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"===i)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)})(r,n),r},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},n="rep",createTools=t=>{const i=createEl("span",{class:`${e}-box-tools`}),renderFn=e=>{const t={},i=e.extendable?`<i ${n}="arrow"></i>`:"",r=(e.icon?`<i ${n}="icon">${e.icon}</i>`:"")+(e.disk?`<i ${n}="disk"><img src="${e.disk}"/></i>`:"")+(e.cube?`<i ${n}="cube"><img src="${e.cube}"/></i>`:"")+(e.image?`<i ${n}="image"><img src="${e.image}"/></i>`:"")+(e.label?`<i ${n}="label">${e.label}</i>`:"")+i;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(`[${n}="icon"]`),e.cubeEl=e.wrapEl.querySelector(`[${n}="cube"]`),e.diskEl=e.wrapEl.querySelector(`[${n}="disk"]`),e.imageEl=e.wrapEl.querySelector(`[${n}="image"]`),e.labelEl=e.wrapEl.querySelector(`[${n}="label"]`),!isEmpty(e.classes)&&((e,t)=>{const n=getEl(e),i=parseClasses(t);n&&0!==i.length&&i.forEach(e=>{n.classList.add(e)})})(e.wrapEl,e.classes),!isEmpty(e.styles)&&(e.wrapEl.style.cssText+=e.styles)};for(let e of t)renderFn(e),i.appendChild(e.wrapEl),e?.action?.(e);return i};class Coax extends HTMLElement{static languages=new Map;static tools=[];source;_renderQueued=!1;baseStylesEl;themeStylesEl;dynamicStylesEl;highlightedCodeEl;headerEl;codeNameEl;codeToolsEl;codeBodyEl;lang="plain";alias="Plain Text";lineString="";lastLineString="";speed=5;autoScroll=!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(--${e}-code-font-size,var(--font-size));\n display: block; \n box-sizing:border-box;\n background:var(--${e}-code-background-color,var(--background));\n color:var(--${e}-code-color,var(--color-code));\n border:var(--${e}-code-border-width,var(--border-width)) var(--${e}-code-border-style,var(--border-style)) var(--${e}-code-border-color,var(--border-color));\n transition: border-color 0.3s ease,color 0.3s ease; \n border-radius: var(--${e}-code-radius,var(--radius));\n }\n #code-header{\n line-height:calc(var(--${e}-code-line-height,var(--line-height))*1.5);\n padding-inline-start:var(--${e}-code-padding,var(--padding));\n display:flex;\n \n >:first-child{\n flex:auto;\n }\n }\n #code-body{\n padding: var(--${e}-code-padding,var(--padding)) 0;\n height:var(--${e}-code-height,var(--height));\n max-height:var(--${e}-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(--${e}-code-padding,var(--padding));\n line-height: var(--${e}-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(--${e}-code-index-width,2em);\n margin-inline-end:var(--${e}-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 .${e}-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){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&&("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(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(t,n){if(!(n=n||Coax.languages.get(this.lang)))return t;const i=this.getCssPrefix(n),r=new RegExp(n.rules.map(e=>`(${e.pattern.source})`).join("|"),"g");return t.replace(r,(t,...r)=>{const o=r.findIndex(e=>void 0!==e);return-1!==o&&n.rules[o]?`<span class="${e}-${i}-${n.rules[o].token}">${t}</span>`:t})}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||Coax.languages.get(this.lang);let i=this.getHighLightString(t,n);e.innerHTML=i}async highlight(e){const t=Coax.languages.get(this.lang),n=this.highlightedCodeEl.children.length,i=e?e.split("\n"):[];if(this.updateName(t),!i.length)return!0;for(let[e,r]of i.entries()){if(!r.trim()&&this.hasAttribute("sanitized"))continue;const i=this.createLineWrap(e,n),o=i.lastElementChild;i.completed=!0,this.hasAttribute("speed")?(this.highlightedCodeEl.appendChild(i),await typeWriter(r,{speed:this.speed,onDuringType:(e,t)=>{o.innerHTML=t}}),this.getLineToFill(o,r,t)):(this.getLineToFill(o,r,t),this.highlightedCodeEl.appendChild(i))}return this.autoScrollCode(),!0}autoScrollCode(){this.autoScroll&&(this.codeBodyEl.scrollTop=this.codeBodyEl.scrollHeight)}injectThemeStyles(){const t=Coax.languages.get(this.lang);if(!t)return;let n=this.getCssPrefix(t),i=t.rules.map(t=>`\n .${e}-${n}-${t.token} { color: var(--${e}-${n}-${t.token}${t.light?","+t.light:""});}`).join("\n"),r="",o="";r+=':host([scheme="dark"]){',r+=t.rules.map(t=>"\n "+(t.light?`\n .${e}-${n}-${t.token} {color: var(--${e}-${n}-${t.token},${t.dark});}`:"")).join("\n"),r+="}",o="@media (prefers-color-scheme: dark){\n :host{\n ",o+=t.rules.map(t=>`\n ${t.light?`\n .${e}-${n}-${t.token} { color: var(--${e}-${n}-${t.token},${t.dark}); }`:""} `).join("\n"),o+="}",this.dynamicStylesEl.textContent=i+r+o,t?.themeStyles&&(this.themeStylesEl.textContent=t.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)}getLastLine(){const e=this.highlightedCodeEl.lastElementChild,t=!e||this.highlightedCodeEl.lastElementChild?.completed?this.createLineWrap():e;return{lineWrap:t,codeWrap:t.lastElementChild}}close(){const e=this.highlightedCodeEl.lastElementChild;e&&(e.completed=!0,this.lastLineString=this.lineString,this.getLineToFill(e?.lastElementChild,this.lineString),this.lineString="")}open(){const e=this.highlightedCodeEl.lastElementChild;e&&(e.completed=!1,(e?.lastElementChild).textContent=this.lineString=this.lastLineString)}stream(e,t=!1){const{lineWrap:n,codeWrap:i}=this.getLastLine();this.highlightedCodeEl.appendChild(n),this.source+=e,t||e.startsWith("\n")||e.endsWith("\n")?this.close():(i.innerHTML+=e,this.lineString+=e),this.autoScrollCode()}}return Coax.register("css",{alias:"CSS",rules:[{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"}]}),Coax.register("html",{alias:"HTML",rules:[{token:"comment",pattern:/&lt;!--[\s\S]*?--&gt;/,light:"#999999",dark:"#6e7681"},{token:"doctype",pattern:/&lt;!DOCTYPE[\s\S]*?&gt;/i,light:"#6a737d",dark:"#8b949e"},{token:"tag",pattern:/&lt;\/?[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:/\/?&gt;/,light:"#24292e",dark:"#c9d1d9"}]}),Coax.register("js",{alias:"Javascript",rules:[{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"}]}),Coax.register("ts",{alias:"Typescript",rules:[{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"}]}),Coax.register("md",{alias:"Markdown",rules:[{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"}]}),Coax.addTools([t]),customElements.define(`${e}-code`,Coax),Coax});
15
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).coax=t()}(this,function(){"use strict";const e="ax",trim$1=(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," ")}},wrap=(e,t,n=!1,i)=>{const r=i?.size||"1em",o=i?.color||"currentColor",a=i?.thickness||2,l=i?.classes?(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)})(i.classes).join(" "):"",s=t.name.replace(/([A-Z])/g,"-$1").toLowerCase();return`<svg xmlns="http://www.w3.org/2000/svg" width="${r}" height="${r}" viewBox="0 0 24 24" fill="none" stroke="${o}"\n stroke-width="${a}" stroke-linecap="round" stroke-linejoin="round" class="${s} ${l}">\n ${n?((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`)(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),t={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=>{})}}},typeWriter=(e,t)=>{const n=t.speed||100;return new Promise(i=>{t?.onBeforeType?.(e);let r=0;const o=setInterval(()=>{if(r<e.length){const n=e.charAt(r),i=e.substring(0,r+1);t?.onDuringType?.(n,i),r++}else clearInterval(o),i(e),t?.onAfterType?.(e)},n)})},trim=(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=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)},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),i=getDataType(t),r=i.includes("HTML")||"ShadowRoot"===i?t:document.querySelector(t),o=r&&r instanceof HTMLTemplateElement?r.content:r,a=null;if(e)if(n.includes("HTML"))a=e;else if("String"===n)try{a=(o||document).querySelector(e.trim())}catch{a=null}return a},createEl=(e,t,n)=>{let i=(e=e||"div").toUpperCase().trim(),r=document.createElement(i),o=getDataType(t);if(t&&"Object"===o)for(let e in t)t.hasOwnProperty(e)&&r.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"===i)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)})(r,n),r},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},n="rep",createTools=t=>{const i=createEl("span",{class:`${e}-box-tools`}),renderFn=e=>{const t={},i=e.extendable?`<i ${n}="arrow"></i>`:"",r=(e.icon?`<i ${n}="icon">${e.icon}</i>`:"")+(e.disk?`<i ${n}="disk"><img src="${e.disk}"/></i>`:"")+(e.cube?`<i ${n}="cube"><img src="${e.cube}"/></i>`:"")+(e.image?`<i ${n}="image"><img src="${e.image}"/></i>`:"")+(e.label?`<i ${n}="label">${e.label}</i>`:"")+i;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(`[${n}="icon"]`),e.cubeEl=e.wrapEl.querySelector(`[${n}="cube"]`),e.diskEl=e.wrapEl.querySelector(`[${n}="disk"]`),e.imageEl=e.wrapEl.querySelector(`[${n}="image"]`),e.labelEl=e.wrapEl.querySelector(`[${n}="label"]`),!isEmpty(e.classes)&&((e,t)=>{const n=getEl(e),i=parseClasses(t);n&&0!==i.length&&i.forEach(e=>{n.classList.add(e)})})(e.wrapEl,e.classes),!isEmpty(e.styles)&&(e.wrapEl.style.cssText+=e.styles)};for(let e of t)renderFn(e),i.appendChild(e.wrapEl),e?.action?.(e);return i};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(--${e}-code-font-size,var(--font-size));\n display: block; \n box-sizing:border-box;\n background:var(--${e}-code-background-color,var(--background));\n color:var(--${e}-code-color,var(--color-code));\n border:var(--${e}-code-border-width,var(--border-width)) var(--${e}-code-border-style,var(--border-style)) var(--${e}-code-border-color,var(--border-color));\n transition: border-color 0.3s ease,color 0.3s ease; \n border-radius: var(--${e}-code-radius,var(--radius));\n }\n #code-header{\n line-height:calc(var(--${e}-code-line-height,var(--line-height))*1.5);\n padding-inline-start:var(--${e}-code-padding,var(--padding));\n display:flex;\n \n >:first-child{\n flex:auto;\n }\n }\n #code-body{\n padding: var(--${e}-code-padding,var(--padding)) 0;\n height:var(--${e}-code-height,var(--height));\n max-height:var(--${e}-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(--${e}-code-padding,var(--padding));\n line-height: var(--${e}-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(--${e}-code-index-width,2em);\n margin-inline-end:var(--${e}-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 .${e}-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(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(t,n){if(!(n=n||Coax.languages.get(this.lang)))return t;const i=this.getCssPrefix(n),r=new RegExp(n.rules.map(e=>`(${e.pattern.source})`).join("|"),"g");return t.replace(r,(t,...r)=>{const o=r.findIndex(e=>void 0!==e);return-1!==o&&n.rules[o]?`<span class="${e}-${i}-${n.rules[o].token}">${t}</span>`:t})}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 i=this.getHighLightString(t,n);e.innerHTML=i}async highlight(e){const t=Coax.languages.get(this.lang),n=this.highlightEl.children.length,i=e?e.split("\n"):[];if(this.updateName(t),!i.length)return!0;for(let[e,r]of i.entries()){if(!r.trim()&&this.hasAttribute("sanitized"))continue;const i=this.createLineWrap(e,n),o=i.lastElementChild;i.completed=!0,this.hasAttribute("speed")?(this.highlightEl.appendChild(i),await typeWriter(r,{speed:this.speed,onDuringType:(e,t)=>{o.innerHTML=t}}),this.getLineToFill(o,r,t)):(this.getLineToFill(o,r,t),this.highlightEl.appendChild(i))}return this.autoScrollCode(),!0}autoScrollCode(){this.autoScroll&&(this.codeBodyEl.scrollTop=this.codeBodyEl.scrollHeight)}injectThemeStyles(){const t=Coax.languages.get(this.lang);if(!t)return;let n=this.getCssPrefix(t),i=t.rules.map(t=>`\n .${e}-${n}-${t.token} { color: var(--${e}-${n}-${t.token}${t.light?","+t.light:""});}`).join("\n"),r="",o="";r+=':host([scheme="dark"]){',r+=t.rules.map(t=>"\n "+(t.light?`\n .${e}-${n}-${t.token} {color: var(--${e}-${n}-${t.token},${t.dark});}`:"")).join("\n"),r+="}",o="@media (prefers-color-scheme: dark){\n :host{\n ",o+=t.rules.map(t=>`\n ${t.light?`\n .${e}-${n}-${t.token} { color: var(--${e}-${n}-${t.token},${t.dark}); }`:""} `).join("\n"),o+="}",this.dynamicStylesEl.textContent=i+r+o,t?.themeStyles&&(this.themeStylesEl.textContent=t.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:i}=this.getLastLine();this.highlightEl.appendChild(n),this.source+=e,t||e.startsWith("\n")||e.endsWith("\n")?this.close():(i.innerHTML+=e,this.lineString+=e),this.autoScrollCode()}}return Coax.register("css",{alias:"CSS",rules:[{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"}]}),Coax.register("html",{alias:"HTML",rules:[{token:"comment",pattern:/&lt;!--[\s\S]*?--&gt;/,light:"#999999",dark:"#6e7681"},{token:"doctype",pattern:/&lt;!DOCTYPE[\s\S]*?&gt;/i,light:"#6a737d",dark:"#8b949e"},{token:"tag",pattern:/&lt;\/?[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:/\/?&gt;/,light:"#24292e",dark:"#c9d1d9"}]}),Coax.register("js",{alias:"Javascript",rules:[{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"}]}),Coax.register("ts",{alias:"Typescript",rules:[{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"}]}),Coax.register("md",{alias:"Markdown",rules:[{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"}]}),Coax.addTools([t]),customElements.define(`${e}-code`,Coax),Coax});
@@ -241,7 +241,7 @@
241
241
  builtin: { light: '#e36209', dark: '#ffa657' }, // 橙色(内置变量)
242
242
  number: { light: '#005cc5', dark: '#79c0ff' }, // 蓝色(数值)
243
243
  comment: { light: '#6a737d', dark: '#8b949e' }, // 灰色(注释)
244
- op: { light: '#069598', dark: '#56b6c2'} // 青色(将运算符与关键字区分开)
244
+ op: { light: '#069598', dark: '#56b6c2' } // 青色(将运算符与关键字区分开)
245
245
  }
246
246
  },
247
247
  ts: {
@@ -257,7 +257,7 @@
257
257
  number: { light: '#005cc5', dark: '#79c0ff' },
258
258
  string: { light: '#032f62', dark: '#98c379' },
259
259
  comment: { light: '#6a737d', dark: '#8b949e' },
260
- op: { light: '#089ba6', dark: '#79c0ff'}
260
+ op: { light: '#089ba6', dark: '#79c0ff' }
261
261
  }
262
262
  },
263
263
  css: {
@@ -380,9 +380,8 @@
380
380
  const langConfig = config[currentLang];
381
381
  let html = langConfig.code
382
382
  .replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
383
-
384
- codeEl.replaceCode(html);
385
383
  codeEl.setAttribute('lang', currentLang);
384
+ codeEl.replace(html);
386
385
  }
387
386
 
388
387
  function toggleDarkMode() {
@@ -1,21 +1,17 @@
1
1
  <!DOCTYPE html>
2
- <html lang="zh-CN">
2
+ <html>
3
3
 
4
4
  <head>
5
5
  <meta charset="UTF-8">
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <title>Coax 代码高亮插件</title>
7
+ <title>Coax</title>
8
8
  <style>
9
- /* 白天模式变量 */
10
- :root {
11
-
12
- }
13
9
  </style>
14
10
 
15
11
  </head>
16
12
 
17
13
  <body>
18
- <ax-code streaming tools="copy" indexed lang="js">
14
+ <ax-code speed="10" tools="copy" indexed lang="js">
19
15
  <code>
20
16
  /**
21
17
  * Simple animation function
@@ -38,8 +34,6 @@ async function animate(element, duration) {
38
34
  </code>
39
35
  </ax-code>
40
36
 
41
-
42
-
43
37
  <script src="../dist/coax.umd.js" type='text/javascript'></script>
44
38
  <script type='text/javascript'>
45
39
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codady/coax",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Last modified: 2026/01/12 14:09:42
2
+ * Last modified: 2026/01/12 15:11:21
3
3
  * Coax - A custom web component for syntax highlighting, code display, and interactive features
4
4
  *
5
5
  */
@@ -19,7 +19,7 @@ class Coax extends HTMLElement {
19
19
  baseStylesEl; // Element for base styles
20
20
  themeStylesEl; // Element for theme styles
21
21
  dynamicStylesEl; // Element for dynamic styles
22
- highlightedCodeEl; // Element that holds the highlighted code
22
+ highlightEl; // Element that holds the highlighted code
23
23
  headerEl; // Header element (for code name, tools, etc.)
24
24
  codeNameEl; // Code name element (shows language or alias)
25
25
  codeToolsEl; // Code tools element (for interactive tools like copy)
@@ -30,6 +30,7 @@ class Coax extends HTMLElement {
30
30
  lastLineString = ''; // The last line's string
31
31
  speed = 5; // Speed of the typing effect (higher is slower)
32
32
  autoScroll = true; // Flag to enable/disable auto-scrolling
33
+ canListen = true; // Flag to enable/disable auto-scrolling
33
34
  constructor() {
34
35
  super();
35
36
  // Attach a Shadow DOM to the custom element
@@ -166,7 +167,7 @@ class Coax extends HTMLElement {
166
167
  <style id="theme-styles"></style>
167
168
  <div id="code-header"><span id="code-name">${this.alias}</span><div id="code-tools"></div></div>
168
169
  <div id="code-body">
169
- <pre><code id="highlight-code"></code></pre>
170
+ <pre><code id="highlight"></code></pre>
170
171
  </div>
171
172
  `;
172
173
  // Cache references to various elements
@@ -177,7 +178,7 @@ class Coax extends HTMLElement {
177
178
  this.codeNameEl = getEl('#code-name', this.shadowRoot);
178
179
  this.codeToolsEl = getEl('#code-tools', this.shadowRoot);
179
180
  this.codeBodyEl = getEl('#code-body', this.shadowRoot);
180
- this.highlightedCodeEl = getEl('#highlight-code', this.shadowRoot);
181
+ this.highlightEl = getEl('#highlight', this.shadowRoot);
181
182
  this.codeBodyEl.addEventListener('scroll', () => {
182
183
  let flag = this.codeBodyEl.scrollTop + this.codeBodyEl.clientHeight < this.codeBodyEl.scrollHeight;
183
184
  // Check if the user manually scrolled
@@ -231,7 +232,7 @@ class Coax extends HTMLElement {
231
232
  * @param newVal - The new value of the attribute.
232
233
  */
233
234
  attributeChangedCallback(name, oldVal, newVal) {
234
- if (oldVal === newVal)
235
+ if (oldVal === newVal || !this.canListen)
235
236
  return;
236
237
  if (name === 'height' || name === 'max-height') {
237
238
  this.updateStyleByRegExp(name, newVal);
@@ -302,10 +303,10 @@ class Coax extends HTMLElement {
302
303
  createLineWrap(index, startIndex) {
303
304
  let dataIndex = 0;
304
305
  if (index == null && startIndex == null) {
305
- dataIndex = this.highlightedCodeEl.children.length;
306
+ dataIndex = this.highlightEl.children.length;
306
307
  }
307
308
  else {
308
- const start = startIndex || this.highlightedCodeEl.children.length;
309
+ const start = startIndex || this.highlightEl.children.length;
309
310
  dataIndex = start + index;
310
311
  }
311
312
  return createEl('div', { 'data-index': dataIndex }, '<div></div>');
@@ -328,7 +329,7 @@ class Coax extends HTMLElement {
328
329
  * @param newCode - The new source code to highlight and append.
329
330
  */
330
331
  async highlight(newCode) {
331
- const config = Coax.languages.get(this.lang), startIndex = this.highlightedCodeEl.children.length,
332
+ const config = Coax.languages.get(this.lang), startIndex = this.highlightEl.children.length,
332
333
  // 将新源码按行分割
333
334
  newCodeLines = newCode ? newCode.split('\n') : [];
334
335
  //更新别名
@@ -345,7 +346,7 @@ class Coax extends HTMLElement {
345
346
  //标记完成
346
347
  lineWrap.completed = true;
347
348
  if (this.hasAttribute('speed')) {
348
- this.highlightedCodeEl.appendChild(lineWrap);
349
+ this.highlightEl.appendChild(lineWrap);
349
350
  //流式打字
350
351
  await typeWriter(lineString, {
351
352
  speed: this.speed,
@@ -359,7 +360,7 @@ class Coax extends HTMLElement {
359
360
  //直接打出
360
361
  this.getLineToFill(codeWrap, lineString, config);
361
362
  //
362
- this.highlightedCodeEl.appendChild(lineWrap);
363
+ this.highlightEl.appendChild(lineWrap);
363
364
  }
364
365
  }
365
366
  //滚动到最底部
@@ -430,20 +431,17 @@ class Coax extends HTMLElement {
430
431
  if (this._renderQueued)
431
432
  return;
432
433
  this._renderQueued = true;
433
- // 使用 requestAnimationFrame 将渲染推迟到下一帧
434
- requestAnimationFrame(async () => {
435
- this.clear();
436
- this.injectThemeStyles();
437
- //一次性渲染
438
- await this.highlight(code);
439
- this._renderQueued = false;
440
- });
434
+ this.clear();
435
+ this.injectThemeStyles();
436
+ //一次性渲染
437
+ this.highlight(code);
438
+ this._renderQueued = false;
441
439
  }
442
440
  /**
443
441
  * Clears the current content and resets the state.
444
442
  */
445
443
  clear() {
446
- this.highlightedCodeEl.innerHTML = this.source = this.lineString = '';
444
+ this.highlightEl.innerHTML = this.source = this.lineString = '';
447
445
  }
448
446
  /**
449
447
  * Replaces the existing code with new source code and re-renders.
@@ -468,7 +466,7 @@ class Coax extends HTMLElement {
468
466
  * @returns An object containing the line wrapper and code wrapper for the last line.
469
467
  */
470
468
  getLastLine() {
471
- const lastChild = this.highlightedCodeEl.lastElementChild, lastLine = !lastChild || this.highlightedCodeEl.lastElementChild?.completed ?
469
+ const lastChild = this.highlightEl.lastElementChild, lastLine = !lastChild || this.highlightEl.lastElementChild?.completed ?
472
470
  this.createLineWrap() : lastChild;
473
471
  return {
474
472
  lineWrap: lastLine,
@@ -479,7 +477,7 @@ class Coax extends HTMLElement {
479
477
  * Marks the current line as completed and updates the displayed code.
480
478
  */
481
479
  close() {
482
- const lineWrap = this.highlightedCodeEl.lastElementChild;
480
+ const lineWrap = this.highlightEl.lastElementChild;
483
481
  if (!lineWrap)
484
482
  return;
485
483
  lineWrap.completed = true;
@@ -493,7 +491,7 @@ class Coax extends HTMLElement {
493
491
  * Reopens the last closed line and restores its original content.
494
492
  */
495
493
  open() {
496
- const lineWrap = this.highlightedCodeEl.lastElementChild;
494
+ const lineWrap = this.highlightEl.lastElementChild;
497
495
  if (!lineWrap)
498
496
  return;
499
497
  lineWrap.completed = false;
@@ -507,7 +505,7 @@ class Coax extends HTMLElement {
507
505
  */
508
506
  stream(str, forceClose = false) {
509
507
  const { lineWrap, codeWrap } = this.getLastLine();
510
- this.highlightedCodeEl.appendChild(lineWrap);
508
+ this.highlightEl.appendChild(lineWrap);
511
509
  //汇集
512
510
  this.source += str;
513
511
  //如果没有遇到换行符号,也可以强制结束
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Last modified: 2026/01/12 14:09:42
2
+ * Last modified: 2026/01/12 15:11:21
3
3
  * Coax - A custom web component for syntax highlighting, code display, and interactive features
4
4
  *
5
5
  */
@@ -39,7 +39,7 @@ class Coax extends HTMLElement {
39
39
  private baseStylesEl!: HTMLStyleElement; // Element for base styles
40
40
  private themeStylesEl!: HTMLStyleElement; // Element for theme styles
41
41
  private dynamicStylesEl!: HTMLStyleElement; // Element for dynamic styles
42
- private highlightedCodeEl!: HTMLElement; // Element that holds the highlighted code
42
+ private highlightEl!: HTMLElement; // Element that holds the highlighted code
43
43
  private headerEl!: HTMLElement; // Header element (for code name, tools, etc.)
44
44
  private codeNameEl!: HTMLElement; // Code name element (shows language or alias)
45
45
  private codeToolsEl!: HTMLElement; // Code tools element (for interactive tools like copy)
@@ -51,6 +51,7 @@ class Coax extends HTMLElement {
51
51
  public lastLineString: string = ''; // The last line's string
52
52
  public speed: number = 5; // Speed of the typing effect (higher is slower)
53
53
  public autoScroll: boolean = true; // Flag to enable/disable auto-scrolling
54
+ public canListen: boolean = true; // Flag to enable/disable auto-scrolling
54
55
 
55
56
  constructor() {
56
57
  super();
@@ -188,7 +189,7 @@ class Coax extends HTMLElement {
188
189
  <style id="theme-styles"></style>
189
190
  <div id="code-header"><span id="code-name">${this.alias}</span><div id="code-tools"></div></div>
190
191
  <div id="code-body">
191
- <pre><code id="highlight-code"></code></pre>
192
+ <pre><code id="highlight"></code></pre>
192
193
  </div>
193
194
  `;
194
195
 
@@ -200,7 +201,7 @@ class Coax extends HTMLElement {
200
201
  this.codeNameEl = getEl('#code-name', this.shadowRoot) as HTMLElement;
201
202
  this.codeToolsEl = getEl('#code-tools', this.shadowRoot) as HTMLElement;
202
203
  this.codeBodyEl = getEl('#code-body', this.shadowRoot) as HTMLElement;
203
- this.highlightedCodeEl = getEl('#highlight-code', this.shadowRoot) as HTMLElement;
204
+ this.highlightEl = getEl('#highlight', this.shadowRoot) as HTMLElement;
204
205
 
205
206
  this.codeBodyEl.addEventListener('scroll', () => {
206
207
  let flag = this.codeBodyEl.scrollTop + this.codeBodyEl.clientHeight < this.codeBodyEl.scrollHeight;
@@ -257,7 +258,7 @@ class Coax extends HTMLElement {
257
258
  * @param newVal - The new value of the attribute.
258
259
  */
259
260
  attributeChangedCallback(name: string, oldVal: string, newVal: string) {
260
- if (oldVal === newVal) return;
261
+ if (oldVal === newVal || !this.canListen) return;
261
262
  if (name === 'height' || name === 'max-height') {
262
263
  this.updateStyleByRegExp(name, newVal);
263
264
  }
@@ -328,9 +329,9 @@ class Coax extends HTMLElement {
328
329
  createLineWrap(index?: number, startIndex?: number) {
329
330
  let dataIndex = 0;
330
331
  if (index == null && startIndex == null) {
331
- dataIndex = this.highlightedCodeEl.children.length;
332
+ dataIndex = this.highlightEl.children.length;
332
333
  } else {
333
- const start = startIndex || this.highlightedCodeEl.children.length;
334
+ const start = startIndex || this.highlightEl.children.length;
334
335
  dataIndex = start + (index as number);
335
336
  }
336
337
  return createEl('div', { 'data-index': dataIndex }, '<div></div>');
@@ -353,7 +354,7 @@ class Coax extends HTMLElement {
353
354
  */
354
355
  async highlight(newCode: string) {
355
356
  const config = Coax.languages.get(this.lang),
356
- startIndex = this.highlightedCodeEl.children.length,
357
+ startIndex = this.highlightEl.children.length,
357
358
  // 将新源码按行分割
358
359
  newCodeLines = newCode ? newCode.split('\n') : [];
359
360
  //更新别名
@@ -370,7 +371,7 @@ class Coax extends HTMLElement {
370
371
  (lineWrap as any).completed = true;
371
372
 
372
373
  if (this.hasAttribute('speed')) {
373
- this.highlightedCodeEl.appendChild(lineWrap);
374
+ this.highlightEl.appendChild(lineWrap);
374
375
  //流式打字
375
376
  await typeWriter(lineString, {
376
377
  speed: this.speed,
@@ -383,7 +384,7 @@ class Coax extends HTMLElement {
383
384
  //直接打出
384
385
  this.getLineToFill(codeWrap, lineString, config);
385
386
  //
386
- this.highlightedCodeEl.appendChild(lineWrap);
387
+ this.highlightEl.appendChild(lineWrap);
387
388
  }
388
389
  }
389
390
  //滚动到最底部
@@ -458,20 +459,17 @@ class Coax extends HTMLElement {
458
459
  //同时多次改变属性,只执行一次
459
460
  if (this._renderQueued) return;
460
461
  this._renderQueued = true;
461
- // 使用 requestAnimationFrame 将渲染推迟到下一帧
462
- requestAnimationFrame(async () => {
463
- this.clear();
464
- this.injectThemeStyles();
465
- //一次性渲染
466
- await this.highlight(code);
467
- this._renderQueued = false;
468
- });
462
+ this.clear();
463
+ this.injectThemeStyles();
464
+ //一次性渲染
465
+ this.highlight(code);
466
+ this._renderQueued = false;
469
467
  }
470
468
  /**
471
469
  * Clears the current content and resets the state.
472
470
  */
473
471
  clear() {
474
- this.highlightedCodeEl.innerHTML = this.source = this.lineString = '';
472
+ this.highlightEl.innerHTML = this.source = this.lineString = '';
475
473
  }
476
474
  /**
477
475
  * Replaces the existing code with new source code and re-renders.
@@ -496,8 +494,8 @@ class Coax extends HTMLElement {
496
494
  * @returns An object containing the line wrapper and code wrapper for the last line.
497
495
  */
498
496
  getLastLine() {
499
- const lastChild = this.highlightedCodeEl.lastElementChild,
500
- lastLine = !lastChild || (this.highlightedCodeEl.lastElementChild as any)?.completed ?
497
+ const lastChild = this.highlightEl.lastElementChild,
498
+ lastLine = !lastChild || (this.highlightEl.lastElementChild as any)?.completed ?
501
499
  this.createLineWrap() : lastChild;
502
500
  return {
503
501
  lineWrap: lastLine,
@@ -508,7 +506,7 @@ class Coax extends HTMLElement {
508
506
  * Marks the current line as completed and updates the displayed code.
509
507
  */
510
508
  close() {
511
- const lineWrap = this.highlightedCodeEl.lastElementChild;
509
+ const lineWrap = this.highlightEl.lastElementChild;
512
510
  if (!lineWrap) return;
513
511
  (lineWrap as any).completed = true;
514
512
  //行结束前保存
@@ -521,7 +519,7 @@ class Coax extends HTMLElement {
521
519
  * Reopens the last closed line and restores its original content.
522
520
  */
523
521
  open() {
524
- const lineWrap = this.highlightedCodeEl.lastElementChild;
522
+ const lineWrap = this.highlightEl.lastElementChild;
525
523
  if (!lineWrap) return;
526
524
  (lineWrap as any).completed = false;
527
525
  //恢复最后一行字符串
@@ -534,7 +532,7 @@ class Coax extends HTMLElement {
534
532
  */
535
533
  stream(str: string, forceClose: boolean = false) {
536
534
  const { lineWrap, codeWrap } = this.getLastLine();
537
- this.highlightedCodeEl.appendChild(lineWrap);
535
+ this.highlightEl.appendChild(lineWrap);
538
536
  //汇集
539
537
  this.source += str;
540
538
 
File without changes
File without changes