Files
2026-02-13 22:24:27 +08:00

14 lines
16 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use strict";var T=Object.defineProperty;var M=(a,e,t)=>e in a?T(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var o=(a,e,t)=>M(a,typeof e!="symbol"?e+"":e,t);const u=require("siyuan");async function U(a,e){let t=await u.fetchSyncPost(a,e);return t.code===0?t.data:null}const V=a=>{let e;switch(a){case"checkbox":e=t=>t.checked;break;case"select":case"slider":case"textinput":case"textarea":e=t=>t.value;break;case"number":e=t=>parseInt(t.value);break;default:e=()=>null;break}return e},C=a=>{let e;switch(a){case"checkbox":e=(t,s)=>{t.checked=s};break;case"select":case"slider":case"textinput":case"textarea":case"number":e=(t,s)=>{t.value=s};break;default:e=()=>{};break}return e};class B{constructor(e){o(this,"plugin");o(this,"name");o(this,"file");o(this,"settings",new Map);o(this,"elements",new Map);this.name=e.name??"settings",this.plugin=e.plugin,this.file=this.name.endsWith(".json")?this.name:`${this.name}.json`,this.plugin.setting=new u.Setting({width:e.width,height:e.height,confirmCallback:()=>{for(let s of this.settings.keys())this.updateValueFromElement(s);let t=this.dump();e.callback!==void 0&&e.callback(t),this.plugin.data[this.name]=t,this.save(t),window.location.reload()},destroyCallback:()=>{for(let t of this.settings.keys())this.updateElementFromValue(t)}})}async load(){let e=await this.plugin.loadData(this.file);if(console.debug("Load config:",e),e)for(let[t,s]of this.settings)s.value=(e==null?void 0:e[t])??s.value;return this.plugin.data[this.name]=this.dump(),e}async save(e){return e=e??this.dump(),await this.plugin.saveData(this.file,this.dump()),console.debug("Save config:",e),e}get(e){var t;return(t=this.settings.get(e))==null?void 0:t.value}set(e,t){let s=this.settings.get(e);s&&(s.value=t,this.updateElementFromValue(e))}async setAndSave(e,t){let s=this.settings.get(e);s&&(s.value=t,this.updateElementFromValue(e),await this.save())}take(e,t=!1){let s=this.settings.get(e),n=this.elements.get(e);if(n)return t&&this.updateValueFromElement(e),s.getEleVal(n)}async takeAndSave(e){let t=this.take(e,!0);return await this.save(),t}disable(e){let t=this.elements.get(e);t&&(t.disabled=!0)}enable(e){let t=this.elements.get(e);t&&(t.disabled=!1)}dump(){let e={};for(let[t,s]of this.settings)s.type!=="button"&&(e[t]=s.value);return e}addItem(e){if(this.settings.set(e.key,e),e.type==="custom"&&(e.createElement===void 0||e.getEleVal===void 0||e.setEleVal===void 0)){console.error("The custom setting item must have createElement, getEleVal and setEleVal methods");return}if(e.getEleVal===void 0&&(e.getEleVal=V(e.type)),e.setEleVal===void 0&&(e.setEleVal=C(e.type)),e.createElement===void 0){let n=this.createDefaultElement(e);this.elements.set(e.key,n),this.plugin.setting.addItem({title:e.title,description:e==null?void 0:e.description,direction:e==null?void 0:e.direction,createActionElement:()=>(this.updateElementFromValue(e.key),this.getElement(e.key))})}else this.plugin.setting.addItem({title:e.title,description:e==null?void 0:e.description,direction:e==null?void 0:e.direction,createActionElement:()=>{let n=this.get(e.key),i=e.createElement(n);return this.elements.set(e.key,i),i}})}createDefaultElement(e){var n,i,l,d,h,f,k,v,y;let t;const s=c=>{c.key==="Enter"&&(c.preventDefault(),c.stopImmediatePropagation())};switch(e.type){case"checkbox":let c=document.createElement("input");c.type="checkbox",c.checked=e.value,c.className="b3-switch fn__flex-center",t=c,c.onchange=((n=e.action)==null?void 0:n.callback)??(()=>{});break;case"select":let b=document.createElement("select");b.className="b3-select fn__flex-center fn__size200";let m=(e==null?void 0:e.options)??{};for(let _ in m){let w=document.createElement("option"),D=m[_];w.value=_,w.text=D,b.appendChild(w)}b.value=e.value,b.onchange=((i=e.action)==null?void 0:i.callback)??(()=>{}),t=b;break;case"slider":let r=document.createElement("input");r.type="range",r.className="b3-slider fn__size200 b3-tooltips b3-tooltips__n",r.ariaLabel=e.value,r.min=((l=e.slider)==null?void 0:l.min.toString())??"0",r.max=((d=e.slider)==null?void 0:d.max.toString())??"100",r.step=((h=e.slider)==null?void 0:h.step.toString())??"1",r.value=e.value,r.onchange=()=>{var _;r.ariaLabel=r.value,(_=e.action)==null||_.callback()},t=r;break;case"textinput":let g=document.createElement("input");g.className="b3-text-field fn__flex-center fn__size200",g.value=e.value,g.onchange=((f=e.action)==null?void 0:f.callback)??(()=>{}),t=g,g.addEventListener("keydown",s);break;case"textarea":let S=document.createElement("textarea");S.className="b3-text-field fn__block",S.value=e.value,S.onchange=((k=e.action)==null?void 0:k.callback)??(()=>{}),t=S;break;case"number":let p=document.createElement("input");p.type="number",p.className="b3-text-field fn__flex-center fn__size200",p.value=e.value,t=p,p.addEventListener("keydown",s);break;case"button":let E=document.createElement("button");E.className="b3-button b3-button--outline fn__flex-center fn__size200",E.innerText=((v=e.button)==null?void 0:v.label)??"Button",E.onclick=((y=e.button)==null?void 0:y.callback)??(()=>{}),t=E;break;case"hint":let A=document.createElement("div");A.className="b3-label fn__flex-center",t=A;break}return t}getElement(e){return this.elements.get(e)}updateValueFromElement(e){let t=this.settings.get(e);if(t.type==="button")return;let s=this.elements.get(e);t.value=t.getEleVal(s)}updateElementFromValue(e){let t=this.settings.get(e);if(t.type==="button")return;let s=this.elements.get(e);t.setEleVal(s,t.value)}}function I(a){return a?new Set(a.split(/[,]/).map(e=>e.trim()).filter(e=>e.length>0)):new Set}const x="menu-config";class L extends u.Plugin{constructor(){super(...arguments);o(this,"settingUtils");o(this,"treatAsSubfolderIdSet");o(this,"treatAsSubfolderEmojiSet");o(this,"mode","normal");o(this,"to_normal_mode_count",0);o(this,"frontend");o(this,"backend");o(this,"isDesktop");o(this,"isPhone");o(this,"isTablet");o(this,"mutationObserver",null);o(this,"trackedElements",new WeakSet);o(this,"handleEvent",null)}async isProvidedIdHasSubDocument(t){const s=t.querySelector(".b3-list-item__toggle");return s?!s.classList.contains("fn__hidden"):!1}async isProvidedIdIsEmptyDocument(t){var d;const i=await U("/api/block/getTreeStat",{id:t});return console.log(i,"res"),(i.runeCount??((d=i.stat)==null?void 0:d.runeCount))===0}async example(){const s=await this.isProvidedIdIsEmptyDocument("20250110144712-on18jor");console.log(s?"empty doc":"not empty doc")}ifProvidedIdInTreatAsSubfolderSet(t){return this.treatAsSubfolderIdSet.has(t)}ifProvidedLiAreUsingUserDefinedIdentifyIcon(t){const s=t.querySelector(".b3-list-item__icon");if(!s)return!1;const n=s.textContent;return n?this.treatAsSubfolderEmojiSet.has(n):!1}appendIdToTreatAsSubfolderSet(t){this.treatAsSubfolderIdSet.add(t)}removeIdFromTreatAsSubfolderSet(t){this.treatAsSubfolderIdSet.delete(t)}onClickDoctreeNode(t){const s=document.querySelector(`li[data-node-id="${t}"]`);if(!s){console.warn("did not found element, probably caused by theme or something");return}if(!s.getAttribute("data-node-id")){console.warn("node missing id attribute, probably caused by theme or something");return}}captureToSetUnsetTreatAsSubfolderSetting(t){const s=this.settingUtils.get("ids_that_should_be_treated_as_subfolder"),n=I(s);n.has(t)?(n.delete(t),u.showMessage(`${this.i18n.recoveredThisDocumentFromSubfolder} ${t}`,2e3,"error")):(n.add(t),u.showMessage(`${this.i18n.consideredThisDocumentAsSubfolder} ${t}`,2e3));const i=Array.from(n).join(",");this.settingUtils.set("ids_that_should_be_treated_as_subfolder",i),this.settingUtils.save(),this.treatAsSubfolderIdSet=n}attachListenerToElement(t){if(this.trackedElements.has(t))return;let s=!1;this.isDesktop?t.addEventListener("click",this.handleEvent):this.isPhone||this.isTablet?t.addEventListener("click",this.handleEvent):s||(u.showMessage("文档树子文件夹插件:开发者没有为您的设备做准备,清将如下信息和你的设备型号反馈给开发者:"+this.frontend+" "+this.backend),u.showMessage("Document Tree Subfolder Plugin: Developer did not prepare for your device, please feedback the following information to the developer: "+this.frontend+" "+this.backend),s=!0),this.trackedElements.add(t)}attachListenersToAllElements(){document.querySelectorAll(".b3-list--background").forEach(s=>this.attachListenerToElement(s))}initListener(){this.handleEvent=async s=>{if(s.sf_openDoc)return;if(!s.target||!(s.target instanceof Element)){console.warn("event target is invalid, probably caused by theme or something");return}const n=s.target.closest('li[data-type="navigation-file"]');if(!n||s.target.closest(".b3-list-item__action"))return;const i=n.getAttribute("data-node-id");try{const l=s.target.closest(".b3-list-item__toggle"),d=s.target.closest(".b3-list-item__icon"),h=!!(l||d);if(!i||!this.mode)return;switch(this.mode){case"normal":if(!h){const f=this.settingUtils.get("enable_using_emoji_as_subfolder_identify"),k=this.settingUtils.get("enable_using_id_as_subfolder_identify"),v=this.settingUtils.get("enable_auto_mode"),y=f&&this.ifProvidedLiAreUsingUserDefinedIdentifyIcon(n),c=k&&this.ifProvidedIdInTreatAsSubfolderSet(i);if(y||c)return s.preventDefault(),s.stopPropagation(),this.expandSubfolder(n),!1;{s.preventDefault(),s.stopPropagation();const b=await this.isProvidedIdIsEmptyDocument(i),m=await this.isProvidedIdHasSubDocument(n);if(console.log(b,m,"isEmpty, hasSubDocument"),b&&m&&v)return this.expandSubfolder(n),!1;{const r=new MouseEvent("click",{bubbles:!0,cancelable:!0});return Object.defineProperty(r,"sf_openDoc",{value:!0}),n.dispatchEvent(r),!1}}}break;case"capture":h||this.captureToSetUnsetTreatAsSubfolderSetting(i);break;case"reveal":break}this.onClickDoctreeNode(i)}catch(l){console.error("error when handle document tree node click:",l)}};const t=()=>{const s=document.querySelectorAll(".b3-list--background");return s.length>0?(console.log(`Found ${s.length} .b3-list--background elements, attaching listeners`),this.attachListenersToAllElements(),!0):!1};t()||(console.log("No .b3-list--background elements found, will retry and watch for DOM changes"),setTimeout(t,200)),this.mutationObserver=new MutationObserver(s=>{s.some(i=>i.addedNodes.length>0)&&s.forEach(i=>{i.addedNodes.forEach(l=>{if(l.nodeType!==Node.ELEMENT_NODE)return;const d=l;if(d.classList.contains("b3-list--background")){console.log("Detected new .b3-list--background element, attaching listener"),this.attachListenerToElement(d);return}const h=d.querySelectorAll(".b3-list--background");h.length>0&&(console.log(`Detected ${h.length} new .b3-list--background elements in subtree, attaching listeners`),h.forEach(f=>this.attachListenerToElement(f)))})})}),this.mutationObserver.observe(document.body,{childList:!0,subtree:!0}),console.log("MutationObserver started, will auto-detect new document tree elements")}expandSubfolder(t){if(!t){console.warn("not found li item, probably caused by theme or something");return}const s=t.querySelector(".b3-list-item__toggle");if(!s){console.warn("arrow button missing. probably caused by theme or something");return}const n=new MouseEvent("click",{view:window,bubbles:!0,cancelable:!0});s.dispatchEvent(n)}async onload(){this.treatAsSubfolderIdSet=new Set,this.treatAsSubfolderEmojiSet=new Set,this.data[x]={readonlyText:"Readonly"},this.settingUtils=new B({plugin:this,name:x}),this.settingUtils.addItem({key:"begging",value:"",type:"hint",title:this.i18n.beggingTitle,description:this.i18n.beggingDesc}),this.settingUtils.addItem({key:"enable_auto_mode",value:!0,type:"checkbox",title:this.i18n.enableAutoMode,description:this.i18n.enableAutoModeDesc}),this.settingUtils.addItem({key:"enable_using_emoji_as_subfolder_identify",value:!0,type:"checkbox",title:this.i18n.enableUsingEmojiAsSubfolderIdentify,description:this.i18n.enableUsingEmojiAsSubfolderIdentifyDesc}),this.settingUtils.addItem({key:"emojies_that_should_be_treated_as_subfolder",value:"🗃️,📂,📁",type:"textarea",title:this.i18n.emojisThatShouldBeTreatedAsSubfolder,description:this.i18n.emojisThatShouldBeTreatedAsSubfolderDesc}),this.settingUtils.addItem({key:"enable_using_id_as_subfolder_identify",value:!0,type:"checkbox",title:this.i18n.enableUsingIdAsSubfolderIdentify,description:this.i18n.enableUsingIdAsSubfolderIdentifyDesc}),this.settingUtils.addItem({key:"ids_that_should_be_treated_as_subfolder",value:"",type:"textarea",title:this.i18n.idsThatShouldBeTreatedAsSubfolder,description:this.i18n.idsThatShouldBeTreatedAsSubfolderDesc}),this.settingUtils.addItem({key:"enable_mode_switch_buttons",value:!0,type:"checkbox",title:this.i18n.enableModeSwitchButtons,description:this.i18n.enableModeSwitchButtonsDesc}),this.settingUtils.addItem({key:"Hint",value:"",type:"hint",title:this.i18n.hintTitle,description:this.i18n.hintDesc});try{this.settingUtils.load()}catch(t){console.error("Error loading settings storage, probably empty config json:",t)}this.addIcons(`
<symbol id="iconDoctreeFakeSubfolderNormalMode" viewBox="0 0 48 48">
<path d="M26,30H42a2,2,0,0,0,2-2V20a2,2,0,0,0-2-2H26a2,2,0,0,0-2,2v2H16V14h6a2,2,0,0,0,2-2V4a2,2,0,0,0-2-2H6A2,2,0,0,0,4,4v8a2,2,0,0,0,2,2h6V40a2,2,0,0,0,2,2H24v2a2,2,0,0,0,2,2H42a2,2,0,0,0,2-2V36a2,2,0,0,0-2-2H26a2,2,0,0,0-2,2v2H16V26h8v2A2,2,0,0,0,26,30Z"></path>
</symbol>
`),this.addIcons(`
<symbol id="iconDoctreeFakeSubfolderCaptureMode" viewBox="0 0 48 48">
<path d="M42,4H6A2,2,0,0,0,4,6V42a2,2,0,0,0,2,2H42a2,2,0,0,0,2-2V6A2,2,0,0,0,42,4ZM34,26H26v8a2,2,0,0,1-4,0V26H14a2,2,0,0,1,0-4h8V14a2,2,0,0,1,4,0v8h8a2,2,0,0,1,0,4Z"></path>
</symbol>
`),this.addIcons(`
<symbol id="iconDoctreeFakeSubfolderRevealMode" viewBox="0 0 24 24">
<path d="M3 14C3 9.02944 7.02944 5 12 5C16.9706 5 21 9.02944 21 14M17 14C17 16.7614 14.7614 19 12 19C9.23858 19 7 16.7614 7 14C7 11.2386 9.23858 9 12 9C14.7614 9 17 11.2386 17 14Z"></path>
</symbol>
`),this.frontend=u.getFrontend(),this.backend=u.getBackend(),this.isPhone=this.frontend==="mobile"||this.frontend==="browser-mobile",this.isTablet=(this.frontend==="desktop"||this.frontend==="browser-desktop")&&this.backend==="ios"||(this.frontend==="desktop"||this.frontend==="browser-desktop")&&this.backend==="android"||(this.frontend==="desktop"||this.frontend==="browser-desktop")&&this.backend==="harmony"||(this.frontend==="desktop"||this.frontend==="browser-desktop")&&this.backend==="docker",this.isDesktop=(this.frontend==="desktop"||this.frontend==="browser-desktop"||this.frontend==="desktop-window")&&this.backend!="ios"&&this.backend!="android"&&this.backend!="harmony"&&this.backend!="docker"}updateTopBarButtonStyles(t,s){const n=(i,l)=>{i.style.backgroundColor=l?"var(--b3-toolbar-color)":"var(--b3-toolbar-background)",i.style.color=l?"var(--b3-toolbar-background)":"var(--b3-toolbar-color)"};n(s.normal,t==="normal"),n(s.capture,t==="capture"),n(s.reveal,t==="reveal")}switchMode(t,s){this.to_normal_mode_count<2&&this.to_normal_mode_count++,this.mode=t,this.updateTopBarButtonStyles(t,s);const n={normal:{text:this.i18n.enterNormalMode,duration:2e3},capture:{text:this.i18n.enterCaptureMode,duration:8e3},reveal:{text:this.i18n.enterRevealMode,duration:8e3}},{text:i,duration:l}=n[t];this.to_normal_mode_count>=2&&u.showMessage(i,l)}onLayoutReady(){console.log(this.frontend,this.backend),console.log(this.isPhone,this.isTablet,this.isDesktop),this.initListener(),this.settingUtils.load();const t=this.settingUtils.get("emojies_that_should_be_treated_as_subfolder");this.treatAsSubfolderEmojiSet=I(t);const s=this.settingUtils.get("ids_that_should_be_treated_as_subfolder");if(this.treatAsSubfolderIdSet=I(s),this.settingUtils.get("enable_mode_switch_buttons")){const n={normal:this.addTopBar({icon:"iconDoctreeFakeSubfolderNormalMode",title:this.i18n.normalMode,position:"left",callback:()=>this.switchMode("normal",n)}),capture:this.addTopBar({icon:"iconDoctreeFakeSubfolderCaptureMode",title:this.i18n.captureMode,position:"left",callback:()=>this.switchMode("capture",n)}),reveal:this.addTopBar({icon:"iconDoctreeFakeSubfolderRevealMode",title:this.i18n.revealMode,position:"left",callback:()=>this.switchMode("reveal",n)})};this.settingUtils.get("enable_auto_mode")&&!this.settingUtils.get("enable_using_id_as_subfolder_identify")&&(n.capture.style.display="none"),this.switchMode("normal",n)}}async onunload(){this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null,console.log("MutationObserver disconnected"))}uninstall(){}}module.exports=L;