├── www
├── favicon.ico
└── index.html
├── dist
├── res
│ ├── polyfill.js
│ ├── style.css
│ ├── sdrag.min.js
│ ├── split.css
│ ├── split.js
│ ├── html.min.js
│ └── moloader.min.js
├── z-minifier.min.js
├── preview.html
├── z-data.min.js
├── z-data.min.es2015.js
├── index.html
└── z-data.min.all.js
├── hello-world.html
├── LICENSE
├── package.json
├── css
├── README.md
└── atomic-css-rules.txt
├── README-cn.md
├── CHANGE.txt
├── README-en.md
├── README.md
└── src
└── z-data.js
/www/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Funlang/z-data/HEAD/www/favicon.ico
--------------------------------------------------------------------------------
/dist/res/polyfill.js:
--------------------------------------------------------------------------------
1 | if (Element.prototype.getAttributeNames == undefined) {
2 | Element.prototype.getAttributeNames = function () {
3 | var attributes = this.attributes;
4 | var length = attributes.length;
5 | var result = new Array(length);
6 | for (var i = 0; i < length; i++) {
7 | result[i] = attributes[i].name;
8 | }
9 | return result;
10 | };
11 | }
12 |
--------------------------------------------------------------------------------
/hello-world.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
12 | [if !i] i=${i}
17 |
18 |
19 | [if k=="j"] k=${k}
20 |
21 |
22 | [else] k=${k}
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/dist/res/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 |
5 | html,
6 | body {
7 | padding: 0;
8 | margin: 0;
9 | height: 100%;
10 | overflow: hidden;
11 | }
12 |
13 | /* @media screen and (min-width: 768px) {
14 | ::-webkit-scrollbar {
15 | width: 8px;
16 | height: 8px;
17 | }
18 | :hover::-webkit-scrollbar {
19 | background: #eee7;
20 | }
21 | :hover::-webkit-scrollbar-thumb {
22 | background: #cccc;
23 | }
24 | :hover::-webkit-scrollbar-button {
25 | height: 8px;
26 | width: 8px;
27 | background: #9999;
28 | }
29 | :hover::-webkit-scrollbar-track:hover {
30 | background: #fff;
31 | }
32 | :hover::-webkit-scrollbar-thumb:hover {
33 | background: #aaa;
34 | }
35 | :hover::-webkit-scrollbar-button:hover {
36 | background: #666;
37 | }
38 | } */
39 |
--------------------------------------------------------------------------------
/dist/res/sdrag.min.js:
--------------------------------------------------------------------------------
1 | Element.prototype.sdrag=function(o,e,r){var a=["left","top","right","bottom"],i={true:"left",false:"right"},s={true:"top",false:"bottom"},p=!0,g=!0,u=0,l=0,m=this,f=!1;function d(t){var e,n={};o&&o(m,t.pageX,u,t.pageY,l,n),"vertical"!==r&&(e=("pageX"in n?n:t).pageX,"startX"in n&&(u=n.startX),!1=="skipX"in n&&(m.style[i[p]]=(e-u)*(p?1:-1)+"px",m.style[i[!p]]="unset")),"horizontal"!==r&&(t=("pageY"in n?n:t).pageY,"startY"in n&&(l=n.startY),!1=="skipY"in n&&(m.style[s[g]]=(t-l)*(g?1:-1)+"px",m.style[s[!g]]="unset"))}this.addEventListener("mousedown",function(t){if(!(t.currentTarget instanceof HTMLElement||t.currentTarget instanceof SVGElement))throw new Error("Your target must be an html element");f=!0;var e=getComputedStyle(m),n={};a.forEach(t=>n[t]=e[t]?parseInt(e[t]):0),p=n.left{let s=UglifyJS.minify(t?"$_z_d="+e:e).code;return s?s.replace(/;$|^\$_z_d=/g,""):e},n=e=>e.replace(/^\s+|\s+$|\/\*[^]*?\*\//g,"").replace(/\s{2,}|\r?\n/g," ").replace(/('[^']*'|"[^"]*")|\s*([{};:,])\s*|([(\[])\s+|\s+([)\]])/g,(e,t,s,a,l)=>(t||"")+(s||"")+(a||"")+(l||"")).replace(/[-\w]+:\s*;/g,"").replace(/;+([;}]|$)/g,"$1"),r=(e,t)=>"style"==e?n(t):"class"==e?t.replace(/^\s+|\s+$|(\s)\s+/g,"$1"):/^(?:[@:.#]|on)\w+|^z-data$/.test(e)?c(t,!e.startsWith("on")):t;let i=[],s;if("string"==typeof t){let e=document.createElement("z-temp");e.innerHTML=t.replace(/<[^>]*? html>/,e=>(s=e,"")).replace(/<\/?(html|head|body)\b/g,e=>e+"-mini"),t=e}return p(t),i.join("").replace(/(<\/?(html|head|body))-mini\b/g,(e,t)=>t).replace(//,e=>s||e);function p(t){for(let e=(t.content||t).firstChild;e;e=e.nextSibling)!function(s){switch(s.nodeType){case 1:i.push("<",s.localName),s.getAttributeNames().forEach(e=>{i.push(" ",e);let t;(t=r(e,s.getAttribute(e)))&&(i.push("="),/[\s>'"]/.test(t)&&(t=t.includes('"')?"'"+t+"'":'"'+t+'"'),i.push(t))}),i.push(">"),"script"==s.localName?i.push(c(s.textContent)):"style"==s.localName?i.push(n(s.textContent)):p(s),l.includes(s.localName)||i.push("",s.localName,">");break;case 3:/\S/.test(s.nodeValue)&&i.push(s.nodeValue.replace(/\s{2,}/g," "));break;case 8:let e;a&&(e=s.data.match(/^\s*@(\w+):\s*([^]+?)\s*\/?$/))&&(a[e[1]]=e[2])}}(e)}}
--------------------------------------------------------------------------------
/dist/preview.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | z-data studio
7 |
8 |
9 |
10 |
11 |
12 |
13 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
46 |
47 |
--------------------------------------------------------------------------------
/dist/res/split.css:
--------------------------------------------------------------------------------
1 | [data-flex-splitter-horizontal],
2 | [data-flex-splitter-vertical] {
3 | display: flex;
4 | height: 100%;
5 | }
6 | [data-flex-splitter-horizontal] > *,
7 | [data-flex-splitter-vertical] > * {
8 | flex: none;
9 | /* overflow: auto; */
10 | box-sizing: border-box;
11 | }
12 | [data-flex-splitter-horizontal] > [role="separator"],
13 | [data-flex-splitter-vertical] > [role="separator"] {
14 | touch-action: none;
15 | display: flex;
16 | align-items: center;
17 | justify-content: center;
18 | background-color: rgba(160, 160, 160, 0.15);
19 | z-index: 100;
20 | }
21 | [data-flex-splitter-horizontal] > [role="separator"]:hover,
22 | [data-flex-splitter-vertical] > [role="separator"]:hover {
23 | background-color: rgba(160, 160, 160, 0.45);
24 | }
25 | [data-flex-splitter-horizontal] > [role="separator"]::before,
26 | [data-flex-splitter-vertical] > [role="separator"]::before {
27 | content: "";
28 | box-sizing: border-box;
29 | border: 4px rgba(160, 160, 160, 0.8);
30 | }
31 | [data-flex-splitter-horizontal] > [role="separator"] {
32 | cursor: ew-resize;
33 | width: 4px;
34 | }
35 | [data-flex-splitter-horizontal] > [role="separator"]::before {
36 | width: 8px;
37 | margin: -2px;
38 | height: 24px;
39 | border-style: double;
40 | }
41 | [data-flex-splitter-vertical] {
42 | flex-direction: column;
43 | }
44 | [data-flex-splitter-vertical] > [role="separator"] {
45 | cursor: ns-resize;
46 | height: 4px;
47 | }
48 | [data-flex-splitter-vertical] > [role="separator"]::before {
49 | width: 24px;
50 | height: 8px;
51 | margin: -2px;
52 | border-style: double;
53 | }
54 |
--------------------------------------------------------------------------------
/css/atomic-css-rules.txt:
--------------------------------------------------------------------------------
1 |
2 | s = \w+ # 小写字母, 正则表达式, 在规则中使用时换成大写
3 | ss = [\w\-]+
4 | n = -?(\d*\.)?\d+|--\w+
5 | u = \w+|%
6 | PM = {p: 'padding', m: 'margin'} # 大写, 缩写列表, 在规则左侧时为 p|m, 在规则右侧时展开为 PM[pm]
7 | HW = {h: 'height', w: 'width'}
8 | XN = {x: 'max', n: 'min'}
9 | LTRB = {l: 'left', t: 'top', r: 'right', b: 'bottom'}
10 | FSLH = {font: 'font-size', lh: 'line-height', gap: 'gap', gapr: 'row-gap', gapc: 'column-gap', brad: 'border-radius'}
11 | OOZ = {op: 'opacity', ord: 'order', z: 'z-index'}
12 | POS = {pos: 'position', d: 'display', cs: 'cursor', v: 'visibility', ws: 'white-space', us: 'user-select', pe: 'pointer-events'}
13 | OF = {o: 'overflow'}
14 | COLOR = {b: 'background', c: 'color'}
15 | IF = (s, set, b = '-', a = '') => s ? b + (set[s]||s) + a : '' # 大写, 函数, 可以应用在规则右侧
16 | NUMS = (num, unit) => /^--/.test(num) ? `var(${num})` : `${unit ? num : num / 4}${unit || 'rem'}`
17 | MINW = {sm: 640, s: 640, md: 768, m: 768, lg: 1024, l: 1024, xl: 1280, '2xl': 1536, xxl: 1536}
18 |
19 | # 规则, 左侧为 BNF 形正则式, (名称 类型), 方括号 [] 表示可选; 规则右式中 {} 翻译为 ${}, [] 翻译为可选的 ${IF(...)}
20 | # padding/margin
21 | (pm PM) [side LTRB] (num N) [unit U] = {pm}[-side]:{NUMS(num,unit)}
22 | # 上式翻译为下式
23 | # /^(?p|m)(?l|t|r|b)?(?-?(\d*\.)?\d+)(?\w+|%)?$/, `${PM[pm]}${IF(side,LTRB)}:${NUMS(num,unit)}`
24 |
25 | # 合并式规则, 翻译成多条短语, 可以再次应用规则
26 | (pm [pm]) x (any) => {pm}l{any} {pm}r{any}
27 | (pm [pm]) y (any) => {pm}t{any} {pm}b{any}
28 |
29 | # max/min - height/width, font-size/line-height
30 | [xn XN] (hw HW) (num N) [unit U] = [xn-]{hw}:{NUMS(num,unit)}
31 | (fslh FSLH) (num N) [unit U] = {fslh}:{NUMS(num,unit)}
32 | # left/top/right/bottom
33 | (side LTRB) (num N) [unit U] = {side}:{NUMS(num,unit)}
34 | # opacity/order/z-index
35 | (ooz OOZ) (num N) = {ooz}:{/^--/.test(num) ? `var(${num})` : num > 1 && ooz == 'op' ? num / 100 : num}
36 | # position/display/overflow
37 | (pos POS) - (value SS) = {pos}:{value}
38 | (of OF) [xy x|y] - (value S) = {of}[-xy]:{value}
39 | # content/color/background
40 | (name content) [value -\S+] = {name}:'{value ? value.slice(1) : ''}'
41 | (name COLOR) (color #[0-9a-fA-F]+|--\w+) = {name}:{/^--/.test(color) ? `var(${color})` : color}
42 |
43 | # brad - border-radius
44 | (a brad) (side LTRB) (sidE LTRB) (num N) [unit U] = border-{side}-{sidE}-radius:{NUMS(num,unit)}
45 | (a brad) (side [tb]) (any) => brad{side}l{any} brad{side}r{any}
46 |
47 | # 属性样式语法
48 | # 1. 空属性, 表达 样式和值, 用 正则表达式 可以直接替换
49 | # 2. 属性=值, 表达为 修饰符=样式和值 组
50 | # 修饰符主要分为 3 种:
51 | # 1. 伪类, 后修饰符, 如 hover=m1, after="p1 text-center", 用于 :hover, :after 等
52 | # 2. 父/前 伪类, 前修饰符, 如 a-hover=m1, a~not-hover=d-none 等
53 | # 3. 媒体查询类
54 | # 3. 属性=值, 表达为 分组=样式和值 组, 如
55 | # bg="... ... ...", animate="... ... ..."
56 | #
57 |
58 | media = ((?sm?|md?|lg?|xl|[2x]xl|print):)?
59 | state = ((?(?!not)\w+)(?[-+~\^]))?(?not-)?(?hover|focus(-\w+)?|active|after|before|(first|last)(-\w+)*)
60 | group = (?bd|bl|bt|br|bb|bg|a|al|font|flex|grid|mask)
61 |
--------------------------------------------------------------------------------
/dist/res/split.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | addEventListener("pointerdown", function(t) {
3 | var e = t.target,
4 | i = e.parentElement;
5 | if (
6 | i &&
7 | t.isPrimary &&
8 | 0 === t.button &&
9 | "separator" === e.getAttribute("role")
10 | ) {
11 | var n = i.hasAttribute("data-flex-splitter-vertical"),
12 | r = i.hasAttribute("data-flex-splitter-horizontal");
13 | if (n || r) {
14 | t.preventDefault();
15 | var a,
16 | o = t.pointerId,
17 | s = e.previousElementSibling,
18 | p = e.nextElementSibling;
19 | if (getComputedStyle(i).flexDirection.indexOf('reverse') > 0) {
20 | [s, p] = [p, s]
21 | }
22 | var h = getComputedStyle(s),
23 | l = getComputedStyle(p),
24 | d = s.getBoundingClientRect();
25 | if (n) {
26 | var m = d.top + t.offsetY,
27 | f = s.offsetHeight + p.offsetHeight,
28 | v = Math.max(
29 | parseInt(h.minHeight, 10) || 0,
30 | f - (parseInt(l.maxHeight, 10) || f)
31 | ),
32 | u = Math.min(
33 | parseInt(h.maxHeight, 10) || f,
34 | f - (parseInt(l.minHeight, 10) || 0)
35 | );
36 | a = function(t) {
37 | if (t.pointerId === o) {
38 | var e = Math.round(
39 | Math.min(Math.max(t.clientY - m, v), u)
40 | );
41 | (s.style.height = e + "px"),
42 | (p.style.height = f - e + "px");
43 | }
44 | };
45 | } else {
46 | var x = d.left + t.offsetX,
47 | g = s.offsetWidth + p.clientWidth,
48 | c = Math.max(
49 | parseInt(h.minWidth, 10) || 0,
50 | g - (parseInt(l.maxWidth, 10) || g)
51 | ),
52 | I = Math.min(
53 | parseInt(h.maxWidth, 10) || g,
54 | g - (parseInt(l.minWidth, 10) || 0)
55 | );
56 | a = function(t) {
57 | if (t.pointerId === o) {
58 | var e = Math.round(
59 | Math.min(Math.max(t.clientX - x, c), I)
60 | );
61 | (s.style.width = e + "px"),
62 | (p.style.width = g - e + "px");
63 | }
64 | };
65 | }
66 | var E = function(t) {
67 | t.pointerId === o &&
68 | (e.releasePointerCapture(o),
69 | e.removeEventListener("pointermove", a),
70 | e.removeEventListener("pointerup", E),
71 | e.removeEventListener("pointercancel", E));
72 | };
73 | a(t),
74 | (s.style.flexShrink = p.style.flexShrink = 1),
75 | e.addEventListener("pointercancel", E),
76 | e.addEventListener("pointerup", E),
77 | e.addEventListener("pointermove", a),
78 | e.setPointerCapture(o);
79 | }
80 | }
81 | });
82 |
--------------------------------------------------------------------------------
/dist/res/html.min.js:
--------------------------------------------------------------------------------
1 | var lang_zdata={defaultToken:"",tokenPostfix:".html",ignoreCase:!0,tokenizer:{root:[[/)/,["delimiter","tag","","delimiter"]],[/(<)(script)/,["delimiter",{token:"tag",next:"@script"}]],[/(<)(style)/,["delimiter",{token:"tag",next:"@style"}]],[/(<)((?:[\w\-]+:)?[\w\-]+)/,["delimiter",{token:"tag",next:"@otherTag"}]],[/(<\/)((?:[\w\-]+:)?[\w\-]+)/,["delimiter",{token:"tag",next:"@otherTag"}]],[/,"delimiter"],[/[^<]+/]],doctype:[[/[^>]+/,"metatag.content"],[/>/,"metatag","@pop"]],comment:[[/-->/,"comment","@pop"],[/[^-]+/,"comment.content"],[/./,"comment.content"]],otherTag:[[/\/?>/,"delimiter","@pop"],[/(=)(\s*)("(?:[^"]*?)"|'(?:[^']*?)'|[^\s>]+)/,["delimiter","","attribute.value"]],[/\b(z-data)(=)(')/,["keyword","delimiter",{token:"attribute.name",next:"@scriptEmbedded1",nextEmbedded:"text/javascript"}]],[/\b(z-data)(=)(")/,["keyword","delimiter",{token:"attribute.name",next:"@scriptEmbedded2",nextEmbedded:"text/javascript"}]],[/([:.@!#]*)([\w\-]+)/,["attribute.value","attribute.name"]],[/=/,"delimiter"],[/[ \t\r\n]+/]],script:[[/type/,"attribute.name","@scriptAfterType"],[/(=)(\s*)("(?:[^"]*?)"|'(?:[^']*?)'|[^\s>]+)/,["delimiter","","attribute.value"]],[/([:.@!#]*)([\w\-]+)/,["attribute.value","attribute.name"]],[/=/,"delimiter"],[/>/,{token:"delimiter",next:"@scriptEmbedded",nextEmbedded:"text/javascript"}],[/[ \t\r\n]+/],[/(<\/)(script\s*)(>)/,["delimiter","tag",{token:"delimiter",next:"@pop"}]]],scriptAfterType:[[/=/,"delimiter","@scriptAfterTypeEquals"],[/>/,{token:"delimiter",next:"@scriptEmbedded",nextEmbedded:"text/javascript"}],[/[ \t\r\n]+/],[/<\/script\s*>/,{token:"@rematch",next:"@pop"}]],scriptAfterTypeEquals:[[/"([^"]*)"/,{token:"attribute.value",switchTo:"@scriptWithCustomType.$1"}],[/'([^']*)'/,{token:"attribute.value",switchTo:"@scriptWithCustomType.$1"}],[/>/,{token:"delimiter",next:"@scriptEmbedded",nextEmbedded:"text/javascript"}],[/[ \t\r\n]+/],[/<\/script\s*>/,{token:"@rematch",next:"@pop"}]],scriptWithCustomType:[[/>/,{token:"delimiter",next:"@scriptEmbedded.$S2",nextEmbedded:"$S2"}],[/(=)(\s*)("(?:[^"]*?)"|'(?:[^']*?)'|[^\s>]+)/,["delimiter","","attribute.value"]],[/([:.@!#]*)([\w\-]+)/,["attribute.value","attribute.name"]],[/=/,"delimiter"],[/[ \t\r\n]+/],[/<\/script\s*>/,{token:"@rematch",next:"@pop"}]],scriptEmbedded:[[/<\/script/,{token:"@rematch",next:"@pop",nextEmbedded:"@pop"}],[/[^<]+/,""]],scriptEmbedded1:[[/'/,{token:"attribute.name",next:"@pop",nextEmbedded:"@pop"}],[/[^']+/,""]],scriptEmbedded2:[[/"/,{token:"attribute.name",next:"@pop",nextEmbedded:"@pop"}],[/[^"]+/,""]],style:[[/type/,"attribute.name","@styleAfterType"],[/(=)(\s*)("(?:[^"]*?)"|'(?:[^']*?)'|[^\s>]+)/,["delimiter","","attribute.value"]],[/([:.@!#]*)([\w\-]+)/,["attribute.value","attribute.name"]],[/=/,"delimiter"],[/>/,{token:"delimiter",next:"@styleEmbedded",nextEmbedded:"text/css"}],[/[ \t\r\n]+/],[/(<\/)(style\s*)(>)/,["delimiter","tag",{token:"delimiter",next:"@pop"}]]],styleAfterType:[[/=/,"delimiter","@styleAfterTypeEquals"],[/>/,{token:"delimiter",next:"@styleEmbedded",nextEmbedded:"text/css"}],[/[ \t\r\n]+/],[/<\/style\s*>/,{token:"@rematch",next:"@pop"}]],styleAfterTypeEquals:[[/"([^"]*)"/,{token:"attribute.value",switchTo:"@styleWithCustomType.$1"}],[/'([^']*)'/,{token:"attribute.value",switchTo:"@styleWithCustomType.$1"}],[/>/,{token:"delimiter",next:"@styleEmbedded",nextEmbedded:"text/css"}],[/[ \t\r\n]+/],[/<\/style\s*>/,{token:"@rematch",next:"@pop"}]],styleWithCustomType:[[/>/,{token:"delimiter",next:"@styleEmbedded.$S2",nextEmbedded:"$S2"}],[/(=)(\s*)("(?:[^"]*?)"|'(?:[^']*?)'|[^\s>]+)/,["delimiter","","attribute.value"]],[/([:.@!#]*)([\w\-]+)/,["attribute.value","attribute.name"]],[/=/,"delimiter"],[/[ \t\r\n]+/],[/<\/style\s*>/,{token:"@rematch",next:"@pop"}]],styleEmbedded:[[/<\/style/,{token:"@rematch",next:"@pop",nextEmbedded:"@pop"}],[/[^<]+/,""]]}};
2 | const EmpELs=["area","base","br","col","embed","hr","img","input","keygen","link","menuitem","meta","param","source","track","wbr"],lang_conf={wordPattern:/(-?\d*\.\d\w*)|([^\`\~\!\@\$\^\&\*\(\)\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\s]+)/g,comments:{blockComment:[""]},brackets:[[""],["<",">"],["{","}"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],surroundingPairs:[{open:'"',close:'"'},{open:"'",close:"'"},{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"<",close:">"}],onEnterRules:[{beforeText:new RegExp(`<(?!(?:${EmpELs.join("|")}))([_:\\w][_:\\w-.\\d]*)([^/>]*(?!/)>)[^<]*$`,"i"),afterText:/^<\/([_:\w][_:\w-.\d]*)\s*>$/i,action:{indentAction:2}},{beforeText:new RegExp(`<(?!(?:${EmpELs.join("|")}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`,"i"),action:{indentAction:1}}],folding:{markers:{start:new RegExp("^\\s*"),end:new RegExp("^\\s*")}}};
3 |
--------------------------------------------------------------------------------
/dist/z-data.min.js:
--------------------------------------------------------------------------------
1 | const ZData=(()=>{var n,i=0,B=0,g=0,u=0,e="Attribute",t="Element",s=t+"Sibling",r=t+"Child";const k="z-data",$="z-comp",x="z-none",p="init",w="args",U="key",G="use",z="_z_d",v=`[${k}]`,D="get"+e,Z="set"+e,m="remove",C=m+e,E="first"+r,I="last"+r,J="previous"+s,P="next",A=P+s,y="create"+t,f="parent"+t,L="insertBefore",_="forEach",O="includes",j="length",Q="startsWith",M=(e,t=/ +/)=>e.trim().split(t),T="replace",N="textContent",X="input",Y="change",ee="class",W="style",h="querySelector",F=document,te=(e,t=F)=>t[h+"All"](e),o=(e,t=`[${x}]`)=>e.closest(t),se="addEventListener",K=Object.keys,a=Object.values,dP="deleteProperty",R=(e,t="object")=>typeof e==t,l=e=>R(e,"function"),S=void 0,re=/^(?:camel|prevent|stop|debounce|(\d+)(?:(m?)s)|capture|once|passive|self|out|window|document|(shift|ctrl|alt|meta)|(cmd))$/,ie=/^(?:\s*(?:(\w+)\s*:\s*)?(\w*)(?:\s*,\s*(\w+))?\s+in\s+)?(.+)$/,ae=/^[:@.#!].|^z-d-/,le=/^(?:(:)(:?)(!?)|(@)|([.#!])|(z-d-))?([^.]*)(?:[.]([^.].*))?$/,ne=e=>e&&0<=e.indexOf("${")&&e.indexOf("`")<0,oe=/[-_ ]+/g,c=/-([a-z])/g,d=new WeakMap,pe=(t,s)=>{if(!t||!R(t)||l(t)||t.__ob__||t._isVue||!delete t[s.i])return t;{let e=d.get(t);if(e||((e={s:{},set(e,t,s,r){for(var i in this.s)this.s[i].set(e,t,s,r);return!0},[dP](e,t){let s,r=!0;for(s in this.s)r=this.s[s][dP](e,t)&&r;return r}}).p=new Proxy(t,e),d.set(t,e).set(e.p,e)),!e.s[s.i])for(var r in e.s[s.i]=s,t)try{t[r]=n(t[r],s)}catch(e){}return e.p}},fe=(e,t,s)=>e.dispatchEvent(new CustomEvent(t,{detail:s,bubbles:!0})),q=(t,s)=>{if(!t[z]||!(i<=t[z].age||t[z].ing)){(t[z]||(t[z]={})).age=i,t[z].ing=(t[z].ing||0)+1,s=s&&(t[z].env=s)||t[z].env||{ps:{$emit:fe},d:{}};var e=e=>{u++,Ce(F.body),de({p:t[f],el:t},{...s,d:t[z].zd,r:t},e||i),u--,Ee(F.body)};let l=b(e);var r=t[z].zd;if(!r){let a={i:z+Math.random(),set(e,t,s,r,i){l();try{i||(e[t]=n(s,a))}catch(e){}return!0},[dP](e,t){return t!=this.i&&(l(),delete e[t])}};n=window.ZDataProxy||pe,ZData.proxy=e=>n(e,a),r=V(t,t[D](k),s,S,t[w]||{})||{},t.$data=t[z].zd=r=n(r,a),t[Z](k,""),t[w]&&(r[w]=t[w]),V(t,t[D](p),{...s,d:r})}e(1),t[z].ing--}},ce={},de=(r,i,c)=>{let{p:s,el:a,cp:e}=r,t;var l=a[z]||(a[z]={});let n=l.as||(l.as=(t=ce[a[D]("z-d")])?(l.ps=t.ps,t.as):a.getAttributeNames());if(!n[O](x)){if(!e){let e,t;if(c===S&&n[O](k))return q(a,i);if(n[O]($)&&(e=a[D]($))){try{a[C]($),(t=/^([.\/]|https?:)/.test(e)?fetch(e).then(e=>e.text()):/^z:/.test(e)&&ZData.get?ZData.get(e):V(a,e,i)).then(e=>{var t=V(a,a[D](w),i);"-"==a.tagName[1]||n[O]("del")?Ze(e,s,a,t,1):Ze(e,a,S,t)}).catch(ve)}catch(e){}return}if("template"==a.localName){if(a.content||(a.content=F.createDocumentFragment())[L](a[E],S),e=a[D]("for")){var p=r;l=e;var f=i;c=ie.exec(l);if(c){var d,{p:u,el:v}=p;let e=V(v,c[4],f),t={k:c[1],v:c[2],i:c[3]},i={...f,ps:{...f.ps}},s=v[D](U),r=s&&M(s,"."),a=v[z].ns||(v[z].ns={}),l=0,n=v,o=v[z].age=(v[z].age||0)+1;for(d in r=r&&2==r[j]&&r[0]==t.v&&r[1],t.k&&(i.ps[t.k]=S),t.v&&(i.ps[t.v]=S),t.i&&(i.ps[t.i]=S),e){var m=e[d],m=(t.k&&(i.ps[t.k]=d),t.v&&(i.ps[t.v]=m),t.i&&(i.ps[t.i]=l++),r?m[r]:s?V(v,s,i):t.k?d:m);if(m!==S){t.k&&(i.ps[t.k]=m);let r=n[A],e=a[m];if(e){if(e.age==o)continue;let t=e.t[A],s=e.s!=r;s&&r&&!e.s[z].skip&&(r[z].skip=1,r=(p.el=r)[z].t[A],H(p,i,e=>e!=r,ve),s=e.s!=(r=p[P])),p.el=e.s,p.el[z].skip=0,H({...p},i,e=>e!=t),H(p,i,e=>e!=t,({p:e,el:t})=>{s&&e[L](t,r)}),s?p[P]=r:r=p[P],e.age=o}else p.el=v,me(p,i),p.el=n[A],e=a[m]={age:o,s:p.el},H(p,i,e=>e!=r);e.s[z].t=e.t=n=r?r[J]:u[I]}}K(a).filter(e=>a[e].age!=o)[_](e=>{be({el:a[e].s},a[e].t[A],f),delete a[e]}),p[P]=n[A]}}else{e=a[D]("if");var l=r,c=e,o=i,{p:h,el:b}=l;if(!c||V(b,c,o)){let e,t=l[P],s=ve;b[z].fi?(t=b[z].fi[A],(e=(e=b[D](G))&&V(b,"`"+e+"`",o))&&b[z].u!=e&&(he(l,o),me({...l,el:b,next:t},o))):(me(l,o),s=he),l.el=b[A],H(l,o,e=>e!=t),H(l,o,ue,s),b[z].fi=t?t[J]:h[I]}else he(l,o)}return}}{var g=r;var y=i;c=n;let p=g["el"],s=p[z],a=s.vs||(s.vs=[]),f=s.ps;if(!f){f=s.ps={ps:[]};if(g.cp){ce[++B]={as:c,ps:f};p[Z]("z-d",B)}c[_](n=>{let o=p[D](n);if(ae.test(n)||ne(o)){let s=le.exec(n),r=s[7],i=s[5],a=s[6],l=i?i!="."||!r?(r=ZData.ss(r),W):ee:r;l=ye[l]||l;if(l){let e=s[8]&&M(s[8],".")||[];let t={a:n,k:a?S:l==ee||!e[O]("camel")?l:ge(l),b:s[4]&&3||s[2]&&2||(s[1]||i||a)&&1||S,m:i&&r?[r,...e]:e,e:a?`${ge(l)}({e:this,v:${o||true},m:{${e.map(e=>e+":1").join()}}})`:o,A:s[3]||e[O]("attr")};if(!t.b||i=="!")t.e="`"+t.e+"`";f.ps.push(t);t.b&&p[C](n)}}else ZData.ss(n,o)});let e,t;if((e=p.firstChild)&&e==p.lastChild&&e.nodeType==3&&ne(t=e.nodeValue))f.ps.push({k:N,e:"`"+t+"`",m:[]})}if(!g.cp){let i=0,t=s=>{if("*"==s.k)for(var e in s.K=V(p,s.e,y,s)||{})t({...s,k:e,e:s.K[e],E:1,f:S});else if(3==s.b)$e(g,s,y);else{let t=s.e;s.E||(t=V(p,t,y,s,s.k?S:1),s.k)||(s.e=S);var r=s.m[O]("number");if(s.k&&a[i]!==t&&(ke(p,s,r&&p.u&&R(t,"string")?t[T](/[^\d.-]/g,""):t===S?"":t,a[i]),a[i]=t),2==s.b){if(!s.b2){t="this."+s.k,s.k==W&&s.m[j]&&(t+="[`"+s.m[0]+"`]");let e="text"==p.type?X:Y;s.m[O](X)?e=X:s.m[O](Y)&&(e=Y),s.m[O]("trim")&&(t+=".trim()"),r&&(t="this.u?this.u.replace(/1/,"+t+"):parseFloat("+t+")");r="=this."+z+".vs["+i+"]=";t=/==/.test(s.e)?t+"&&("+s.e[T](/==+/,r)+")":s.e+r+t,s.b2={...s,e:t,k:e,ev:e,f:S}}$e(g,s.b2,y)}i++}};f.ps[_](t)}}H({cp:e,p:a,el:a[E]},i)}},H=(e,t,s,r)=>{for(;e.el&&(!s||s(e.el));e.el=e[P])e[P]=e.el[A],r&&!r(e,t)||de(e,t)},ue=e=>e.hasAttribute("else"),ve=()=>0,me=({p:e,el:t,next:s,n:r},i,a)=>{(r=t[z].node)||(r=(r=t[D](G))&&(t[z].u=r=V(t,"`"+r+"`",i))&&(r=i.r[h](r)||(a=o(i.r[f],v))&&a[h](r))&&r.content||t.content,t[z].u||(t[z].node=r),H({cp:1,p:r,el:r[E]}));for(let l=r[E];l;l=l[A])r=l.cloneNode(!0),e[L](r,s)},he=(e,t)=>{var s;e.el[z]&&e.el[z].fi&&(s=e.el[z].fi[A],e.el[z].fi=S,e.el=e[P],be(e,s,t))},be=(e,t,s)=>{H(e,s,e=>e!=t,({el:e})=>{e[m]()})},ge=e=>e[T](c,(e,t)=>t.toUpperCase()),ye={css:W,text:N,html:"innerHTML"},ke=(s,e,r,i)=>{if(e.k==ee){if(e.m[j]){let t=""===e.e||r;r={},e.m[_](e=>{e.endsWith("-")?(r[e+t]=1,i&&(r[e+i]=0)):r[e]=t})}let t=s.classList;if(!Array.isArray(r)){if(R(r)){for(var a in r)r[a]?t.add(a):t[m](a);return}r=r?M(r):[]}r[_](e=>t.add(e))}else e.k==W&&(e.m[j]&&(r=1==e.m[j]?{[e.m[0]]:r}:{[e.m[0]]:r&&e.m[1]}),R(r))?K(r)[_](e=>{!1===r[e]?s[W].removeProperty(e):"-"==e[0]?s[W].setProperty(e,r[e]):s[W][e]=r[e]}):e.A?!1===r?s[C](e.k):s[Z](e.k,r):s[e.k]=r},b=(s,r)=>{let i;return(...e)=>{let t=this;i=(i=r?clearTimeout(i):i)||setTimeout(()=>{i=S,s.apply(t,e)},r)}},$e=({el:n},t,o)=>{let{a:p,k:f,e:c,ev:s,m:d}=t;if(!n[z][p]){let i=d[O]("window")?window:d[O]("document")||d[O]("out")?F:n,a=e=>{if(!(d[O]("self")&&n!=e.target||d[O]("out")&&n.contains(e.target))){if(f[Q]("key")||f[Q]("mouse")||f.endsWith("click")){for(var t of d){t=re.exec(t);if(t&&(t[3]||t[4])){t=t[3]||t[4]&&"meta";if(!t||!e[t+"Key"])return}}var s=d.filter(e=>!re.test(e));if(1==s[j])if(f[Q]("key")&&e.key){var r=s[0][T](oe,"");if(({space:" ",slash:"/",gt:">",eq:"="}[r]||r)!=(e.key.toLowerCase()[T](oe,"")||" "))return}else if(["left","mid","right"][e.button]!=s[0])return}return d[O]("prevent")&&e.preventDefault(),d[O]("stop")&&e.stopPropagation(),d[O]("once")&&i.removeEventListener(f,a,l),V(n,c,{...o,ps:{...n[z][p],$el:o.r}})}},e=d.indexOf("debounce");0<=e&&(e=d[e+1],t=re.exec(e),e=t&&t[1]?t[2]?+t[1]:1e3*t[1]:250,a=b(a,e));let l={capture:d[O]("capture"),passive:d[O]("passive")};i[se](f,a,l),s&&!n[e="fireChange"]&&(n[e]=()=>fe(n,s))}n[z][p]={...o.ps}},xe={},we=(e,t,s,r)=>{s=r&&r.f||xe[s+=e]||(xe[s]=new Function(["$2D",...t],"var R3$;with($2D){R3$="+e+"};return R3$"));return r&&!r.f&&(r.f=s),s},V=(e,t,s,r,i)=>t&&De(()=>l(t)?t.call(e,s.r):(t=we(t,K(s.ps),K(s.ps).join(","),r).call(e,s.d,...a(s.ps)),i&&l(t)?t(i):t),{el:e,exp:t}),ze=(e,t,s)=>console.warn(`E ${k}: ${s} [${t}]`,e),De=(e,{el:t,exp:s})=>{try{var r=e();return r instanceof Promise?r.catch(e=>ze(t,s,e)):r}catch(e){ze(t,s,e)}},Ze=(e,s,r,t,i,a)=>{s=s||F.body;let l,n=[],o,p="",f,c=F[y](k),d=((l=s[D]("z-i"))||s[Z]("z-i",l=++g),b(()=>{--u<0&&(u=0),n[j]&&n.shift()()}));c[ye.html]=e[T](//g,"")[T](/^z-data\s*/,()=>a=1)[T](/<(script)([^>]*)>([^]*?)<\/\1>/gi,(e,t,r,i)=>{var s=r.match(/src\s*=\s*(?:'([^']+)|"([^"]+)|(\S+))/);if((r=s&&(s[1]||s[2]||s[3]))&&!te(`script[src="${r}"]`)[j]||i){let s=F[y]("script"),t=(e,t)=>(o=()=>(F.body[L](s,S),e&&e()),t?o():n.push(o));s[Z](x,""),r?ZData.get?n.push(()=>ZData.get(r).then(e=>(s[N]=e,t(d,1)))):(s.src=r,s.onload=s.onerror=d,t()):a&&!p?p=i:(s[N]=i,t(d))}return""})[T](/(
74 | ```
75 |
76 | ## 2.1. z-data studio
77 |
78 | 可以在线创建/调试/预览 z-data 代码
79 |
80 | * https://funlang.org/z-data/
81 |
82 | # 3. 用法
83 |
84 | ## 3.1. 安装
85 |
86 | - CDN https://cdn.jsdelivr.net/gh/Funlang/z-data@main/dist/z-data.min.js
87 |
88 | ```html
89 |
90 | ```
91 |
92 | ## 3.2. 作用域
93 |
94 | - z-data 属性创建 ZData 作用域
95 |
96 | ```html
97 |
98 | ```
99 | z-data 支持一个 init 函数, 在组件初始化时执行
100 |
101 | ```html
102 |
103 | ```
104 |
105 | z-data 表达式可以是一个函数表达式, 如:
106 |
107 | ```html
108 |
114 |
115 |
121 | ```
122 |
123 | z-data HTML 模块文件 (文件开头是 z-data)
124 |
125 | ```html
126 | z-data
127 |
128 |
129 |
135 | ```
136 |
137 | - z-none 关闭 ZData 作用域, 其内部节点 ZData 会跳过
138 |
139 | ```html
140 |
141 | ...
142 |
143 | ```
144 |
145 | - 与其他框架共存
146 |
147 | 在 ZData 根节点用类似以下的方式处理 (x-ignore 改为其他框架关闭作用域的属性名)
148 | ```html
149 |
150 | ```
151 | 在其他框架根节点加 z-none 即可
152 |
153 | ## 3.3. 模板
154 |
155 | - template for
156 |
157 | ```html
158 |
159 | ```
160 | ZData 依赖 key, 如果没有指定 key, 则优先选用 k 做 key, 否则用 v 做 key 键
161 | k : v , i 可以部分可选, 如:
162 |
163 | ```html
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 | ```
172 |
173 | - template if/else
174 |
175 | ```html
176 |
177 |
178 |
179 | ```
180 |
181 | - template use
182 |
183 | ```html
184 |
185 |
186 | template id = t1
187 |
188 |
189 |
190 |
191 | ```
192 |
193 | ## 3.4. 绑定
194 |
195 | - : 用来做属性绑定, 其中 :: 是双向绑定
196 |
197 | ```html
198 |
199 | ```
200 |
201 | ### 3.4.1. :text :html
202 |
203 | :text :html 分别对应 textContent 和 innerHTML
204 |
205 | ### 3.4.2. :class
206 |
207 | :class 支持 [] {} 和 字符串三种, 这些 classname 会按顺序合并处理
208 |
209 | ### 3.4.3. :class 简写
210 |
211 | :class 支持 :class.name1.name2=...
212 | ```
213 | 可以简写为 .name1.name2=...
214 | 如果 classname 后面为 -, 且返回值不是 boolean, 则将其值加入到 classname, 如:
215 | .p-=1 则 classList 里会增加 p-1
216 | ```
217 |
218 | ### 3.4.4. :style
219 |
220 | :style 支持 :css 别名, 支持 {} 和字符串两种, 字符串会按顺序覆盖
221 |
222 | ### 3.4.5. :style 简写
223 |
224 | :style 支持 :style.name.value=...
225 | ```
226 | :style.name=value / :css.name=value
227 | :style.name.value=条件 / :css.name.value=...
228 | 可以简写为 ..name 和 #name, 以及 !name=string-value, 如下:
229 | ..width=`100px`
230 | #border-width=`4px`
231 | !border-width=4px
232 | #--a-css-var=`'${theCssVarValue}'`
233 | ```
234 |
235 | #### 3.4.5.1 ZData.ss(s)
236 |
237 | ```
238 | ZData.ss = (s) => AShorthandMap[s] || s;
239 | ```
240 |
241 | ### 3.4.6. !!! 特别注意
242 |
243 | #### 3.4.6.1. : :: @ . .. \#
244 |
245 | 后面的值全部都是 js 表达式, 可以是 js 变量, 或者是字符串, 字符串要用 ' " ` 套住
246 |
247 | #### 3.4.6.2. ${...}
248 |
249 | 非绑定的属性值中含有 \${...}, 会自动解析成一个字符串, 相当于 \`...${...}...`
250 |
251 | #### 3.4.6.3. !
252 |
253 | ! 与 含有 ${} 的属性值类似, 会自动解析成 :css.style-name=\`string-value`
254 |
255 | ### 3.4.7. attr
256 |
257 | :xxx.attr 表示为可视 attribute 属性, 否则默认为不可见 prop 属性
258 |
259 | :xxx.attr === false 表示为 boolean attribute 属性
260 |
261 | #### 3.4.7.1. attr 简写
262 | ```
263 | :!tag-attr -> :tag-attr.attr
264 | ::!tag-attr -> ::tag-attr.attr
265 | ```
266 | ### 3.4.8. camel
267 |
268 | :xxx.camel 支持驼峰表示法
269 |
270 | ::value=propName, ::style.value=propName, ::css.value=propName
271 | ```
272 | 其中 propName 只支持驼峰表示法, DOM 属性(包括 style)可以增加 .camel 修饰符
273 | 双向绑定默认在 change 中触发回写行为, 只有 input text 同时在 input 中触发回写
274 | 可以增加 .input / .change 强制在 input / change 中回写
275 | 支持 .trim / .number 修饰符
276 | ```
277 | ```
278 | 目前有些属性如 style.value 修改, 不会自动触发响应式, 需要在当前执行 el 执行 el.fireChange()
279 | ```
280 |
281 | ### 3.4.9. input type='radio'
282 | ```
283 | ::checked=opt==this.value
284 |
285 | 注: opt 是一个 data 内的属性变量名
286 | ```
287 |
288 | ## 3.5. 事件
289 |
290 | @ 用来绑定事件, 支持 modifiers
291 |
292 | ### 3.5.1. 全局
293 |
294 | ```
295 | camel 事件名驼峰表示法
296 | prevent preventDefault
297 | stop stopPropagation
298 | debounce debounce mode, follow a time optional, such as
299 | debounce.750ms, debounce.2s, default 250ms
300 | capture capture mode
301 | once once mode, run once only
302 | passive passive mode
303 | ```
304 |
305 | ### 3.5.2. 范围
306 |
307 | ```
308 | self tag only
309 | out tag not
310 | window
311 | document
312 | ```
313 |
314 | ### 3.5.3. 键鼠
315 |
316 | ```
317 | shift
318 | ctrl
319 | alt
320 | meta or cmd
321 | ```
322 |
323 | ### 3.5.4. 键盘
324 | ```
325 | enter, escape, space, f1 etc., details refer to:
326 | https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values
327 | alias: space: " ", slash: /, gt: >, eq: =
328 | ```
329 |
330 | ### 3.5.5. 鼠标
331 | ```
332 |