Vanessa 2023-08-30 16:32:54 +08:00
parent 2349b080db
commit c0535ffb98
10 changed files with 1754 additions and 1712 deletions

View File

@ -0,0 +1,74 @@
import {getAllModels} from "../../layout/getAll";
import {hasClosestByAttribute, hasClosestByClassName, hasTopClosestByClassName} from "../../protyle/util/hasClosest";
import {hideAllElements} from "../../protyle/ui/hideElements";
import {isWindow} from "../../util/functions";
import {writeText} from "../../protyle/util/compatibility";
import {showMessage} from "../../dialog/message";
export const globalClick = (event: MouseEvent & { target: HTMLElement }) => {
if (!window.siyuan.menus.menu.element.contains(event.target) && !hasClosestByAttribute(event.target, "data-menu", "true")) {
if (getSelection().rangeCount > 0 && window.siyuan.menus.menu.element.contains(getSelection().getRangeAt(0).startContainer) &&
window.siyuan.menus.menu.element.contains(document.activeElement)) {
// https://ld246.com/article/1654567749834/comment/1654589171218#comments
} else {
window.siyuan.menus.menu.remove();
}
}
// protyle.toolbar 点击空白处时进行隐藏
if (!hasClosestByClassName(event.target, "protyle-toolbar")) {
hideAllElements(["toolbar"]);
}
if (!hasClosestByClassName(event.target, "pdf__outer")) {
hideAllElements(["pdfutil"]);
}
// dock float 时,点击空白处,隐藏 dock
const floatDockLayoutElement = hasClosestByClassName(event.target, "layout--float", true);
if (floatDockLayoutElement && window.siyuan.layout.leftDock) {
if (!floatDockLayoutElement.isSameNode(window.siyuan.layout.bottomDock.layout.element)) {
window.siyuan.layout.bottomDock.hideDock();
}
if (!floatDockLayoutElement.isSameNode(window.siyuan.layout.leftDock.layout.element)) {
window.siyuan.layout.leftDock.hideDock();
}
if (!floatDockLayoutElement.isSameNode(window.siyuan.layout.rightDock.layout.element)) {
window.siyuan.layout.rightDock.hideDock();
}
} else if (!hasClosestByClassName(event.target, "dock") && !isWindow() && window.siyuan.layout.leftDock) {
window.siyuan.layout.bottomDock.hideDock();
window.siyuan.layout.leftDock.hideDock();
window.siyuan.layout.rightDock.hideDock();
}
const copyElement = hasTopClosestByClassName(event.target, "protyle-action__copy");
if (copyElement) {
writeText(copyElement.parentElement.nextElementSibling.textContent.trimEnd());
showMessage(window.siyuan.languages.copied, 2000);
event.preventDefault();
}
// 点击空白pdf 搜索、更多消失
if (hasClosestByAttribute(event.target, "id", "secondaryToolbarToggle") ||
hasClosestByAttribute(event.target, "id", "viewFind") ||
hasClosestByAttribute(event.target, "id", "findbar")) {
return;
}
let currentPDFViewerObject: any;
getAllModels().asset.find(item => {
if (item.pdfObject &&
!item.pdfObject.appConfig.appContainer.classList.contains("fn__none")) {
currentPDFViewerObject = item.pdfObject;
return true;
}
});
if (!currentPDFViewerObject) {
return;
}
if (currentPDFViewerObject.secondaryToolbar.isOpen) {
currentPDFViewerObject.secondaryToolbar.close();
}
if (
!currentPDFViewerObject.supportsIntegratedFind &&
currentPDFViewerObject.findBar.opened
) {
currentPDFViewerObject.findBar.close();
}
}

View File

