@codady/coax 0.0.5 → 0.0.7
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 +62 -23
- package/dist/coax.cjs.min.js +3 -3
- package/dist/coax.esm.js +62 -23
- package/dist/coax.esm.min.js +3 -3
- package/dist/coax.umd.js +62 -23
- package/dist/coax.umd.min.js +3 -3
- package/examples/{append-highlight.html → append.html} +2 -5
- package/examples/{css-highlight.html → css.html} +2 -5
- package/examples/{deepseek-highlight.html → deepseek.html} +3 -2
- package/examples/{html-highlight.html → html.html} +3 -13
- package/examples/index.html +214 -0
- package/examples/{js-highlight.html → js.html} +3 -4
- package/examples/{md-highlight.html → md.html} +2 -12
- package/examples/{theme-highlight.html → module.html} +4 -7
- package/examples/{plain-highlight.html → plain.html} +2 -5
- package/examples/{replace-highlight.html → replace.html} +2 -6
- package/examples/{stream-highlight.html → steam.html} +11 -16
- package/examples/{color-selector.html → theme.html} +1 -3
- package/examples/tools.html +42 -0
- package/examples/{ts-highlight.html → ts.html} +2 -20
- package/examples/typewriter.html +42 -0
- package/package.json +2 -2
- package/src/Coax.js +1 -1
- package/src/Coax.ts +1 -1
- package/src/components/Coax.js +44 -22
- package/src/components/Coax.ts +52 -23
- package/src/modules.js +1 -1
- package/src/modules.ts +1 -1
package/dist/coax.esm.min.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @since Last modified: 2026-1-
|
|
2
|
+
* @since Last modified: 2026-1-15 19:21:59
|
|
3
3
|
* @name Coax event management system.
|
|
4
|
-
* @version 0.0.
|
|
4
|
+
* @version 0.0.6
|
|
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;highlightEl;headerEl;codeNameEl;codeToolsEl;codeBodyEl;lang="plain";alias="Plain Text";lineString="";lastLineString="";speed=5;autoScroll=!0;canListen=!0;constructor(){super(),this.attachShadow({mode:"open"}),this.source=this.textContent?.replace(/^\s*\n|\n\s*$/g,"")||"",this.shadowRoot.innerHTML=`\n <style id="base-styles">\n :host { \n --border-width:1px;\n --border-style:solid;\n --radius:9px;\n --height:auto;\n --max-height:500px;\n --radius:9px;\n --padding:1em;\n --font-size:16px;\n --line-height:1.8;\n --background:rgb(247, 247, 247);\n --border-color:rgb(224, 224, 224);\n --color-code:rgb(51, 51, 51);\n --color-index:rgb(153, 153, 153);\n --color-stripe:rgba(0,0,0,0.04);\n --color-hover:rgba(0,0,0,0.06);\n } \n :host([scheme="dark"]){\n --background: #282c34;\n --border-color: transparent;\n --color-code: #abb2bf;\n --color-index:rgb(153, 153, 153);\n --color-stripe:rgba(255,255,255,0.04);\n --color-hover:rgba(255,255,255,0.06);\n }\n @media (prefers-color-scheme: dark) {\n :host{\n --background: #282c34;\n --border-color: transparent;\n --color-code: #abb2bf;\n --color-index:rgb(153, 153, 153);\n --color-stripe:rgba(255,255,255,0.04);\n --color-hover:rgba(255,255,255,0.06);\n }\n }\n :host {\n font-size: var(--ax-code-font-size,var(--font-size));\n display: block; \n box-sizing:border-box;\n background:var(--ax-code-background-color,var(--background));\n color:var(--ax-code-color,var(--color-code));\n border:var(--ax-code-border-width,var(--border-width)) var(--ax-code-border-style,var(--border-style)) var(--ax-code-border-color,var(--border-color));\n transition: border-color 0.3s ease,color 0.3s ease; \n border-radius: var(--ax-code-radius,var(--radius));\n }\n #code-header{\n line-height:calc(var(--ax-code-line-height,var(--line-height))*1.5);\n padding-inline-start:var(--ax-code-padding,var(--padding));\n display:flex;\n \n >:first-child{\n flex:auto;\n }\n }\n #code-body{\n padding: var(--ax-code-padding,var(--padding)) 0;\n height:var(--ax-code-height,var(--height));\n max-height:var(--ax-code-max-height,var(--max-height));\n overflow:auto;\n }\n pre,code{\n font-family:"Consolas", "Monaco", "Andale Mono", "Ubuntu Mono", "monospace";\n margin:0; padding:0;\n }\n code>div{\n display:flex;\n padding:0 var(--ax-code-padding,var(--padding));\n line-height: var(--ax-code-line-height,var(--line-height));\n box-sizing:border-box;\n \n >div{\n flex:auto;\n }\n }\n code>div>div:empty:before{\n content:' ';\n }\n :host([indexed]) code>div:before{\n display:inline-flex;\n color:var(--color-index);\n content: attr(data-index);\n min-width:var(--ax-code-index-width,2em);\n margin-inline-end:var(--ax-code-padding,8px);\n }\n :host([striped]) code>div:nth-child(odd){\n background-color:var(--color-stripe);\n }\n :host([hoverable]) code>div:hover{\n background-color:var(--color-hover);\n }\n :host([wrapped]) code>div>div{\n white-space: pre-wrap;\n }\n :host([unnamed]) #code-name{\n display:none;\n }\n .ax-box-tools{\n >*{\n font-size:14px;\n display:inline-flex;\n align-items:center;\n justify-content:center;\n height:2em;\n line-height:2em;\n aspect-ratio:1/1;\n margin-inline-end:8px;\n transition:all 200ms ease;\n border-radius:6px;\n &:hover{\n cursor:pointer;\n background-color:rgba(0,0,0,.04);\n }\n }\n [rep=icon]{\n display:inline-flex;\n align-items:center;\n justify-content:center;\n }\n }\n [disabled]{\n pointer-event:none;\n }\n </style>\n <style id="dynamic-styles"></style>\n <style id="theme-styles"></style>\n <div id="code-header"><span id="code-name">${this.alias}</span><div id="code-tools"></div></div>\n <div id="code-body">\n <pre><code id="highlight"></code></pre>\n </div>\n `,this.baseStylesEl=getEl("#base-styles",this.shadowRoot),this.themeStylesEl=getEl("#theme-styles",this.shadowRoot),this.dynamicStylesEl=getEl("#dynamic-styles",this.shadowRoot),this.headerEl=getEl("#code-header",this.shadowRoot),this.codeNameEl=getEl("#code-name",this.shadowRoot),this.codeToolsEl=getEl("#code-tools",this.shadowRoot),this.codeBodyEl=getEl("#code-body",this.shadowRoot),this.highlightEl=getEl("#highlight",this.shadowRoot),this.codeBodyEl.addEventListener("scroll",()=>{let e=this.codeBodyEl.scrollTop+this.codeBodyEl.clientHeight<this.codeBodyEl.scrollHeight;this.autoScroll=!e})}static register(e,t){this.languages.set(e,{...t})}static addTools(e){Coax.tools=e}mountTools(e){requestAnimationFrame(()=>{this.codeToolsEl.innerHTML="";let t=e.map(e=>(e.action=e.action.bind(this),e));this.codeToolsEl.appendChild(createTools(t))})}connectedCallback(){this.render()}static get observedAttributes(){return["lang","height","max-height","tools","speed"]}attributeChangedCallback(e,t,n){if(t!==n&&this.canListen&&("height"!==e&&"max-height"!==e||this.updateStyleByRegExp(e,n),"speed"===e&&(this.speed=~~!!n),"lang"===e&&(this.lang=n,this.render()),"tools"===e)){n||(this.codeToolsEl.innerHTML="");const e=parseClasses$1(n),t=Coax.tools.filter(t=>e.includes(t.name));if(!t.length)return;this.mountTools(t)}}updateStyleByRegExp(e,t){const n=new RegExp(`;\\n\\s*${e}:\\s*[^;]+;`,"g");this.baseStylesEl.textContent=this.baseStylesEl.textContent.replace(n,`;\n${e}: ${t};`)}getCssPrefix(e){return(e?.cssPrefix||this.lang).replace(/[^a-zA-Z0-9_-]/g,"\\$&")}getHighLightString(e,t){if(!(t=t||Coax.languages.get(this.lang)))return e;const n=this.getCssPrefix(t),r=new RegExp(t.rules.map(e=>`(${e.pattern.source})`).join("|"),"g");return e.replace(r,(e,...r)=>{const i=r.findIndex(e=>void 0!==e);return-1!==i&&t.rules[i]?`<span class="ax-${n}-${t.rules[i].token}">${e}</span>`:e})}createLineWrap(e,t){let n=0;if(null==e&&null==t)n=this.highlightEl.children.length;else{n=(t||this.highlightEl.children.length)+e}return createEl("div",{"data-index":n},"<div></div>")}getLineToFill(e,t,n){n=n||Coax.languages.get(this.lang);let r=this.getHighLightString(t,n);e.innerHTML=r}async highlight(e){const t=Coax.languages.get(this.lang),n=this.highlightEl.children.length,r=e?e.split("\n"):[];if(this.updateName(t),!r.length)return!0;for(let[e,i]of r.entries()){if(!i.trim()&&this.hasAttribute("sanitized"))continue;const r=this.createLineWrap(e,n),a=r.lastElementChild;r.completed=!0,this.hasAttribute("speed")?(this.highlightEl.appendChild(r),await typeWriter(i,{speed:this.speed,onDuringType:(e,t)=>{a.innerHTML=t}}),this.getLineToFill(a,i,t)):(this.getLineToFill(a,i,t),this.highlightEl.appendChild(r))}return this.autoScrollCode(),!0}autoScrollCode(){this.autoScroll&&(this.codeBodyEl.scrollTop=this.codeBodyEl.scrollHeight)}injectThemeStyles(){const e=Coax.languages.get(this.lang);if(!e)return;let t=this.getCssPrefix(e),n=e.rules.map(e=>`\n .ax-${t}-${e.token} { color: var(--ax-${t}-${e.token}${e.light?","+e.light:""});}`).join("\n"),r="",i="";r+=':host([scheme="dark"]){',r+=e.rules.map(e=>"\n "+(e.light?`\n .ax-${t}-${e.token} {color: var(--ax-${t}-${e.token},${e.dark});}`:"")).join("\n"),r+="}",i="@media (prefers-color-scheme: dark){\n :host{\n ",i+=e.rules.map(e=>`\n ${e.light?`\n .ax-${t}-${e.token} { color: var(--ax-${t}-${e.token},${e.dark}); }`:""} `).join("\n"),i+="}",this.dynamicStylesEl.textContent=n+r+i,e?.themeStyles&&(this.themeStylesEl.textContent=e.themeStyles)}updateName(e){this.hasAttribute("unnamed")||(e?(this.alias=e.alias||this.lang,this.codeNameEl.innerHTML=this.alias):this.codeNameEl.innerHTML="Plain Text")}render(e=this.source){this._renderQueued||(this._renderQueued=!0,this.clear(),this.injectThemeStyles(),this.highlight(e),this._renderQueued=!1)}clear(){this.highlightEl.innerHTML=this.source=this.lineString=""}async replace(e){this.clear(),await this.highlight(e)}async append(e){this.source+=`\n${e}`,await this.highlight(e)}getLastLine(){const e=this.highlightEl.lastElementChild,t=!e||this.highlightEl.lastElementChild?.completed?this.createLineWrap():e;return{lineWrap:t,codeWrap:t.lastElementChild}}close(){const e=this.highlightEl.lastElementChild;e&&(e.completed=!0,this.lastLineString=this.lineString,this.getLineToFill(e?.lastElementChild,this.lineString),this.lineString="")}open(){const e=this.highlightEl.lastElementChild;e&&(e.completed=!1,(e?.lastElementChild).textContent=this.lineString=this.lastLineString)}stream(e,t=!1){const{lineWrap:n,codeWrap:r}=this.getLastLine();this.highlightEl.appendChild(n),this.source+=e,t||e.startsWith("\n")||e.endsWith("\n")?this.close():(r.innerHTML+=e,this.lineString+=e),this.autoScrollCode()}}const css=[{token:"comment",pattern:/\/\*[\s\S]*?\*\//,light:"#6a737d",dark:"#8b949e"},{token:"value",pattern:/(?:'|")(?:\\.|[^\\'"\b])*?(?:'|")/,light:"#032f62",dark:"#a5d6ff"},{token:"func",pattern:/[a-z-]+\(?=/,light:"#e36209",dark:"#ffa657"},{token:"property",pattern:/[a-z-]+(?=\s*:)/,light:"#005cc5",dark:"#79c0ff"},{token:"selector",pattern:/[.#a-z0-9, \n\t>:+()_-]+(?=\s*\{)/i,light:"#22863a",dark:"#7ee787"},{token:"unit",pattern:/(?<=\d)(px|em|rem|%|vh|vw|ms|s|deg)/,light:"#d73a49",dark:"#ff7b72"},{token:"number",pattern:/\b\d+(\.\d+)?\b/,light:"#005cc5",dark:"#79c0ff"},{token:"punct",pattern:/[{}();:]/,light:"#24292e",dark:"#c9d1d9"}],html=[{token:"comment",pattern:/<!--[\s\S]*?-->/,light:"#999999",dark:"#6e7681"},{token:"doctype",pattern:/<!DOCTYPE[\s\S]*?>/i,light:"#6a737d",dark:"#8b949e"},{token:"tag",pattern:/<\/?[a-zA-Z0-9]+/,light:"#22863a",dark:"#7ee787"},{token:"attr",pattern:/[a-zA-Z-]+(?=\s*=\s*)/,light:"#6f42c1",dark:"#d2a8ff"},{token:"string",pattern:/(['"])(?:\\.|[^\\])*?\1/,light:"#032f62",dark:"#a5d6ff"},{token:"bracket",pattern:/\/?>/,light:"#24292e",dark:"#c9d1d9"}],javascript=[{token:"comment",pattern:/\/\/[^\n]*|\/\*[\s\S]*?\*\//,light:"#6a737d",dark:"#8b949e"},{token:"string",pattern:/(?:'|"|`)(?:\\.|[^\\'"\b])*?(?:'|"|`)/,light:"#032f62",dark:"#98c379"},{token:"keyword",pattern:/\b(async|await|break|case|catch|class|const|continue|default|delete|do|else|export|extends|finally|for|function|if|import|in|instanceof|new|return|super|switch|this|throw|try|typeof|var|while|with|yield|let|static)\b/,light:"#d73a49",dark:"#ff7b72"},{token:"builtin",pattern:/\b(console|window|document|Math|JSON|true|false|null|undefined|Object|Array|Promise|Number|String|Boolean)\b/,light:"#e36209",dark:"#ffa657"},{token:"number",pattern:/\b(0x[\da-fA-F]+|0b[01]+|\d+(\.\d+)?)\b/,light:"#005cc5",dark:"#79c0ff"},{token:"func",pattern:/\b[a-zA-Z_]\w*(?=\s*\()/,light:"#6f42c1",dark:"#d2a8ff"},{token:"op",pattern:/[+\-*/%=<>!&|^~]+/,light:"#069598",dark:"#56b6c2"}],markdown=[{token:"comment",pattern:/<!--[\s\S]*?-->/,light:"#6a737d",dark:"#8b949e"},{token:"heading",pattern:/(^|\n)(#{1,6})\s*(.+)/,light:"#e36209",dark:"#ffa657"},{token:"bold",pattern:/\*\*([^*]+)\*\*|__([^_]+)__/g,light:"#d73a49",dark:"#ff7b72"},{token:"italic",pattern:/\*([^*]+)\*|_([^_]+)_/g,light:"#032f62",dark:"#a5d6ff"},{token:"link",pattern:/\[([^\]]+)\]\(([^)]+)\)/g,light:"#0288d1",dark:"#80c0ff"},{token:"inline-code",pattern:/`([^`]+)`/g,light:"#032f62",dark:"#98c379"},{token:"code-block",pattern:/```([^\n]+)\n([\s\S]*?)```/g,light:"#24292e",dark:"#c9d1d9"},{token:"list-item",pattern:/(^|\n)([-*])\s+(.+)/g,light:"#5c6e7c",dark:"#8b949e"},{token:"quote",pattern:/(^|\n)>[ \t]*(.+)/g,light:"#6f42c1",dark:"#d2a8ff"},{token:"image",pattern:/!\[([^\]]+)\]\(([^)]+)\)/g,light:"#d73a49",dark:"#ff7b72"},{token:"hr",pattern:/^(---|___|\*\*\*)\s*$/gm,light:"#24292e",dark:"#c9d1d9"},{token:"strikethrough",pattern:/~~([^~]+)~~/g,light:"#e36209",dark:"#ffa657"},{token:"table",pattern:/\|([^\|]+)\|([^\|]+)\|/g,light:"#5c6e7c",dark:"#8b949e"}],typescript=[{token:"comment",pattern:/\/\/[^\n]*|\/\*[\s\S]*?\*\//,light:"#6a737d",dark:"#8b949e"},{token:"string",pattern:/(?:'|"|`)(?:\\.|[^\\'"\b])*?(?:'|"|`)/,light:"#032f62",dark:"#98c379"},{token:"decorator",pattern:/@[a-zA-Z_]\w*/,light:"#953800",dark:"#ffa657"},{token:"keyword",pattern:/\b(abstract|as|async|await|break|case|catch|class|const|continue|debugger|declare|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|is|keyof|let|module|namespace|new|package|private|protected|public|readonly|return|set|static|super|switch|this|throw|try|type|typeof|var|while|with|yield)\b/,light:"#d73a49",dark:"#ff7b72"},{token:"builtin",pattern:/\b(any|boolean|never|number|string|symbol|unknown|void|undefined|null|true|false|console|window|document)\b/,light:"#e36209",dark:"#ffa657"},{token:"type",pattern:/\b[A-Z]\w*\b/,light:"#005cc5",dark:"#79c0ff"},{token:"number",pattern:/\b(0x[\da-fA-F]+|0b[01]+|\d+(\.\d+)?)\b/,light:"#005cc5",dark:"#79c0ff"},{token:"func",pattern:/\b[a-zA-Z_]\w*(?=\s*\()/,light:"#6f42c1",dark:"#d2a8ff"},{token:"op",pattern:/(\?\.|![:\.]|[+\-*/%=<>!&|^~]+)/,light:"#089ba6",dark:"#79c0ff"}],COMMA=",",SPACE=" ",trim=(e,t="")=>{if("string"!=typeof e)return"";switch(t){case"start":return e.trimStart();case"end":return e.trimEnd();case"both":return e.trim();case"global":return e.replace(/[\s\r\n]+/g,"");default:return e.trim().replace(/[\s\r\n]+/g," ")}},parseClasses=e=>{let t,n=[];return Array.isArray(e)?n=e.filter(e=>e&&"string"==typeof e):(t=(e=trim(e)).includes(",")?",":" ",n=e.split(t)),n.map(e=>trim(e,"global")).filter(Boolean)},rtlStyle=(e="")=>`\n <style>\n :where([dir="rtl"]) .icax-${e},\n :where(:dir(rtl)) .icax-${e} {\n transform: scaleX(-1);\n transform-origin: center;\n }\n </style>\n`,wrap=(e,t,n=!1,r)=>{const i=r?.size||"1em",a=r?.color||"currentColor",o=r?.thickness||2,l=r?.classes?parseClasses(r.classes).join(" "):"",s=t.name.replace(/([A-Z])/g,"-$1").toLowerCase();return`<svg xmlns="http://www.w3.org/2000/svg" width="${i}" height="${i}" viewBox="0 0 24 24" fill="none" stroke="${a}"\n stroke-width="${o}" stroke-linecap="round" stroke-linejoin="round" class="${s} ${l}">\n ${n?rtlStyle(s.split("-")[1]):""}\n ${e}\n </svg>`},icaxCheck=e=>wrap('<polyline points="20 6 9 17 4 12"></polyline>',icaxCheck,!1,e),icaxCopy=e=>wrap('<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>',icaxCopy,!1,e),copy={name:"copy",icon:icaxCopy(),action:function(e){e.wrapEl.onclick=()=>{navigator.clipboard.writeText(this.source).then(()=>{e.iconEl.innerHTML=icaxCheck(),e.iconEl.toggleAttribute("disabled",!0),setTimeout(()=>{e.iconEl.removeAttribute("disabled"),e.iconEl.innerHTML=icaxCopy()},2e3)}).catch(e=>{})}}};export{Coax,copy,css,html,javascript,markdown,typescript};
|
|
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},trimEmptyLines=e=>null==e?"":e.replace(/^\s*\n|\n\s*$/g,"")||"",escapeHtmlChars=e=>e?e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"):"";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=escapeHtmlChars(trimEmptyLines(this.textContent)),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>")}getLineToFillHighLight(e,t,n){n=n||Coax.languages.get(this.lang);let r=this.getHighLightString(t,n);e.innerHTML=r}async highlight(e=this.source){const t=Coax.languages.get(this.lang),n=this.highlightEl.children.length,r=e?e.split("\n"):[],i=this.hasAttribute("speed"),a=this.hasAttribute("sanitized");if(this.updateName(t),!r.length)return!0;for(let[e,o]of r.entries()){if(!o.trim()&&a)continue;const r=this.createLineWrap(e,n),l=r.lastElementChild;r.completed=!0,i?(this.highlightEl.appendChild(r),await typeWriter(o,{speed:this.speed,onDuringType:(e,t)=>{l.innerHTML=t}}),this.getLineToFillHighLight(l,o,t)):(this.getLineToFillHighLight(l,o,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")}trimLineString(e){return e.startsWith("\n")&&(e=e.substring(1)),e.endsWith("\n")&&(e=e.slice(0,-1)),e}render(){this._renderQueued||(this._renderQueued=!0,requestAnimationFrame(async()=>{this.highlightEl.innerHTML="",this.injectThemeStyles(),await this.highlight(),this._renderQueued=!1}))}clear(){this.highlightEl.innerHTML=this.source=this.lineString=""}async replace(e){e=escapeHtmlChars(e),this.source=trimEmptyLines(e),this._renderQueued||(this.highlightEl.innerHTML="",await this.highlight())}async append(e){e=escapeHtmlChars(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.getLineToFillHighLight(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){e=escapeHtmlChars(e);const{lineWrap:n,codeWrap:r}=this.getLastLine(),i=e.startsWith("\n")||e.endsWith("\n");this.highlightEl.appendChild(n),this.source+=e,this.lineString+=i?this.trimLineString(e):e,t||i?this.close():r.innerHTML+=e,this.autoScrollCode()}}const css=[{token:"comment",pattern:/\/\*[\s\S]*?\*\//,light:"#6a737d",dark:"#8b949e"},{token:"value",pattern:/(?:'|")(?:\\.|[^\\'"\b])*?(?:'|")/,light:"#032f62",dark:"#a5d6ff"},{token:"func",pattern:/[a-z-]+\(?=/,light:"#e36209",dark:"#ffa657"},{token:"property",pattern:/[a-z-]+(?=\s*:)/,light:"#005cc5",dark:"#79c0ff"},{token:"selector",pattern:/[.#a-z0-9, \n\t>:+()_-]+(?=\s*\{)/i,light:"#22863a",dark:"#7ee787"},{token:"unit",pattern:/(?<=\d)(px|em|rem|%|vh|vw|ms|s|deg)/,light:"#d73a49",dark:"#ff7b72"},{token:"number",pattern:/\b\d+(\.\d+)?\b/,light:"#005cc5",dark:"#79c0ff"},{token:"punct",pattern:/[{}();:]/,light:"#24292e",dark:"#c9d1d9"}],html=[{token:"comment",pattern:/<!--[\s\S]*?-->/,light:"#999999",dark:"#6e7681"},{token:"doctype",pattern:/<!DOCTYPE[\s\S]*?>/i,light:"#6a737d",dark:"#8b949e"},{token:"tag",pattern:/<\/?[a-zA-Z0-9]+/,light:"#22863a",dark:"#7ee787"},{token:"attr",pattern:/[a-zA-Z-]+(?=\s*=\s*)/,light:"#6f42c1",dark:"#d2a8ff"},{token:"string",pattern:/(['"])(?:\\.|[^\\])*?\1/,light:"#032f62",dark:"#a5d6ff"},{token:"bracket",pattern:/\/?>/,light:"#24292e",dark:"#c9d1d9"}],javascript=[{token:"comment",pattern:/\/\/[^\n]*|\/\*[\s\S]*?\*\//,light:"#6a737d",dark:"#8b949e"},{token:"string",pattern:/(?:'|"|`)(?:\\.|[^\\'"\b])*?(?:'|"|`)/,light:"#032f62",dark:"#98c379"},{token:"keyword",pattern:/\b(async|await|break|case|catch|class|const|continue|default|delete|do|else|export|extends|finally|for|function|if|import|in|instanceof|new|return|super|switch|this|throw|try|typeof|var|while|with|yield|let|static)\b/,light:"#d73a49",dark:"#ff7b72"},{token:"builtin",pattern:/\b(console|window|document|Math|JSON|true|false|null|undefined|Object|Array|Promise|Number|String|Boolean)\b/,light:"#e36209",dark:"#ffa657"},{token:"number",pattern:/\b(0x[\da-fA-F]+|0b[01]+|\d+(\.\d+)?)\b/,light:"#005cc5",dark:"#79c0ff"},{token:"func",pattern:/\b[a-zA-Z_]\w*(?=\s*\()/,light:"#6f42c1",dark:"#d2a8ff"},{token:"op",pattern:/[+\-*/%=<>!&|^~]+/,light:"#069598",dark:"#56b6c2"}],markdown=[{token:"comment",pattern:/<!--[\s\S]*?-->/,light:"#6a737d",dark:"#8b949e"},{token:"heading",pattern:/(^|\n)(#{1,6})\s*(.+)/,light:"#e36209",dark:"#ffa657"},{token:"bold",pattern:/\*\*([^*]+)\*\*|__([^_]+)__/g,light:"#d73a49",dark:"#ff7b72"},{token:"italic",pattern:/\*([^*]+)\*|_([^_]+)_/g,light:"#032f62",dark:"#a5d6ff"},{token:"link",pattern:/\[([^\]]+)\]\(([^)]+)\)/g,light:"#0288d1",dark:"#80c0ff"},{token:"inline-code",pattern:/`([^`]+)`/g,light:"#032f62",dark:"#98c379"},{token:"code-block",pattern:/```([^\n]+)\n([\s\S]*?)```/g,light:"#24292e",dark:"#c9d1d9"},{token:"list-item",pattern:/(^|\n)([-*])\s+(.+)/g,light:"#5c6e7c",dark:"#8b949e"},{token:"quote",pattern:/(^|\n)>[ \t]*(.+)/g,light:"#6f42c1",dark:"#d2a8ff"},{token:"image",pattern:/!\[([^\]]+)\]\(([^)]+)\)/g,light:"#d73a49",dark:"#ff7b72"},{token:"hr",pattern:/^(---|___|\*\*\*)\s*$/gm,light:"#24292e",dark:"#c9d1d9"},{token:"strikethrough",pattern:/~~([^~]+)~~/g,light:"#e36209",dark:"#ffa657"},{token:"table",pattern:/\|([^\|]+)\|([^\|]+)\|/g,light:"#5c6e7c",dark:"#8b949e"}],typescript=[{token:"comment",pattern:/\/\/[^\n]*|\/\*[\s\S]*?\*\//,light:"#6a737d",dark:"#8b949e"},{token:"string",pattern:/(?:'|"|`)(?:\\.|[^\\'"\b])*?(?:'|"|`)/,light:"#032f62",dark:"#98c379"},{token:"decorator",pattern:/@[a-zA-Z_]\w*/,light:"#953800",dark:"#ffa657"},{token:"keyword",pattern:/\b(abstract|as|async|await|break|case|catch|class|const|continue|debugger|declare|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|is|keyof|let|module|namespace|new|package|private|protected|public|readonly|return|set|static|super|switch|this|throw|try|type|typeof|var|while|with|yield)\b/,light:"#d73a49",dark:"#ff7b72"},{token:"builtin",pattern:/\b(any|boolean|never|number|string|symbol|unknown|void|undefined|null|true|false|console|window|document)\b/,light:"#e36209",dark:"#ffa657"},{token:"type",pattern:/\b[A-Z]\w*\b/,light:"#005cc5",dark:"#79c0ff"},{token:"number",pattern:/\b(0x[\da-fA-F]+|0b[01]+|\d+(\.\d+)?)\b/,light:"#005cc5",dark:"#79c0ff"},{token:"func",pattern:/\b[a-zA-Z_]\w*(?=\s*\()/,light:"#6f42c1",dark:"#d2a8ff"},{token:"op",pattern:/(\?\.|![:\.]|[+\-*/%=<>!&|^~]+)/,light:"#089ba6",dark:"#79c0ff"}],COMMA=",",SPACE=" ",trim=(e,t="")=>{if("string"!=typeof e)return"";switch(t){case"start":return e.trimStart();case"end":return e.trimEnd();case"both":return e.trim();case"global":return e.replace(/[\s\r\n]+/g,"");default:return e.trim().replace(/[\s\r\n]+/g," ")}},parseClasses=e=>{let t,n=[];return Array.isArray(e)?n=e.filter(e=>e&&"string"==typeof e):(t=(e=trim(e)).includes(",")?",":" ",n=e.split(t)),n.map(e=>trim(e,"global")).filter(Boolean)},rtlStyle=(e="")=>`\n <style>\n :where([dir="rtl"]) .icax-${e},\n :where(:dir(rtl)) .icax-${e} {\n transform: scaleX(-1);\n transform-origin: center;\n }\n </style>\n`,wrap=(e,t,n=!1,r)=>{const i=r?.size||"1em",a=r?.color||"currentColor",o=r?.thickness||2,l=r?.classes?parseClasses(r.classes).join(" "):"",s=t.name.replace(/([A-Z])/g,"-$1").toLowerCase();return`<svg xmlns="http://www.w3.org/2000/svg" width="${i}" height="${i}" viewBox="0 0 24 24" fill="none" stroke="${a}"\n stroke-width="${o}" stroke-linecap="round" stroke-linejoin="round" class="${s} ${l}">\n ${n?rtlStyle(s.split("-")[1]):""}\n ${e}\n </svg>`},icaxCheck=e=>wrap('<polyline points="20 6 9 17 4 12"></polyline>',icaxCheck,!1,e),icaxCopy=e=>wrap('<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>',icaxCopy,!1,e),copy={name:"copy",icon:icaxCopy(),action:function(e){e.wrapEl.onclick=()=>{navigator.clipboard.writeText(this.source).then(()=>{e.iconEl.innerHTML=icaxCheck(),e.iconEl.toggleAttribute("disabled",!0),setTimeout(()=>{e.iconEl.removeAttribute("disabled"),e.iconEl.innerHTML=icaxCopy()},2e3)}).catch(e=>{})}}};export{Coax,copy,css,html,javascript,markdown,typescript};
|
package/dist/coax.umd.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
/*!
|
|
3
|
-
* @since Last modified: 2026-1-
|
|
3
|
+
* @since Last modified: 2026-1-15 19:21:59
|
|
4
4
|
* @name Coax event management system.
|
|
5
|
-
* @version 0.0.
|
|
5
|
+
* @version 0.0.6
|
|
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}
|
|
@@ -436,6 +436,25 @@
|
|
|
436
436
|
return toolsEl;
|
|
437
437
|
};
|
|
438
438
|
|
|
439
|
+
const trimEmptyLines = (str) => {
|
|
440
|
+
if (str == null)
|
|
441
|
+
return '';
|
|
442
|
+
return str.replace(/^\s*\n|\n\s*$/g, '') || '';
|
|
443
|
+
};
|
|
444
|
+
|
|
445
|
+
const escapeHtmlChars = (text) => {
|
|
446
|
+
// Check if the input text is empty or undefined
|
|
447
|
+
if (!text)
|
|
448
|
+
return '';
|
|
449
|
+
// Replace the special characters with their corresponding HTML entities
|
|
450
|
+
return text
|
|
451
|
+
.replace(/&/g, '&') // Replace '&' with '&'
|
|
452
|
+
.replace(/</g, '<') // Replace '<' with '<'
|
|
453
|
+
.replace(/>/g, '>') // Replace '>' with '>'
|
|
454
|
+
.replace(/"/g, '"') // Replace '"' with '"'
|
|
455
|
+
.replace(/'/g, '''); // Replace "'" with '''
|
|
456
|
+
};
|
|
457
|
+
|
|
439
458
|
class Coax extends HTMLElement {
|
|
440
459
|
// A static Map to hold the configuration for different languages
|
|
441
460
|
static languages = new Map();
|
|
@@ -463,7 +482,7 @@
|
|
|
463
482
|
// Attach a Shadow DOM to the custom element
|
|
464
483
|
this.attachShadow({ mode: 'open' });
|
|
465
484
|
// Remove leading/trailing whitespace from the raw code content
|
|
466
|
-
this.source = this.textContent
|
|
485
|
+
this.source = escapeHtmlChars(trimEmptyLines(this.textContent));
|
|
467
486
|
// Initialize the basic structure of the component
|
|
468
487
|
this.shadowRoot.innerHTML = `
|
|
469
488
|
<style id="base-styles">
|
|
@@ -702,7 +721,7 @@
|
|
|
702
721
|
return createEl('div', { 'data-index': dataIndex }, '<div></div>');
|
|
703
722
|
}
|
|
704
723
|
|
|
705
|
-
|
|
724
|
+
getLineToFillHighLight(codeWrap, line, config) {
|
|
706
725
|
config = config || Coax.languages.get(this.lang);
|
|
707
726
|
let highlightedLine = this.getHighLightString(line, config);
|
|
708
727
|
// 将高亮后的内容填充到 div 中
|
|
@@ -710,10 +729,10 @@
|
|
|
710
729
|
}
|
|
711
730
|
;
|
|
712
731
|
|
|
713
|
-
async highlight(newCode) {
|
|
732
|
+
async highlight(newCode = this.source) {
|
|
714
733
|
const config = Coax.languages.get(this.lang), startIndex = this.highlightEl.children.length,
|
|
715
734
|
// 将新源码按行分割
|
|
716
|
-
newCodeLines = newCode ? newCode.split('\n') : [];
|
|
735
|
+
newCodeLines = newCode ? newCode.split('\n') : [], hasSpeedAttr = this.hasAttribute('speed'), hasSanitizedAttr = this.hasAttribute('sanitized');
|
|
717
736
|
//更新别名
|
|
718
737
|
this.updateName(config);
|
|
719
738
|
if (!newCodeLines.length)
|
|
@@ -721,13 +740,13 @@
|
|
|
721
740
|
// 如果没有找到配置,则输出原始代码,并不进行高亮处理
|
|
722
741
|
for (let [index, lineString] of newCodeLines.entries()) {
|
|
723
742
|
//如果是空行则跳过
|
|
724
|
-
if (!lineString.trim() &&
|
|
743
|
+
if (!lineString.trim() && hasSanitizedAttr)
|
|
725
744
|
continue;
|
|
726
745
|
// 创建一个 div 包裹每一行
|
|
727
746
|
const lineWrap = this.createLineWrap(index, startIndex), codeWrap = lineWrap.lastElementChild;
|
|
728
747
|
//标记完成
|
|
729
748
|
lineWrap.completed = true;
|
|
730
|
-
if (
|
|
749
|
+
if (hasSpeedAttr) {
|
|
731
750
|
this.highlightEl.appendChild(lineWrap);
|
|
732
751
|
//流式打字
|
|
733
752
|
await typeWriter(lineString, {
|
|
@@ -736,11 +755,11 @@
|
|
|
736
755
|
codeWrap.innerHTML = fullText;
|
|
737
756
|
}
|
|
738
757
|
});
|
|
739
|
-
this.
|
|
758
|
+
this.getLineToFillHighLight(codeWrap, lineString, config);
|
|
740
759
|
}
|
|
741
760
|
else {
|
|
742
761
|
//直接打出
|
|
743
|
-
this.
|
|
762
|
+
this.getLineToFillHighLight(codeWrap, lineString, config);
|
|
744
763
|
//
|
|
745
764
|
this.highlightEl.appendChild(lineWrap);
|
|
746
765
|
}
|
|
@@ -798,17 +817,30 @@
|
|
|
798
817
|
this.codeNameEl.innerHTML = this.alias;
|
|
799
818
|
}
|
|
800
819
|
}
|
|
820
|
+
trimLineString(str) {
|
|
821
|
+
// 删除开头的第一个换行符
|
|
822
|
+
if (str.startsWith('\n')) {
|
|
823
|
+
str = str.substring(1);
|
|
824
|
+
}
|
|
825
|
+
// 删除结尾的第一个换行符
|
|
826
|
+
if (str.endsWith('\n')) {
|
|
827
|
+
str = str.slice(0, -1);
|
|
828
|
+
}
|
|
829
|
+
return str;
|
|
830
|
+
}
|
|
801
831
|
|
|
802
|
-
render(
|
|
832
|
+
render() {
|
|
803
833
|
//同时多次改变属性,只执行一次
|
|
804
834
|
if (this._renderQueued)
|
|
805
835
|
return;
|
|
806
836
|
this._renderQueued = true;
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
837
|
+
requestAnimationFrame(async () => {
|
|
838
|
+
this.highlightEl.innerHTML = '';
|
|
839
|
+
this.injectThemeStyles();
|
|
840
|
+
//一次性渲染
|
|
841
|
+
await this.highlight();
|
|
842
|
+
this._renderQueued = false;
|
|
843
|
+
});
|
|
812
844
|
}
|
|
813
845
|
|
|
814
846
|
clear() {
|
|
@@ -816,11 +848,17 @@
|
|
|
816
848
|
}
|
|
817
849
|
|
|
818
850
|
async replace(newCode) {
|
|
819
|
-
|
|
820
|
-
|
|
851
|
+
newCode = escapeHtmlChars(newCode);
|
|
852
|
+
this.source = trimEmptyLines(newCode);
|
|
853
|
+
if (this._renderQueued)
|
|
854
|
+
return;
|
|
855
|
+
this.highlightEl.innerHTML = '';
|
|
856
|
+
//一次性渲染
|
|
857
|
+
await this.highlight();
|
|
821
858
|
}
|
|
822
859
|
|
|
823
860
|
async append(newCode) {
|
|
861
|
+
newCode = escapeHtmlChars(newCode);
|
|
824
862
|
// 将新的代码追加到现有代码末尾
|
|
825
863
|
this.source += `\n${newCode}`;
|
|
826
864
|
// 高亮新的部分
|
|
@@ -843,7 +881,7 @@
|
|
|
843
881
|
lineWrap.completed = true;
|
|
844
882
|
//行结束前保存
|
|
845
883
|
this.lastLineString = this.lineString;
|
|
846
|
-
this.
|
|
884
|
+
this.getLineToFillHighLight(lineWrap?.lastElementChild, this.lineString);
|
|
847
885
|
//一行结束,清空临时行文本
|
|
848
886
|
this.lineString = '';
|
|
849
887
|
}
|
|
@@ -858,20 +896,21 @@
|
|
|
858
896
|
}
|
|
859
897
|
|
|
860
898
|
stream(str, forceClose = false) {
|
|
861
|
-
|
|
899
|
+
str = escapeHtmlChars(str);
|
|
900
|
+
const { lineWrap, codeWrap } = this.getLastLine(), isLine = str.startsWith('\n') || str.endsWith('\n');
|
|
862
901
|
this.highlightEl.appendChild(lineWrap);
|
|
863
902
|
//汇集
|
|
864
903
|
this.source += str;
|
|
904
|
+
//临时保存行文本
|
|
905
|
+
this.lineString += isLine ? this.trimLineString(str) : str;
|
|
865
906
|
//如果没有遇到换行符号,也可以强制结束
|
|
866
|
-
if (forceClose ||
|
|
907
|
+
if (forceClose || isLine) {
|
|
867
908
|
//标记完成
|
|
868
909
|
this.close();
|
|
869
910
|
}
|
|
870
911
|
else {
|
|
871
912
|
//插入文本
|
|
872
913
|
codeWrap.innerHTML += str;
|
|
873
|
-
//临时保存行文本
|
|
874
|
-
this.lineString += str;
|
|
875
914
|
}
|
|
876
915
|
//滚动到最底部
|
|
877
916
|
this.autoScrollCode();
|
package/dist/coax.umd.min.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @since Last modified: 2026-1-
|
|
2
|
+
* @since Last modified: 2026-1-15 19:21:59
|
|
3
3
|
* @name Coax event management system.
|
|
4
|
-
* @version 0.0.
|
|
4
|
+
* @version 0.0.6
|
|
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;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:/<!--[\s\S]*?-->/,light:"#999999",dark:"#6e7681"},{token:"doctype",pattern:/<!DOCTYPE[\s\S]*?>/i,light:"#6a737d",dark:"#8b949e"},{token:"tag",pattern:/<\/?[a-zA-Z0-9]+/,light:"#22863a",dark:"#7ee787"},{token:"attr",pattern:/[a-zA-Z-]+(?=\s*=\s*)/,light:"#6f42c1",dark:"#d2a8ff"},{token:"string",pattern:/(['"])(?:\\.|[^\\])*?\1/,light:"#032f62",dark:"#a5d6ff"},{token:"bracket",pattern:/\/?>/,light:"#24292e",dark:"#c9d1d9"}]}),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",a=i?.color||"currentColor",o=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="${a}"\n stroke-width="${o}" 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 a=setInterval(()=>{if(r<e.length){const n=e.charAt(r),i=e.substring(0,r+1);t?.onDuringType?.(n,i),r++}else clearInterval(a),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),a=r&&r instanceof HTMLTemplateElement?r.content:r,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 i=(e=e||"div").toUpperCase().trim(),r=document.createElement(i),a=getDataType(t);if(t&&"Object"===a)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},trimEmptyLines=e=>null==e?"":e.replace(/^\s*\n|\n\s*$/g,"")||"",escapeHtmlChars=e=>e?e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"):"";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=escapeHtmlChars(trimEmptyLines(this.textContent)),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 a=r.findIndex(e=>void 0!==e);return-1!==a&&n.rules[a]?`<span class="${e}-${i}-${n.rules[a].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>")}getLineToFillHighLight(e,t,n){n=n||Coax.languages.get(this.lang);let i=this.getHighLightString(t,n);e.innerHTML=i}async highlight(e=this.source){const t=Coax.languages.get(this.lang),n=this.highlightEl.children.length,i=e?e.split("\n"):[],r=this.hasAttribute("speed"),a=this.hasAttribute("sanitized");if(this.updateName(t),!i.length)return!0;for(let[e,o]of i.entries()){if(!o.trim()&&a)continue;const i=this.createLineWrap(e,n),l=i.lastElementChild;i.completed=!0,r?(this.highlightEl.appendChild(i),await typeWriter(o,{speed:this.speed,onDuringType:(e,t)=>{l.innerHTML=t}}),this.getLineToFillHighLight(l,o,t)):(this.getLineToFillHighLight(l,o,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="",a="";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+="}",a="@media (prefers-color-scheme: dark){\n :host{\n ",a+=t.rules.map(t=>`\n ${t.light?`\n .${e}-${n}-${t.token} { color: var(--${e}-${n}-${t.token},${t.dark}); }`:""} `).join("\n"),a+="}",this.dynamicStylesEl.textContent=i+r+a,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")}trimLineString(e){return e.startsWith("\n")&&(e=e.substring(1)),e.endsWith("\n")&&(e=e.slice(0,-1)),e}render(){this._renderQueued||(this._renderQueued=!0,requestAnimationFrame(async()=>{this.highlightEl.innerHTML="",this.injectThemeStyles(),await this.highlight(),this._renderQueued=!1}))}clear(){this.highlightEl.innerHTML=this.source=this.lineString=""}async replace(e){e=escapeHtmlChars(e),this.source=trimEmptyLines(e),this._renderQueued||(this.highlightEl.innerHTML="",await this.highlight())}async append(e){e=escapeHtmlChars(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.getLineToFillHighLight(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){e=escapeHtmlChars(e);const{lineWrap:n,codeWrap:i}=this.getLastLine(),r=e.startsWith("\n")||e.endsWith("\n");this.highlightEl.appendChild(n),this.source+=e,this.lineString+=r?this.trimLineString(e):e,t||r?this.close():i.innerHTML+=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:/<!--[\s\S]*?-->/,light:"#999999",dark:"#6e7681"},{token:"doctype",pattern:/<!DOCTYPE[\s\S]*?>/i,light:"#6a737d",dark:"#8b949e"},{token:"tag",pattern:/<\/?[a-zA-Z0-9]+/,light:"#22863a",dark:"#7ee787"},{token:"attr",pattern:/[a-zA-Z-]+(?=\s*=\s*)/,light:"#6f42c1",dark:"#d2a8ff"},{token:"string",pattern:/(['"])(?:\\.|[^\\])*?\1/,light:"#032f62",dark:"#a5d6ff"},{token:"bracket",pattern:/\/?>/,light:"#24292e",dark:"#c9d1d9"}]}),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});
|
|
@@ -4,15 +4,12 @@
|
|
|
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
|
|
8
|
-
<style>
|
|
9
|
-
/* 白天模式变量 */
|
|
10
|
-
:root {}
|
|
11
|
-
</style>
|
|
7
|
+
<title>Coax - 使用append方法在末尾追加新代码高亮渲染</title>
|
|
12
8
|
|
|
13
9
|
</head>
|
|
14
10
|
|
|
15
11
|
<body>
|
|
12
|
+
<h1>Coax - 使用append方法在末尾追加新代码高亮渲染</h1>
|
|
16
13
|
<ax-code streaming tools="copy" indexed lang="js">
|
|
17
14
|
<code>
|
|
18
15
|
/**
|
|
@@ -4,15 +4,12 @@
|
|
|
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
|
|
8
|
-
<style>
|
|
9
|
-
/* 白天模式变量 */
|
|
10
|
-
:root {}
|
|
11
|
-
</style>
|
|
7
|
+
<title>Coax - 渲染css代码</title>
|
|
12
8
|
|
|
13
9
|
</head>
|
|
14
10
|
|
|
15
11
|
<body>
|
|
12
|
+
<h1>Coax - 渲染css代码</h1>
|
|
16
13
|
<ax-code lang="css">
|
|
17
14
|
<code>
|
|
18
15
|
/* Main Layout Style */
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<head>
|
|
5
5
|
<meta charset="UTF-8">
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
-
<title>
|
|
7
|
+
<title>Coax - deepseek 真实流式输出代码</title>
|
|
8
8
|
<style>
|
|
9
9
|
#output {
|
|
10
10
|
font-family: monospace;
|
|
@@ -22,10 +22,11 @@
|
|
|
22
22
|
</head>
|
|
23
23
|
|
|
24
24
|
<body>
|
|
25
|
+
<h1>Coax - deepseek 真实流式输出代码</h1>
|
|
25
26
|
<ax-code lang="js" indexed></ax-code>
|
|
26
27
|
|
|
27
28
|
<button>随机展示javascript</button>
|
|
28
|
-
<script src="
|
|
29
|
+
<script src="https://unpkg.com/@codady/utils/dist/utils.umd.js" type='text/javascript'></script>
|
|
29
30
|
<script src="../dist/coax.umd.js" type='text/javascript'></script>
|
|
30
31
|
<script type='text/javascript'>
|
|
31
32
|
|
|
@@ -4,23 +4,13 @@
|
|
|
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
|
|
8
|
-
<style>
|
|
9
|
-
/* 白天模式变量 */
|
|
10
|
-
:root {
|
|
11
|
-
--ax-html-comment: #6a737d;
|
|
12
|
-
--ax-html-doctype: #005cc5;
|
|
13
|
-
--ax-html-tag: #22863a;
|
|
14
|
-
--ax-html-attr: #6f42c1;
|
|
15
|
-
--ax-html-string: #032f62;
|
|
16
|
-
--ax-html-bracket: #24292e;
|
|
17
|
-
}
|
|
18
|
-
</style>
|
|
7
|
+
<title>Coax - 渲染html代码</title>
|
|
19
8
|
|
|
20
9
|
</head>
|
|
21
10
|
|
|
22
11
|
<body>
|
|
23
|
-
<
|
|
12
|
+
<h1>Coax - 渲染html代码</h1>
|
|
13
|
+
<ax-code lang="html" indexed>
|
|
24
14
|
<code>
|
|
25
15
|
<!---->
|
|
26
16
|
<!DOCTYPE html>
|