A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. (PERSONAL FORK)
1import {hasClosestByClassName} from "../protyle/util/hasClosest";
2import {Constants} from "../constants";
3import {hideAllElements} from "../protyle/ui/hideElements";
4import {setStorageVal} from "../protyle/util/compatibility";
5
6export const moveResize = (element: HTMLElement, afterCB?: (type: string) => void) => {
7 element.addEventListener("mousedown", (event: MouseEvent & { target: HTMLElement }) => {
8 // https://github.com/siyuan-note/siyuan/issues/8746
9 if (hasClosestByClassName(event.target, "protyle-util") && !element.classList.contains("protyle-util")) {
10 return;
11 }
12 let iconsElement = hasClosestByClassName(event.target, "resize__move");
13 let x: number;
14 let y: number;
15 const elementRect = element.getBoundingClientRect();
16 if (!iconsElement) {
17 x = event.clientX;
18 y = event.clientY;
19 iconsElement = hasClosestByClassName(event.target, "resize__rd") ||
20 hasClosestByClassName(event.target, "resize__r") ||
21 hasClosestByClassName(event.target, "resize__rt") ||
22 hasClosestByClassName(event.target, "resize__d") ||
23 hasClosestByClassName(event.target, "resize__l") ||
24 hasClosestByClassName(event.target, "resize__ld") ||
25 hasClosestByClassName(event.target, "resize__lt") ||
26 hasClosestByClassName(event.target, "resize__t");
27
28 } else {
29 x = event.clientX - elementRect.left;
30 y = event.clientY - elementRect.top;
31 }
32 if (!iconsElement) {
33 return;
34 }
35 const height = element.clientHeight;
36 const width = element.clientWidth;
37 const type = iconsElement.className.split("resize__")[1].split(" ")[0];
38 const documentSelf = document;
39 element.style.userSelect = "none";
40 if (element.classList.contains("b3-dialog__container") && element.parentElement.style.display !== "block") {
41 element.parentElement.style.display = "block";
42 element.style.left = elementRect.left + "px";
43 element.style.top = elementRect.top + "px";
44 element.style.width = elementRect.width + "px";
45 }
46
47 documentSelf.ondragstart = () => false;
48
49 let hasMove = false;
50 documentSelf.onmousemove = (moveEvent: MouseEvent) => {
51 hasMove = true;
52 if (!element) {
53 return;
54 }
55 if (type === "move") {
56 let positionX = moveEvent.clientX - x;
57 let positionY = moveEvent.clientY - y;
58 if (positionX > window.innerWidth - width) {
59 positionX = window.innerWidth - width;
60 }
61 if (positionY > window.innerHeight - height) {
62 positionY = window.innerHeight - height;
63 }
64 element.style.left = Math.max(positionX, 0) + "px";
65 element.style.top = Math.max(positionY, Constants.SIZE_TOOLBAR_HEIGHT) + "px";
66 } else {
67 if (type === "r" &&
68 moveEvent.clientX - x + width > 200 && moveEvent.clientX - x + width < window.innerWidth) {
69 element.style.width = moveEvent.clientX - x + width + "px";
70 element.style.maxWidth = "none";
71 } else if (type === "d" &&
72 moveEvent.clientY - y + height > 160 && moveEvent.clientY - y + height < window.innerHeight - Constants.SIZE_TOOLBAR_HEIGHT) {
73 element.style.height = moveEvent.clientY - y + height + "px";
74 element.style.maxHeight = "";
75 } else if (type === "t" &&
76 moveEvent.clientY > Constants.SIZE_TOOLBAR_HEIGHT && y - moveEvent.clientY + height > 160) {
77 element.style.top = moveEvent.clientY + "px";
78 element.style.maxHeight = "";
79 element.style.height = (y - moveEvent.clientY + height) + "px";
80 } else if (type === "l" &&
81 moveEvent.clientX > 0 && x - moveEvent.clientX + width > 200) {
82 element.style.left = moveEvent.clientX + "px";
83 element.style.width = (x - moveEvent.clientX + width) + "px";
84 element.style.maxWidth = "none";
85 } else if (type === "rd" &&
86 moveEvent.clientX - x + width > 200 && moveEvent.clientX - x + width < window.innerWidth &&
87 moveEvent.clientY - y + height > 160 && moveEvent.clientY - y + height < window.innerHeight - Constants.SIZE_TOOLBAR_HEIGHT) {
88 element.style.height = moveEvent.clientY - y + height + "px";
89 element.style.maxHeight = "";
90 element.style.maxWidth = "none";
91 element.style.width = moveEvent.clientX - x + width + "px";
92 } else if (type === "rt" &&
93 moveEvent.clientX - x + width > 200 && moveEvent.clientX - x + width < window.innerWidth &&
94 moveEvent.clientY > Constants.SIZE_TOOLBAR_HEIGHT && y - moveEvent.clientY + height > 160) {
95 element.style.width = moveEvent.clientX - x + width + "px";
96 element.style.top = moveEvent.clientY + "px";
97 element.style.maxHeight = "";
98 element.style.maxWidth = "none";
99 element.style.height = (y - moveEvent.clientY + height) + "px";
100 } else if (type === "lt" &&
101 moveEvent.clientX > 0 && x - moveEvent.clientX + width > 200 &&
102 moveEvent.clientY > Constants.SIZE_TOOLBAR_HEIGHT && y - moveEvent.clientY + height > 160) {
103 element.style.left = moveEvent.clientX + "px";
104 element.style.width = (x - moveEvent.clientX + width) + "px";
105 element.style.top = moveEvent.clientY + "px";
106 element.style.maxHeight = "";
107 element.style.maxWidth = "none";
108 element.style.height = (y - moveEvent.clientY + height) + "px";
109 } else if (type === "ld" &&
110 moveEvent.clientX > 0 && x - moveEvent.clientX + width > 200 &&
111 moveEvent.clientY - y + height > 160 && moveEvent.clientY - y + height < window.innerHeight - Constants.SIZE_TOOLBAR_HEIGHT) {
112 element.style.left = moveEvent.clientX + "px";
113 element.style.width = (x - moveEvent.clientX + width) + "px";
114 element.style.height = moveEvent.clientY - y + height + "px";
115 element.style.maxHeight = "";
116 element.style.maxWidth = "none";
117 }
118 }
119 };
120
121 documentSelf.onmouseup = () => {
122 if (!element) {
123 return;
124 }
125 if (window.siyuan.dragElement) {
126 // 反向链接拖拽 https://ld246.com/article/1632915506502
127 window.siyuan.dragElement.style.opacity = "";
128 window.siyuan.dragElement = undefined;
129 }
130 element.style.userSelect = "auto";
131 documentSelf.onmousemove = null;
132 documentSelf.onmouseup = null;
133 documentSelf.ondragstart = null;
134 documentSelf.onselectstart = null;
135 documentSelf.onselect = null;
136 hideAllElements(["gutter"]);
137 const dialogElement = hasClosestByClassName(element, "b3-dialog--open");
138 if (dialogElement) {
139 const dialogId = dialogElement.dataset.key;
140 if (dialogId && element.offsetWidth) {
141 window.siyuan.storage[Constants.LOCAL_DIALOGPOSITION][dialogId] = {
142 width: element.offsetWidth,
143 height: element.offsetHeight,
144 left: parseInt(element.style.left),
145 top: parseInt(element.style.top),
146 };
147 setStorageVal(Constants.LOCAL_DIALOGPOSITION, window.siyuan.storage[Constants.LOCAL_DIALOGPOSITION]);
148 }
149 }
150 if (hasMove && afterCB) {
151 afterCB(type);
152 }
153 };
154 });
155};