diff --git a/dist/bundle.esm.js b/dist/bundle.esm.js index e2ccb3a..94c8943 100644 --- a/dist/bundle.esm.js +++ b/dist/bundle.esm.js @@ -1 +1 @@ -import{when as e,complement as s,isNil as t,replace as r,both as n,isEmpty as l,compose as i,equals as c,type as a,map as o,ifElse as u,identity as f,prop as h,toPairs as p,length as d,last as m,curry as g,join as $,forEach as w,filter as b,trim as y,always as x,fromPairs as C}from"pepka";import{createRenderer as N,combineRules as v}from"fela";import{renderToMarkup as S,rehydrate as k,render as j}from"fela-dom";import _ from"fela-plugin-embedded";import z from"fela-plugin-prefixer";import O from"fela-plugin-fallback-value";import A from"fela-plugin-unit";const E=Object.freeze({}),W=Object.freeze({f:"function",o:"object",s:"string"}),F=e=>e.replace(/-(\w)/gu,((e,s)=>s.toUpperCase())),L=(()=>{const e=/url\(.*?\)/g,s=/[,:;]/g;return t=>t.replace(e,(e=>e.replace(s,(e=>`\\${e}`))))})(),R=e(s(t),r(/([^\\])\\([^\\])/g,"$1$2")),U=n(s(l),s(t)),Z=i(c("Object"),a),q=i(c("Window"),a),B=(e,s)=>{for(let t in s)Z(e[t])&&Z(s[t])?B(e[t],s[t]):e[t]=s[t];return e},D=(()=>{try{return q(window)}catch{return!1}})(),G=o(u(i(c("Function"),a),f,h("default"))),H=(e,s)=>i(o((([e,t])=>((e,s,t)=>t(...e[s]||[]))(s,e,t))),p,G)(e);class I{s;rules={};get complex(){return null!==this.s.className&&null!==this.s.modifier}serialize(){const{className:e,modifier:s}=this.s;return(e?`.${e}`:"")+(s||"")}constructor(e){const s=e.match(/^\.[\w-_]+/);this.s={className:s?s[0].slice(1):null,modifier:s?e.slice(s[0].length)||null:e}}}const J=(e,s=0)=>{const t={};let r,n,l,i,c;for(c in e.rules)r=e.rules[c],r instanceof I?(n=r.complex?r.s.className:r.serialize(),l=0==s&&"."==n[0]?n.slice(1):"."==n[0]?`& ${n}`:n,i=r.complex?{[r.s.modifier]:J(r,s+1)}:J(r,s+1),t[l]?B(t[l],i):t[l]=i):t[c]=r;return t};class K{path=[];get out(){return J(this.path[0][0])}get depth(){return this.path.length}add(e){const s=m(this.path),t=[];for(const r of e){const e=new I(r);for(const r of s){const s=e.serialize(),n=r.rules[s];t.push(n||e),n||(r.rules[s]=e)}}this.path.push(t)}merge(e,s){if(U(s)&&U(e))for(const t of m(this.path))t.rules[e]=s}pop(){return this.path.pop()}constructor(){this.path.push([new I("__root")])}}const M=(()=>{const s=/^([\w-]+)(: *| +)(.*)$/,t=/^(([\|~\$@>\*\.:&\(\)\^="\-\[\]]+).*[ ,]*)+:?$/,r=/\s*,\s*/g,n=/(.*):$/;return(l,i,c)=>{let a;switch(!0){case"{"==i:l.add(c);break;case"}"==i:l.pop();break;case null!=(a=s.exec(i)):l.merge(R(F(a[1])),e(isNaN,R,(e=>{switch(e){case"undefined":case"":return;case"null":return null;default:return isNaN(+e)?e:+e}})(a[3])));break;case null!=(a=t.exec(i)):c.splice(0),c.push(...i.split(r).map((e=>e.replace(n,"$1"))))}}})(),P=g((([e,s],t)=>{let r,n,l=t.length,i=e.length,c=0,a=[];for(r=0;r{const s=[];let t=0;for(let[r,n]of P(["[","]"],e))s.push(e.slice(t,r),`\${${e.slice(r+1,n).replace(/(\W|^)\$([a-zA-Z_]+)\b/g,"$1$$ps.$2").replace(/(\W|^)@(.+?)\b/g,"$1$t.$2")}}`),t=n+1;return s.push(e.slice(t)),s.join("")}))),T=e=>{const s=[];let t,r,n,l=0,i=[];for(t of e)if(l>0)switch(t){case"{":l++,i[i.length-1]+=t;break;case"}":if(1==--l){const e=new Function("$t,css,$ps",`return css\`\n ${Q(i)}\n \``);s.push([n,(s,t)=>e(t,X,s)]),l=0,i.splice(0)}else i[i.length-1]+=t;break;default:i.push(t)}else r=t.indexOf("=>"),~r?(l=1,n=t.slice(0,r).trim().replace(/^\./,"")):s.push(t);return s},V=(()=>{const e=["\n","\r",";"],t=s=>e.includes(s),n=/(([\s^]+?\/\/.*$)|\/\*(.|[\n\r])*?\*\/)/gm;return c=>{const u=new K,f=[];return i((()=>u.out),w((e=>{if("Array"==a(e))u.merge(e[0],e[1]);else if(e&&M(u,e,f),u.depth<1)throw new Error("lit-css parse error: unbalanced {} braces !")})),T,b(s(l)),o(y),(h=e,e=>{const s=o(d,h),t=[];let r,n,l=0,i=h.length,c=e.length;for(r=0;r(t(n[r-1])||(s=";"+s),t(n[r+1])||(s+=";"),s))),L,r(n,""))(c);var h}})(),X=(e,...s)=>V(((e,s)=>e.reduce(((e,t,r)=>e+t+(s.length>r?s[r]:"")),""))(e,s)),Y=(e,s)=>e[s]||e[F(s)],ee=(e,s,t,r)=>{switch(s||(s=E),typeof t){case W.f:return[t.name,[e=>t(e,r)]];case W.o:return[t.className,[x(t)]];case W.s:const n=((e,s,t)=>t.split(/[,\s\t]+/g).map((t=>[t,Y(s,t)||Y(e(),t)||E])))(e,s,t),l=[],i=[];for(const[t,c]of n)l.push(t),i.push(...ee(e,s,c,r)[1]);return[l.join("_"),i];default:return["",[f]]}},se={method:"f",defStyles:void 0,plugins:[],enhancers:[],preset:{unit:[]},ssr:!1};class te{static devClassNames=!1;renderer;_mixin;renderClasses;styl;get mixin(){return Object.freeze(this._mixin)}get style(){return S(this.renderer)}constructor(e={}){const{method:s,ssr:t,preset:r,plugins:n,enhancers:l,...c}=((e,s={})=>i(C,o((([e,t])=>{switch(a(t)){case"Array":return[e,[...t,...s[e]||[]]];case"Object":return[e,{...t,...s[e]||{}}];default:return[e,s[e]||t]}})),p)(e))(se,e),u={...se.preset,...r||{}},h=this;if(e.fdef)throw new Error("fela-vue: Change deprecated `fdef` to `defStyles`!");this.renderer=N({...c,enhancers:l,plugins:H([A,_,z,O,...n],{0:u.unit})});const{renderer:d}=this,m=e.defStyles;let g,$;switch(typeof m){case W.o:[g,$]=[m.key,m.value];break;case W.f:[g,$]=["fdef",m]}D&&(t?k(d):j(d)),this.renderClasses=function(e,s,t={}){const[r,n]=ee((e=>{let s,t=!1;return()=>t?s:(t=!0,s=e())})((()=>$?$(this):E)),e,s,this);return d.renderRule(((e,s,t)=>{if(t&&s&&"anonymous"!==s)return{[s]:(s,t)=>e(s,t)}[s];return e})(v(...n),r,te.devClassNames),t)||void 0},this.styl=e=>(...s)=>this.renderClasses(e,...s),this._mixin=b(f,{methods:{[s]:function(...e){return h.renderClasses.call(this,this.style,...e)}},computed:m&&{[g](){return $(this)}}})}}class re extends te{static get devClassNames(){return te.devClassNames}static set devClassNames(e){te.devClassNames=e}f;fdef;getCSS(){return e=>{const s={style:e,fdef:this.fdef};return(e,t)=>this.f.call(s,e,t)}}getLiteralCSS(){const e=this.getCSS();return(...s)=>e(X(...s))}constructor(e={}){super(e);const s=this.mixin;this.f=s.methods.f,this.fdef="function"==typeof e.defStyles?s.computed.fdef:e.defStyles&&s.computed[e.defStyles.key]}}export{te as Renderer,re as SvelteRenderer,X as css}; +import{when as e,complement as s,isNil as t,replace as r,both as n,isEmpty as l,compose as i,equals as c,type as o,map as a,ifElse as u,identity as f,prop as h,toPairs as p,length as d,last as m,qmergeDeep as g,curry as $,join as w,forEach as b,filter as y,trim as C,always as x,fromPairs as N}from"pepka";import{createRenderer as S,combineRules as _}from"fela";import{renderToMarkup as v,rehydrate as k,render as j}from"fela-dom";import z from"fela-plugin-embedded";import O from"fela-plugin-prefixer";import A from"fela-plugin-fallback-value";import E from"fela-plugin-unit";const W=Object.freeze({}),F=Object.freeze({f:"function",o:"object",s:"string"}),B=e=>e.replace(/-(\w)/gu,((e,s)=>s.toUpperCase())),L=(()=>{const e=/url\(.*?\)/g,s=/[,:;]/g;return t=>t.replace(e,(e=>e.replace(s,(e=>`\\${e}`))))})(),R=e(s(t),r(/([^\\])\\([^\\])/g,"$1$2")),U=n(s(l),s(t));i(c("Object"),o);const Z=i(c("Window"),o),q=(()=>{try{return Z(window)}catch{return!1}})(),D=a(u(i(c("Function"),o),f,h("default"))),G=(e,s)=>i(a((([e,t])=>((e,s,t)=>t(...e[s]||[]))(s,e,t))),p,D)(e);class H{s;rules={};__selector__=!0;get complex(){return null!==this.s.className&&null!==this.s.modifier}static isSelector(e){return Boolean(e&&e.__selector__)}serialize(){const{className:e,modifier:s}=this.s;return(e?`.${e}`:"")+(s||"")}findClass(e,s=this){if(s.s.className===e)return s;for(const t in s.rules){const r=s.rules[t];if(H.isSelector(r)){const s=r.findClass(e);if(s)return s}}return null}constructor(e){const s=e.match(/^\.[\w-_]+/);this.s={className:s?s[0].slice(1):null,modifier:s?e.slice(s[0].length)||null:e}}}const I=(e,s=0)=>{const t={};let r,n,l,i,c;for(c in e.rules)r=e.rules[c],H.isSelector(r)?(n=r.complex?r.s.className:r.serialize(),l=0==s&&"."==n[0]?n.slice(1):"."==n[0]?`& ${n}`:n,i=r.complex?{[r.s.modifier]:I(r,s+1)}:I(r,s+1),t[l]?g(t[l],i):t[l]=i):t[c]=r;return t};class J{path=[];get out(){return I(this.path[0][0])}get depth(){return this.path.length}add(e){const s=m(this.path),t=[];for(const r of e){const e=new H(r);for(const r of s){const s=e.serialize(),n=r.rules[s];t.push(n||e),n||(r.rules[s]=e)}}this.path.push(t)}merge(e,s){if(U(s)&&U(e))for(const t of m(this.path))t.rules[e]=s}findClass(e){for(const s of this.path)for(const t of s){const s=t.findClass(e);if(s)return s}return null}pop(){return this.path.pop()}constructor(){this.path.push([new H("__root")])}}const K=(()=>{const s=/^([\w-]+)(: *| +)(.*)$/,t=/^(([\|~\$@>\*\.:&\(\)\^="\-\[\]]+).*[ ,]*)+:?$/,r=/\.\.\.(\S*)$/,n=/\s*,\s*/g,l=/(.*):$/;return(i,c,o)=>{let a;switch(!0){case"{"==c:i.add(o);break;case"}"==c:i.pop();break;case null!==(a=r.exec(c)):const u=i.findClass(a[1]);if(u)for(const e in u.rules)i.merge(e,u.rules[e]);break;case null!==(a=s.exec(c)):i.merge(R(B(a[1])),e(isNaN,R,(e=>{switch(e){case"undefined":case"":return;case"null":return null;default:return isNaN(+e)?e:+e}})(a[3])));break;case null!==(a=t.exec(c)):o.splice(0),o.push(...c.split(n).map((e=>e.replace(l,"$1"))))}}})(),M=$((([e,s],t)=>{let r,n,l=t.length,i=e.length,c=0,o=[];for(r=0;r{const s=[];let t=0;for(let[r,n]of M(["[","]"],e))s.push(e.slice(t,r),`\${${e.slice(r+1,n).replace(/(\W|^)\$([a-zA-Z_]+)\b/g,"$1$$ps.$2").replace(/(\W|^)@(.+?)\b/g,"$1$t.$2")}}`),t=n+1;return s.push(e.slice(t)),s.join("")}))),Q=e=>{const s=[];let t,r,n,l=0,i=[];for(t of e)if(l>0)switch(t){case"{":l++,i[i.length-1]+=t;break;case"}":if(1==--l){const e=new Function("$t,css,$ps",`return css\`\n ${P(i)}\n \``);s.push([n,(s,t)=>e(t,V,s)]),l=0,i.splice(0)}else i[i.length-1]+=t;break;default:i.push(t)}else r=t.indexOf("=>"),~r?(l=1,n=t.slice(0,r).trim().replace(/^\./,"")):s.push(t);return s},T=(()=>{const e=["\n","\r",";"],t=s=>e.includes(s),n=/(([\s^]+?\/\/.*$)|\/\*(.|[\n\r])*?\*\/)/gm;return c=>{const u=new J,f=[];return i((()=>u.out),b((e=>{if("Array"==o(e))u.merge(e[0],e[1]);else if(e&&K(u,e,f),u.depth<1)throw new Error("lit-css parse error: unbalanced {} braces !")})),Q,y(s(l)),a(C),(h=e,e=>{const s=a(d,h),t=[];let r,n,l=0,i=h.length,c=e.length;for(r=0;r(t(n[r-1])||(s=";"+s),t(n[r+1])||(s+=";"),s))),L,r(n,""))(c);var h}})(),V=(e,...s)=>T(((e,s)=>e.reduce(((e,t,r)=>e+t+(s.length>r?s[r]:"")),""))(e,s)),X=(e,s)=>e[s]||e[B(s)],Y=(e,s,t,r)=>{switch(s||(s=W),typeof t){case F.f:return[t.name,[e=>t(e,r)]];case F.o:return[t.className,[x(t)]];case F.s:const n=((e,s,t)=>t.split(/[,\s\t]+/g).map((t=>[t,X(s,t)||X(e(),t)||W])))(e,s,t),l=[],i=[];for(const[t,c]of n)l.push(t),i.push(...Y(e,s,c,r)[1]);return[l.join("_"),i];default:return["",[f]]}},ee={method:"f",defStyles:void 0,plugins:[],enhancers:[],preset:{unit:[]},ssr:!1};class se{static devClassNames=!1;renderer;_mixin;renderClasses;styl;get mixin(){return Object.freeze(this._mixin)}get style(){return v(this.renderer)}constructor(e={}){const{method:s,ssr:t,preset:r,plugins:n,enhancers:l,...c}=((e,s={})=>i(N,a((([e,t])=>{switch(o(t)){case"Array":return[e,[...t,...s[e]||[]]];case"Object":return[e,{...t,...s[e]||{}}];default:return[e,s[e]||t]}})),p)(e))(ee,e),u={...ee.preset,...r||{}},h=this;if(e.fdef)throw new Error("fela-vue: Change deprecated `fdef` to `defStyles`!");this.renderer=S({...c,enhancers:l,plugins:G([E,z,O,A,...n],{0:u.unit})});const{renderer:d}=this,m=e.defStyles;let g,$;switch(typeof m){case F.o:[g,$]=[m.key,m.value];break;case F.f:[g,$]=["fdef",m]}q&&(t?k(d):j(d)),this.renderClasses=function(e,s,t={}){const[r,n]=Y((e=>{let s,t=!1;return()=>t?s:(t=!0,s=e())})((()=>$?$(this):W)),e,s,this);return d.renderRule(((e,s,t)=>{if(t&&s&&"anonymous"!==s)return{[s]:(s,t)=>e(s,t)}[s];return e})(_(...n),r,se.devClassNames),t)||void 0},this.styl=e=>(...s)=>this.renderClasses(e,...s),this._mixin=y(f,{methods:{[s]:function(...e){return h.renderClasses.call(this,this.style,...e)}},computed:m&&{[g](){return $(this)}}})}}class te extends se{static get devClassNames(){return se.devClassNames}static set devClassNames(e){se.devClassNames=e}f;fdef;getCSS(){return e=>{const s={style:e,fdef:this.fdef};return(e,t)=>this.f.call(s,e,t)}}getLiteralCSS(){const e=this.getCSS();return(...s)=>e(V(...s))}constructor(e={}){super(e);const s=this.mixin;this.f=s.methods.f,this.fdef="function"==typeof e.defStyles?s.computed.fdef:e.defStyles&&s.computed[e.defStyles.key]}}export{se as Renderer,te as SvelteRenderer,V as css}; diff --git a/dist/bundle.js b/dist/bundle.js index 0e3d5db..729b94b 100644 --- a/dist/bundle.js +++ b/dist/bundle.js @@ -1 +1 @@ -"use strict";var e=require("pepka"),s=require("fela"),t=require("fela-dom"),r=require("fela-plugin-embedded"),n=require("fela-plugin-prefixer"),l=require("fela-plugin-fallback-value"),i=require("fela-plugin-unit");const c=Object.freeze({}),a=Object.freeze({f:"function",o:"object",s:"string"}),o=e=>e.replace(/-(\w)/gu,((e,s)=>s.toUpperCase())),u=(()=>{const e=/url\(.*?\)/g,s=/[,:;]/g;return t=>t.replace(e,(e=>e.replace(s,(e=>`\\${e}`))))})(),p=e.when(e.complement(e.isNil),e.replace(/([^\\])\\([^\\])/g,"$1$2")),f=e.both(e.complement(e.isEmpty),e.complement(e.isNil)),h=e.compose(e.equals("Object"),e.type),d=e.compose(e.equals("Window"),e.type),m=(e,s)=>{for(let t in s)h(e[t])&&h(s[t])?m(e[t],s[t]):e[t]=s[t];return e},g=(()=>{try{return d(window)}catch{return!1}})(),y=e.map(e.ifElse(e.compose(e.equals("Function"),e.type),e.identity,e.prop("default"))),w=(s,t)=>e.compose(e.map((([e,s])=>((e,s,t)=>t(...e[s]||[]))(t,e,s))),e.toPairs,y)(s);class ${s;rules={};get complex(){return null!==this.s.className&&null!==this.s.modifier}serialize(){const{className:e,modifier:s}=this.s;return(e?`.${e}`:"")+(s||"")}constructor(e){const s=e.match(/^\.[\w-_]+/);this.s={className:s?s[0].slice(1):null,modifier:s?e.slice(s[0].length)||null:e}}}const b=(e,s=0)=>{const t={};let r,n,l,i,c;for(c in e.rules)r=e.rules[c],r instanceof $?(n=r.complex?r.s.className:r.serialize(),l=0==s&&"."==n[0]?n.slice(1):"."==n[0]?`& ${n}`:n,i=r.complex?{[r.s.modifier]:b(r,s+1)}:b(r,s+1),t[l]?m(t[l],i):t[l]=i):t[c]=r;return t};class x{path=[];get out(){return b(this.path[0][0])}get depth(){return this.path.length}add(s){const t=e.last(this.path),r=[];for(const e of s){const s=new $(e);for(const e of t){const t=s.serialize(),n=e.rules[t];r.push(n||s),n||(e.rules[t]=s)}}this.path.push(r)}merge(s,t){if(f(t)&&f(s))for(const r of e.last(this.path))r.rules[s]=t}pop(){return this.path.pop()}constructor(){this.path.push([new $("__root")])}}const N=(()=>{const s=/^([\w-]+)(: *| +)(.*)$/,t=/^(([\|~\$@>\*\.:&\(\)\^="\-\[\]]+).*[ ,]*)+:?$/,r=/\s*,\s*/g,n=/(.*):$/;return(l,i,c)=>{let a;switch(!0){case"{"==i:l.add(c);break;case"}"==i:l.pop();break;case null!=(a=s.exec(i)):l.merge(p(o(a[1])),e.when(isNaN,p,(e=>{switch(e){case"undefined":case"":return;case"null":return null;default:return isNaN(+e)?e:+e}})(a[3])));break;case null!=(a=t.exec(i)):c.splice(0),c.push(...i.split(r).map((e=>e.replace(n,"$1"))))}}})(),v=e.curry((([e,s],t)=>{let r,n,l=t.length,i=e.length,c=0,a=[];for(r=0;r{const s=[];let t=0;for(let[r,n]of v(["[","]"],e))s.push(e.slice(t,r),`\${${e.slice(r+1,n).replace(/(\W|^)\$([a-zA-Z_]+)\b/g,"$1$$ps.$2").replace(/(\W|^)@(.+?)\b/g,"$1$t.$2")}}`),t=n+1;return s.push(e.slice(t)),s.join("")}))),S=e=>{const s=[];let t,r,n,l=0,i=[];for(t of e)if(l>0)switch(t){case"{":l++,i[i.length-1]+=t;break;case"}":if(1==--l){const e=new Function("$t,css,$ps",`return css\`\n ${C(i)}\n \``);s.push([n,(s,t)=>e(t,q,s)]),l=0,i.splice(0)}else i[i.length-1]+=t;break;default:i.push(t)}else r=t.indexOf("=>"),~r?(l=1,n=t.slice(0,r).trim().replace(/^\./,"")):s.push(t);return s},k=(()=>{const s=["\n","\r",";"],t=e=>s.includes(e),r=/(([\s^]+?\/\/.*$)|\/\*(.|[\n\r])*?\*\/)/gm;return n=>{const l=new x,i=[];return e.compose((()=>l.out),e.forEach((s=>{if("Array"==e.type(s))l.merge(s[0],s[1]);else if(s&&N(l,s,i),l.depth<1)throw new Error("lit-css parse error: unbalanced {} braces !")})),S,e.filter(e.complement(e.isEmpty)),e.map(e.trim),(c=s,s=>{const t=e.map(e.length,c),r=[];let n,l,i=0,a=c.length,o=s.length;for(n=0;n(t(n[r-1])||(s=";"+s),t(n[r+1])||(s+=";"),s))),u,e.replace(r,""))(n);var c}})(),q=(e,...s)=>k(((e,s)=>e.reduce(((e,t,r)=>e+t+(s.length>r?s[r]:"")),""))(e,s)),j=(e,s)=>e[s]||e[o(s)],_=(s,t,r,n)=>{switch(t||(t=c),typeof r){case a.f:return[r.name,[e=>r(e,n)]];case a.o:return[r.className,[e.always(r)]];case a.s:const l=((e,s,t)=>t.split(/[,\s\t]+/g).map((t=>[t,j(s,t)||j(e(),t)||c])))(s,t,r),i=[],o=[];for(const[e,r]of l)i.push(e),o.push(..._(s,t,r,n)[1]);return[i.join("_"),o];default:return["",[e.identity]]}},z={method:"f",defStyles:void 0,plugins:[],enhancers:[],preset:{unit:[]},ssr:!1};class E{static devClassNames=!1;renderer;_mixin;renderClasses;styl;get mixin(){return Object.freeze(this._mixin)}get style(){return t.renderToMarkup(this.renderer)}constructor(o={}){const{method:u,ssr:p,preset:f,plugins:h,enhancers:d,...m}=((s,t={})=>e.compose(e.fromPairs,e.map((([s,r])=>{switch(e.type(r)){case"Array":return[s,[...r,...t[s]||[]]];case"Object":return[s,{...r,...t[s]||{}}];default:return[s,t[s]||r]}})),e.toPairs)(s))(z,o),y={...z.preset,...f||{}},$=this;if(o.fdef)throw new Error("fela-vue: Change deprecated `fdef` to `defStyles`!");this.renderer=s.createRenderer({...m,enhancers:d,plugins:w([i,r,n,l,...h],{0:y.unit})});const{renderer:b}=this,x=o.defStyles;let N,v;switch(typeof x){case a.o:[N,v]=[x.key,x.value];break;case a.f:[N,v]=["fdef",x]}g&&(p?t.rehydrate(b):t.render(b)),this.renderClasses=function(e,t,r={}){const[n,l]=_((e=>{let s,t=!1;return()=>t?s:(t=!0,s=e())})((()=>v?v(this):c)),e,t,this);return b.renderRule(((e,s,t)=>{if(t&&s&&"anonymous"!==s)return{[s]:(s,t)=>e(s,t)}[s];return e})(s.combineRules(...l),n,E.devClassNames),r)||void 0},this.styl=e=>(...s)=>this.renderClasses(e,...s),this._mixin=e.filter(e.identity,{methods:{[u]:function(...e){return $.renderClasses.call(this,this.style,...e)}},computed:x&&{[N](){return v(this)}}})}}exports.Renderer=E,exports.SvelteRenderer=class extends E{static get devClassNames(){return E.devClassNames}static set devClassNames(e){E.devClassNames=e}f;fdef;getCSS(){return e=>{const s={style:e,fdef:this.fdef};return(e,t)=>this.f.call(s,e,t)}}getLiteralCSS(){const e=this.getCSS();return(...s)=>e(q(...s))}constructor(e={}){super(e);const s=this.mixin;this.f=s.methods.f,this.fdef="function"==typeof e.defStyles?s.computed.fdef:e.defStyles&&s.computed[e.defStyles.key]}},exports.css=q; +"use strict";var e=require("pepka"),s=require("fela"),t=require("fela-dom"),r=require("fela-plugin-embedded"),n=require("fela-plugin-prefixer"),l=require("fela-plugin-fallback-value"),i=require("fela-plugin-unit");const c=Object.freeze({}),a=Object.freeze({f:"function",o:"object",s:"string"}),o=e=>e.replace(/-(\w)/gu,((e,s)=>s.toUpperCase())),u=(()=>{const e=/url\(.*?\)/g,s=/[,:;]/g;return t=>t.replace(e,(e=>e.replace(s,(e=>`\\${e}`))))})(),f=e.when(e.complement(e.isNil),e.replace(/([^\\])\\([^\\])/g,"$1$2")),p=e.both(e.complement(e.isEmpty),e.complement(e.isNil));e.compose(e.equals("Object"),e.type);const h=e.compose(e.equals("Window"),e.type),d=(()=>{try{return h(window)}catch{return!1}})(),m=e.map(e.ifElse(e.compose(e.equals("Function"),e.type),e.identity,e.prop("default"))),g=(s,t)=>e.compose(e.map((([e,s])=>((e,s,t)=>t(...e[s]||[]))(t,e,s))),e.toPairs,m)(s);class y{s;rules={};__selector__=!0;get complex(){return null!==this.s.className&&null!==this.s.modifier}static isSelector(e){return Boolean(e&&e.__selector__)}serialize(){const{className:e,modifier:s}=this.s;return(e?`.${e}`:"")+(s||"")}findClass(e,s=this){if(s.s.className===e)return s;for(const t in s.rules){const r=s.rules[t];if(y.isSelector(r)){const s=r.findClass(e);if(s)return s}}return null}constructor(e){const s=e.match(/^\.[\w-_]+/);this.s={className:s?s[0].slice(1):null,modifier:s?e.slice(s[0].length)||null:e}}}const w=(s,t=0)=>{const r={};let n,l,i,c,a;for(a in s.rules)n=s.rules[a],y.isSelector(n)?(l=n.complex?n.s.className:n.serialize(),i=0==t&&"."==l[0]?l.slice(1):"."==l[0]?`& ${l}`:l,c=n.complex?{[n.s.modifier]:w(n,t+1)}:w(n,t+1),r[i]?e.qmergeDeep(r[i],c):r[i]=c):r[a]=n;return r};class ${path=[];get out(){return w(this.path[0][0])}get depth(){return this.path.length}add(s){const t=e.last(this.path),r=[];for(const e of s){const s=new y(e);for(const e of t){const t=s.serialize(),n=e.rules[t];r.push(n||s),n||(e.rules[t]=s)}}this.path.push(r)}merge(s,t){if(p(t)&&p(s))for(const r of e.last(this.path))r.rules[s]=t}findClass(e){for(const s of this.path)for(const t of s){const s=t.findClass(e);if(s)return s}return null}pop(){return this.path.pop()}constructor(){this.path.push([new y("__root")])}}const b=(()=>{const s=/^([\w-]+)(: *| +)(.*)$/,t=/^(([\|~\$@>\*\.:&\(\)\^="\-\[\]]+).*[ ,]*)+:?$/,r=/\.\.\.(\S*)$/,n=/\s*,\s*/g,l=/(.*):$/;return(i,c,a)=>{let u;switch(!0){case"{"==c:i.add(a);break;case"}"==c:i.pop();break;case null!==(u=r.exec(c)):const p=i.findClass(u[1]);if(p)for(const e in p.rules)i.merge(e,p.rules[e]);break;case null!==(u=s.exec(c)):i.merge(f(o(u[1])),e.when(isNaN,f,(e=>{switch(e){case"undefined":case"":return;case"null":return null;default:return isNaN(+e)?e:+e}})(u[3])));break;case null!==(u=t.exec(c)):a.splice(0),a.push(...c.split(n).map((e=>e.replace(l,"$1"))))}}})(),C=e.curry((([e,s],t)=>{let r,n,l=t.length,i=e.length,c=0,a=[];for(r=0;r{const s=[];let t=0;for(let[r,n]of C(["[","]"],e))s.push(e.slice(t,r),`\${${e.slice(r+1,n).replace(/(\W|^)\$([a-zA-Z_]+)\b/g,"$1$$ps.$2").replace(/(\W|^)@(.+?)\b/g,"$1$t.$2")}}`),t=n+1;return s.push(e.slice(t)),s.join("")}))),N=e=>{const s=[];let t,r,n,l=0,i=[];for(t of e)if(l>0)switch(t){case"{":l++,i[i.length-1]+=t;break;case"}":if(1==--l){const e=new Function("$t,css,$ps",`return css\`\n ${x(i)}\n \``);s.push([n,(s,t)=>e(t,_,s)]),l=0,i.splice(0)}else i[i.length-1]+=t;break;default:i.push(t)}else r=t.indexOf("=>"),~r?(l=1,n=t.slice(0,r).trim().replace(/^\./,"")):s.push(t);return s},S=(()=>{const s=["\n","\r",";"],t=e=>s.includes(e),r=/(([\s^]+?\/\/.*$)|\/\*(.|[\n\r])*?\*\/)/gm;return n=>{const l=new $,i=[];return e.compose((()=>l.out),e.forEach((s=>{if("Array"==e.type(s))l.merge(s[0],s[1]);else if(s&&b(l,s,i),l.depth<1)throw new Error("lit-css parse error: unbalanced {} braces !")})),N,e.filter(e.complement(e.isEmpty)),e.map(e.trim),(c=s,s=>{const t=e.map(e.length,c),r=[];let n,l,i=0,a=c.length,o=s.length;for(n=0;n(t(n[r-1])||(s=";"+s),t(n[r+1])||(s+=";"),s))),u,e.replace(r,""))(n);var c}})(),_=(e,...s)=>S(((e,s)=>e.reduce(((e,t,r)=>e+t+(s.length>r?s[r]:"")),""))(e,s)),v=(e,s)=>e[s]||e[o(s)],k=(s,t,r,n)=>{switch(t||(t=c),typeof r){case a.f:return[r.name,[e=>r(e,n)]];case a.o:return[r.className,[e.always(r)]];case a.s:const l=((e,s,t)=>t.split(/[,\s\t]+/g).map((t=>[t,v(s,t)||v(e(),t)||c])))(s,t,r),i=[],o=[];for(const[e,r]of l)i.push(e),o.push(...k(s,t,r,n)[1]);return[i.join("_"),o];default:return["",[e.identity]]}},q={method:"f",defStyles:void 0,plugins:[],enhancers:[],preset:{unit:[]},ssr:!1};class j{static devClassNames=!1;renderer;_mixin;renderClasses;styl;get mixin(){return Object.freeze(this._mixin)}get style(){return t.renderToMarkup(this.renderer)}constructor(o={}){const{method:u,ssr:f,preset:p,plugins:h,enhancers:m,...y}=((s,t={})=>e.compose(e.fromPairs,e.map((([s,r])=>{switch(e.type(r)){case"Array":return[s,[...r,...t[s]||[]]];case"Object":return[s,{...r,...t[s]||{}}];default:return[s,t[s]||r]}})),e.toPairs)(s))(q,o),w={...q.preset,...p||{}},$=this;if(o.fdef)throw new Error("fela-vue: Change deprecated `fdef` to `defStyles`!");this.renderer=s.createRenderer({...y,enhancers:m,plugins:g([i,r,n,l,...h],{0:w.unit})});const{renderer:b}=this,C=o.defStyles;let x,N;switch(typeof C){case a.o:[x,N]=[C.key,C.value];break;case a.f:[x,N]=["fdef",C]}d&&(f?t.rehydrate(b):t.render(b)),this.renderClasses=function(e,t,r={}){const[n,l]=k((e=>{let s,t=!1;return()=>t?s:(t=!0,s=e())})((()=>N?N(this):c)),e,t,this);return b.renderRule(((e,s,t)=>{if(t&&s&&"anonymous"!==s)return{[s]:(s,t)=>e(s,t)}[s];return e})(s.combineRules(...l),n,j.devClassNames),r)||void 0},this.styl=e=>(...s)=>this.renderClasses(e,...s),this._mixin=e.filter(e.identity,{methods:{[u]:function(...e){return $.renderClasses.call(this,this.style,...e)}},computed:C&&{[x](){return N(this)}}})}}exports.Renderer=j,exports.SvelteRenderer=class extends j{static get devClassNames(){return j.devClassNames}static set devClassNames(e){j.devClassNames=e}f;fdef;getCSS(){return e=>{const s={style:e,fdef:this.fdef};return(e,t)=>this.f.call(s,e,t)}}getLiteralCSS(){const e=this.getCSS();return(...s)=>e(_(...s))}constructor(e={}){super(e);const s=this.mixin;this.f=s.methods.f,this.fdef="function"==typeof e.defStyles?s.computed.fdef:e.defStyles&&s.computed[e.defStyles.key]}},exports.css=_; diff --git a/docs/literal.md b/docs/literal.md index a8eadda..0f44701 100644 --- a/docs/literal.md +++ b/docs/literal.md @@ -37,11 +37,32 @@ css` // See correspondent options parameter. ``` +Use `...spread` operator with classes to share rules. +Use when class names composition in f('class1 class2') decrease readability. + +```javascript +import { css } from 'fela-vue' +css` + .common1 { + display flex + color green + } + .common2 { + position relative + } + .cls { + ...common1 + ...common2 + color cyan // cyan is better. + background magenta // wow. + } +` +``` + Both `/* multi-line comments */` end `// one-line` are supported: ```javascript import { css } from 'fela-vue' -const shouldMargin = false css` .cls { /* color red diff --git a/package.json b/package.json index c0c4bfb..97119be 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "prod:es": "cross-env NODE_ENV=production BUILD=es rollup -c", "prod": "npm run gentypes && npm run prod:es && npm run prod:cjs" }, - "version": "2.6.3", + "version": "2.7.0", "ava": { "files": [ "./test/specs/*.js" @@ -55,11 +55,11 @@ "fela-plugin-fallback-value": "*", "fela-plugin-prefixer": "*", "fela-plugin-unit": "*", - "lafetch": "0.4.5", "pepka": "^0.13.0-beta12" }, "devDependencies": { "@types/node": "^18.11.11", + "lafetch": "0.4.5", "ava": "^5.1.0", "codecov": "^3.8.2", "cross-env": "^7.0.3", diff --git a/src/classes/Levels.ts b/src/classes/Levels.ts index d023de6..2d25545 100644 --- a/src/classes/Levels.ts +++ b/src/classes/Levels.ts @@ -1,8 +1,6 @@ -import { last } from 'pepka' +import { last, AnyObject, qmergeDeep } from 'pepka' import { Selector } from './Selector' -import { deepMerge, valuable } from '../utils' -import { AnyObject } from '../types' -import { Renderer } from '../Renderer' +import { valuable } from '../utils' const extractRules = (s: Selector, depth=0): AnyObject => { const o: AnyObject = {} @@ -10,7 +8,8 @@ const extractRules = (s: Selector, depth=0): AnyObject => { key: string, newRules: AnyObject, k: string for(k in s.rules) { tmp = s.rules[k] - if(tmp instanceof Selector) { + if(Selector.isSelector(tmp)) { + tmp = tmp as Selector // will get erased by minifier. full = tmp.complex ? tmp.s.className : tmp.serialize() key = (depth==0 && full[0]=='.') ? full.slice(1) @@ -18,15 +17,9 @@ const extractRules = (s: Selector, depth=0): AnyObject => { newRules = tmp.complex ? { [tmp.s.modifier]: extractRules(tmp, depth+1) } : extractRules(tmp, depth+1) - if(o[key]) deepMerge(o[key], newRules) - else { - o[key] = newRules - // if(Renderer.devClassNames) newRules.className = tmp.s.className - } - } else { - o[k] = tmp - // if(Renderer.devClassNames) o.className = tmp - } + if(o[key]) qmergeDeep(o[key], newRules) + else o[key] = newRules + } else o[k] = tmp } return o } @@ -40,7 +33,7 @@ export class Levels { public get depth() { return this.path.length } - add(selectors: string[]) { + public add(selectors: string[]) { const curSelectors = last(this.path) const newCurs: Selector[] = [] for(const rawSel of selectors) { @@ -56,13 +49,21 @@ export class Levels { } this.path.push(newCurs) } - merge(k: string, v: any) { + public merge(k: string, v: any) { if(valuable(v) && valuable(k)) { for(const o of last(this.path)) { o.rules[k] = v } } } + public findClass(name: string): Selector | null { + for(const group of this.path) + for(const s of group) { + const res = s.findClass(name) + if(res) return res + } + return null + } pop() { return this.path.pop() } diff --git a/src/classes/Selector.ts b/src/classes/Selector.ts index 9d515e3..c1990fd 100644 --- a/src/classes/Selector.ts +++ b/src/classes/Selector.ts @@ -8,13 +8,30 @@ export interface SelectorSet { export class Selector { public readonly s: SelectorSet public rules: AnyObject = {} + // @ts-disable-next it is being read in Selector.isSelector() + private readonly __selector__ = true public get complex() { return this.s.className!==null && this.s.modifier!==null } + static isSelector(x: Selector | any) { + return Boolean(x && x.__selector__) + } public serialize(): string { const { className, modifier } = this.s return (className ? `.${className}` : '') + (modifier||'') } + public findClass(name: string, s = this) { + if(s.s.className === name) + return s + else for(const ruleName in s.rules) { + const rule = s.rules[ruleName] + if(Selector.isSelector(rule)) { + const res = rule.findClass(name) + if(res) return res + } + } + return null + } constructor(selector: string) { const cls = selector.match(/^\.[\w-_]+/) this.s = { diff --git a/src/fns/analyseLine.ts b/src/fns/analyseLine.ts index abad672..5e53db1 100644 --- a/src/fns/analyseLine.ts +++ b/src/fns/analyseLine.ts @@ -5,6 +5,7 @@ import { Levels } from '../classes/Levels' export const analyseLine = (() => { const ruleRE = /^([\w-]+)(: *| +)(.*)$/ const selectorRE = /^(([\|~\$@>\*\.:&\(\)\^="\-\[\]]+).*[ ,]*)+:?$/ + const spreadRE = /\.\.\.(\S*)$/ const delimRE = /\s*,\s*/g const trailingColonRE = /(.*):$/ const getValue = (value: string) => { @@ -23,13 +24,18 @@ export const analyseLine = (() => { case line=='}': levels.pop() break - case (groups = ruleRE.exec(line)) != null: + case (groups = spreadRE.exec(line)) !== null: + const cls = levels.findClass(groups[1]) + if(cls) for(const name in cls.rules) + levels.merge(name, cls.rules[name]) + break + case (groups = ruleRE.exec(line)) !== null: levels.merge( unescape(camelify(groups[1])), when(isNaN, unescape, getValue(groups[3])) ) break - case (groups = selectorRE.exec(line)) != null: + case (groups = selectorRE.exec(line)) !== null: names.splice(0) names.push(...line.split(delimRE).map((selector) => selector.replace(trailingColonRE, '$1') diff --git a/src/fns/parse.ts b/src/fns/parse.ts index daf5948..412bbc8 100644 --- a/src/fns/parse.ts +++ b/src/fns/parse.ts @@ -16,18 +16,14 @@ export const parse = (() => { return (css: string) => { const levels = new Levels() const names: string[] = [] // selector names, class names. - return (compose as any)( + return compose( () => levels.out, forEach((line: string | [string, StyleGenerator]) => { - if(type(line) == 'Array') { - levels.merge(line[0], line[1]) - } else { - if(line) { - analyseLine(levels, line as string, names) - } - if(levels.depth < 1) { + if(type(line) == 'Array') levels.merge(line[0], line[1]) + else { + if(line) analyseLine(levels, line as string, names) + if(levels.depth < 1) throw new Error('lit-css parse error: unbalanced {} braces !') - } } }), createFunctions, @@ -35,12 +31,8 @@ export const parse = (() => { map(trim), splitNonEscaped(delimiters), replace(/(\{|\})/g, (_, brace, offset, full) => { - if(!isDelimiter(full[offset-1])) { - brace = ';' + brace - } - if(!isDelimiter(full[offset+1])) { - brace += ';' - } + if(!isDelimiter(full[offset-1])) brace = ';' + brace + if(!isDelimiter(full[offset+1])) brace += ';' return brace }), escape, diff --git a/src/utils.ts b/src/utils.ts index 2842c2c..bdb2351 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -60,17 +60,6 @@ export const join = (strings: string[], values: any[]) => export const isObject = compose(equals('Object'), type) export const isWindow = compose(equals('Window'), type) -export const deepMerge = (o1: AnyObject, o2: AnyObject): AnyObject => { - for(let k in o2) { - if(isObject(o1[k]) && isObject(o2[k])) { - deepMerge(o1[k], o2[k]) - } else { - o1[k] = o2[k] - } - } - return o1 -} - export const tryNamedFn = (rule: AnyFunc, name: string, useNamed: boolean) => { if(useNamed && name && name!=='anonymous') { const tmpObj = { diff --git a/test/specs/lit.js b/test/specs/lit.js index c899e07..359fb23 100644 --- a/test/specs/lit.js +++ b/test/specs/lit.js @@ -51,6 +51,28 @@ test('lit-css', (t) => { display: 'block', alignItems: 'center' } + }, + grandpa: { + position: 'flex', + margin: 0 + }, + pa: { + position: 'flex', + margin: 0, + left: 1 + }, + misc: { + float: 'right', + width: '100%', + left: 11 + }, + son: { + position: 'flex', + margin: 0, + left: 11, + float: 'right', + width: '100%', + top: 42 } } const rule = () => css` @@ -99,6 +121,25 @@ test('lit-css', (t) => { .cls:after { align-items: center; } + .grandpa { + position flex + margin 0 + } + .pa { + ...grandpa + left 1 + } + .misc { + float right + width 100% + left 11 + } + .son { + ...pa + ...misc + ...nonexistent + top 42 + } ` t.deepEqual(obj, rule())