A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. (PERSONAL FORK)
1import {App} from "../../index";
2import {windowMouseMove} from "./mousemove";
3import {windowKeyUp} from "./keyup";
4import {windowKeyDown} from "./keydown";
5import {globalClick} from "./click";
6import {goBack, goForward} from "../../util/backForward";
7import {Constants} from "../../constants";
8import {isIPad} from "../../protyle/util/compatibility";
9import {globalTouchEnd, globalTouchStart} from "./touch";
10import {initDockMenu} from "../../menus/dock";
11import {
12 hasClosestByAttribute,
13 hasClosestByClassName,
14 isInEmbedBlock
15} from "../../protyle/util/hasClosest";
16import {initTabMenu} from "../../menus/tab";
17import {getInstanceById} from "../../layout/util";
18import {Tab} from "../../layout/Tab";
19import {hideTooltip} from "../../dialog/tooltip";
20import {openFileById} from "../../editor/util";
21import {checkFold} from "../../util/noRelyPCFunction";
22import {hideAllElements} from "../../protyle/ui/hideElements";
23
24export const initWindowEvent = (app: App) => {
25 document.body.addEventListener("mouseleave", () => {
26 if (window.siyuan.layout.leftDock) {
27 window.siyuan.layout.leftDock.hideDock();
28 window.siyuan.layout.rightDock.hideDock();
29 window.siyuan.layout.bottomDock.hideDock();
30 }
31 document.querySelectorAll(".protyle-gutters").forEach(item => {
32 item.classList.add("fn__none");
33 item.innerHTML = "";
34 });
35 hideTooltip();
36 });
37 let mouseIsEnter = false;
38 document.body.addEventListener("mouseenter", () => {
39 if (window.siyuan.layout.leftDock) {
40 mouseIsEnter = true;
41 setTimeout(() => {
42 mouseIsEnter = false;
43 }, Constants.TIMEOUT_TRANSITION);
44 }
45 });
46
47 window.addEventListener("mousemove", (event: MouseEvent & { target: HTMLElement }) => {
48 windowMouseMove(event, mouseIsEnter);
49 });
50
51 window.addEventListener("mouseup", (event) => {
52 if (event.button === 3) {
53 event.preventDefault();
54 goBack(app);
55 } else if (event.button === 4) {
56 event.preventDefault();
57 goForward(app);
58 }
59 });
60
61 window.addEventListener("mousedown", (event) => {
62 // protyle.toolbar 点击空白处时进行隐藏
63 if (!hasClosestByClassName(event.target as Element, "protyle-toolbar")) {
64 hideAllElements(["toolbar"]);
65 }
66 });
67
68 window.addEventListener("keyup", (event) => {
69 windowKeyUp(app, event);
70 });
71
72 window.addEventListener("keydown", (event) => {
73 windowKeyDown(app, event);
74 });
75
76 window.addEventListener("blur", () => {
77 window.siyuan.ctrlIsPressed = false;
78 window.siyuan.shiftIsPressed = false;
79 window.siyuan.altIsPressed = false;
80 });
81
82 window.addEventListener("click", (event: MouseEvent & { target: HTMLElement }) => {
83 globalClick(event);
84 });
85
86 let time = 0;
87 document.addEventListener("touchstart", (event) => {
88 time = new Date().getTime();
89 // https://github.com/siyuan-note/siyuan/issues/6328
90 const target = event.target as HTMLElement;
91 if (hasClosestByClassName(target, "protyle-icons") ||
92 hasClosestByClassName(target, "item") ||
93 target.classList.contains("protyle-background__icon")) {
94 return;
95 }
96 const embedBlockElement = isInEmbedBlock(target);
97 if (embedBlockElement) {
98 embedBlockElement.firstElementChild.classList.toggle("protyle-icons--show");
99 return;
100 }
101 // 触摸屏背景和嵌入块按钮显示
102 globalTouchStart(event);
103 }, false);
104 document.addEventListener("touchend", (event) => {
105 if (isIPad()) {
106 // https://github.com/siyuan-note/siyuan/issues/9113
107 if (globalTouchEnd(event, undefined, time, app)) {
108 event.stopImmediatePropagation();
109 event.preventDefault();
110 return;
111 }
112 if (new Date().getTime() - time <= 900) {
113 return;
114 }
115 const target = event.target as HTMLElement;
116 // dock right menu
117 const dockElement = hasClosestByClassName(target, "dock__item");
118 if (dockElement && dockElement.getAttribute("data-type")) {
119 const dockRect = dockElement.getBoundingClientRect();
120 initDockMenu(dockElement).popup({x: dockRect.right, y: dockRect.top});
121 event.stopImmediatePropagation();
122 event.preventDefault();
123 return;
124 }
125
126 // tab right menu
127 const tabElement = hasClosestByAttribute(target, "data-type", "tab-header");
128 if (tabElement) {
129 const tabRect = tabElement.getBoundingClientRect();
130 initTabMenu(app, (getInstanceById(tabElement.getAttribute("data-id")) as Tab)).popup({
131 x: tabRect.left,
132 y: tabRect.bottom
133 });
134 hideTooltip();
135 event.stopImmediatePropagation();
136 event.preventDefault();
137 return;
138 }
139
140 const backlinkBreadcrumbItemElement = hasClosestByClassName(target, "protyle-breadcrumb__item");
141 if (backlinkBreadcrumbItemElement) {
142 const breadcrumbId = backlinkBreadcrumbItemElement.getAttribute("data-id") || backlinkBreadcrumbItemElement.getAttribute("data-node-id");
143 if (breadcrumbId) {
144 checkFold(breadcrumbId, (zoomIn) => {
145 openFileById({
146 app,
147 id: breadcrumbId,
148 action: zoomIn ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL] : [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT],
149 zoomIn,
150 });
151 window.siyuan.menus.menu.remove();
152 });
153 }
154 event.stopImmediatePropagation();
155 event.preventDefault();
156 return;
157 }
158 }
159 }, false);
160};