import * as path from "path"; import {fetchPost, fetchSyncPost} from "./fetch"; import {Dialog} from "../dialog"; import {escapeHtml} from "./escape"; import {isMobile} from "./functions"; import {focusByRange} from "../protyle/util/selection"; import {hasClosestByClassName} from "../protyle/util/hasClosest"; import {unicode2Emoji} from "../emoji"; import {Constants} from "../constants"; export const addBaseURL = () => { let baseURLElement = document.getElementById("baseURL"); if (!baseURLElement) { baseURLElement = document.createElement("base"); baseURLElement.id = "baseURL"; } baseURLElement.setAttribute("href", location.origin); document.getElementsByTagName("head")[0].appendChild(baseURLElement); }; export const getDisplayName = (filePath: string, basename = true, removeSY = false) => { let name = filePath; if (basename) { name = pathPosix().basename(filePath); } if (removeSY && name.endsWith(".sy")) { name = name.substr(0, name.length - 3); } return name; }; export const getAssetName = (assetPath: string) => { return assetPath.substring(7, assetPath.length - pathPosix().extname(assetPath).length - 23); }; export const isLocalPath = (link: string) => { if (!link) { return false; } link = link.trim(); if (1 > link.length) { return false; } link = link.toLowerCase(); if (link.startsWith("assets/") || link.startsWith("file://") || link.startsWith("\\\\") /* Windows 网络共享路径 */) { return true; } const colonIdx = link.indexOf(":"); return 1 === colonIdx; // 冒号前面只有一个字符认为是 Windows 盘符而不是网络协议 }; export const pathPosix = () => { if (path.posix) { return path.posix; } return path; }; export const getTopPaths = (liElements:Element[]) => { const fromPaths:string[] = []; liElements.forEach((item: HTMLElement) => { if (item.getAttribute("data-type") !== "navigation-root") { const dataPath = item.getAttribute("data-path"); const isChild = fromPaths.find(item => { if (dataPath.startsWith(item.replace(".sy", ""))) { return true; } }); if (!isChild) { fromPaths.push(dataPath); } } }); return fromPaths; }; const moveToPath = (fromPaths: string[], toNotebook: string, toPath: string, dialog: Dialog) => { fetchPost("/api/filetree/moveDocs", { toNotebook, fromPaths, toPath, }); dialog.destroy(); }; export const movePathTo = async (paths: string[], focus = true) => { const exitDialog = window.siyuan.dialogs.find((item) => { if (item.element.querySelector("#foldList")) { item.destroy(); return true; } }); if (exitDialog) { return; } const response = await fetchSyncPost("/api/filetree/getHPathsByPaths", { paths }); let range: Range; if (getSelection().rangeCount > 0) { range = getSelection().getRangeAt(0); } const dialog = new Dialog({ title: `${window.siyuan.languages.move} ${escapeHtml(response.data.join(", "))}`, content: `
`, width: isMobile() ? "80vw" : "50vw", destroyCallback() { if (range && focus) { focusByRange(range); } } }); const searchPanelElement = dialog.element.querySelector("#foldList"); const inputElement = dialog.element.querySelector(".b3-text-field") as HTMLInputElement; inputElement.focus(); const inputEvent = (event?: InputEvent) => { if (event && event.isComposing) { return; } fetchPost("/api/filetree/searchDocs", { k: inputElement.value }, (data) => { let fileHTML = ""; data.data.forEach((item: { boxIcon: string, box: string, hPath: string, path: string }) => { if (paths.includes(item.path)) { return; } fileHTML += `
  • ${unicode2Emoji(item.boxIcon || Constants.SIYUAN_IMAGE_NOTE)} ${escapeHtml(item.hPath)}
  • `; }); searchPanelElement.innerHTML = fileHTML; }); }; inputEvent(); inputElement.addEventListener("compositionend", (event: InputEvent) => { inputEvent(event); }); inputElement.addEventListener("input", (event: InputEvent) => { inputEvent(event); }); const lineHeight = 28; inputElement.addEventListener("keydown", (event: KeyboardEvent) => { let currentList: HTMLElement = dialog.element.querySelector(".b3-list-item--focus"); if (!currentList) { return; } if (event.key === "ArrowDown") { currentList.classList.remove("b3-list-item--focus"); if (!currentList.nextElementSibling) { searchPanelElement.children[0].classList.add("b3-list-item--focus"); } else { currentList.nextElementSibling.classList.add("b3-list-item--focus"); } currentList = searchPanelElement.querySelector(".b3-list-item--focus"); if (searchPanelElement.scrollTop < currentList.offsetTop - searchPanelElement.clientHeight + lineHeight || searchPanelElement.scrollTop > currentList.offsetTop) { searchPanelElement.scrollTop = currentList.offsetTop - searchPanelElement.clientHeight + lineHeight; } event.preventDefault(); } else if (event.key === "ArrowUp") { currentList.classList.remove("b3-list-item--focus"); if (!currentList.previousElementSibling) { const length = searchPanelElement.children.length; searchPanelElement.children[length - 1].classList.add("b3-list-item--focus"); } else { currentList.previousElementSibling.classList.add("b3-list-item--focus"); } currentList = searchPanelElement.querySelector(".b3-list-item--focus"); if (searchPanelElement.scrollTop < currentList.offsetTop - searchPanelElement.clientHeight + lineHeight || searchPanelElement.scrollTop > currentList.offsetTop - lineHeight * 2) { searchPanelElement.scrollTop = currentList.offsetTop - lineHeight * 2; } event.preventDefault(); } else if (event.key === "Enter") { moveToPath(paths, currentList.getAttribute("data-box"), currentList.getAttribute("data-path"), dialog); event.preventDefault(); } }); dialog.element.addEventListener("click", (event) => { const target = event.target as HTMLElement; const liElement = hasClosestByClassName(target, "b3-list-item"); if (liElement) { moveToPath(paths, liElement.getAttribute("data-box"), liElement.getAttribute("data-path"), dialog); } }); }; export const getNotebookName = (id: string) => { let rootPath = ""; window.siyuan.notebooks.find((item) => { if (item.id === id) { rootPath = item.name; return true; } }); return rootPath; }; export const setNotebookName = (id: string, name: string) => { window.siyuan.notebooks.find((item) => { if (item.id === id) { item.name = name; return true; } }); }; export const getOpenNotebookCount = () => { let count = 0; window.siyuan.notebooks.forEach(item => { if (!item.closed) { count++; } }); return count; }; export const setNoteBook = (cb?: (notebook: INotebook[]) => void) => { fetchPost("/api/notebook/lsNotebooks", {}, (response) => { window.siyuan.notebooks = response.data.notebooks; if (cb) { cb(response.data.notebooks); } }); };