@codady/coax 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/LICENSE +24 -0
- package/README.md +236 -0
- package/dist/coax.cjs.js +181 -0
- package/dist/coax.cjs.min.js +15 -0
- package/dist/coax.esm.js +179 -0
- package/dist/coax.esm.min.js +15 -0
- package/dist/coax.umd.js +186 -0
- package/dist/coax.umd.min.js +15 -0
- package/examples/css-highlight.html +62 -0
- package/examples/html-highlight.html +43 -0
- package/examples/js-highlight.html +64 -0
- package/examples/ts-highlight.html +65 -0
- package/package.json +74 -0
- package/rollup.config.js +68 -0
- package/script-mini.js +43 -0
- package/script-note.js +34 -0
- package/src/Coax.js +192 -0
- package/src/Coax.ts +217 -0
- package/tsconfig.json +108 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @since Last modified: 2026-1-4 16:0:48
|
|
3
|
+
* @name Coax event management system.
|
|
4
|
+
* @version 0.0.1
|
|
5
|
+
* @author AXUI development team <3217728223@qq.com>
|
|
6
|
+
* @description Coax is a custom web component that enables syntax highlighting for various programming languages inside your HTML documents.
|
|
7
|
+
* @see {@link https://coax.axui.cn|Official website}
|
|
8
|
+
* @see {@link https://github.com/codady/coax/issues|github issues}
|
|
9
|
+
* @see {@link https://gitee.com/codady/coax/issues|Gitee issues}
|
|
10
|
+
* @see {@link https://www.npmjs.com/package/@codady/coax|NPM}
|
|
11
|
+
* @issue QQ Group No.1:952502085
|
|
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
|
+
* @license MIT license
|
|
14
|
+
*/
|
|
15
|
+
class Coax extends HTMLElement{static languages=new Map;rawCode;constructor(){super(),this.attachShadow({mode:"open"}),this.rawCode=this.textContent?.replace(/^\s*\n|\n\s*$/g,"")||""}static register(e,{rules:n,theme:t={},internalCss:a="",cssPrefix:r=""}){this.languages.set(e,{rules:n,theme:t,internalCss:a,cssPrefix:r}),document.querySelectorAll("ax-code").forEach(n=>{n.getAttribute("lang")===e&&n.render()})}connectedCallback(){this.render()}static get observedAttributes(){return["lang","height","max-height"]}attributeChangedCallback(){this.render()}render(){const e=this.getAttribute("lang")||"js",n=Coax.languages.get(e),t=n?.cssPrefix||e,a=this.getAttribute("height"),r=this.getAttribute("max-height");let s="",o="";if(n){const e=new RegExp(n.rules.map(e=>`(${e.reg.source})`).join("|"),"g");s=this.rawCode.replace(/[&<>]/g,e=>({"&":"&","<":"<",">":">"}[e])).replace(e,(e,...a)=>{const r=a.findIndex(e=>void 0!==e);return-1!==r&&n.rules[r]?`<span class="ax-${t}-${n.rules[r].name}">${e}</span>`:e}),o=n.rules.map(e=>`\n .ax-${t}-${e.name} { color: var(--ax-${t}-${e.name}); }\n `).join("\n")}else s=this.rawCode;const i=n?.theme?Object.entries(n.theme).map(([e,n])=>`--ax-${t}-${e}: ${n};`).join("\n"):"";this.shadowRoot.innerHTML=`\n <style>\n :host { \n ${i} \n\n font-size: var(--ax-code-fs,14px);\n display: block; \n padding: var(--ax-code-p,1em);\n box-sizing:border-box;\n line-height: var(--ax-code-lh,1.5);\n background-color:var(--ax-code-bg,rgba(0,0,0,0.02));\n color:var(--ax-code-c,#333);\n border:var(--ax-code-bw,1px) solid var(--ax-code-bc,rgba(0,0,0,0.08));\n height:${a||"var(--ax-code-h,auto)"};\n max-height:${r||"var(--ax-code-mh,500px)"};\n overflow:auto;\n transition: border-color 0.3s ease,color 0.3s ease; \n border-radius: var(--ax-code-r,9px);\n }\n pre,code{\n font-family:"Consolas", "Monaco", "Andale Mono", "Ubuntu Mono", "monospace", "microsoft yahei", "Microsoft JhengHei", "Yu Mincho", "simsun";\n margin:0;\n padding:0;\n }\n \n \n \n ${o}\n \n \n ${n?.internalCss||""}\n </style>\n <pre><code>${s}</code></pre>`}}customElements.define("ax-code",Coax),Coax.register("html",{rules:[{name:"comment",reg:/<!--[\s\S]*?-->/},{name:"doctype",reg:/<!DOCTYPE[\s\S]*?>/i},{name:"tag",reg:/<\/?[a-zA-Z0-9]+/},{name:"attr",reg:/[a-zA-Z-]+(?=\s*=\s*)/},{name:"string",reg:/(['"])(?:\\.|[^\\])*?\1/},{name:"bracket",reg:/\/?>/}]}),Coax.register("css",{rules:[{name:"comment",reg:/\/\*[\s\S]*?\*\//},{name:"value",reg:/(?:'|")(?:\\.|[^\\'"\b])*?(?:'|")/},{name:"func",reg:/[a-z-]+\(?=/},{name:"property",reg:/[a-z-]+(?=\s*:)/},{name:"selector",reg:/[.#a-z0-9, \n\t>:+()_-]+(?=\s*\{)/i},{name:"unit",reg:/(?<=\d)(px|em|rem|%|vh|vw|ms|s|deg)/},{name:"number",reg:/\b\d+(\.\d+)?\b/},{name:"punct",reg:/[{}();:]/}],theme:{type:"#61afef",keyword:"#d19a66",string:"#98c379",op:"#abb2bf"},internalCss:"\n .ax-css-string { color: var(--ax-code-string); }\n .ax-css-string::first-letter { color: var(--ax-code-c); }\n "}),Coax.register("js",{rules:[{name:"comment",reg:/\/\/[^\n]*|\/\*[\s\S]*?\*\//},{name:"string",reg:/(?:'|"|`)(?:\\.|[^\\'"\b])*?(?:'|"|`)/},{name:"keyword",reg:/\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/},{name:"builtin",reg:/\b(console|window|document|Math|JSON|true|false|null|undefined|Object|Array|Promise)\b/},{name:"number",reg:/\b\d+\b/},{name:"func",reg:/\b[a-zA-Z_]\w*(?=\s*\()/},{name:"op",reg:/[+\-*/%=<>!&|^~]+/}]}),Coax.register("ts",{rules:[{name:"comment",reg:/\/\/[^\n]*|\/\*[\s\S]*?\*\//},{name:"string",reg:/(?:'|"|`)(?:\\.|[^\\'"\b])*?(?:'|"|`)/},{name:"decorator",reg:/@[a-zA-Z_]\w*/},{name:"keyword",reg:/\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/},{name:"builtin",reg:/\b(any|boolean|never|number|string|symbol|unknown|void|undefined|null|boolean|true|false|console|window|document)\b/},{name:"type",reg:/\b[A-Z]\w*\b/},{name:"number",reg:/\b\d+\b/},{name:"func",reg:/\b[a-zA-Z_]\w*(?=\s*\()/},{name:"op",reg:/(\?\.|![:\.]|[+\-*/%=<>!&|^~]+)/}]});
|
package/dist/coax.umd.js
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
|
|
2
|
+
/*!
|
|
3
|
+
* @since Last modified: 2026-1-4 16:0:48
|
|
4
|
+
* @name Coax event management system.
|
|
5
|
+
* @version 0.0.1
|
|
6
|
+
* @author AXUI development team <3217728223@qq.com>
|
|
7
|
+
* @description Coax is a custom web component that enables syntax highlighting for various programming languages inside your HTML documents.
|
|
8
|
+
* @see {@link https://coax.axui.cn|Official website}
|
|
9
|
+
* @see {@link https://github.com/codady/coax/issues|github issues}
|
|
10
|
+
* @see {@link https://gitee.com/codady/coax/issues|Gitee issues}
|
|
11
|
+
* @see {@link https://www.npmjs.com/package/@codady/coax|NPM}
|
|
12
|
+
* @issue QQ Group No.1:952502085
|
|
13
|
+
* @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.
|
|
14
|
+
* @license MIT license
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
(function (factory) {
|
|
18
|
+
typeof define === 'function' && define.amd ? define(factory) :
|
|
19
|
+
factory();
|
|
20
|
+
})((function () { 'use strict';
|
|
21
|
+
|
|
22
|
+
class Coax extends HTMLElement {
|
|
23
|
+
// A static Map to hold the configuration for different languages
|
|
24
|
+
static languages = new Map();
|
|
25
|
+
// Raw code as text from the HTML content
|
|
26
|
+
rawCode;
|
|
27
|
+
constructor() {
|
|
28
|
+
super();
|
|
29
|
+
// Attach a Shadow DOM to the custom element
|
|
30
|
+
this.attachShadow({ mode: 'open' });
|
|
31
|
+
// Remove leading/trailing whitespace from the raw code content
|
|
32
|
+
this.rawCode = this.textContent?.replace(/^\s*\n|\n\s*$/g, '') || '';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static register(name, { rules, theme = {}, internalCss = '', cssPrefix = '' }) {
|
|
36
|
+
// Store the language configuration in the static map
|
|
37
|
+
this.languages.set(name, { rules, theme, internalCss, cssPrefix });
|
|
38
|
+
// Render the highlighted code for all elements with the registered language
|
|
39
|
+
document.querySelectorAll('ax-code').forEach(el => {
|
|
40
|
+
if (el.getAttribute('lang') === name)
|
|
41
|
+
el.render();
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
// Called when the element is connected to the DOM
|
|
45
|
+
connectedCallback() { this.render(); }
|
|
46
|
+
// Observed attributes for changes
|
|
47
|
+
static get observedAttributes() { return ['lang', 'height', 'max-height']; }
|
|
48
|
+
|
|
49
|
+
attributeChangedCallback() {
|
|
50
|
+
this.render();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
render() {
|
|
54
|
+
// Get language name, fallback to 'js' if not provided
|
|
55
|
+
const lang = this.getAttribute('lang') || 'js',
|
|
56
|
+
// Get the language configuration
|
|
57
|
+
config = Coax.languages.get(lang),
|
|
58
|
+
// Default to language name if no prefix is set
|
|
59
|
+
cssPrefix = config?.cssPrefix || lang, height = this.getAttribute('height'), maxHeight = this.getAttribute('max-height');
|
|
60
|
+
let highlightedCode = '', dynamicStyles = '';
|
|
61
|
+
if (config) {
|
|
62
|
+
//Generate the highlighted HTML by applying the syntax rules
|
|
63
|
+
const combinedRegex = new RegExp(config.rules.map((r) => `(${r.reg.source})`).join('|'), 'g'), escaped = this.rawCode.replace(/[&<>]/g, m => ({ '&': '&', '<': '<', '>': '>' }[m]));
|
|
64
|
+
// Replace code with highlighted syntax
|
|
65
|
+
highlightedCode = escaped.replace(combinedRegex, (match, ...args) => {
|
|
66
|
+
const index = args.findIndex(val => val !== undefined);
|
|
67
|
+
return index !== -1 && config.rules[index] ? `<span class="ax-${cssPrefix}-${config.rules[index].name}">${match}</span>` : match;
|
|
68
|
+
});
|
|
69
|
+
//Generate dynamic CSS classes for each syntax rule
|
|
70
|
+
// 为 rules 中的每一个 name 生成类似 .hl-name { color: var(--ax-code-name); }
|
|
71
|
+
dynamicStyles = config.rules.map((rule) => `
|
|
72
|
+
.ax-${cssPrefix}-${rule.name} { color: var(--ax-${cssPrefix}-${rule.name}); }
|
|
73
|
+
`).join('\n');
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
// If no config, display raw code without highlighting
|
|
77
|
+
highlightedCode = this.rawCode;
|
|
78
|
+
}
|
|
79
|
+
//Generate CSS theme variables if a theme is provided
|
|
80
|
+
const themeVars = config?.theme
|
|
81
|
+
? Object.entries(config.theme).map(([k, v]) => `--ax-${cssPrefix}-${k}: ${v};`).join('\n')
|
|
82
|
+
: '';
|
|
83
|
+
// Set the inner HTML of the shadow root, including styles and highlighted code
|
|
84
|
+
this.shadowRoot.innerHTML = `
|
|
85
|
+
<style>
|
|
86
|
+
:host {
|
|
87
|
+
${themeVars}
|
|
88
|
+
|
|
89
|
+
font-size: var(--ax-code-fs,14px);
|
|
90
|
+
display: block;
|
|
91
|
+
padding: var(--ax-code-p,1em);
|
|
92
|
+
box-sizing:border-box;
|
|
93
|
+
line-height: var(--ax-code-lh,1.5);
|
|
94
|
+
background-color:var(--ax-code-bg,rgba(0,0,0,0.02));
|
|
95
|
+
color:var(--ax-code-c,#333);
|
|
96
|
+
border:var(--ax-code-bw,1px) solid var(--ax-code-bc,rgba(0,0,0,0.08));
|
|
97
|
+
height:${height || 'var(--ax-code-h,auto)'};
|
|
98
|
+
max-height:${maxHeight || 'var(--ax-code-mh,500px)'};
|
|
99
|
+
overflow:auto;
|
|
100
|
+
transition: border-color 0.3s ease,color 0.3s ease;
|
|
101
|
+
border-radius: var(--ax-code-r,9px);
|
|
102
|
+
}
|
|
103
|
+
pre,code{
|
|
104
|
+
font-family:"Consolas", "Monaco", "Andale Mono", "Ubuntu Mono", "monospace", "microsoft yahei", "Microsoft JhengHei", "Yu Mincho", "simsun";
|
|
105
|
+
margin:0;
|
|
106
|
+
padding:0;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
${dynamicStyles}
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
${config?.internalCss || ''}
|
|
115
|
+
</style>
|
|
116
|
+
<pre><code>${highlightedCode}</code></pre>`;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
customElements.define('ax-code', Coax);
|
|
120
|
+
Coax.register('html', {
|
|
121
|
+
rules: [
|
|
122
|
+
{ name: 'comment', reg: /<!--[\s\S]*?-->/ },
|
|
123
|
+
{ name: 'doctype', reg: /<!DOCTYPE[\s\S]*?>/i },
|
|
124
|
+
// 匹配标签名: <div, </div
|
|
125
|
+
{ name: 'tag', reg: /<\/?[a-zA-Z0-9]+/ },
|
|
126
|
+
// 匹配属性名: class=
|
|
127
|
+
{ name: 'attr', reg: /[a-zA-Z-]+(?=\s*=\s*)/ },
|
|
128
|
+
// 匹配属性值: "value"
|
|
129
|
+
{ name: 'string', reg: /(['"])(?:\\.|[^\\])*?\1/ },
|
|
130
|
+
// 匹配标签闭合: >, />
|
|
131
|
+
{ name: 'bracket', reg: /\/?>/ }
|
|
132
|
+
],
|
|
133
|
+
//添加root变量:--ax-html-keyword
|
|
134
|
+
|
|
135
|
+
});
|
|
136
|
+
Coax.register('css', {
|
|
137
|
+
rules: [
|
|
138
|
+
{ name: 'comment', reg: /\/\*[\s\S]*?\*\// },
|
|
139
|
+
{ name: 'value', reg: /(?:'|")(?:\\.|[^\\'"\b])*?(?:'|")/ },
|
|
140
|
+
{ name: 'func', reg: /[a-z-]+\(?=/ },
|
|
141
|
+
{ name: 'property', reg: /[a-z-]+(?=\s*:)/ },
|
|
142
|
+
{ name: 'selector', reg: /[.#a-z0-9, \n\t>:+()_-]+(?=\s*\{)/i },
|
|
143
|
+
{ name: 'unit', reg: /(?<=\d)(px|em|rem|%|vh|vw|ms|s|deg)/ },
|
|
144
|
+
{ name: 'number', reg: /\b\d+(\.\d+)?\b/ },
|
|
145
|
+
{ name: 'punct', reg: /[{}();:]/ }
|
|
146
|
+
],
|
|
147
|
+
//添加root变量:--ax-code-keyword
|
|
148
|
+
theme: {
|
|
149
|
+
'type': '#61afef', // 蓝色选择器
|
|
150
|
+
'keyword': '#d19a66', // 橙色属性名
|
|
151
|
+
'string': '#98c379', // 绿色属性值
|
|
152
|
+
'op': '#abb2bf' // 灰色符号
|
|
153
|
+
},
|
|
154
|
+
internalCss: `
|
|
155
|
+
.ax-css-string { color: var(--ax-code-string); }
|
|
156
|
+
.ax-css-string::first-letter { color: var(--ax-code-c); }
|
|
157
|
+
`
|
|
158
|
+
});
|
|
159
|
+
Coax.register('js', {
|
|
160
|
+
rules: [
|
|
161
|
+
{ name: 'comment', reg: /\/\/[^\n]*|\/\*[\s\S]*?\*\// },
|
|
162
|
+
{ name: 'string', reg: /(?:'|"|`)(?:\\.|[^\\'"\b])*?(?:'|"|`)/ },
|
|
163
|
+
{ name: 'keyword', reg: /\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/ },
|
|
164
|
+
{ name: 'builtin', reg: /\b(console|window|document|Math|JSON|true|false|null|undefined|Object|Array|Promise)\b/ },
|
|
165
|
+
{ name: 'number', reg: /\b\d+\b/ },
|
|
166
|
+
{ name: 'func', reg: /\b[a-zA-Z_]\w*(?=\s*\()/ },
|
|
167
|
+
{ name: 'op', reg: /[+\-*/%=<>!&|^~]+/ }
|
|
168
|
+
],
|
|
169
|
+
|
|
170
|
+
});
|
|
171
|
+
Coax.register('ts', {
|
|
172
|
+
rules: [
|
|
173
|
+
{ name: 'comment', reg: /\/\/[^\n]*|\/\*[\s\S]*?\*\// },
|
|
174
|
+
{ name: 'string', reg: /(?:'|"|`)(?:\\.|[^\\'"\b])*?(?:'|"|`)/ },
|
|
175
|
+
{ name: 'decorator', reg: /@[a-zA-Z_]\w*/ },
|
|
176
|
+
{ name: 'keyword', reg: /\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/ },
|
|
177
|
+
{ name: 'builtin', reg: /\b(any|boolean|never|number|string|symbol|unknown|void|undefined|null|boolean|true|false|console|window|document)\b/ },
|
|
178
|
+
{ name: 'type', reg: /\b[A-Z]\w*\b/ },
|
|
179
|
+
{ name: 'number', reg: /\b\d+\b/ },
|
|
180
|
+
{ name: 'func', reg: /\b[a-zA-Z_]\w*(?=\s*\()/ },
|
|
181
|
+
{ name: 'op', reg: /(\?\.|![:\.]|[+\-*/%=<>!&|^~]+)/ }
|
|
182
|
+
],
|
|
183
|
+
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
}));
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @since Last modified: 2026-1-4 16:0:48
|
|
3
|
+
* @name Coax event management system.
|
|
4
|
+
* @version 0.0.1
|
|
5
|
+
* @author AXUI development team <3217728223@qq.com>
|
|
6
|
+
* @description Coax is a custom web component that enables syntax highlighting for various programming languages inside your HTML documents.
|
|
7
|
+
* @see {@link https://coax.axui.cn|Official website}
|
|
8
|
+
* @see {@link https://github.com/codady/coax/issues|github issues}
|
|
9
|
+
* @see {@link https://gitee.com/codady/coax/issues|Gitee issues}
|
|
10
|
+
* @see {@link https://www.npmjs.com/package/@codady/coax|NPM}
|
|
11
|
+
* @issue QQ Group No.1:952502085
|
|
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
|
+
* @license MIT license
|
|
14
|
+
*/
|
|
15
|
+
!function(e){"function"==typeof define&&define.amd?define(e):e()}(function(){"use strict";class Coax extends HTMLElement{static languages=new Map;rawCode;constructor(){super(),this.attachShadow({mode:"open"}),this.rawCode=this.textContent?.replace(/^\s*\n|\n\s*$/g,"")||""}static register(e,{rules:n,theme:t={},internalCss:a="",cssPrefix:r=""}){this.languages.set(e,{rules:n,theme:t,internalCss:a,cssPrefix:r}),document.querySelectorAll("ax-code").forEach(n=>{n.getAttribute("lang")===e&&n.render()})}connectedCallback(){this.render()}static get observedAttributes(){return["lang","height","max-height"]}attributeChangedCallback(){this.render()}render(){const e=this.getAttribute("lang")||"js",n=Coax.languages.get(e),t=n?.cssPrefix||e,a=this.getAttribute("height"),r=this.getAttribute("max-height");let s="",o="";if(n){const e=new RegExp(n.rules.map(e=>`(${e.reg.source})`).join("|"),"g");s=this.rawCode.replace(/[&<>]/g,e=>({"&":"&","<":"<",">":">"}[e])).replace(e,(e,...a)=>{const r=a.findIndex(e=>void 0!==e);return-1!==r&&n.rules[r]?`<span class="ax-${t}-${n.rules[r].name}">${e}</span>`:e}),o=n.rules.map(e=>`\n .ax-${t}-${e.name} { color: var(--ax-${t}-${e.name}); }\n `).join("\n")}else s=this.rawCode;const i=n?.theme?Object.entries(n.theme).map(([e,n])=>`--ax-${t}-${e}: ${n};`).join("\n"):"";this.shadowRoot.innerHTML=`\n <style>\n :host { \n ${i} \n\n font-size: var(--ax-code-fs,14px);\n display: block; \n padding: var(--ax-code-p,1em);\n box-sizing:border-box;\n line-height: var(--ax-code-lh,1.5);\n background-color:var(--ax-code-bg,rgba(0,0,0,0.02));\n color:var(--ax-code-c,#333);\n border:var(--ax-code-bw,1px) solid var(--ax-code-bc,rgba(0,0,0,0.08));\n height:${a||"var(--ax-code-h,auto)"};\n max-height:${r||"var(--ax-code-mh,500px)"};\n overflow:auto;\n transition: border-color 0.3s ease,color 0.3s ease; \n border-radius: var(--ax-code-r,9px);\n }\n pre,code{\n font-family:"Consolas", "Monaco", "Andale Mono", "Ubuntu Mono", "monospace", "microsoft yahei", "Microsoft JhengHei", "Yu Mincho", "simsun";\n margin:0;\n padding:0;\n }\n \n \n \n ${o}\n \n \n ${n?.internalCss||""}\n </style>\n <pre><code>${s}</code></pre>`}}customElements.define("ax-code",Coax),Coax.register("html",{rules:[{name:"comment",reg:/<!--[\s\S]*?-->/},{name:"doctype",reg:/<!DOCTYPE[\s\S]*?>/i},{name:"tag",reg:/<\/?[a-zA-Z0-9]+/},{name:"attr",reg:/[a-zA-Z-]+(?=\s*=\s*)/},{name:"string",reg:/(['"])(?:\\.|[^\\])*?\1/},{name:"bracket",reg:/\/?>/}]}),Coax.register("css",{rules:[{name:"comment",reg:/\/\*[\s\S]*?\*\//},{name:"value",reg:/(?:'|")(?:\\.|[^\\'"\b])*?(?:'|")/},{name:"func",reg:/[a-z-]+\(?=/},{name:"property",reg:/[a-z-]+(?=\s*:)/},{name:"selector",reg:/[.#a-z0-9, \n\t>:+()_-]+(?=\s*\{)/i},{name:"unit",reg:/(?<=\d)(px|em|rem|%|vh|vw|ms|s|deg)/},{name:"number",reg:/\b\d+(\.\d+)?\b/},{name:"punct",reg:/[{}();:]/}],theme:{type:"#61afef",keyword:"#d19a66",string:"#98c379",op:"#abb2bf"},internalCss:"\n .ax-css-string { color: var(--ax-code-string); }\n .ax-css-string::first-letter { color: var(--ax-code-c); }\n "}),Coax.register("js",{rules:[{name:"comment",reg:/\/\/[^\n]*|\/\*[\s\S]*?\*\//},{name:"string",reg:/(?:'|"|`)(?:\\.|[^\\'"\b])*?(?:'|"|`)/},{name:"keyword",reg:/\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/},{name:"builtin",reg:/\b(console|window|document|Math|JSON|true|false|null|undefined|Object|Array|Promise)\b/},{name:"number",reg:/\b\d+\b/},{name:"func",reg:/\b[a-zA-Z_]\w*(?=\s*\()/},{name:"op",reg:/[+\-*/%=<>!&|^~]+/}]}),Coax.register("ts",{rules:[{name:"comment",reg:/\/\/[^\n]*|\/\*[\s\S]*?\*\//},{name:"string",reg:/(?:'|"|`)(?:\\.|[^\\'"\b])*?(?:'|"|`)/},{name:"decorator",reg:/@[a-zA-Z_]\w*/},{name:"keyword",reg:/\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/},{name:"builtin",reg:/\b(any|boolean|never|number|string|symbol|unknown|void|undefined|null|boolean|true|false|console|window|document)\b/},{name:"type",reg:/\b[A-Z]\w*\b/},{name:"number",reg:/\b\d+\b/},{name:"func",reg:/\b[a-zA-Z_]\w*(?=\s*\()/},{name:"op",reg:/(\?\.|![:\.]|[+\-*/%=<>!&|^~]+)/}]})});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>Coax 代码高亮插件</title>
|
|
8
|
+
<style>
|
|
9
|
+
/* 白天模式变量 */
|
|
10
|
+
:root {
|
|
11
|
+
--ax-css-selector: #6f42c1;
|
|
12
|
+
/* 紫色:选择器最显眼 */
|
|
13
|
+
--ax-css-property: #005cc5;
|
|
14
|
+
/* 蓝色:属性名 */
|
|
15
|
+
--ax-css-string: #22863a;
|
|
16
|
+
/* 绿色:内容字符串 */
|
|
17
|
+
--ax-css-unit: #d73a49;
|
|
18
|
+
/* 红色:单位(如 px, rem) */
|
|
19
|
+
--ax-css-number: #005cc5;
|
|
20
|
+
/* 蓝色:数值 */
|
|
21
|
+
--ax-css-func: #e36209;
|
|
22
|
+
/* 橙色:函数如 var(), rgba() */
|
|
23
|
+
--ax-css-comment: #6a737d;
|
|
24
|
+
/* 灰色:注释 */
|
|
25
|
+
--ax-css-punct: #24292e;
|
|
26
|
+
/* 深灰:符号 */
|
|
27
|
+
}
|
|
28
|
+
</style>
|
|
29
|
+
|
|
30
|
+
</head>
|
|
31
|
+
|
|
32
|
+
<body>
|
|
33
|
+
<ax-code lang="css">
|
|
34
|
+
<code>
|
|
35
|
+
/* Main Layout Style */
|
|
36
|
+
.container > .header:hover {
|
|
37
|
+
display: flex;
|
|
38
|
+
width: 100%;
|
|
39
|
+
max-width: 1200px;
|
|
40
|
+
padding: 20px 1.5rem;
|
|
41
|
+
background-color: var(--primary-bg, #fff);
|
|
42
|
+
transition: all 300ms ease-in-out;
|
|
43
|
+
transform: rotate(5deg);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@media (max-width: 768px) {
|
|
47
|
+
.container {
|
|
48
|
+
grid-template-columns: 1fr;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
</code>
|
|
52
|
+
</ax-code>
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
<script src="../dist/coax.umd.js" type='text/javascript'></script>
|
|
57
|
+
<script type='text/javascript'>
|
|
58
|
+
|
|
59
|
+
</script>
|
|
60
|
+
</body>
|
|
61
|
+
|
|
62
|
+
</html>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>Coax 代码高亮插件</title>
|
|
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>
|
|
19
|
+
|
|
20
|
+
</head>
|
|
21
|
+
|
|
22
|
+
<body>
|
|
23
|
+
<ax-code lang="html">
|
|
24
|
+
<code>
|
|
25
|
+
<!---->
|
|
26
|
+
<!DOCTYPE html>
|
|
27
|
+
<div class="container" id="main-view">
|
|
28
|
+
<h1 title="Welcome">Hello World</h1>
|
|
29
|
+
<p data-info="example">
|
|
30
|
+
This is a Web Component demo.
|
|
31
|
+
</p>
|
|
32
|
+
<img src="logo.png" alt="Logo" />
|
|
33
|
+
</div>
|
|
34
|
+
</code>
|
|
35
|
+
</ax-code>
|
|
36
|
+
|
|
37
|
+
<script src="../dist/coax.umd.js" type='text/javascript'></script>
|
|
38
|
+
<script type='text/javascript'>
|
|
39
|
+
|
|
40
|
+
</script>
|
|
41
|
+
</body>
|
|
42
|
+
|
|
43
|
+
</html>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>Coax 代码高亮插件</title>
|
|
8
|
+
<style>
|
|
9
|
+
/* 白天模式变量 */
|
|
10
|
+
:root {
|
|
11
|
+
--ax-js-keyword: #d73a49;
|
|
12
|
+
/* 鲜红色:用于 if, const, return */
|
|
13
|
+
--ax-js-string: #032f62;
|
|
14
|
+
/* 藏青色:字符串内容 */
|
|
15
|
+
--ax-js-func: #6f42c1;
|
|
16
|
+
/* 靓紫色:函数名调用 */
|
|
17
|
+
--ax-js-builtin: #e36209;
|
|
18
|
+
/* 亮橙色:console, Math, true */
|
|
19
|
+
--ax-js-number: #005cc5;
|
|
20
|
+
/* 蓝色:数字 */
|
|
21
|
+
--ax-js-op: #d73a49;
|
|
22
|
+
/* 红色:操作符,突出逻辑 */
|
|
23
|
+
--ax-js-comment: #6a737d;
|
|
24
|
+
/* 灰色:注释 */
|
|
25
|
+
--ax-js-punct: #24292e;
|
|
26
|
+
/* 深灰色:标点符号 */
|
|
27
|
+
}
|
|
28
|
+
</style>
|
|
29
|
+
|
|
30
|
+
</head>
|
|
31
|
+
|
|
32
|
+
<body>
|
|
33
|
+
<ax-code lang="js">
|
|
34
|
+
<code>
|
|
35
|
+
/**
|
|
36
|
+
* Simple animation function
|
|
37
|
+
*/
|
|
38
|
+
async function animate(element, duration) {
|
|
39
|
+
const start = Date.now();
|
|
40
|
+
|
|
41
|
+
if (!element) return false;
|
|
42
|
+
|
|
43
|
+
console.log("Animation started...");
|
|
44
|
+
|
|
45
|
+
while (Date.now() - start < duration) {
|
|
46
|
+
let progress = (Date.now() - start) / duration;
|
|
47
|
+
element.style.opacity = Math.min(progress, 1);
|
|
48
|
+
await Promise.resolve();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
</code>
|
|
54
|
+
</ax-code>
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
<script src="../dist/coax.umd.js" type='text/javascript'></script>
|
|
59
|
+
<script type='text/javascript'>
|
|
60
|
+
|
|
61
|
+
</script>
|
|
62
|
+
</body>
|
|
63
|
+
|
|
64
|
+
</html>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>Coax 代码高亮插件</title>
|
|
8
|
+
<style>
|
|
9
|
+
/* 白天模式变量 */
|
|
10
|
+
:root {
|
|
11
|
+
--ax-ts-keyword: #d73a49;
|
|
12
|
+
/* 红色 */
|
|
13
|
+
--ax-ts-string: #032f62;
|
|
14
|
+
/* 深蓝 */
|
|
15
|
+
--ax-ts-decorator: #e36209;
|
|
16
|
+
/* 橙色 */
|
|
17
|
+
--ax-ts-type: #22863a;
|
|
18
|
+
/* 绿色:类和接口 */
|
|
19
|
+
--ax-ts-builtin: #005cc5;
|
|
20
|
+
/* 蓝色:基本类型 */
|
|
21
|
+
--ax-ts-func: #6f42c1;
|
|
22
|
+
/* 紫色 */
|
|
23
|
+
--ax-ts-op: #d73a49;
|
|
24
|
+
--ax-ts-comment: #6a737d;
|
|
25
|
+
}
|
|
26
|
+
</style>
|
|
27
|
+
|
|
28
|
+
</head>
|
|
29
|
+
|
|
30
|
+
<body>
|
|
31
|
+
<ax-code lang="ts">
|
|
32
|
+
<code>
|
|
33
|
+
@Component({
|
|
34
|
+
selector: 'app-user',
|
|
35
|
+
template: `<h1>{{ user.name }}</h1>`
|
|
36
|
+
})
|
|
37
|
+
export class UserProfile implements OnInit {
|
|
38
|
+
private userId: number = 101;
|
|
39
|
+
public user?: UserRecord;
|
|
40
|
+
|
|
41
|
+
constructor(private service: UserService) {}
|
|
42
|
+
|
|
43
|
+
async ngOnInit(): Promise<void> {
|
|
44
|
+
this.user = await this.service.getUser(this.userId);
|
|
45
|
+
console.log("User Loaded", this.user?.name);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
type UserRecord = {
|
|
50
|
+
id: number;
|
|
51
|
+
name: string;
|
|
52
|
+
isAdmin: boolean;
|
|
53
|
+
};
|
|
54
|
+
</code>
|
|
55
|
+
</ax-code>
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
<script src="../dist/coax.umd.js" type='text/javascript'></script>
|
|
60
|
+
<script type='text/javascript'>
|
|
61
|
+
|
|
62
|
+
</script>
|
|
63
|
+
</body>
|
|
64
|
+
|
|
65
|
+
</html>
|
package/package.json
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@codady/coax",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"author": "AXUI Development Team",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"description": "Coax is a custom web component that enables syntax highlighting for various programming languages inside your HTML documents.",
|
|
10
|
+
"main": "./src/Coax.js",
|
|
11
|
+
"type": "module",
|
|
12
|
+
"types": "./src/coax.d.ts",
|
|
13
|
+
"directories": {
|
|
14
|
+
"doc": "docs"
|
|
15
|
+
},
|
|
16
|
+
"private": false,
|
|
17
|
+
"workspaces": [],
|
|
18
|
+
"files": [
|
|
19
|
+
"examples",
|
|
20
|
+
"docs",
|
|
21
|
+
"dist",
|
|
22
|
+
"src",
|
|
23
|
+
"package.json",
|
|
24
|
+
"rollup.config.js",
|
|
25
|
+
"tsconfig.json",
|
|
26
|
+
"script-mini.js",
|
|
27
|
+
"script-note.js",
|
|
28
|
+
"CHANGELOG.md",
|
|
29
|
+
"README.md",
|
|
30
|
+
"LICENSE"
|
|
31
|
+
],
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@rollup/plugin-json": "^6.1.0",
|
|
34
|
+
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
35
|
+
"@types/node": "^22.19.1",
|
|
36
|
+
"archiver": "^7.0.1",
|
|
37
|
+
"cross-env": "^7.0.3",
|
|
38
|
+
"rollup": "^4.18.1",
|
|
39
|
+
"rollup-plugin-replace": "^2.2.0",
|
|
40
|
+
"terser": "^5.27.2"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "rollup --config",
|
|
44
|
+
"mini": "node script-mini.js",
|
|
45
|
+
"push": "node script-push.js",
|
|
46
|
+
"all": "cross-env REPLACE=true npm run build && npm run css && npm run mini && npm publish && (npm run push || true)"
|
|
47
|
+
},
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "https://github.com/codady/coax"
|
|
51
|
+
},
|
|
52
|
+
"extraRepositories": [
|
|
53
|
+
{
|
|
54
|
+
"type": "git",
|
|
55
|
+
"url": "https://gitee.com/codady/coax"
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
"keywords": [
|
|
59
|
+
"javascript",
|
|
60
|
+
"es6",
|
|
61
|
+
"components",
|
|
62
|
+
"vnode",
|
|
63
|
+
"mvvm",
|
|
64
|
+
"html5",
|
|
65
|
+
"css3"
|
|
66
|
+
],
|
|
67
|
+
"bugs": {
|
|
68
|
+
"url": "https://github.com/codady/coax/issues"
|
|
69
|
+
},
|
|
70
|
+
"homepage": "https://www.axui.cn",
|
|
71
|
+
"dependencies": {
|
|
72
|
+
"simple-git": "^3.27.0"
|
|
73
|
+
}
|
|
74
|
+
}
|
package/rollup.config.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Last modified: 2026/01/04 16:00:42
|
|
3
|
+
*/
|
|
4
|
+
import resolve from '@rollup/plugin-node-resolve';
|
|
5
|
+
import replace from 'rollup-plugin-replace';
|
|
6
|
+
import note from './script-note.js';
|
|
7
|
+
import json from '@rollup/plugin-json';
|
|
8
|
+
|
|
9
|
+
const sharePlugins = [
|
|
10
|
+
{
|
|
11
|
+
name: "remove-comments",
|
|
12
|
+
transform(code) {
|
|
13
|
+
const cleanedCode = code.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
14
|
+
return {
|
|
15
|
+
code: cleanedCode,
|
|
16
|
+
map: null,
|
|
17
|
+
};
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
process.env.REPLACE === 'true' && replace({
|
|
21
|
+
preventAssignment: true,
|
|
22
|
+
'console.log': '',
|
|
23
|
+
}),
|
|
24
|
+
resolve(),
|
|
25
|
+
json(),
|
|
26
|
+
].filter(Boolean);
|
|
27
|
+
export default [
|
|
28
|
+
{
|
|
29
|
+
input: './src/Coax.js',
|
|
30
|
+
output:
|
|
31
|
+
{
|
|
32
|
+
dir: './dist/',
|
|
33
|
+
format: 'umd',
|
|
34
|
+
name: 'coax',
|
|
35
|
+
entryFileNames: 'coax.umd.js',
|
|
36
|
+
banner: note,
|
|
37
|
+
},
|
|
38
|
+
plugins: [
|
|
39
|
+
...sharePlugins,
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
input: './src/Coax.js',
|
|
44
|
+
output:
|
|
45
|
+
{
|
|
46
|
+
dir: './dist/',
|
|
47
|
+
format: 'es',
|
|
48
|
+
entryFileNames: 'coax.esm.js',
|
|
49
|
+
banner: note,
|
|
50
|
+
},
|
|
51
|
+
plugins: [
|
|
52
|
+
...sharePlugins
|
|
53
|
+
],
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
input: './src/Coax.js',
|
|
57
|
+
output:
|
|
58
|
+
{
|
|
59
|
+
dir: './dist/',
|
|
60
|
+
format: 'cjs',
|
|
61
|
+
entryFileNames: 'coax.cjs.js',
|
|
62
|
+
banner: note,
|
|
63
|
+
},
|
|
64
|
+
plugins: [
|
|
65
|
+
...sharePlugins
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
]
|
package/script-mini.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* Last modified: 2026/01/04 16:02:23
|
|
4
|
+
*/
|
|
5
|
+
import { exec } from 'child_process';
|
|
6
|
+
|
|
7
|
+
const runCommand = (command) => {
|
|
8
|
+
return new Promise((resolve, reject) => {
|
|
9
|
+
exec(command, (error, stdout, stderr) => {
|
|
10
|
+
if (error) {
|
|
11
|
+
reject(`exec error: ${error}`);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (stderr) {
|
|
15
|
+
reject(`stderr: ${stderr}`);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
resolve(stdout);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const minifyJsFile = (input, output) => {
|
|
24
|
+
const command = `npx terser ${input} -o ${output} -c arguments,dead_code,directives,arrows,drop_console -m keep_classnames=true,keep_fnames=true`;
|
|
25
|
+
return runCommand(command);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
const minifyJs = async () => {
|
|
30
|
+
try {
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
await minifyJsFile('./dist/coax.umd.js', './dist/coax.umd.min.js');
|
|
34
|
+
await minifyJsFile('./dist/coax.esm.js', './dist/coax.esm.min.js');
|
|
35
|
+
await minifyJsFile('./dist/coax.cjs.js', './dist/coax.cjs.min.js');
|
|
36
|
+
|
|
37
|
+
console.log('Minification complete.');
|
|
38
|
+
} catch (error) {
|
|
39
|
+
console.error(`Error during minification: ${error}`);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
minifyJs();
|