@ -0,0 +1,51 @@
import {App} from "../../index";
import {windowMouseMove} from "./mousemove";
import {Dialog} from "../../dialog";
import {windowKeyUp} from "./keyup";
import {windowKeyDown} from "./keydown";
import {globalClick} from "./click";
import {goBack, goForward} from "../../util/backForward";
export const initWindowEvent = (app: App) => {
document.body.addEventListener("mouseleave", () => {
if (window.siyuan.layout.leftDock) {
window.siyuan.layout.leftDock.hideDock();
window.siyuan.layout.rightDock.hideDock();
window.siyuan.layout.bottomDock.hideDock();
}
});
window.addEventListener("mousemove", (event: MouseEvent & { target: HTMLElement }) => {
windowMouseMove(event);
});
window.addEventListener("mouseup", (event) => {
if (event.button === 3) {
event.preventDefault();
goBack(app);
} else if (event.button === 4) {
event.preventDefault();
goForward(app);
}
});
let switchDialog: Dialog;
window.addEventListener("keyup", (event) => {
windowKeyUp(app, event, switchDialog);
});
window.addEventListener("keydown", (event) => {
windowKeyDown(app, event, switchDialog);
});
window.addEventListener("blur", () => {
window.siyuan.ctrlIsPressed = false;
window.siyuan.shiftIsPressed = false;
window.siyuan.altIsPressed = false;
});
window.addEventListener("click", (event: MouseEvent & { target: HTMLElement }) => {
globalClick(event);
});
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,118 @@
import {Dialog} from "../../dialog";
import {fetchPost} from "../../util/fetch";
import {escapeHtml} from "../../util/escape";
import {openCard} from "../../card/openCard";
import {getDockByType} from "../../layout/util";
import {getAllTabs} from "../../layout/getAll";
import {App} from "../../index";
export const windowKeyUp = (app: App,event:KeyboardEvent, switchDialog:Dialog) => {
window.siyuan.ctrlIsPressed = false;
window.siyuan.shiftIsPressed = false;
window.siyuan.altIsPressed = false;
if (switchDialog && switchDialog.element.parentElement) {
if (event.key === "Tab") {
let currentLiElement = switchDialog.element.querySelector(".b3-list-item--focus");
currentLiElement.classList.remove("b3-list-item--focus");
if (event.shiftKey) {
if (currentLiElement.previousElementSibling) {
currentLiElement.previousElementSibling.classList.add("b3-list-item--focus");
} else if (currentLiElement.getAttribute("data-original")) {
currentLiElement.parentElement.lastElementChild.classList.add("b3-list-item--focus");
currentLiElement.removeAttribute("data-original");
} else if (currentLiElement.parentElement.nextElementSibling) {
if (currentLiElement.parentElement.nextElementSibling.lastElementChild) {
currentLiElement.parentElement.nextElementSibling.lastElementChild.classList.add("b3-list-item--focus");
} else {
currentLiElement.parentElement.lastElementChild.classList.add("b3-list-item--focus");
}
} else if (currentLiElement.parentElement.previousElementSibling) {
currentLiElement.parentElement.previousElementSibling.lastElementChild.classList.add("b3-list-item--focus");
}
} else {
if (currentLiElement.nextElementSibling) {
currentLiElement.nextElementSibling.classList.add("b3-list-item--focus");
} else if (currentLiElement.getAttribute("data-original")) {
currentLiElement.parentElement.firstElementChild.classList.add("b3-list-item--focus");
currentLiElement.removeAttribute("data-original");
} else if (currentLiElement.parentElement.nextElementSibling) {
if (currentLiElement.parentElement.nextElementSibling.firstElementChild) {
currentLiElement.parentElement.nextElementSibling.firstElementChild.classList.add("b3-list-item--focus");
} else {
currentLiElement.parentElement.firstElementChild.classList.add("b3-list-item--focus");
}
} else if (currentLiElement.parentElement.previousElementSibling) {
currentLiElement.parentElement.previousElementSibling.firstElementChild.classList.add("b3-list-item--focus");
}
}
currentLiElement = switchDialog.element.querySelector(".b3-list-item--focus");
if (currentLiElement) {
const rootId = currentLiElement.getAttribute("data-node-id");
if (rootId) {
fetchPost("/api/filetree/getFullHPathByID", {
id: rootId
}, (response) => {
currentLiElement.parentElement.parentElement.nextElementSibling.innerHTML = escapeHtml(response.data);
});
} else {
currentLiElement.parentElement.parentElement.nextElementSibling.innerHTML = currentLiElement.querySelector(".b3-list-item__text").innerHTML;
}
const currentRect = currentLiElement.getBoundingClientRect();
const currentParentRect = currentLiElement.parentElement.getBoundingClientRect();
if (currentRect.top < currentParentRect.top) {
currentLiElement.scrollIntoView(true);
} else if (currentRect.bottom > currentParentRect.bottom) {
currentLiElement.scrollIntoView(false);
}
}
const originalElement = switchDialog.element.querySelector('[data-original="true"]');
if (originalElement) {
originalElement.removeAttribute("data-original");
}
} else if (event.key === "Control") {
let currentLiElement = switchDialog.element.querySelector(".b3-list-item--focus");
// 快速切换时,不触发 Tab
if (currentLiElement.getAttribute("data-original")) {
currentLiElement.classList.remove("b3-list-item--focus");
if (event.shiftKey) {
if (currentLiElement.previousElementSibling) {
currentLiElement.previousElementSibling.classList.add("b3-list-item--focus");
} else {
currentLiElement.parentElement.lastElementChild.classList.add("b3-list-item--focus");
currentLiElement.removeAttribute("data-original");
}
} else {
if (currentLiElement.nextElementSibling) {
currentLiElement.nextElementSibling.classList.add("b3-list-item--focus");
} else {
currentLiElement.parentElement.firstElementChild.classList.add("b3-list-item--focus");
}
}
currentLiElement.removeAttribute("data-original");
currentLiElement = switchDialog.element.querySelector(".b3-list-item--focus");
}
const currentType = currentLiElement.getAttribute("data-type");
if (currentType) {
if (currentType === "riffCard") {
openCard(app);
} else {
getDockByType(currentType).toggleModel(currentType, true);
}
if (document.activeElement) {
(document.activeElement as HTMLElement).blur();
}
} else {
const currentId = currentLiElement.getAttribute("data-id");
getAllTabs().find(item => {
if (item.id === currentId) {
item.parent.switchTab(item.headElement);
item.parent.showHeading();
return true;
}
});
}
switchDialog.destroy();
switchDialog = undefined;
}
}
}

View File

@ -0,0 +1,197 @@
import {getAllModels} from "../../layout/getAll";
import {isWindow} from "../../util/functions";
import {hasClosestBlock, hasClosestByClassName, hasClosestByMatchTag} from "../../protyle/util/hasClosest";
import {getColIndex} from "../../protyle/util/table";
const getRightBlock = (element: HTMLElement, x: number, y: number) => {
let index = 1;
let nodeElement = element;
while (nodeElement && (nodeElement.classList.contains("list") || nodeElement.classList.contains("li"))) {
nodeElement = document.elementFromPoint(x + 73 * index, y) as HTMLElement;
nodeElement = hasClosestBlock(nodeElement) as HTMLElement;
index++;
}
return nodeElement;
};
export const windowMouseMove = (event: MouseEvent & { target: HTMLElement }) => {
// https://github.com/siyuan-note/siyuan/pull/8793
const coordinates = window.siyuan.coordinates ?? (window.siyuan.coordinates = {
pageX: 0,
pageY: 0,
clientX: 0,
clientY: 0,
screenX: 0,
screenY: 0,
});
coordinates.pageX = event.pageX;
coordinates.pageY = event.pageY;
coordinates.clientX = event.clientX;
coordinates.clientY = event.clientY;
coordinates.screenX = event.screenX;
coordinates.screenY = event.screenY;
if (window.siyuan.hideBreadcrumb) {
document.querySelectorAll(".protyle-breadcrumb__bar--hide").forEach(item => {
item.classList.remove("protyle-breadcrumb__bar--hide");
});
window.siyuan.hideBreadcrumb = false;
getAllModels().editor.forEach(item => {
item.editor.protyle.breadcrumb.render(item.editor.protyle, true);
});
}
if (event.buttons === 0 && // 鼠标按键被按下时不触发
window.siyuan.layout.bottomDock &&
!isWindow() && !hasClosestByClassName(event.target, "b3-dialog") && !hasClosestByClassName(event.target, "b3-menu")) {
if (event.clientX < 43) {
if (!window.siyuan.layout.leftDock.pin && window.siyuan.layout.leftDock.layout.element.clientWidth > 0 &&
// 隐藏停靠栏会导致点击两侧内容触发浮动面板弹出,因此需减小鼠标范围
(window.siyuan.layout.leftDock.element.clientWidth > 0 || (window.siyuan.layout.leftDock.element.clientWidth === 0 && event.clientX < 8))) {
if (event.clientY > document.getElementById("toolbar").clientHeight &&
event.clientY < window.innerHeight - document.getElementById("status").clientHeight - document.getElementById("dockBottom").clientHeight) {
if (!hasClosestByClassName(event.target, "b3-menu") &&
!hasClosestByClassName(event.target, "layout--float")) {
window.siyuan.layout.leftDock.showDock();
}
} else {
window.siyuan.layout.leftDock.hideDock();
}
}
} else if (event.clientX > window.innerWidth - 41) {
if (!window.siyuan.layout.rightDock.pin && window.siyuan.layout.rightDock.layout.element.clientWidth > 0 &&
(window.siyuan.layout.rightDock.element.clientWidth > 0 || (window.siyuan.layout.rightDock.element.clientWidth === 0 && event.clientX > window.innerWidth - 8))) {
if (event.clientY > document.getElementById("toolbar").clientHeight &&
event.clientY < window.innerHeight - document.getElementById("status").clientHeight - document.getElementById("dockBottom").clientHeight) {
if (!hasClosestByClassName(event.target, "layout--float")) {
window.siyuan.layout.rightDock.showDock();
}
} else {
window.siyuan.layout.rightDock.hideDock();
}
}
}
if (event.clientY > window.innerHeight - 73) {
window.siyuan.layout.bottomDock.showDock();
}
}
const eventPath0 = event.composedPath()[0] as HTMLElement;
if (eventPath0 && eventPath0.nodeType !== 3 && eventPath0.classList.contains("protyle-wysiwyg") && eventPath0.style.paddingLeft) {
// 光标在编辑器右边也需要进行显示
const mouseElement = document.elementFromPoint(eventPath0.getBoundingClientRect().left + parseInt(eventPath0.style.paddingLeft) + 13, event.clientY);
const blockElement = hasClosestBlock(mouseElement);
if (blockElement) {
const targetBlockElement = getRightBlock(blockElement, blockElement.getBoundingClientRect().left + 1, event.clientY);
if (!targetBlockElement) {
return;
}
const allModels = getAllModels();
let findNode = false;
allModels.editor.find(item => {
if (item.editor.protyle.wysiwyg.element.isSameNode(eventPath0)) {
item.editor.protyle.gutter.render(item.editor.protyle, targetBlockElement, item.editor.protyle.wysiwyg.element);
findNode = true;
return true;
}
});
if (!findNode) {
window.siyuan.blockPanels.find(item => {
item.editors.find(eItem => {
if (eItem.protyle.wysiwyg.element.contains(eventPath0)) {
eItem.protyle.gutter.render(eItem.protyle, targetBlockElement, eItem.protyle.wysiwyg.element);
findNode = true;
return true;
}
});
if (findNode) {
return true;
}
});
}
if (!findNode) {
allModels.backlink.find(item => {
item.editors.find(eItem => {
if (eItem.protyle.wysiwyg.element.isSameNode(eventPath0)) {
eItem.protyle.gutter.render(eItem.protyle, targetBlockElement, eItem.protyle.wysiwyg.element);
findNode = true;
return true;
}
});
if (findNode) {
return true;
}
});
}
}
return;
}
if (eventPath0 && eventPath0.nodeType !== 3 && (eventPath0.classList.contains("li") || eventPath0.classList.contains("list"))) {
// 光标在列表下部应显示右侧的元素,而不是列表本身
const targetBlockElement = getRightBlock(eventPath0, eventPath0.getBoundingClientRect().left + 1, event.clientY);
if (!targetBlockElement) {
return;
}
const allModels = getAllModels();
let findNode = false;
allModels.editor.find(item => {
if (item.editor.protyle.wysiwyg.element.contains(eventPath0)) {
item.editor.protyle.gutter.render(item.editor.protyle, targetBlockElement, item.editor.protyle.wysiwyg.element);
findNode = true;
return true;
}
});
if (!findNode) {
window.siyuan.blockPanels.find(item => {
item.editors.find(eItem => {
if (eItem.protyle.wysiwyg.element.contains(eventPath0)) {
eItem.protyle.gutter.render(eItem.protyle, targetBlockElement, eItem.protyle.wysiwyg.element);
findNode = true;
return true;
}
});
if (findNode) {
return true;
}
});
}
if (!findNode) {
allModels.backlink.find(item => {
item.editors.find(eItem => {
if (eItem.protyle.wysiwyg.element.contains(eventPath0)) {
eItem.protyle.gutter.render(eItem.protyle, targetBlockElement, eItem.protyle.wysiwyg.element);
findNode = true;
return true;
}
});
if (findNode) {
return true;
}
});
}
return;
}
const target = event.target as Element;
const blockElement = hasClosestByClassName(target, "table");
if (blockElement && blockElement.style.cursor !== "col-resize" && !hasClosestByClassName(blockElement, "protyle-wysiwyg__embed")) {
const cellElement = (hasClosestByMatchTag(target, "TH") || hasClosestByMatchTag(target, "TD")) as HTMLTableCellElement;
if (cellElement) {
const tableElement = blockElement.querySelector("table");
const tableHeight = blockElement.querySelector("table").clientHeight;
const resizeElement = blockElement.querySelector(".table__resize");
if (blockElement.style.textAlign === "center" || blockElement.style.textAlign === "right") {
resizeElement.parentElement.style.left = tableElement.offsetLeft + "px";
} else {
resizeElement.parentElement.style.left = "";
}
const rect = cellElement.getBoundingClientRect();
if (rect.right - event.clientX < 3 && rect.right - event.clientX > 0) {
resizeElement.setAttribute("data-col-index", (getColIndex(cellElement) + cellElement.colSpan - 1).toString());
resizeElement.setAttribute("style", `height:${tableHeight}px;left: ${Math.round(cellElement.offsetWidth + cellElement.offsetLeft - blockElement.firstElementChild.scrollLeft - 3)}px;display:block`);
} else if (event.clientX - rect.left < 3 && event.clientX - rect.left > 0 && cellElement.previousElementSibling) {
resizeElement.setAttribute("data-col-index", (getColIndex(cellElement) - 1).toString());
resizeElement.setAttribute("style", `height:${tableHeight}px;left: ${Math.round(cellElement.offsetLeft - blockElement.firstElementChild.scrollLeft - 3)}px;display:block`);
}
}
}
};

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,6 @@ import {onWindowsMsg} from "../window/onWindowsMsg";
/// #endif /// #endif
import {Constants} from "../constants"; import {Constants} from "../constants";
import {appearance} from "../config/appearance"; import {appearance} from "../config/appearance";
import {globalShortcut} from "../boot/globalShortcut";
import {fetchPost, fetchSyncPost} from "../util/fetch"; import {fetchPost, fetchSyncPost} from "../util/fetch";
import {addGA, initAssets, setInlineStyle} from "../util/assets"; import {addGA, initAssets, setInlineStyle} from "../util/assets";
import {renderSnippet} from "../config/util/snippets"; import {renderSnippet} from "../config/util/snippets";
@ -27,6 +26,7 @@ import {setProxy} from "../config/util/about";
import {openChangelog} from "./openChangelog"; import {openChangelog} from "./openChangelog";
import {getIdFromSYProtocol, isSYProtocol} from "../util/pathName"; import {getIdFromSYProtocol, isSYProtocol} from "../util/pathName";
import {App} from "../index"; import {App} from "../index";
import {initWindowEvent} from "./globalEvent/event";
const matchKeymap = (keymap: Record<string, IKeymapItem>, key1: "general" | "editor", key2?: "general" | "insert" | "heading" | "list" | "table") => { const matchKeymap = (keymap: Record<string, IKeymapItem>, key1: "general" | "editor", key2?: "general" | "insert" | "heading" | "list" | "table") => {
if (key1 === "general") { if (key1 === "general") {
@ -131,7 +131,7 @@ export const onGetConfig = (isStart: boolean, app: App) => {
if (!window.siyuan.config.uiLayout || (window.siyuan.config.uiLayout && !window.siyuan.config.uiLayout.left)) { if (!window.siyuan.config.uiLayout || (window.siyuan.config.uiLayout && !window.siyuan.config.uiLayout.left)) {
window.siyuan.config.uiLayout = Constants.SIYUAN_EMPTY_LAYOUT; window.siyuan.config.uiLayout = Constants.SIYUAN_EMPTY_LAYOUT;
} }
globalShortcut(app); initWindowEvent(app);
fetchPost("/api/system/getEmojiConf", {}, response => { fetchPost("/api/system/getEmojiConf", {}, response => {
window.siyuan.emojis = response.data as IEmoji[]; window.siyuan.emojis = response.data as IEmoji[];
try { try {

View File

@ -1410,7 +1410,7 @@ export class WYSIWYG {
} }
const nodeElement = hasClosestBlock(event.target); const nodeElement = hasClosestBlock(event.target);
if (nodeElement && (nodeElement.classList.contains("list") || nodeElement.classList.contains("li"))) { if (nodeElement && (nodeElement.classList.contains("list") || nodeElement.classList.contains("li"))) {
// 光标在列表下部应显示右侧的元素,而不是列表本身。放在 globalShortcut 中的 mousemove 下处理 // 光标在列表下部应显示右侧的元素,而不是列表本身。放在 windowEvent 中的 mousemove 下处理
return; return;
} }
if (nodeElement) { if (nodeElement) {

View File

@ -407,10 +407,11 @@ interface ICommand {
langText?: string, // 显示的文本, 指定后不再使用 langKey 对应的 i18n 文本 langText?: string, // 显示的文本, 指定后不再使用 langKey 对应的 i18n 文本
hotkey: string, hotkey: string,
customHotkey?: string, customHotkey?: string,
callback?: () => void callback?: () => void // 其余回调存在时将不会触
fileTreeCallback?: (file: import("../layout/dock/Files").Files) => void globalCallback?: () => void // 焦点不在应用内时执行的回调
editorCallback?: (protyle: IProtyle) => void fileTreeCallback?: (file: import("../layout/dock/Files").Files) => void // 焦点在文档树上时执行的回调
dockCallback?: (element: HTMLElement) => void editorCallback?: (protyle: IProtyle) => void // 焦点在编辑器上时执行的回调
dockCallback?: (element: HTMLElement) => void // 焦点在 dock 上时执行的回调
} }
interface IPluginData { interface IPluginData {

View File

@ -1,6 +1,5 @@
import {Constants} from "../constants"; import {Constants} from "../constants";
import {webFrame} from "electron"; import {webFrame} from "electron";
import {globalShortcut} from "../boot/globalShortcut";
import {fetchPost} from "../util/fetch"; import {fetchPost} from "../util/fetch";
import {getInstanceById, JSONToCenter, resizeTabs} from "../layout/util"; import {getInstanceById, JSONToCenter, resizeTabs} from "../layout/util";
import {initStatus} from "../layout/status"; import {initStatus} from "../layout/status";
@ -12,10 +11,11 @@ import {initWindow} from "../boot/onGetConfig";
import {App} from "../index"; import {App} from "../index";
import {afterLoadPlugin} from "../plugin/loader"; import {afterLoadPlugin} from "../plugin/loader";
import {Tab} from "../layout/Tab"; import {Tab} from "../layout/Tab";
import {initWindowEvent} from "../boot/globalEvent/event";
export const init = (app: App) => { export const init = (app: App) => {
webFrame.setZoomFactor(window.siyuan.storage[Constants.LOCAL_ZOOM]); webFrame.setZoomFactor(window.siyuan.storage[Constants.LOCAL_ZOOM]);
globalShortcut(app); initWindowEvent(app);
fetchPost("/api/system/getEmojiConf", {}, response => { fetchPost("/api/system/getEmojiConf", {}, response => {
window.siyuan.emojis = response.data as IEmoji[]; window.siyuan.emojis = response.data as IEmoji[];