Files
2025-11-25 21:38:17 -05:00

3 lines
33 KiB
JavaScript

"use strict";var obsidian=require("obsidian");class MermaidPopupSettingTab extends obsidian.PluginSettingTab{plugin;constructor(app,plugin){super(app,plugin);this.plugin=plugin}display(){const{containerEl:containerEl}=this;containerEl.empty();const tableContainer=containerEl.createDiv({cls:"setting-table"});const table=tableContainer.createEl("table");const tbody=table.createEl("table");const row_01_popup_sz_and_dg_h_title=tbody.createEl("tr");const row_02_popup_sz_and_dg_h_val=tbody.createEl("tr");const td_01_1_popup_sz_title=row_01_popup_sz_and_dg_h_title.createEl("td");let popup_sz_title=td_01_1_popup_sz_title.createEl("h2",{text:"Popup Size Init"});popup_sz_title.classList.add("config-text");const td_02_1_popup_sz=row_02_popup_sz_and_dg_h_val.createEl("td");new obsidian.Setting(td_02_1_popup_sz).setName("Choose the Popup Size").addDropdown((dropdown=>{let ddPopupSizeInit=this.plugin.settings.kvMapPopupSizeInit;for(const key in ddPopupSizeInit){dropdown.addOption(key,ddPopupSizeInit[key])}dropdown.setValue(this.plugin.settings.PopupSizeInitValue).onChange((async value=>{this.plugin.settings.PopupSizeInitValue=value;await this.plugin.saveSettings()}))}));let td_01_2_dg_h=row_01_popup_sz_and_dg_h_title.createEl("td");let td_02_1_dg_h_title=td_01_2_dg_h.createEl("h2",{text:"Original Target Height"});td_02_1_dg_h_title.classList.add("config-text");const td_02_2_dg_h_val=row_02_popup_sz_and_dg_h_val.createEl("td");td_02_2_dg_h_val.classList.add("ori_diagram_height");let dg_h_val=this.plugin.settings.DiagramHeightVal;let dg_h_min=this.plugin.settings.DiagramHeightMin;let dg_h_max=this.plugin.settings.DiagramHeightMax;let dg_h_step=this.plugin.settings.DiagramHeightStep;let dg_h_val_min=td_02_2_dg_h_val.createEl("p");dg_h_val_min.setText(dg_h_min);let dg_h_val_input=td_02_2_dg_h_val.createEl("input");dg_h_val_input.setAttribute("type","range");dg_h_val_input.setAttribute("min",dg_h_min);dg_h_val_input.setAttribute("max",dg_h_max);dg_h_val_input.setAttribute("step",dg_h_step);dg_h_val_input.setAttribute("value",dg_h_val);let dg_h_val_max=td_02_2_dg_h_val.createEl("p");dg_h_val_max.setText(dg_h_max);let dg_h_val_cur_title=td_02_2_dg_h_val.createEl("p",{text:"current:"});dg_h_val_cur_title.classList.add("ori_diagram_height_cur");let dg_h_val_cur=td_02_2_dg_h_val.createEl("p");dg_h_val_cur.classList.add("ori_diagram_height_val");dg_h_val_cur.setText(dg_h_val);dg_h_val_input.addEventListener("input",(event=>{const value=dg_h_val_input.value;dg_h_val_cur.setText(value+"");this.plugin.settings.DiagramHeightVal=value;this.plugin.saveSettings()}));this.setInfo(td_02_2_dg_h_val,"Click for tips on Original Target Height Setting.","Original Target Height Setting","Under proportional scaling, "+"adapt to the width of editor, "+"and then if the height is still greater than the value of 'Original Target Height',"+"it will adapt again. ");const row_1=tbody.createEl("tr");const row_2=tbody.createEl("tr");const td_1_1=row_1.createEl("td");let titleZoomRatio=td_1_1.createEl("h2",{text:"Zoom Ratio"});titleZoomRatio.classList.add("config-text");const td_2_1=row_2.createEl("td");new obsidian.Setting(td_2_1).setName("Choose the ratio for zooming in or out").addDropdown((dropdown=>{let ddZoomRatio=this.plugin.settings.kvMapZoomRatio;for(const key in ddZoomRatio){dropdown.addOption(key,ddZoomRatio[key])}dropdown.setValue(this.plugin.settings.ZoomRatioValue).onChange((async value=>{this.plugin.settings.ZoomRatioValue=value;await this.plugin.saveSettings()}))}));const td_1_2=row_1.createEl("td");let titleMoveStep=td_1_2.createEl("h2",{text:"Move Step"});titleMoveStep.classList.add("config-text");const td_2_2=row_2.createEl("td");new obsidian.Setting(td_2_2).setName("Choose the step for moving").addDropdown((dropdown=>{let ddZoomRatio=this.plugin.settings.kvMapMoveStep;for(const key in ddZoomRatio){dropdown.addOption(key,ddZoomRatio[key])}dropdown.setValue(this.plugin.settings.MoveStepValue).onChange((async value=>{this.plugin.settings.MoveStepValue=value;await this.plugin.saveSettings()}))}));const row=tbody.createEl("tr");const td_title_a=row.createEl("td");let titlePpBgA=td_title_a.createEl("h2",{text:"Popup Background Alpha Value"});titlePpBgA.classList.add("config-text");new obsidian.Setting(td_title_a).setName("Choose the alpha value").addDropdown((dropdown=>{let bgAlphaStep=this.plugin.settings.bgAlphaStep;for(const key in bgAlphaStep){dropdown.addOption(key,bgAlphaStep[key])}dropdown.setValue(this.plugin.settings.bgAlpha).onChange((async value=>{this.plugin.settings.bgAlpha=value;await this.plugin.saveSettings()}))}));this.addClass(td_title_a,"setting-item","setting-item-on-top-line");const td_title_blur=row.createEl("td");let titleBlur=td_title_blur.createEl("h2",{text:"Popup Background Blur"});titleBlur.classList.add("config-text");new obsidian.Setting(td_title_blur).setName("Enable blur").addToggle((toggle=>toggle.setValue(this.plugin.settings.bgIsBlur=="1"?true:false).onChange((async value=>{this.plugin.settings.bgIsBlur=value?"1":"0";await this.plugin.saveSettings()}))));this.addClass(td_title_blur,"setting-item","setting-item-on-top-line");let title_btn_pos=containerEl.createEl("h2",{text:"Open Popup Button Relative Position Init"});title_btn_pos.classList.add("config-text");const kvRow_open_btn=containerEl.createDiv({cls:"kv-row open_btn_pos"});this.slideInput(kvRow_open_btn,"x:",this.plugin.settings.open_btn_pos_x,(val=>{this.plugin.settings.open_btn_pos_x=val}),"1","500","px");this.setInfo(kvRow_open_btn,"Click for tips on Open Popup Button Relative Position Init Setting.","Open Popup Button Relative Position Init Setting","x represents the pixels to the right edge of the target container.");const kvRow_open_btn_y=containerEl.createDiv({cls:"kv-row open_btn_pos"});this.slideInput(kvRow_open_btn_y,"y:",this.plugin.settings.open_btn_pos_y,(val=>{this.plugin.settings.open_btn_pos_y=val}),"1","500","px");this.setInfo(kvRow_open_btn_y,"Click for tips on Open Popup Button Relative Position Init Setting.","Open Popup Button Relative Position Init Setting","y represents the pixels to the top edge of the target container.");let title=containerEl.createEl("h2",{text:"Add New Target"});title.classList.add("config-text");containerEl.createEl("p",{text:"This plugin supports customing target from mermaid, plantuml, graphviz, image and so on. "});const kvRow=containerEl.createDiv({cls:"kv-row"});const keyInput=kvRow.createEl("input",{type:"text",placeholder:"Input Key please"});const valueInput=kvRow.createEl("input",{type:"text",placeholder:"Input Class Name please"});const classname_fmt="classanme format: start with 'A-Za-z' or '-' and then 'A-Za-z0-9' or '-'";valueInput.setAttr("title",classname_fmt);const isContainer=kvRow.createEl("input",{type:"checkbox"});isContainer.setAttr("title","Please check it if the classname is the container of the object you want to control");isContainer.addClass("kv-chk");const saveButton=kvRow.createEl("button",{text:"save"});saveButton.onclick=async()=>{const key=keyInput.value.trim();const value=valueInput.value.trim();const chk=isContainer.checked;if(key&&value){if(this.plugin.settings.kvMapReserved[key]||this.plugin.settings.kvMap[key]||this.plugin.settings.kvMapDefault[key]){new obsidian.Notice("Target exists");return}if(!this.isValidClassname(value)){new obsidian.Notice(classname_fmt);return}this.plugin.settings.kvMap[key]=value+"|"+chk;await this.plugin.saveSettings();this.display();new obsidian.Notice(`Saved Target And Class Name: ${key} -> ${value}`);keyInput.value="";valueInput.value="";isContainer.value=""}else{new obsidian.Notice("Input Target and Class Name please")}};const resetButton=kvRow.createEl("button",{text:"reset"});resetButton.onclick=async()=>{const confirmed=resetButton.win.confirm("Confirm to reset? It could not be restored!");if(confirmed){this.plugin.settings.kvMap={};this.plugin.saveData(this.plugin.settings);new obsidian.Notice("reset success");this.display()}else{new obsidian.Notice("reset canceled")}};this.displayKvMap(containerEl);let titleConnect=containerEl.createEl("h2",{text:"How to work in other plugins"});titleConnect.classList.add("config-text-connect");containerEl.createEl("p",{text:"'.diagram-popup' is a reserved class for other plugins to work with."});containerEl.createEl("p",{text:"if you add it to the class list of your target container, it will get the functionality."})}isValidClassname(classname){return/^[A-Za-z-][A-Za-z0-9-]*$/.test(classname)}addClass(_container,_targetElementClass,_class){let dropdownElement=_container.querySelector("."+_targetElementClass);if(dropdownElement){dropdownElement.classList.add(_class)}}setInfo(containerEl,tip,title,msg){const addSettings=new obsidian.Setting(containerEl);addSettings.addExtraButton((extra=>{extra.setIcon("info");extra.setTooltip(tip);extra.onClick((()=>{let msgModal=new obsidian.Modal(this.app);msgModal.setTitle(title);msgModal.setContent(msg);msgModal.open()}));extra.extraSettingsEl.closest(".setting-item")?.classList.add("settings-icon")}))}slideInput(containerEl,title,value,saveVal,step="10",max="100",unit="%"){let input_title=containerEl.createEl("p");input_title.classList.add("open_btn_pos_slide_title");input_title.setText(title);let input_val_min=containerEl.createEl("p");input_val_min.setText("0");let input=containerEl.createEl("input");input.classList.add("open_btn_pos_slide_width");input.setAttribute("type","range");input.setAttribute("min","0");input.setAttribute("max",max);input.setAttribute("step",step);input.setAttribute("value",value);let input_val_max=containerEl.createEl("p");input_val_max.setText(max+unit);let input_val_cur_title=containerEl.createEl("p",{text:"current:"});input_val_cur_title.classList.add("open_btn_pos_cur_title");let input_val_cur=containerEl.createEl("p");input_val_cur.classList.add("open_btn_pos_cur_val");input_val_cur.setText(value);let input_val_cur_per=containerEl.createEl("p");input_val_cur_per.setText(unit);input_val_cur_per.classList.add("open_btn_pos_cur_per");input.addEventListener("input",(event=>{const value=input.value;input_val_cur.setText(value+"");saveVal(value);this.plugin.saveSettings()}))}displayKvMap(containerEl){const existingDisplay=containerEl.querySelector(".kv-display");if(existingDisplay)existingDisplay.remove();const kvDisplay=containerEl.createDiv({cls:"kv-display"});let mergedMap={...this.plugin.settings.kvMapReserved,...this.plugin.settings.kvMapDefault,...this.plugin.settings.kvMap};let kvEntries=Object.entries(mergedMap);if(kvEntries.length>0){const table=kvDisplay.createEl("table");const thead=table.createEl("thead");const headerRow=thead.createEl("tr");headerRow.createEl("th",{text:"Target"});headerRow.createEl("th",{text:"Class Name"});headerRow.createEl("th",{text:"Is Container"});headerRow.createEl("th",{text:"Actions"});const tbody=table.createEl("tbody");kvEntries.forEach((([key,value])=>{const row=tbody.createEl("tr");row.createEl("td",{text:key});let arrVal=value.split("|");let val=arrVal[0].replace(".","");let chk=arrVal[1]=="true"?"Y":"";row.createEl("td",{text:val});row.createEl("td",{text:chk});const actionsTd=row.createEl("td");if(Object.values(this.plugin.settings.kvMapDefault).includes(value))return;if(Object.values(this.plugin.settings.kvMapReserved).includes(value))return;const deleteButton=actionsTd.createEl("button",{text:"del"});deleteButton.addEventListener("click",(()=>{delete this.plugin.settings.kvMap[key];this.display();this.plugin.saveData(this.plugin.settings)}))}))}else{kvDisplay.setText("No Target Setting Saved")}}}const DEFAULT_SETTINGS={kvMap:{},kvMapDefault:{Mermaid:".mermaid"},kvMapReserved:{Reserved:".diagram-popup"},PopupSizeInitValue:"1.50",kvMapPopupSizeInit:{"1.00":"1.00",1.25:"1.25","1.50":"1.50",1.75:"1.75","2.00":"2.00",2.25:"2.25","2.50":"2.50",2.75:"2.75","3.00":"3.00"},DiagramHeightVal:"600",DiagramHeightMin:"50",DiagramHeightMax:"1500",DiagramHeightStep:"50",ZoomRatioValue:"0.2",kvMapZoomRatio:{.1:"0.1",.2:"0.2",.3:"0.3",.4:"0.4"},MoveStepValue:"30",kvMapMoveStep:{20:"20",30:"30",40:"40",50:"60",60:"60"},open_btn_pos_x:"35",open_btn_pos_y:"90",bgColorLight:"rgba(255,255,255, 0.5)",bgColorDark:"rgba(51,51,51, 0.5)",bgAlpha:"0.5",bgAlphaStep:{"0.0":"0.0",.1:"0.1",.2:"0.2",.3:"0.3",.4:"0.4",.5:"0.5",.6:"0.6",.7:"0.7",.8:"0.8",.9:"0.9","1.0":"1.0"},bgIsBlur:"1"};class MermaidPopupPlugin extends obsidian.Plugin{settings;observer_editting;observer_reading;class_editBlockBtn="edit-block-button";class_openPopupBtn="mermaid-popup-button";class_openPopupBtnReading="mermaid-popup-button-reading";class_openPopupBtn_container="mermaid-popup-button-container";class_openPopupBtnReading_container="mermaid-popup-button-reading-container";class_md_containerRead="markdown-reading-view";class_md_containerEdit="markdown-source-view";async onload(){console.log(`Loading ${this.manifest.name} ${this.manifest.version}`);await this.loadSettings();this.addSettingTab(new MermaidPopupSettingTab(this.app,this));this.registerEvent(this.app.workspace.on("layout-change",(()=>{let view=this.app.workspace.getActiveViewOfType(obsidian.MarkdownView);if(!view){this.RelaseWhenfileClose()}if(view){let container=view.containerEl;let targetArr=this.GetSettingsClassElementAll(container);if(targetArr==null||targetArr.length==0){this.RelaseWhenfileClose()}for(var i=0;i<targetArr.length;i++){this.addPopupButton(targetArr[i])}this.ObserveToAddPopupButton(container)}})))}RelaseWhenfileClose(){this.observer_editting?.disconnect();this.observer_editting=null;this.observer_reading?.disconnect();this.observer_reading=null}onunload(){console.log(`Unloading ${this.manifest.name} ${this.manifest.version}`)}async loadSettings(){this.settings=Object.assign({},DEFAULT_SETTINGS,await this.loadData())}async saveSettings(){await this.saveData(this.settings)}isPreviewMode(){let view=this.app.workspace.getActiveViewOfType(obsidian.MarkdownView);return view&&view.getMode()=="preview"}getOpenBtnInMd_Mark_ByParam(isPreviewMode){let popupButtonClass=this.class_openPopupBtn;let popupButtonClass_container=this.class_openPopupBtn_container;if(isPreviewMode){popupButtonClass=this.class_openPopupBtnReading;popupButtonClass_container=this.class_openPopupBtnReading_container}return{popupButtonClass:popupButtonClass,popupButtonClass_container:popupButtonClass_container}}getOpenBtnInMd_Mark(){let popupButtonClass=this.class_openPopupBtn;let popupButtonClass_container=this.class_openPopupBtn_container;if(this.isPreviewMode()){popupButtonClass=this.class_openPopupBtnReading;popupButtonClass_container=this.class_openPopupBtnReading_container}return{popupButtonClass:popupButtonClass,popupButtonClass_container:popupButtonClass_container}}getOpenBtnInMd_Mark_editMode(){let popupButtonClass_edit=this.class_openPopupBtn;let popupButtonClass_container_edit=this.class_openPopupBtn_container;return{popupButtonClass_edit:popupButtonClass_edit,popupButtonClass_container_edit:popupButtonClass_container_edit}}getOpenBtnInMd_Mark_readMode(){let popupButtonClass_read=this.class_openPopupBtnReading;let popupButtonClass_container_read=this.class_openPopupBtnReading_container;return{popupButtonClass_read:popupButtonClass_read,popupButtonClass_container_read:popupButtonClass_container_read}}ObserveToAddPopupButton(myView){if(this.observer_editting)return;this.observer_editting=new MutationObserver(((mutationsList,observer)=>{let containerArr=this.GetSettingsClassElementAll(myView);for(var i=0;i<containerArr.length;i++){let container=containerArr[i];let isTarget=this.IsClassListContains_SettingsDiagramClass(container[0]);if(isTarget){this.addPopupButton(container,true)}}}));this.observer_editting.observe(myView,{childList:true,subtree:true})}ObserveToAddPopupButton_Reading(myView){if(this.observer_reading)return;this.observer_reading=new MutationObserver(((mutationsList,observer)=>{let containerArr=this.GetSettingsClassElementAll(myView);for(var i=0;i<containerArr.length;i++){let container=containerArr[i];if(this.IsClassListContains_SettingsDiagramClass(container[0])){this.addPopupButton(container)}}}));this.observer_reading.observe(myView,{childList:true,subtree:true})}GetSettingsClassElementAll(contentEl){let selectors=this.GetSelectorAll(true);selectors=selectors;if(selectors==null||selectors.length==0){return null}let targetArr=[];for(var i=0;i<selectors.length;i++){let item=selectors[i];let target=contentEl.querySelectorAll(item[0]);if(target!=null&&target.length>0){for(var j=0;j<target.length;j++){targetArr.push([target[j],item[1]])}}}return targetArr}GetSelectorAll(isWithCheck=false){let classnameArr=this.GetSettingsDiagramClassNameAll();let arrSelector=[];for(var i=0;i<classnameArr.length;i++){var name="";var chk="";if(classnameArr[i].contains("|")){var arr=classnameArr[i].split("|");name=arr[0];chk=arr[1]}else{name=classnameArr[i]}name="."+name.replace(".","");if(isWithCheck){arrSelector.push([name,chk])}else{arrSelector.push(name)}}return arrSelector}escapeClassName(className){if(/^\d/.test(className)){const firstChar=className.charCodeAt(0).toString(16);return`\\3${firstChar} ${className.slice(1)}`}return className}GetSettingsDiagramClassNameAll(){let mapDiagramClassAll={...this.settings.kvMapReserved,...this.settings.kvMapDefault,...this.settings.kvMap};return Object.values(mapDiagramClassAll)}addPopupButton(target_and_flagContainer,isDebug=false){let target=target_and_flagContainer[0];if(this.isPreviewMode()&&this.isParentEditting(target))return;if(!this.isPreviewMode()&&this.isParentReading(target))return;let{popupButtonClass:popupButtonClass}=this.getOpenBtnInMd_Mark();let popupButton;let flagContainer=target_and_flagContainer[1]=="true";let targetContainer=flagContainer?target:target.parentElement;popupButton=targetContainer.querySelector("."+popupButtonClass);if(popupButton){this.adjustDiagramWidthAndHeight_ToContainer(targetContainer);return}this.create_open_button(target_and_flagContainer,isDebug)}create_open_button(target_and_flagContainer,isDebug=false){let{popupButtonClass:popupButtonClass}=this.getOpenBtnInMd_Mark();let target=target_and_flagContainer[0];let flagContainer=target_and_flagContainer[1]=="true";let targetContainer=flagContainer?target:target.parentElement;let popupButton=targetContainer.doc.createElement("div");popupButton.classList.add(popupButtonClass);popupButton.textContent="Open Popup";obsidian.setIcon(popupButton,"maximize");popupButton.title="Open Popup";targetContainer.insertAdjacentElement("afterbegin",popupButton);this.adjustDiagramWidthAndHeight_ToContainer(targetContainer);if(this.isPreviewMode())targetContainer.setCssStyles({position:"relative"});if(flagContainer){targetContainer.setCssStyles({display:"inline-block",position:"relative"})}this.setPopupBtnPos(popupButton);this.registerDomEvent(target,"click",this.handleMermaidClick);let isDragging=false;popupButton.addEventListener("click",(evt=>{if(!isDragging){evt.stopPropagation();this.openPopup(targetContainer)}isDragging=false}));popupButton.setCssStyles({display:"none"});this.makePopupButtonDisplay_WhenHoverOnContainer(popupButton,targetContainer)}isParentReading(ele){return this.isParent(ele,this.class_md_containerRead)}isParentEditting(ele){return this.isParent(ele,this.class_md_containerEdit)}isParent(ele,parentClass){return ele.closest(`.${parentClass}`)!==null}makePopupButtonDisplay_WhenHoverOnContainer(button,container){container.addEventListener("mouseenter",(()=>{button.setCssStyles({display:"block"})}));container.addEventListener("mouseleave",(()=>{button.setCssStyles({display:"none"})}))}getAppContainerRect(ele){return ele.doc.getElementsByClassName("app-container")[0].getBoundingClientRect()}setPopupBtnPos(btn){let x=this.settings.open_btn_pos_x;let y=this.settings.open_btn_pos_y;btn.setCssStyles({right:x+"px",top:y+"px"})}adjustDiagramWidthAndHeight_ToContainer(container,isInPopup=false){let coreDeepEle=this.getCoreDeepElement(container);if(!coreDeepEle){let coreEle=this.getCoreElement(container);if(!coreEle)return;let dg_h_val=parseInt(this.settings.DiagramHeightVal);if(dg_h_val<this.getHeight(coreEle))this.setHeight(coreEle,dg_h_val.toString());return}let coreDeep_w=this.getWidth(coreDeepEle);let coreDeep_h=this.getHeight(coreDeepEle);let container_w_o=this.getWidth(container);let rate_by_width=1;if(coreDeep_w>container_w_o){rate_by_width=container_w_o/coreDeep_w}let rate_by_height=1;let dg_h_val=parseInt(this.settings.DiagramHeightVal);if(coreDeep_h>dg_h_val){rate_by_height=dg_h_val/coreDeep_h}if(rate_by_width==1&&rate_by_height==1)return;let rate=rate_by_width<rate_by_height?rate_by_width:rate_by_height;let container_w=coreDeep_w*rate;let container_h=coreDeep_h*rate;let w=container_w;let h=container_h;if(!isInPopup){container_w=container_w<container_w_o?container_w_o:container_w}coreDeepEle.setCssStyles({height:h+"px",width:w+"px"});container.setCssStyles({height:container_h+"px",width:container_w+"px"})}getWidth(ele){return parseFloat(ele.getCssPropertyValue("width"))}getHeight(ele){return parseFloat(ele.getCssPropertyValue("height"))}setWidth(ele,w){ele.setCssStyles({width:w+"px"})}setHeight(ele,h){ele.setCssStyles({height:h+"px"})}getCoreElement(container){let{popupButtonClass:popupButtonClass}=this.getOpenBtnInMd_Mark();let diagramSvg=container.querySelector("."+popupButtonClass);if(diagramSvg)return diagramSvg.nextElementSibling;return null}getCoreDeepElement(container){let core=this.getCoreElement(container);if(core==null)return null;let coreEle=core;if(coreEle.children.length<1)return null;return coreEle.children[0]}getCoreElement_old_before_nextSibling(container){let diagramSvg=Array.from(container.children).find((child=>child.tagName.toLowerCase()==="svg"));if(diagramSvg){return diagramSvg}let diagramImg=Array.from(container.children).find((child=>child.tagName.toLowerCase()==="img"));if(diagramImg)return diagramImg;return null}GetPosButtonToMermaid(eleBtn,eleDiv){const divRect=eleDiv.getBoundingClientRect();const buttonRect=eleBtn.getBoundingClientRect();const buttonRelativeTop=buttonRect.top-divRect.top;const buttonRelativeLeft=buttonRect.left-divRect.left;return{top:buttonRelativeTop,left:buttonRelativeLeft}}IsClassListContains_SettingsDiagramClass(ele){if(ele==null||ele.classList==null||ele.classList.length==0)return false;let classnameArr=this.GetSelectorAll();for(var i=0;i<classnameArr.length;i++){let name=classnameArr[i];name=name.substring(1);if(ele.classList.contains(name))return true}return false}IsClassListContains(ele,name){if(ele==null||ele.classList==null||ele.classList.length==0)return false;if(ele.classList.contains(name))return true;return false}GetSettingsClassElementClosest(startElement){let _parent=startElement;while(_parent){if(this.IsClassListContains_SettingsDiagramClass(_parent)){return _parent}if(_parent.parentElement)_parent=_parent.parentElement;else break}return null}handleMermaidClick=evt=>{if(!evt.ctrlKey)return;evt.stopPropagation();let targetElement=evt.target;let closestElement=this.GetSettingsClassElementClosest(targetElement);if(closestElement)this.openPopup(closestElement)};openPopup(containerElement){let _doc=containerElement.doc;const overlay=_doc.createElement("div");overlay.classList.add("popup-overlay");this.setPopupBgAlpha(overlay);this.setPopupBgBlur(overlay);let containerElementClone=containerElement.cloneNode(true);let containerElementInPopup=containerElementClone;let{popupButtonClass:popupButtonClass}=this.getOpenBtnInMd_Mark();let childElementArr=containerElementInPopup.querySelectorAll("."+popupButtonClass);if(childElementArr){childElementArr.forEach((child=>{let childEle=child;this.hideElement(childEle)}))}containerElementInPopup.classList.add("popup-content","draggable","resizable");let _buttonContainer=this.createButtonContainer(containerElementInPopup,overlay);overlay.appendChild(containerElementInPopup);overlay.appendChild(_buttonContainer);_doc.body.appendChild(overlay);this.adjustInPopup(containerElementInPopup);overlay.addEventListener("click",(evt=>{evt.doc.body.removeChild(overlay)}));containerElementInPopup.addEventListener("click",(evt=>{evt.stopPropagation()}));containerElementInPopup.doc.addEventListener("keydown",(evt=>{if(evt.key==="Escape"){if(containerElementInPopup.doc.body.contains(overlay))containerElementInPopup.doc.body.removeChild(overlay)}}));this.setPopupSize(containerElementInPopup,containerElement);this.makeDraggable(containerElementInPopup);containerElementInPopup.classList.add("resizable");containerElementInPopup.addEventListener("wheel",(evt=>{evt.preventDefault();const isOut=evt.deltaY>0;this.zoomPopupAtCursor(containerElementInPopup,isOut,evt)}))}hideElement(ele){ele.setCssStyles({display:"none"})}adjustInPopup(containerInPopupEle){let mark=this.getOpenBtnInMd_Mark();let btn_in_p=containerInPopupEle.querySelector("."+mark.popupButtonClass);if(btn_in_p==null)return;let coreEle_in_p=btn_in_p.nextElementSibling;if(coreEle_in_p==null)return;let btnAfterCore=coreEle_in_p.nextElementSibling;if(btnAfterCore){this.hideElement(btnAfterCore)}}setPopupBgBlur(_popupElement){if(!_popupElement)return;let bgIsBlur=this.settings.bgIsBlur;let cssBgIsBlur=bgIsBlur=="1"?"blur(10px)":"";_popupElement.setCssStyles({backdropFilter:cssBgIsBlur})}setPopupBgAlpha(_popupElement){if(!_popupElement)return;let alpha=this.settings.bgAlpha;let newBgColor;if(this.isThemeLight()){newBgColor=`rgba(255, 255, 255, ${alpha})`}else if(this.isThemeDark()){newBgColor=`rgba(51, 51, 51, ${alpha})`}_popupElement.setCssStyles({backgroundColor:newBgColor})}isThemeLight(){return document.body.classList.contains("theme-light")}isThemeDark(){return document.body.classList.contains("theme-dark")}setPopupSize(containerInPopup,container){let multiVal=parseFloat(this.settings.PopupSizeInitValue);if(typeof multiVal!="number"){return}let width_tar_md=this.getWidth(container);let height_tar_md=this.getHeight(container);let core=this.getCoreElement(container);let core_w=this.getWidth(core);let core_h=this.getHeight(core);let core_in_p=this.getCoreElement(containerInPopup);containerInPopup.setCssStyles({width:width_tar_md+"px",height:height_tar_md+"px",transform:`scale(${multiVal})`});core_in_p.setCssStyles({width:core_w+"px",height:core_h+"px"});let coreDeep_in_p=this.getCoreDeepElement(containerInPopup);if(coreDeep_in_p==null)return;let coreDeep_in_p_w=this.getWidth(coreDeep_in_p);if(coreDeep_in_p_w<core_w){core_in_p.setCssStyles({textAlign:"center"})}}createButtonContainer(_targetElementInPopup,_overlay){let _doc=_targetElementInPopup.doc;const buttonContainer=_doc.createElement("div");buttonContainer.classList.add("button-container");const zoomInButton=_doc.createElement("button");zoomInButton.classList.add("control-button","zoom-in");zoomInButton.textContent="+";const zoomOutButton=_doc.createElement("button");zoomOutButton.classList.add("control-button","zoom-out");zoomOutButton.textContent="-";const upButton=_doc.createElement("button");upButton.classList.add("control-button","arrow-up");upButton.textContent="↑";const downButton=_doc.doc.createElement("button");downButton.classList.add("control-button","arrow-down");downButton.textContent="↓";const leftButton=_doc.doc.createElement("button");leftButton.classList.add("control-button","arrow-left");leftButton.textContent="←";const rightButton=_doc.doc.createElement("button");rightButton.classList.add("control-button","arrow-right");rightButton.textContent="→";const closeButton=_doc.doc.createElement("button");closeButton.classList.add("control-button","close-popup");closeButton.textContent="X";buttonContainer.appendChild(zoomInButton);buttonContainer.appendChild(zoomOutButton);buttonContainer.appendChild(upButton);buttonContainer.appendChild(downButton);buttonContainer.appendChild(leftButton);buttonContainer.appendChild(rightButton);buttonContainer.appendChild(closeButton);buttonContainer.addEventListener("click",(evt=>{evt.stopPropagation()}));zoomInButton.addEventListener("click",(evt=>{evt.stopPropagation();this.zoomPopup(_targetElementInPopup,false)}));zoomOutButton.addEventListener("click",(evt=>{evt.stopPropagation();this.zoomPopup(_targetElementInPopup,true)}));upButton.addEventListener("click",(evt=>{evt.stopPropagation();this.movePopup(_targetElementInPopup,0,-1)}));downButton.addEventListener("click",(evt=>{evt.stopPropagation();this.movePopup(_targetElementInPopup,0,1)}));leftButton.addEventListener("click",(evt=>{evt.stopPropagation();this.movePopup(_targetElementInPopup,-1,0)}));rightButton.addEventListener("click",(evt=>{evt.stopPropagation();this.movePopup(_targetElementInPopup,1,0)}));closeButton.addEventListener("click",(evt=>{evt.stopPropagation();evt.doc.body.removeChild(_overlay)}));return buttonContainer}movePopup(popup,dx,dy){const style=popup.win.getComputedStyle(popup);const matrix=style.transform==="none"?new DOMMatrix:new DOMMatrixReadOnly(style.transform);const newX=matrix.m41+(dx==0?dx:dx*parseInt(this.settings.MoveStepValue));const newY=matrix.m42+(dy==0?dy:dy*parseInt(this.settings.MoveStepValue));popup.setCssStyles({transform:`translate(${newX}px, ${newY}px) scale(${matrix.a})`})}zoomPopup(popup,isOut){this.zoomPopupCore(popup,isOut,1,1)}zoomPopupAtCursor(popup,isOut,evt){const popupRect=popup.getBoundingClientRect();const popupCenterX=popupRect.left+popupRect.width/2;const popupCenterY=popupRect.top+popupRect.height/2;const offsetX=evt.clientX-popupCenterX;const offsetY=evt.clientY-popupCenterY;this.zoomPopupCore(popup,isOut,offsetX,offsetY)}zoomPopupCore(popup,isOut,offsetX,offsetY){const style=popup.win.getComputedStyle(popup);const matrix=style.transform==="none"?new DOMMatrix:new DOMMatrixReadOnly(style.transform);const currentScale=matrix.a;let symbol=isOut?-1:1;const newScale=currentScale*(1+symbol*parseFloat(this.settings.ZoomRatioValue));const newX=matrix.m41-offsetX*symbol*parseFloat(this.settings.ZoomRatioValue);const newY=matrix.m42-offsetY*symbol*parseFloat(this.settings.ZoomRatioValue);popup.setCssStyles({transformOrigin:"center center",transform:`translate(${newX}px, ${newY}px) scale(${newScale})`})}makeDraggable(element){let isDragging=false;let startX=0;let startY=0;let initialX=0;let initialY=0;const mouseDownHandler=e=>{e.preventDefault();e.stopPropagation();isDragging=true;if(!e.target)return;const ele_target=e.target;const style=ele_target.win.getComputedStyle(element);const matrix=style.transform==="none"?new DOMMatrix:new DOMMatrixReadOnly(style.transform);startX=e.clientX-matrix.m41;startY=e.clientY-matrix.m42;e.doc.addEventListener("mousemove",mouseMoveHandler);e.doc.addEventListener("mouseup",mouseUpHandler);ele_target.closest(".popup-content")?.classList.add("dragging")};const mouseMoveHandler=e=>{if(!isDragging)return;if(!e.target)return;const ele_target=e.target;const style=ele_target.win.getComputedStyle(element);const matrix=style.transform==="none"?new DOMMatrix:new DOMMatrixReadOnly(style.transform);initialX=e.clientX-startX;initialY=e.clientY-startY;element.setCssStyles({transform:`translate(${initialX}px, ${initialY}px) scale(${matrix.a})`})};const mouseUpHandler=e=>{isDragging=false;e.doc.removeEventListener("mousemove",mouseMoveHandler);e.doc.removeEventListener("mouseup",mouseUpHandler);const ele_target=e.target;ele_target.closest(".popup-content")?.classList.remove("dragging")};element.addEventListener("mousedown",mouseDownHandler);let lastScale=1;let initialDistance=0;let t={scaleX:1,obliqueX:0,obliqueY:0,scaleY:1,translateX:0,translateY:0};element.addEventListener("touchstart",(e=>{e.stopPropagation();e.preventDefault();if(e.touches.length===1){const touch=e.touches[0];initialX=touch.clientX;initialY=touch.clientY}else if(e.touches.length===2){t=getTransform(element);lastScale=t.scaleX;initialX=e.touches[0].clientX;initialY=e.touches[0].clientY;initialDistance=getDistance(e.touches[0],e.touches[1])}}));element.addEventListener("touchmove",(e=>{e.stopPropagation();e.preventDefault();if(e.touches.length===1){t=getTransform(element);touch_move(e,t)}else if(e.touches.length===2){const distance=getDistance(e.touches[0],e.touches[1]);lastScale=distance/initialDistance*lastScale;initialDistance=distance;t=getTransform(element);t.scaleX=lastScale;t.scaleY=lastScale;touch_move(e,t)}}));const touch_move=(e,t)=>{const touch=e.touches[0];const deltaX=touch.clientX-initialX;const deltaY=touch.clientY-initialY;initialX=touch.clientX;initialY=touch.clientY;let tx=t.translateX+deltaX;let ty=t.translateY+deltaY;setTransform(element,tx,ty,t.scaleX)};const getTransform=touchArea=>{const transform=window.getComputedStyle(touchArea).getPropertyValue("transform");if(transform&&transform!=="none"){const match=transform.match(/matrix\((.+)\)/);if(match){const values=match[1].split(", ").map(parseFloat);if(values.length>=6){const scaleX=values[0];const obliqueX=values[1];const obliqueY=values[2];const scaleY=values[3];const translateX=values[4];const translateY=values[5];return{scaleX:scaleX,obliqueX:obliqueX,obliqueY:obliqueY,scaleY:scaleY,translateX:translateX,translateY:translateY}}}}return{scaleX:1,obliqueX:0,obliqueY:0,scaleY:1,translateX:0,translateY:0}};const setTransform=(touchArea,_translateX,_translateY,_scale)=>{let transform=`translate(${_translateX}px, ${_translateY}px) scale(${_scale})`;touchArea.setCssStyles({transform:transform})};const getDistance=(touch1,touch2)=>{const dx=touch1.clientX-touch2.clientX;const dy=touch1.clientY-touch2.clientY;return Math.sqrt(dx*dx+dy*dy)}}}module.exports=MermaidPopupPlugin;
/* nosourcemap */