diff --git a/buffe.js b/buffe.js index 0d6ddb7c..fffe8cc7 100644 --- a/buffe.js +++ b/buffe.js @@ -20,7 +20,7 @@ function Buffe($, { h, w, s = 4 } = {}) { if (!(this instanceof Buffe)) return new Buffe($, arguments[1]); - const coreVersion = '17.7.0-alpha.1'; + const coreVersion = '17.8.0-alpha.1'; // y is 0-indexed model line numbers, x is column. // cursor IFF head === anchor, else is a selection. const anchor = { y: 0, x: 0 }, detached = {}; diff --git a/buffee.js b/buffee.js index 5013fe51..e55579cc 100644 --- a/buffee.js +++ b/buffee.js @@ -70,7 +70,7 @@ function BuffeeNativeController(editor) { * const editor = Buffee(Buffe(document.getElementById('editor'), { h: 25 })); */ function Buffee(editorOrEl, opts) { - const buffeeVersion = '17.7.0-alpha.1'; + const buffeeVersion = '17.8.0-alpha.1'; const editor = editorOrEl instanceof Buffe ? editorOrEl : new Buffe(editorOrEl, opts); editor.Ctrl = BuffeeNativeController(editor); editor.Mode.ext.push('Buffee@' + buffeeVersion); diff --git a/dev/changelog.txt b/dev/changelog.txt index b3432c77..756e8a95 100644 --- a/dev/changelog.txt +++ b/dev/changelog.txt @@ -1,5 +1,10 @@ * Project Devlog +** 17.8.0-alpha.1 [2026-01-14] +*** core (buffe) : gz: 1809 / 1.77 KB (-4), br: 1675 / 1.64 KB (-1), min: 3708 / 3.62 KB (-10) +*** combined (buffee): gz: 2378 / 2.32 KB (-3), br: 2190 / 2.14 KB (-1), min: 5122 / 5.00 KB (-10) +- build: add terser pure_getters option (-10 bytes) + ** 17.7.0-alpha.1 [2026-01-14] *** core (buffe) : gz: 1813 / 1.77 KB (0), br: 1676 / 1.64 KB (-4), min: 3718 / 3.63 KB (0) *** combined (buffee): gz: 2381 / 2.33 KB (0), br: 2192 / 2.14 KB (-4), min: 5132 / 5.01 KB (0) diff --git a/dist/buffe.min.js b/dist/buffe.min.js index b29433b0..01662e6a 100644 --- a/dist/buffe.min.js +++ b/dist/buffe.min.js @@ -1 +1 @@ -function Buffe(t,{h:e,w:l,s:i=4}={}){if(!(this instanceof Buffe))return new Buffe(t,arguments[1]);let n={y:0,x:0},s={},h=n,[r,y,x,f]=["cell","padding","rail-init","rail-pad"].map(e=>parseFloat(getComputedStyle(t).getPropertyValue("--buffee-"+e))),[a,o,d,c,g,u]=["pane","lines","caret","rail","ztxt","zsel"].map(e=>t.querySelector(".buffee-"+e));this.$=t,this.$lines=o;let m=o.getBoundingClientRect(),p=[[g,(t,e)=>t.textContent=w._[C+e]??null],[c,(t,e)=>t.textContent=C+e+1],[u,t=>t.style.width=0]].map(([t,e])=>[[],document.createDocumentFragment(),t,e]),_=this.Span={mvY(t,e){if(t>0?h.y0){let l=w._[t>0?++h.y:--h.y].length;h.x=e?t>0?0:l:Math.min(b.mx,l),e&&(b.mx=h.x),h.yv.last?v.first=t>0?h.y-$+1:h.y:R()}},mvX(t){let e=t>0;(e?h.x0?w._[h.y].length:0,R()},bounds:t=>t&&_.dir>0?[n,h]:[h,n],get dir(){return h==n?0:n.y==h.y&&n.x0));return e.x>=l.length&&t.y0))]},cursor(t=h){n.y=t.y,n.x=t.x,h=n},select(t=n){h=s,h.y=t.y,h.x=t.x},ins(t){if(this.dir){let[e,l]=_.bounds(1);w.del(e.y,e.x,l.y,l.x+(this.dir>0)),w.ins(e.y,e.x,t),h.y=e.y,t.length>1?(h.y+=t.length-1,h.x=t.at(-1).length):h.x=e.x+(t[0]?.length||0),this.cursor()}else w.ins(h.y,h.x,t),t.length>1?(h.y+=t.length-1,b.mx=h.x=t.at(-1).length):b.mx=h.x+=t[0]?.length||0;h.y>v.last?v.first=h.y-$+1:R()},del(){this.dir?this.ins([""]):h.x>0?(w.del(h.y,h.x-1,h.y,h.x),h.x--,R()):h.y>0&&(h.x=w._[h.y-1].length,w.del(h.y-1,h.x,h.y,0),--h.y0&&!this.dir)return;let[e,l]=_.bounds(1);for(let i=e.y;i<=l.y;i++){let n=w._[i];if(t>0)w._[i]=" ".repeat(t)+n;else{let s=Math.min(-t,n.search(/[^ ]|$/));w._[i]=n.slice(s),i===e.y&&(e.x=Math.max(0,e.x-s)),i===l.y&&e!==l&&(l.x=Math.max(0,l.x-s))}}t>0&&(e.x+=t,l.x+=t),R()}},M=d.getBoundingClientRect().width,b=this.Mode={s:i,i:1,f:0,mx:0,ch:r,cw:M,sub:[],ext:["17.7.0-alpha.1"]},w=this.Model={_:[""],get end(){return{y:this._.length-1,x:this._.at(-1).length}},ins(t,e,l){let i=this._[t].slice(e);this._[t]=this._[t].slice(0,e)+l[0],1==l.length?this._[t]+=i:this._.splice(t+1,0,...l.slice(1,-1),l.at(-1)+i)},del(t,e,l,i){this._[t]=this._[t].slice(0,e)+this._[l].slice(i),t!=l&&this._.splice(t+1,l-t)}},C=0,$=e?0:-1,v=this.View={get first(){return C},set first(t){C=Math.max(0,Math.min(t,w.end.y)),B()},get n(){return $},set n(t){let e=t-$;$=t,B(e)},get last(){return Math.min(C+$-1,w.end.y)}},B=v.RENDER=t=>{if(t){let e=t;for(;e>0;e--)for(let[t,e]of p)t.push(e.appendChild(document.createElement("pre")));if(t>0)for(let[,t,e]of p)e?.appendChild(t);for(e=t;e<0;e++)for(let[t]of p)t.pop()?.remove()}if(c){let t=Math.max(x,`${C+$+!e}`.length)+f;c.style.width=t+"ch",l&&(a.style.width=`calc(${t+l}ch + ${4*y}px)`)}R(t)},R=v.render=(t=0)=>{b.f++;let l=$+!e;for(;l--;)for(let[t,,,e]of p)t[l]&&e(t[l],l);let i=-1;if(b.i>=0){let[t,e]=_.bounds(1),l=Math.min(C+$,e.y+1);for(let i=Math.max(C,t.y);i=0&&n<$){d.style.top=n*r+"px",i=h.x;let{left:t,right:e}=m,l=t+h.x*M-o.scrollLeft,s=l+M;o.scrollLeft=Math.round((o.scrollLeft+(le?s-e:0))/M)*M}}d.style.left=i+"ch";for(let e of b.sub)e(o,v,t)};if(l&&!c&&(a.style.width=`calc(${l}ch + ${2*y}px)`),e){for(let[,,t]of p)t&&(t.style.height=e*r+"px");v.n=e}else new ResizeObserver(()=>{m=o.getBoundingClientRect(),v.n=Math.floor(o.clientHeight/r)}).observe(a);this.Ctrl} \ No newline at end of file +function Buffe(e,{h:t,w:l,s:i=4}={}){if(!(this instanceof Buffe))return new Buffe(e,arguments[1]);let n={y:0,x:0},s={},h=n,[r,y,x,f]=["cell","padding","rail-init","rail-pad"].map(t=>parseFloat(getComputedStyle(e).getPropertyValue("--buffee-"+t))),[a,o,d,c,g,u]=["pane","lines","caret","rail","ztxt","zsel"].map(t=>e.querySelector(".buffee-"+t));this.$=e,this.$lines=o;let m=o.getBoundingClientRect(),p=[[g,(e,t)=>e.textContent=w._[C+t]??null],[c,(e,t)=>e.textContent=C+t+1],[u,e=>e.style.width=0]].map(([e,t])=>[[],document.createDocumentFragment(),e,t]),_=this.Span={mvY(e,t){if(e>0?h.y0){let l=w._[e>0?++h.y:--h.y].length;h.x=t?e>0?0:l:Math.min(b.mx,l),t&&(b.mx=h.x),h.yv.last?v.first=e>0?h.y-$+1:h.y:R()}},mvX(e){let t=e>0;(t?h.x0?w._[h.y].length:0,R()},bounds:e=>e&&_.dir>0?[n,h]:[h,n],get dir(){return h==n?0:n.y==h.y&&n.x0));return t.x>=l.length&&e.y0))]},cursor(e=h){n.y=e.y,n.x=e.x,h=n},select(e=n){h=s,h.y=e.y,h.x=e.x},ins(e){if(this.dir){let[t,l]=_.bounds(1);w.del(t.y,t.x,l.y,l.x+(this.dir>0)),w.ins(t.y,t.x,e),h.y=t.y,e.length>1?(h.y+=e.length-1,h.x=e.at(-1).length):h.x=t.x+(e[0]?.length||0),this.cursor()}else w.ins(h.y,h.x,e),e.length>1?(h.y+=e.length-1,b.mx=h.x=e.at(-1).length):b.mx=h.x+=e[0]?.length||0;h.y>v.last?v.first=h.y-$+1:R()},del(){this.dir?this.ins([""]):h.x>0?(w.del(h.y,h.x-1,h.y,h.x),h.x--,R()):h.y>0&&(h.x=w._[h.y-1].length,w.del(h.y-1,h.x,h.y,0),--h.y0&&!this.dir)return;let[t,l]=_.bounds(1);for(let i=t.y;i<=l.y;i++){let n=w._[i];if(e>0)w._[i]=" ".repeat(e)+n;else{let s=Math.min(-e,n.search(/[^ ]|$/));w._[i]=n.slice(s),i===t.y&&(t.x=Math.max(0,t.x-s)),i===l.y&&t!==l&&(l.x=Math.max(0,l.x-s))}}e>0&&(t.x+=e,l.x+=e),R()}},M=d.getBoundingClientRect().width,b=this.Mode={s:i,i:1,f:0,mx:0,ch:r,cw:M,sub:[],ext:["17.8.0-alpha.1"]},w=this.Model={_:[""],get end(){return{y:this._.length-1,x:this._.at(-1).length}},ins(e,t,l){let i=this._[e].slice(t);this._[e]=this._[e].slice(0,t)+l[0],1==l.length?this._[e]+=i:this._.splice(e+1,0,...l.slice(1,-1),l.at(-1)+i)},del(e,t,l,i){this._[e]=this._[e].slice(0,t)+this._[l].slice(i),e!=l&&this._.splice(e+1,l-e)}},C=0,$=t?0:-1,v=this.View={get first(){return C},set first(e){C=Math.max(0,Math.min(e,w.end.y)),B()},get n(){return $},set n(e){let t=e-$;$=e,B(t)},get last(){return Math.min(C+$-1,w.end.y)}},B=v.RENDER=e=>{if(e){let t=e;for(;t>0;t--)for(let[e,t]of p)e.push(t.appendChild(document.createElement("pre")));if(e>0)for(let[,e,t]of p)t?.appendChild(e);for(t=e;t<0;t++)for(let[e]of p)e.pop()?.remove()}if(c){let e=Math.max(x,`${C+$+!t}`.length)+f;c.style.width=e+"ch",l&&(a.style.width=`calc(${e+l}ch + ${4*y}px)`)}R(e)},R=v.render=(e=0)=>{b.f++;let l=$+!t;for(;l--;)for(let[e,,,t]of p)e[l]&&t(e[l],l);let i=-1;if(b.i>=0){let[e,t]=_.bounds(1),l=Math.min(C+$,t.y+1);for(let i=Math.max(C,e.y);i=0&&n<$){d.style.top=n*r+"px",i=h.x;let{left:e,right:t}=m,l=e+h.x*M-o.scrollLeft,s=l+M;o.scrollLeft=Math.round((o.scrollLeft+(lt?s-t:0))/M)*M}}d.style.left=i+"ch";for(let t of b.sub)t(o,v,e)};if(l&&!c&&(a.style.width=`calc(${l}ch + ${2*y}px)`),t){for(let[,,e]of p)e&&(e.style.height=t*r+"px");v.n=t}else new ResizeObserver(()=>{m=o.getBoundingClientRect(),v.n=Math.floor(o.clientHeight/r)}).observe(a)} \ No newline at end of file diff --git a/dist/buffee.min.js b/dist/buffee.min.js index defac769..40cf2837 100644 --- a/dist/buffee.min.js +++ b/dist/buffee.min.js @@ -1 +1 @@ -function Buffe(e,{h:t,w:n,s:l=4}={}){if(!(this instanceof Buffe))return new Buffe(e,arguments[1]);let i={y:0,x:0},s={},r=i,[a,h,y,f]=["cell","padding","rail-init","rail-pad"].map(t=>parseFloat(getComputedStyle(e).getPropertyValue("--buffee-"+t))),[o,d,x,c,u,p]=["pane","lines","caret","rail","ztxt","zsel"].map(t=>e.querySelector(".buffee-"+t));this.$=e,this.$lines=d;let m=d.getBoundingClientRect(),g=[[u,(e,t)=>e.textContent=b._[D+t]??null],[c,(e,t)=>e.textContent=D+t+1],[p,e=>e.style.width=0]].map(([e,t])=>[[],document.createDocumentFragment(),e,t]),v=this.Span={mvY(e,t){if(e>0?r.y0){let n=b._[e>0?++r.y:--r.y].length;r.x=t?e>0?0:n:Math.min(M.mx,n),t&&(M.mx=r.x),r.yw.last?w.first=e>0?r.y-L+1:r.y:E()}},mvX(e){let t=e>0;(t?r.x0?b._[r.y].length:0,E()},bounds:e=>e&&v.dir>0?[i,r]:[r,i],get dir(){return r==i?0:i.y==r.y&&i.x0));return t.x>=n.length&&e.y0))]},cursor(e=r){i.y=e.y,i.x=e.x,r=i},select(e=i){r=s,r.y=e.y,r.x=e.x},ins(e){if(this.dir){let[t,n]=v.bounds(1);b.del(t.y,t.x,n.y,n.x+(this.dir>0)),b.ins(t.y,t.x,e),r.y=t.y,e.length>1?(r.y+=e.length-1,r.x=e.at(-1).length):r.x=t.x+(e[0]?.length||0),this.cursor()}else b.ins(r.y,r.x,e),e.length>1?(r.y+=e.length-1,M.mx=r.x=e.at(-1).length):M.mx=r.x+=e[0]?.length||0;r.y>w.last?w.first=r.y-L+1:E()},del(){this.dir?this.ins([""]):r.x>0?(b.del(r.y,r.x-1,r.y,r.x),r.x--,E()):r.y>0&&(r.x=b._[r.y-1].length,b.del(r.y-1,r.x,r.y,0),--r.y0&&!this.dir)return;let[t,n]=v.bounds(1);for(let l=t.y;l<=n.y;l++){let i=b._[l];if(e>0)b._[l]=" ".repeat(e)+i;else{let s=Math.min(-e,i.search(/[^ ]|$/));b._[l]=i.slice(s),l===t.y&&(t.x=Math.max(0,t.x-s)),l===n.y&&t!==n&&(n.x=Math.max(0,n.x-s))}}e>0&&(t.x+=e,n.x+=e),E()}},_=x.getBoundingClientRect().width,M=this.Mode={s:l,i:1,f:0,mx:0,ch:a,cw:_,sub:[],ext:["17.7.0-alpha.1"]},b=this.Model={_:[""],get end(){return{y:this._.length-1,x:this._.at(-1).length}},ins(e,t,n){let l=this._[e].slice(t);this._[e]=this._[e].slice(0,t)+n[0],1==n.length?this._[e]+=l:this._.splice(e+1,0,...n.slice(1,-1),n.at(-1)+l)},del(e,t,n,l){this._[e]=this._[e].slice(0,t)+this._[n].slice(l),e!=n&&this._.splice(e+1,n-e)}},D=0,L=t?0:-1,w=this.View={get first(){return D},set first(e){D=Math.max(0,Math.min(e,b.end.y)),B()},get n(){return L},set n(e){let t=e-L;L=e,B(t)},get last(){return Math.min(D+L-1,b.end.y)}},B=w.RENDER=e=>{if(e){let t=e;for(;t>0;t--)for(let[e,t]of g)e.push(t.appendChild(document.createElement("pre")));if(e>0)for(let[,e,t]of g)t?.appendChild(e);for(t=e;t<0;t++)for(let[e]of g)e.pop()?.remove()}if(c){let e=Math.max(y,`${D+L+!t}`.length)+f;c.style.width=e+"ch",n&&(o.style.width=`calc(${e+n}ch + ${4*h}px)`)}E(e)},E=w.render=(e=0)=>{M.f++;let n=L+!t;for(;n--;)for(let[e,,,t]of g)e[n]&&t(e[n],n);let l=-1;if(M.i>=0){let[e,t]=v.bounds(1),n=Math.min(D+L,t.y+1);for(let l=Math.max(D,e.y);l=0&&it?s-t:0))/_)*_}}x.style.left=l+"ch";for(let t of M.sub)t(d,w,e)};if(n&&!c&&(o.style.width=`calc(${n}ch + ${2*h}px)`),t){for(let[,,e]of g)e&&(e.style.height=t*a+"px");w.n=t}else new ResizeObserver(()=>{m=d.getBoundingClientRect(),w.n=Math.floor(d.clientHeight/a)}).observe(o);this.Ctrl}function BuffeeNativeController(e){let{Span:t,Model:n,Mode:l,View:i,$lines:s}=e,r=i.render,a=e=>{e.preventDefault(),t.ins(e.clipboardData.getData("text/plain").split("\n"))},h=e=>{e.preventDefault(),e.clipboardData.setData("text/plain",t._.join("\n"))},y=e=>{e.preventDefault(),e.clipboardData.setData("text/plain",t._.join("\n")),t.del()},f=i=>{let s=i.metaKey||i.ctrlKey,a=i.key,h=i.shiftKey,y=s?"mvLn":"mvX",f={D:[1,"mvY"],U:[-1,"mvY"],L:[-1,y],R:[1,y]}[a[5]]||{Home:[0,"mvLn"],End:[1,"mvLn"]}[a];if(f)i.preventDefault(),l.i>=0&&(!h&&t.dir?(t.cursor(t.bounds(1)[f[0]>0|0]),s?t[f[1]](f[0]):r()):(h&&!t.dir&&t.select(),t[f[1]](f[0])));else if(1==a.length){let y={z:()=>e.History?.[h?"redo":"undo"](),a:()=>{let e=n.end;t.cursor({y:0,x:0}),(e.y||e.x)&&t.select(e),r()}};s?y[a]&&(i.preventDefault(),y[a]()):l.i>0&&(" "==a&&i.preventDefault(),t.ins([a]))}else l.i>=1&&{Backspace:()=>t.del(),Enter:()=>t.ins(["",""]),Tab:()=>{i.preventDefault(),t.dir||h?t.dent(h?-l.s:l.s):t.ins([" ".repeat(l.s)])}}[a]?.()};return s.addEventListener("paste",a),s.addEventListener("copy",h),s.addEventListener("cut",y),s.addEventListener("keydown",f),()=>{s.removeEventListener("paste",a),s.removeEventListener("copy",h),s.removeEventListener("cut",y),s.removeEventListener("keydown",f)}}function Buffee(e,t){let n=e instanceof Buffe?e:new Buffe(e,t);return n.Ctrl=BuffeeNativeController(n),n.Mode.ext.push("Buffee@17.7.0-alpha.1"),n} \ No newline at end of file +function Buffe(e,{h:t,w:n,s:l=4}={}){if(!(this instanceof Buffe))return new Buffe(e,arguments[1]);let i={y:0,x:0},s={},r=i,[a,h,y,f]=["cell","padding","rail-init","rail-pad"].map(t=>parseFloat(getComputedStyle(e).getPropertyValue("--buffee-"+t))),[o,d,x,c,u,p]=["pane","lines","caret","rail","ztxt","zsel"].map(t=>e.querySelector(".buffee-"+t));this.$=e,this.$lines=d;let m=d.getBoundingClientRect(),g=[[u,(e,t)=>e.textContent=b._[D+t]??null],[c,(e,t)=>e.textContent=D+t+1],[p,e=>e.style.width=0]].map(([e,t])=>[[],document.createDocumentFragment(),e,t]),v=this.Span={mvY(e,t){if(e>0?r.y0){let n=b._[e>0?++r.y:--r.y].length;r.x=t?e>0?0:n:Math.min(M.mx,n),t&&(M.mx=r.x),r.yw.last?w.first=e>0?r.y-L+1:r.y:E()}},mvX(e){let t=e>0;(t?r.x0?b._[r.y].length:0,E()},bounds:e=>e&&v.dir>0?[i,r]:[r,i],get dir(){return r==i?0:i.y==r.y&&i.x0));return t.x>=n.length&&e.y0))]},cursor(e=r){i.y=e.y,i.x=e.x,r=i},select(e=i){r=s,r.y=e.y,r.x=e.x},ins(e){if(this.dir){let[t,n]=v.bounds(1);b.del(t.y,t.x,n.y,n.x+(this.dir>0)),b.ins(t.y,t.x,e),r.y=t.y,e.length>1?(r.y+=e.length-1,r.x=e.at(-1).length):r.x=t.x+(e[0]?.length||0),this.cursor()}else b.ins(r.y,r.x,e),e.length>1?(r.y+=e.length-1,M.mx=r.x=e.at(-1).length):M.mx=r.x+=e[0]?.length||0;r.y>w.last?w.first=r.y-L+1:E()},del(){this.dir?this.ins([""]):r.x>0?(b.del(r.y,r.x-1,r.y,r.x),r.x--,E()):r.y>0&&(r.x=b._[r.y-1].length,b.del(r.y-1,r.x,r.y,0),--r.y0&&!this.dir)return;let[t,n]=v.bounds(1);for(let l=t.y;l<=n.y;l++){let i=b._[l];if(e>0)b._[l]=" ".repeat(e)+i;else{let s=Math.min(-e,i.search(/[^ ]|$/));b._[l]=i.slice(s),l===t.y&&(t.x=Math.max(0,t.x-s)),l===n.y&&t!==n&&(n.x=Math.max(0,n.x-s))}}e>0&&(t.x+=e,n.x+=e),E()}},_=x.getBoundingClientRect().width,M=this.Mode={s:l,i:1,f:0,mx:0,ch:a,cw:_,sub:[],ext:["17.8.0-alpha.1"]},b=this.Model={_:[""],get end(){return{y:this._.length-1,x:this._.at(-1).length}},ins(e,t,n){let l=this._[e].slice(t);this._[e]=this._[e].slice(0,t)+n[0],1==n.length?this._[e]+=l:this._.splice(e+1,0,...n.slice(1,-1),n.at(-1)+l)},del(e,t,n,l){this._[e]=this._[e].slice(0,t)+this._[n].slice(l),e!=n&&this._.splice(e+1,n-e)}},D=0,L=t?0:-1,w=this.View={get first(){return D},set first(e){D=Math.max(0,Math.min(e,b.end.y)),B()},get n(){return L},set n(e){let t=e-L;L=e,B(t)},get last(){return Math.min(D+L-1,b.end.y)}},B=w.RENDER=e=>{if(e){let t=e;for(;t>0;t--)for(let[e,t]of g)e.push(t.appendChild(document.createElement("pre")));if(e>0)for(let[,e,t]of g)t?.appendChild(e);for(t=e;t<0;t++)for(let[e]of g)e.pop()?.remove()}if(c){let e=Math.max(y,`${D+L+!t}`.length)+f;c.style.width=e+"ch",n&&(o.style.width=`calc(${e+n}ch + ${4*h}px)`)}E(e)},E=w.render=(e=0)=>{M.f++;let n=L+!t;for(;n--;)for(let[e,,,t]of g)e[n]&&t(e[n],n);let l=-1;if(M.i>=0){let[e,t]=v.bounds(1),n=Math.min(D+L,t.y+1);for(let l=Math.max(D,e.y);l=0&&it?s-t:0))/_)*_}}x.style.left=l+"ch";for(let t of M.sub)t(d,w,e)};if(n&&!c&&(o.style.width=`calc(${n}ch + ${2*h}px)`),t){for(let[,,e]of g)e&&(e.style.height=t*a+"px");w.n=t}else new ResizeObserver(()=>{m=d.getBoundingClientRect(),w.n=Math.floor(d.clientHeight/a)}).observe(o)}function BuffeeNativeController(e){let{Span:t,Model:n,Mode:l,View:i,$lines:s}=e,r=i.render,a=e=>{e.preventDefault(),t.ins(e.clipboardData.getData("text/plain").split("\n"))},h=e=>{e.preventDefault(),e.clipboardData.setData("text/plain",t._.join("\n"))},y=e=>{e.preventDefault(),e.clipboardData.setData("text/plain",t._.join("\n")),t.del()},f=i=>{let s=i.metaKey||i.ctrlKey,a=i.key,h=i.shiftKey,y=s?"mvLn":"mvX",f={D:[1,"mvY"],U:[-1,"mvY"],L:[-1,y],R:[1,y]}[a[5]]||{Home:[0,"mvLn"],End:[1,"mvLn"]}[a];if(f)i.preventDefault(),l.i>=0&&(!h&&t.dir?(t.cursor(t.bounds(1)[f[0]>0|0]),s?t[f[1]](f[0]):r()):(h&&!t.dir&&t.select(),t[f[1]](f[0])));else if(1==a.length){let y={z:()=>e.History?.[h?"redo":"undo"](),a:()=>{let e=n.end;t.cursor({y:0,x:0}),(e.y||e.x)&&t.select(e),r()}};s?y[a]&&(i.preventDefault(),y[a]()):l.i>0&&(" "==a&&i.preventDefault(),t.ins([a]))}else l.i>=1&&{Backspace:()=>t.del(),Enter:()=>t.ins(["",""]),Tab:()=>{i.preventDefault(),t.dir||h?t.dent(h?-l.s:l.s):t.ins([" ".repeat(l.s)])}}[a]?.()};return s.addEventListener("paste",a),s.addEventListener("copy",h),s.addEventListener("cut",y),s.addEventListener("keydown",f),()=>{s.removeEventListener("paste",a),s.removeEventListener("copy",h),s.removeEventListener("cut",y),s.removeEventListener("keydown",f)}}function Buffee(e,t){let n=e instanceof Buffe?e:new Buffe(e,t);return n.Ctrl=BuffeeNativeController(n),n.Mode.ext.push("Buffee@17.8.0-alpha.1"),n} \ No newline at end of file diff --git a/hooks/pre-commit b/hooks/pre-commit index 6fa45f23..5685e827 100755 --- a/hooks/pre-commit +++ b/hooks/pre-commit @@ -123,7 +123,7 @@ report_sizes() { # Generate dist/buffe.min.js (core only) get_old_sizes dist/buffe.min.js -perl -pe 's/\bconst\b/let/g' buffe.js | terser -c -m -o dist/buffe.min.js +perl -pe 's/\bconst\b/let/g' buffe.js | terser -c pure_getters -m -o dist/buffe.min.js if [ $? -ne 0 ]; then echo "✗ buffe.min.js minification failed"; exit 1; fi report_sizes "buffe.min.js (core)" dist/buffe.min.js CORE_SIZE=$NEW_SIZE; CORE_GZ=$NEW_GZIPPED; CORE_BR=$NEW_BROTLI @@ -132,7 +132,7 @@ CORE_DIFF=${DIFF:-0}; CORE_DIFF_GZ=${DIFF_GZIPPED:-0}; CORE_DIFF_BR=${DIFF_BROTL # Generate dist/buffee.min.js (core + controller) get_old_sizes dist/buffee.min.js -cat buffe.js buffee.js | perl -pe 's/\bconst\b/let/g' | terser -c -m -o dist/buffee.min.js +cat buffe.js buffee.js | perl -pe 's/\bconst\b/let/g' | terser -c pure_getters -m -o dist/buffee.min.js if [ $? -ne 0 ]; then echo "✗ buffee.min.js minification failed"; exit 1; fi report_sizes "buffee.min.js (combined)" dist/buffee.min.js COMB_SIZE=$NEW_SIZE; COMB_GZ=$NEW_GZIPPED; COMB_BR=$NEW_BROTLI diff --git a/test/index.html b/test/index.html index c62e3622..494159f3 100644 --- a/test/index.html +++ b/test/index.html @@ -4,6 +4,7 @@ buffee - Tests + @@ -224,6 +225,14 @@

This test setup was AI generated with adult supervision.

+ + running tests against + + +
@@ -232,6 +241,10 @@

This test setup was AI generated with adult supervision.

Compilation errors. Some tests may have lines omitted
+
0
@@ -451,9 +464,17 @@

This test setup was AI generated with adult supervision.

- + + + + + + + diff --git a/test/lib/test-ui.js b/test/lib/test-ui.js index b2521e10..97f09036 100644 --- a/test/lib/test-ui.js +++ b/test/lib/test-ui.js @@ -1,3 +1,47 @@ + // Compare source vs minified build behavior + function compareBuildBehavior() { + // Create temporary container + const container = document.createElement('div'); + container.style.cssText = 'position:absolute;left:-9999px;top:-9999px;width:600px;height:400px;'; + container.innerHTML = ` +
+
+
+
`; + document.body.appendChild(container); + + try { + const el = container.querySelector('.buffee'); + + // Test source build + const srcEditor = BuffeeSource(BuffeSource(el.cloneNode(true), { h: 10 })); + srcEditor.Span.ins(['Hello', 'World']); + const srcState = { + model: [...srcEditor.Model._], + cursor: { ...srcEditor.Span.bounds()[0] }, + ext: srcEditor.Mode.ext[0] + }; + + // Test minified build + const minEditor = BuffeeMin(BuffeMin(el.cloneNode(true), { h: 10 })); + minEditor.Span.ins(['Hello', 'World']); + const minState = { + model: [...minEditor.Model._], + cursor: { ...minEditor.Span.bounds()[0] }, + ext: minEditor.Mode.ext[0] + }; + + // Compare states + const modelMatch = JSON.stringify(srcState.model) === JSON.stringify(minState.model); + const cursorMatch = srcState.cursor.y === minState.cursor.y && srcState.cursor.x === minState.cursor.x; + const versionMatch = srcState.ext === minState.ext; + + return !(modelMatch && cursorMatch && versionMatch); + } finally { + container.remove(); + } + } + // DSL Syntax Highlighter function highlightDSL(code) { const lines = code.split('\n'); @@ -587,6 +631,18 @@ compileErrorTestsCount.textContent = '0'; testErrorWarning.style.display = 'none'; } + + // Compare source vs minified builds + if (typeof BuffeSource !== 'undefined' && typeof BuffeMin !== 'undefined') { + const mismatchWarning = document.getElementById('build-mismatch-warning'); + try { + const mismatch = compareBuildBehavior(); + mismatchWarning.style.display = mismatch ? 'flex' : 'none'; + } catch (e) { + console.error('Build comparison failed:', e); + mismatchWarning.style.display = 'flex'; + } + } } catch (error) { const resultsContainer = document.getElementById('test-results');