From d9696e626920cfdecd6f2c29f3b601051ce5f529 Mon Sep 17 00:00:00 2001 From: Ilya Grigoriev Date: Wed, 13 Mar 2024 14:05:38 -0700 Subject: [PATCH] webapp: Create and move some comments, formatting --- .../{index-Ca1uhQEV.js => index-DDtvyCTJ.js} | 10 ++++---- webapp/dist/index.html | 2 +- webapp/src/main.ts | 14 +++++------ webapp/src/merge_state.ts | 23 ++++++++++++++----- 4 files changed, 30 insertions(+), 19 deletions(-) rename webapp/dist/assets/{index-Ca1uhQEV.js => index-DDtvyCTJ.js} (98%) diff --git a/webapp/dist/assets/index-Ca1uhQEV.js b/webapp/dist/assets/index-DDtvyCTJ.js similarity index 98% rename from webapp/dist/assets/index-Ca1uhQEV.js rename to webapp/dist/assets/index-DDtvyCTJ.js index 62d71ca..c179acd 100644 --- a/webapp/dist/assets/index-Ca1uhQEV.js +++ b/webapp/dist/assets/index-DDtvyCTJ.js @@ -32,7 +32,7 @@ b`.split(/\n/).length!=3?function(e){for(var t=0,i=[],r=e.length;t<=r;){var n=e. * SPDX-License-Identifier: BSD-3-Clause */const Si=globalThis,dn=Si.trustedTypes,Ra=dn?dn.createPolicy("lit-html",{createHTML:E=>E}):void 0,Ja="$lit$",Zt=`lit$${(Math.random()+"").slice(9)}$`,ja="?"+Zt,kf=`<${ja}>`,gr=document,Ti=()=>gr.createComment(""),ki=E=>E===null||typeof E!="object"&&typeof E!="function",Va=Array.isArray,xf=E=>Va(E)||typeof(E==null?void 0:E[Symbol.iterator])=="function",Ll=`[ \f\r]`,wi=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,za=/-->/g,Ua=/>/g,hr=RegExp(`>|${Ll}(?:([^\\s"'>=/]+)(${Ll}*=${Ll}*(?:[^ -\f\r"'\`<>=]|("|')|))|$)`,"g"),Ga=/'/g,Ka=/"/g,es=/^(?:script|style|textarea|title)$/i,Af=E=>(m,...w)=>({_$litType$:E,strings:m,values:w}),dr=Af(1),xi=Symbol.for("lit-noChange"),Ye=Symbol.for("lit-nothing"),$a=new WeakMap,cr=gr.createTreeWalker(gr,129);function ts(E,m){if(!Array.isArray(E)||!E.hasOwnProperty("raw"))throw Error("invalid template strings array");return Ra!==void 0?Ra.createHTML(m):m}const Mf=(E,m)=>{const w=E.length-1,N=[];let k,U=m===2?"":"",h=wi;for(let c=0;c"?(h=k??wi,C=-1):b[1]===void 0?C=-2:(C=h.lastIndex-b[2].length,v=b[1],h=b[3]===void 0?hr:b[3]==='"'?Ka:Ga):h===Ka||h===Ga?h=hr:h===za||h===Ua?h=wi:(h=hr,k=void 0);const _=h===hr&&E[c+1].startsWith("/>")?" ":"";U+=h===wi?d+kf:C>=0?(N.push(v),d.slice(0,C)+Ja+d.slice(C)+Zt+_):d+Zt+(C===-2?c:_)}return[ts(E,U+(E[w]||"")+(m===2?"":"")),N]};class Ai{constructor({strings:m,_$litType$:w},N){let k;this.parts=[];let U=0,h=0;const c=m.length-1,d=this.parts,[v,b]=Mf(m,w);if(this.el=Ai.createElement(v,N),cr.currentNode=this.el.content,w===2){const C=this.el.content.firstChild;C.replaceWith(...C.childNodes)}for(;(k=cr.nextNode())!==null&&d.length0){k.textContent=dn?dn.emptyScript:"";for(let _=0;_2||N[0]!==""||N[1]!==""?(this._$AH=Array(N.length-1).fill(new String),this.strings=N):this._$AH=Ye}_$AI(m,w=this,N,k){const U=this.strings;let h=!1;if(U===void 0)m=Rr(this,m,w,0),h=!ki(m)||m!==this._$AH&&m!==xi,h&&(this._$AH=m);else{const c=m;let d,v;for(m=U[0],d=0;d{const N=(w==null?void 0:w.renderBefore)??m;let k=N._$litPart$;if(k===void 0){const U=(w==null?void 0:w.renderBefore)??null;N._$litPart$=k=new _i(m.insertBefore(Ti(),U),U,void 0,w??{})}return k._$AI(E),k};function Wf(){return window.crypto.getRandomValues(new Uint32Array(1))[0]}function Al(E,m=!1){const w=Wf(),N=`_${w}`;return Object.defineProperty(window,N,{value:k=>(m&&Reflect.deleteProperty(window,N),E==null?void 0:E(k)),writable:!1,configurable:!0}),w}async function rs(E,m={}){return new Promise((w,N)=>{const k=Al(h=>{w(h),Reflect.deleteProperty(window,`_${U}`)},!0),U=Al(h=>{N(h),Reflect.deleteProperty(window,`_${k}`)},!0);window.__TAURI_IPC__({cmd:E,callback:k,error:U,...m})})}async function _l(E){return rs("tauri",E)}async function If(E=0){return _l({__tauriModule:"Process",message:{cmd:"exit",exitCode:E}})}function kl(E){return E.type=="Text"?E.value:null}const Dl="__TAURI__"in globalThis;async function is(E,m,w){if(Dl){let N={};return w!=null&&(N={result:w}),await rs(E,N)}else return await ns(E,m,w)}async function ns(E,m,w){let N=null,k={};w!=null&&(N=JSON.stringify(w),k["Content-Type"]="application/json");const U=await fetch(`/api/${E}`,{method:m,body:N,headers:k});if(U.ok)return await U.json();{let h="";throw U.status<500&&(h=`Likely bug in the webapp: got response "${U.status} ${U.statusText}" for "${E}" request. Additional details, if any, follow. `),h+await U.text()}}async function Nl(E){Dl?await If(E):await ns("exit","POST",E)}async function Ff(){await Nl(0)}async function Xa(){await Nl(1)}async function Hf(){await Nl(2)}async function Ya(E){return await is("save","PUT",E)}async function Pf(){const E=await is("get_merge_data","GET");for(const m in E)E[m]={left:E[m][0],right:E[m][1],edit:E[m][2]};return E}function ls(){throw new Error("this statement is unreachable; this check exists to make TS happy")}function Ml(E){const m=document.getElementById(E);if(m==null)return;const w=document.createElement("div");return w.id=E,m.replaceWith(w),w}class Ol{constructor(){fn(this,"merge_views");fn(this,"dom_ids");fn(this,"initial_values");this.merge_views={},this.dom_ids={},this.initial_values={}}values(){const m={};for(const w in this.merge_views)m[w]=this.merge_views[w].editor().getValue();return m}static renderInDomElement(m,w){let N=[],k=c=>`${c}_${m}`;for(const c in w){const d=Za(w[c]);d!=null?N.push(dr` +\f\r"'\`<>=]|("|')|))|$)`,"g"),Ga=/'/g,Ka=/"/g,es=/^(?:script|style|textarea|title)$/i,Af=E=>(m,...w)=>({_$litType$:E,strings:m,values:w}),dr=Af(1),xi=Symbol.for("lit-noChange"),Ye=Symbol.for("lit-nothing"),$a=new WeakMap,cr=gr.createTreeWalker(gr,129);function ts(E,m){if(!Array.isArray(E)||!E.hasOwnProperty("raw"))throw Error("invalid template strings array");return Ra!==void 0?Ra.createHTML(m):m}const Mf=(E,m)=>{const w=E.length-1,N=[];let k,U=m===2?"":"",h=wi;for(let c=0;c"?(h=k??wi,C=-1):b[1]===void 0?C=-2:(C=h.lastIndex-b[2].length,v=b[1],h=b[3]===void 0?hr:b[3]==='"'?Ka:Ga):h===Ka||h===Ga?h=hr:h===za||h===Ua?h=wi:(h=hr,k=void 0);const _=h===hr&&E[c+1].startsWith("/>")?" ":"";U+=h===wi?d+kf:C>=0?(N.push(v),d.slice(0,C)+Ja+d.slice(C)+Zt+_):d+Zt+(C===-2?c:_)}return[ts(E,U+(E[w]||"")+(m===2?"":"")),N]};class Ai{constructor({strings:m,_$litType$:w},N){let k;this.parts=[];let U=0,h=0;const c=m.length-1,d=this.parts,[v,b]=Mf(m,w);if(this.el=Ai.createElement(v,N),cr.currentNode=this.el.content,w===2){const C=this.el.content.firstChild;C.replaceWith(...C.childNodes)}for(;(k=cr.nextNode())!==null&&d.length0){k.textContent=dn?dn.emptyScript:"";for(let _=0;_2||N[0]!==""||N[1]!==""?(this._$AH=Array(N.length-1).fill(new String),this.strings=N):this._$AH=Ye}_$AI(m,w=this,N,k){const U=this.strings;let h=!1;if(U===void 0)m=Rr(this,m,w,0),h=!ki(m)||m!==this._$AH&&m!==xi,h&&(this._$AH=m);else{const c=m;let d,v;for(m=U[0],d=0;d{const N=(w==null?void 0:w.renderBefore)??m;let k=N._$litPart$;if(k===void 0){const U=(w==null?void 0:w.renderBefore)??null;N._$litPart$=k=new _i(m.insertBefore(Ti(),U),U,void 0,w??{})}return k._$AI(E),k};function Wf(){return window.crypto.getRandomValues(new Uint32Array(1))[0]}function Al(E,m=!1){const w=Wf(),N=`_${w}`;return Object.defineProperty(window,N,{value:k=>(m&&Reflect.deleteProperty(window,N),E==null?void 0:E(k)),writable:!1,configurable:!0}),w}async function rs(E,m={}){return new Promise((w,N)=>{const k=Al(h=>{w(h),Reflect.deleteProperty(window,`_${U}`)},!0),U=Al(h=>{N(h),Reflect.deleteProperty(window,`_${k}`)},!0);window.__TAURI_IPC__({cmd:E,callback:k,error:U,...m})})}async function _l(E){return rs("tauri",E)}async function If(E,m){return _l({__tauriModule:"Event",message:{cmd:"unlisten",event:E,eventId:m}})}async function Ff(E,m,w){return _l({__tauriModule:"Event",message:{cmd:"listen",event:E,windowLabel:m,handler:Al(w)}}).then(N=>async()=>If(E,N))}var Xa;(function(E){E.WINDOW_RESIZED="tauri://resize",E.WINDOW_MOVED="tauri://move",E.WINDOW_CLOSE_REQUESTED="tauri://close-requested",E.WINDOW_CREATED="tauri://window-created",E.WINDOW_DESTROYED="tauri://destroyed",E.WINDOW_FOCUS="tauri://focus",E.WINDOW_BLUR="tauri://blur",E.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",E.WINDOW_THEME_CHANGED="tauri://theme-changed",E.WINDOW_FILE_DROP="tauri://file-drop",E.WINDOW_FILE_DROP_HOVER="tauri://file-drop-hover",E.WINDOW_FILE_DROP_CANCELLED="tauri://file-drop-cancelled",E.MENU="tauri://menu",E.CHECK_UPDATE="tauri://update",E.UPDATE_AVAILABLE="tauri://update-available",E.INSTALL_UPDATE="tauri://update-install",E.STATUS_UPDATE="tauri://update-status",E.DOWNLOAD_PROGRESS="tauri://update-download-progress"})(Xa||(Xa={}));async function hn(E,m){return Ff(E,null,m)}async function Hf(E=0){return _l({__tauriModule:"Process",message:{cmd:"exit",exitCode:E}})}function kl(E){return E.type=="Text"?E.value:null}const Dl="__TAURI__"in globalThis;async function is(E,m,w){if(Dl){let N={};return w!=null&&(N={result:w}),await rs(E,N)}else return await ns(E,m,w)}async function ns(E,m,w){let N=null,k={};w!=null&&(N=JSON.stringify(w),k["Content-Type"]="application/json");const U=await fetch(`/api/${E}`,{method:m,body:N,headers:k});if(U.ok)return await U.json();{let h="";throw U.status<500&&(h=`Likely bug in the webapp: got response "${U.status} ${U.statusText}" for "${E}" request. Additional details, if any, follow. `),h+await U.text()}}async function Nl(E){Dl?await Hf(E):await ns("exit","POST",E)}async function Pf(){await Nl(0)}async function Ya(){await Nl(1)}async function Bf(){await Nl(2)}async function Za(E){return await is("save","PUT",E)}async function Rf(){const E=await is("get_merge_data","GET");for(const m in E)E[m]={left:E[m][0],right:E[m][1],edit:E[m][2]};return E}function ls(){throw new Error("this statement is unreachable; this check exists to make TS happy")}function Ml(E){const m=document.getElementById(E);if(m==null)return;const w=document.createElement("div");return w.id=E,m.replaceWith(w),w}class Ol{constructor(){fn(this,"merge_views");fn(this,"dom_ids");fn(this,"initial_values");this.merge_views={},this.dom_ids={},this.initial_values={}}values(){const m={};for(const w in this.merge_views)m[w]=this.merge_views[w].editor().getValue();return m}static renderInDomElement(m,w){let N=[],k=c=>`${c}_${m}`;for(const c in w){const d=qa(w[c]);d!=null?N.push(dr`
${c}: ${d} @@ -93,11 +93,11 @@ b`.split(/\n/).length!=3?function(e){for(var t=0,i=[],r=e.length;t<=r;){var n=e.
- `)}let U=Ml(m);Li(dr`${N}`,U);const h=new Ol;for(let c in w)Za(w[c])==null&&h.createCodeMirrorMergeWidget(k(c),c,Bf(w[c]));return h}createCodeMirrorMergeWidget(m,w,N){const k=N.input,U=document.getElementById(`collapse_${m}`),h=document.getElementById(`linewrap_${m}`),c=document.getElementById(`rightside_${m}`),d=document.getElementById(`align_${m}`),v=document.getElementById(`prevChange_${m}`),b=document.getElementById(`nextChange_${m}`),C=document.getElementById(`details_${m}`),A=document.getElementById(`cm_${m}`);let _;N.showRightSide&&(_=kl(k.right)??"");const F={value:kl(k.edit)??"",origLeft:kl(k.left)??"",orig:_,lineWrapping:N.wrapLines,collapseIdentical:N.collapseIdentical,lineNumbers:!0,mode:"text/plain",connect:N.align?"align":void 0},z=Sf.MergeView(A,F);z.editor().setOption("extraKeys",{"Alt-Down":Ci,"Option-Down":Ci,"Cmd-Down":Ci,"Alt-Up":hn,"Option-Up":hn,"Cmd-Up":hn,Tab:Ci}),N.cursorPosition!=null&&(z.editor().setSelection(N.cursorPosition),z.editor().scrollIntoView(null,50)),U.onclick=()=>this.recreateCodeMirrorFlippingOption(w,"collapseIdentical"),h.onclick=()=>this.recreateCodeMirrorFlippingOption(w,"wrapLines"),c.onclick=()=>this.recreateCodeMirrorFlippingOption(w,"showRightSide"),d.onclick=()=>this.recreateCodeMirrorFlippingOption(w,"align"),v.onclick=()=>hn(z.editor()),b.onclick=()=>Ci(z.editor()),C.open=!1,C.ontoggle=()=>z.editor().refresh(),this.merge_views[w]=z,this.dom_ids[w]=m,this.initial_values[w]=k}getSingleMergeState(m){const w=this.merge_views[m],N=w.editor();return{input:{left:this.initial_values[m].left,right:this.initial_values[m].right,edit:{type:"Text",value:this.merge_views[m].editor().getValue()}},wrapLines:N.getOption("lineWrapping")??!1,collapseIdentical:!!N.getOption("collapseIdentical"),showRightSide:!!w.rightOriginal(),align:N.getOption("connect")=="align",cursorPosition:N.getCursor()}}recreateCodeMirrorFlippingOption(m,w){if(this.merge_views[m]==null){console.warn(`Trying to toggle \`${w}\` option on a non-existent editor`,m,this);return}let k=this.dom_ids[m];const U=this.getSingleMergeState(m);Ml(`cm_${k}`),this.createCodeMirrorMergeWidget(k,m,Rf(U,w));const h=document.getElementById(`details_${k}`);h.open=!0}}function Bf(E){return{input:E,wrapLines:!0,collapseIdentical:!0,align:!0,showRightSide:!0}}function Rf(E,m){let w=Object.assign({},E);return w[m]=!w[m],w}function Za(E){let m=Array.from([{file:E.left,side:"left"},{file:E.right,side:"right"},{file:E.edit,side:"middle"}]).find(w=>w.file.type=="Unsupported");return m==null?null:(m.file.type!="Unsupported"&&ls(),dr`error: ${m.file.value} (occurred on the - ${m.side} side)`)}const os=200;function Ci(E){E.execCommand("goNextDiff"),E.scrollIntoView(null,os)}function hn(E){E.execCommand("goPrevDiff"),E.scrollIntoView(null,os)}async function zf(E,m){return _l({__tauriModule:"Event",message:{cmd:"unlisten",event:E,eventId:m}})}async function Uf(E,m,w){return _l({__tauriModule:"Event",message:{cmd:"listen",event:E,windowLabel:m,handler:Al(w)}}).then(N=>async()=>zf(E,N))}var qa;(function(E){E.WINDOW_RESIZED="tauri://resize",E.WINDOW_MOVED="tauri://move",E.WINDOW_CLOSE_REQUESTED="tauri://close-requested",E.WINDOW_CREATED="tauri://window-created",E.WINDOW_DESTROYED="tauri://destroyed",E.WINDOW_FOCUS="tauri://focus",E.WINDOW_BLUR="tauri://blur",E.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",E.WINDOW_THEME_CHANGED="tauri://theme-changed",E.WINDOW_FILE_DROP="tauri://file-drop",E.WINDOW_FILE_DROP_HOVER="tauri://file-drop-hover",E.WINDOW_FILE_DROP_CANCELLED="tauri://file-drop-cancelled",E.MENU="tauri://menu",E.CHECK_UPDATE="tauri://update",E.UPDATE_AVAILABLE="tauri://update-available",E.INSTALL_UPDATE="tauri://update-install",E.STATUS_UPDATE="tauri://update-status",E.DOWNLOAD_PROGRESS="tauri://update-download-progress"})(qa||(qa={}));async function cn(E,m){return Uf(E,null,m)}function as(E){console.log("Caught error, showing to user:",E);const m=document.getElementById("modal_dialog_with_message"),w=document.getElementById("message_of_modal_dialog_with_message");Li(`${String(E)}`,w),m.showModal(),console.log("Done showing error to user.")}async function xl(E){try{return await E()}catch(m){as(m)}}window.addEventListener("DOMContentLoaded",async()=>{const E=Ml("loading_message");Li(dr` + `)}let U=Ml(m);Li(dr`${N}`,U);const h=new Ol;for(let c in w)qa(w[c])==null&&h.createCodeMirrorMergeWidget(k(c),c,zf(w[c]));return h}createCodeMirrorMergeWidget(m,w,N){const k=N.input,U=document.getElementById(`collapse_${m}`),h=document.getElementById(`linewrap_${m}`),c=document.getElementById(`rightside_${m}`),d=document.getElementById(`align_${m}`),v=document.getElementById(`prevChange_${m}`),b=document.getElementById(`nextChange_${m}`),C=document.getElementById(`details_${m}`),A=document.getElementById(`cm_${m}`);let _;N.showRightSide&&(_=kl(k.right)??"");const F={value:kl(k.edit)??"",origLeft:kl(k.left)??"",orig:_,lineWrapping:N.wrapLines,collapseIdentical:N.collapseIdentical,lineNumbers:!0,mode:"text/plain",connect:N.align?"align":void 0},z=Sf.MergeView(A,F);z.editor().setOption("extraKeys",{"Alt-Down":Ci,"Option-Down":Ci,"Cmd-Down":Ci,"Alt-Up":cn,"Option-Up":cn,"Cmd-Up":cn,Tab:Ci}),N.cursorPosition!=null&&(z.editor().setSelection(N.cursorPosition),z.editor().scrollIntoView(null,50)),U.onclick=()=>this.recreateCodeMirrorFlippingOption(w,"collapseIdentical"),h.onclick=()=>this.recreateCodeMirrorFlippingOption(w,"wrapLines"),c.onclick=()=>this.recreateCodeMirrorFlippingOption(w,"showRightSide"),d.onclick=()=>this.recreateCodeMirrorFlippingOption(w,"align"),v.onclick=()=>cn(z.editor()),b.onclick=()=>Ci(z.editor()),C.open=!1,C.ontoggle=()=>z.editor().refresh(),this.merge_views[w]=z,this.dom_ids[w]=m,this.initial_values[w]=k}getSingleMergeState(m){const w=this.merge_views[m],N=w.editor();return{input:{left:this.initial_values[m].left,right:this.initial_values[m].right,edit:{type:"Text",value:this.merge_views[m].editor().getValue()}},wrapLines:N.getOption("lineWrapping")??!1,collapseIdentical:!!N.getOption("collapseIdentical"),showRightSide:!!w.rightOriginal(),align:N.getOption("connect")=="align",cursorPosition:N.getCursor()}}recreateCodeMirrorFlippingOption(m,w){if(this.merge_views[m]==null){console.warn(`Trying to toggle \`${w}\` option on a non-existent editor`,m,this);return}let k=this.dom_ids[m];const U=this.getSingleMergeState(m);Ml(`cm_${k}`),this.createCodeMirrorMergeWidget(k,m,Uf(U,w));const h=document.getElementById(`details_${k}`);h.open=!0}}function zf(E){return{input:E,wrapLines:!0,collapseIdentical:!0,align:!0,showRightSide:!0}}function Uf(E,m){let w=Object.assign({},E);return w[m]=!w[m],w}function qa(E){let m=Array.from([{file:E.left,side:"left"},{file:E.right,side:"right"},{file:E.edit,side:"middle"}]).find(w=>w.file.type=="Unsupported");return m==null?null:(m.file.type!="Unsupported"&&ls(),dr`error: ${m.file.value} (occurred on the + ${m.side} side)`)}const os=200;function Ci(E){E.execCommand("goNextDiff"),E.scrollIntoView(null,os)}function cn(E){E.execCommand("goPrevDiff"),E.scrollIntoView(null,os)}function as(E){console.log("Caught error, showing to user:",E);const m=document.getElementById("modal_dialog_with_message"),w=document.getElementById("message_of_modal_dialog_with_message");Li(`${String(E)}`,w),m.showModal(),console.log("Done showing error to user.")}async function xl(E){try{return await E()}catch(m){as(m)}}window.addEventListener("DOMContentLoaded",async()=>{const E=Ml("loading_message");Li(dr`

Loading...

Getting the data we want to merge...

- `,E);let m;try{m=await Pf()}catch(v){as(v),await Hf(),ls()}Li(dr` + `,E);let m;try{m=await Rf()}catch(v){as(v),await Bf(),ls()}Li(dr`

Loading...

Rendering diffs...

- `,E);const w=Ol.renderInDomElement("lit",m);Li(dr``,E);const N=async()=>await xl(async()=>{await Ya(w.values())}),k=document.getElementById("button_save"),U=document.getElementById("button_save_and_quit"),h=async()=>await xl(async()=>{await Ya(w.values()),k.disabled=!0,U.disabled=!0,Ff(),await new Promise(v=>setTimeout(v,100)),window.close()}),c=async()=>await xl(async()=>{k.disabled=!0,U.disabled=!0,Xa(),await new Promise(v=>setTimeout(v,100)),window.close()}),d=()=>(window.location.reload(),!1);k.onclick=N,U.onclick=h,document.getElementById("button_abandon_changes_and_quit").onclick=c,document.getElementById("button_revert").onclick=d,Dl?(await cn("save",async v=>N()),await cn("save_and_quit",async v=>h()),await cn("revert",async v=>d()),await cn("abandon_changes_and_quit",async v=>Xa())):document.addEventListener("keydown",async v=>{const b=v.metaKey||v.ctrlKey;return v.key=="s"&&b?(await N(),v.preventDefault(),!1):!0})}); + `,E);const w=Ol.renderInDomElement("lit",m);Li(dr``,E);const N=async()=>await xl(async()=>{await Za(w.values())}),k=document.getElementById("button_save"),U=document.getElementById("button_save_and_quit"),h=async()=>await xl(async()=>{await Za(w.values()),k.disabled=!0,U.disabled=!0,Pf(),await new Promise(v=>setTimeout(v,100)),window.close()}),c=async()=>await xl(async()=>{k.disabled=!0,U.disabled=!0,Ya(),await new Promise(v=>setTimeout(v,100)),window.close()}),d=()=>(window.location.reload(),!1);k.onclick=N,U.onclick=h,document.getElementById("button_abandon_changes_and_quit").onclick=c,document.getElementById("button_revert").onclick=d,Dl?(await hn("save",async v=>N()),await hn("save_and_quit",async v=>h()),await hn("revert",async v=>d()),await hn("abandon_changes_and_quit",async v=>Ya())):document.addEventListener("keydown",async v=>{const b=v.metaKey||v.ctrlKey;return v.key=="s"&&b?(await N(),v.preventDefault(),!1):!0})}); diff --git a/webapp/dist/index.html b/webapp/dist/index.html index 07b132d..ea521f5 100644 --- a/webapp/dist/index.html +++ b/webapp/dist/index.html @@ -4,7 +4,7 @@ Diffedit3 - + diff --git a/webapp/src/main.ts b/webapp/src/main.ts index bab1469..fae222e 100644 --- a/webapp/src/main.ts +++ b/webapp/src/main.ts @@ -1,4 +1,5 @@ import { html, render as lit_html_render } from "lit-html"; +import { listen as tauriListen } from "@tauri-apps/api/event"; import { get_merge_data, @@ -36,7 +37,6 @@ async function run_and_show_any_errors_to_user(f: { } } -import { listen } from "@tauri-apps/api/event"; window.addEventListener("DOMContentLoaded", async () => { const loading_elt = replaceElementByIdWithNewEmptyDiv("loading_message")!; lit_html_render( @@ -75,6 +75,8 @@ window.addEventListener("DOMContentLoaded", async () => { await save(merge_views.values()); }); + // TODO: Let the user see some sort of the description of what we are + // comparing const save_button = ( document.getElementById("button_save")! ); @@ -121,14 +123,14 @@ window.addEventListener("DOMContentLoaded", async () => { if (TAURI_BACKEND) { // Events from the app menu // Not sure whether I need to "unlisten" - /* const unlisten = */ await listen("save", async (_event) => + /* const unlisten = */ await tauriListen("save", async (_event) => save_or_tell_user() ); - await listen("save_and_quit", async (_event) => + await tauriListen("save_and_quit", async (_event) => save_and_quit_or_tell_user() ); - await listen("revert", async (_event) => revert()); - await listen("abandon_changes_and_quit", async (_event) => + await tauriListen("revert", async (_event) => revert()); + await tauriListen("abandon_changes_and_quit", async (_event) => exit_user_abandoned_merge() ); } else { @@ -144,6 +146,4 @@ window.addEventListener("DOMContentLoaded", async () => { return true; }); } - - // TODO: Some sort of the description of what we are comparing }); diff --git a/webapp/src/merge_state.ts b/webapp/src/merge_state.ts index d97dc9f..7dc23c1 100644 --- a/webapp/src/merge_state.ts +++ b/webapp/src/merge_state.ts @@ -31,11 +31,6 @@ export class MergeState { return result; } - // TODO: Split off drawing one editor. Only draw a single div in a loop. - // Or not? Is it reasonable to render lit-html in an element that was just rendered in lit-html? - // If not, could have two functions. - // Or just don't use `lit` for creating the divs in a loop; leave a comment instead. - // /// Renders the input inside the HTML element with id `unique_id`. public static renderInDomElement(unique_id: string, merge_input: MergeInput) { let templates = []; @@ -112,6 +107,22 @@ export class MergeState { } let target_element = replaceElementByIdWithNewEmptyDiv(unique_id)!; + // Rendering the template here defeats lit-htmls's optimizations and is not + // at all in the spirit of lit-html. The original reason for this design is + // to have CodeMirror rendered on an already shown DOM element, which is + // hopefully the use-case CodeMirror 5 was most tested for. lit-html is used + // mainly for its contextual escaping functionality as opposed to its + // rendering opimizations. + // + // TODO: Consider improving this design and making it more modern. + // - We can't use lit-element because it's unlikely CodeMirror5 works + // well with shadow DOM. + // - We could create all the CodeMirror elements first and then return + // the resulting lit-html template. The caller can then render it. This + // could potentially trigger some CodeMirror bugs (or it might be + // fine). It might (or might not) also be slower since all the editor + // elements would be generated before any DOM is rendered. (Or maybe + // it's not slower?) lit_html_render(html`${templates}`, target_element); const merge_state = new MergeState(); @@ -244,7 +255,7 @@ export class MergeState { return; } let dom_id = this.dom_ids[filename]; - + const current_state = this.getSingleMergeState(filename); replaceElementByIdWithNewEmptyDiv(`cm_${dom_id}`); this.createCodeMirrorMergeWidget(