diff --git a/app/src/assets/scss/component/_typography.scss b/app/src/assets/scss/component/_typography.scss index 77cb1d638..cb3c08c02 100644 --- a/app/src/assets/scss/component/_typography.scss +++ b/app/src/assets/scss/component/_typography.scss @@ -480,10 +480,6 @@ right: 4px; top: 4px; display: flex; - - &--show { - opacity: .86; - } } &-icon { diff --git a/app/src/assets/scss/protyle/_wysiwyg.scss b/app/src/assets/scss/protyle/_wysiwyg.scss index e9b64fe63..d66b3b46b 100644 --- a/app/src/assets/scss/protyle/_wysiwyg.scss +++ b/app/src/assets/scss/protyle/_wysiwyg.scss @@ -559,6 +559,7 @@ } } } + } // 只读情况下列表前的圆点需要可以点击进行缩放 @@ -615,7 +616,8 @@ } .img:hover .protyle-icons, - .render-node:hover > .protyle-icons { + .render-node:hover > .protyle-icons, + .protyle-icons--show { opacity: .86; } } diff --git a/app/src/block/popover.ts b/app/src/block/popover.ts index e85927da8..89dbcf942 100644 --- a/app/src/block/popover.ts +++ b/app/src/block/popover.ts @@ -4,6 +4,7 @@ import {fetchSyncPost} from "../util/fetch"; import {hideTooltip, showTooltip} from "../dialog/tooltip"; import {getIdFromSYProtocol} from "../util/pathName"; import {App} from "../index"; +import {Constants} from "../constants"; let popoverTargetElement: HTMLElement; export const initBlockPopover = (app: App) => { @@ -56,7 +57,7 @@ export const initBlockPopover = (app: App) => { clearTimeout(timeoutHide); timeoutHide = window.setTimeout(() => { hidePopover(event); - }, 200); + }, Constants.TIMEOUT_INPUT); if (!getTarget(event, aElement)) { return; @@ -84,7 +85,7 @@ export const initBlockPopover = (app: App) => { if (!popoverTargetElement && !aElement) { clearTimeout(timeout); } - }, 200); + }, Constants.TIMEOUT_INPUT); timeout = window.setTimeout(() => { if (!getTarget(event, aElement)) { return; @@ -95,32 +96,34 @@ export const initBlockPopover = (app: App) => { }); }; -const hidePopover = (event: MouseEvent & { target: HTMLElement, path: HTMLElement[] }) => { - if (hasClosestByClassName(event.target, "b3-menu") || - (event.target.id && event.target.tagName !== "svg" && (event.target.id.startsWith("minder_node") || event.target.id.startsWith("kity_") || event.target.id.startsWith("node_"))) - || event.target.classList.contains("counter") - || event.target.tagName === "circle" +const hidePopover = (event: MouseEvent & { path: HTMLElement[] }) => { + // pad 端点击后 event.target 不会更新。 + const target = document.elementFromPoint(event.clientX, event.clientY); + if (hasClosestByClassName(target, "b3-menu") || + (target.id && target.tagName !== "svg" && (target.id.startsWith("minder_node") || target.id.startsWith("kity_") || target.id.startsWith("node_"))) + || target.classList.contains("counter") + || target.tagName === "circle" ) { // b3-menu 需要处理,(( 后的 hint 上的图表移上去需显示预览 // gutter & mindmap & 文件树上的数字 & 关系图节点不处理 return false; } - popoverTargetElement = hasClosestByAttribute(event.target, "data-type", "block-ref") as HTMLElement || - hasClosestByAttribute(event.target, "data-type", "virtual-block-ref") as HTMLElement; + popoverTargetElement = hasClosestByAttribute(target, "data-type", "block-ref") as HTMLElement || + hasClosestByAttribute(target, "data-type", "virtual-block-ref") as HTMLElement; if (popoverTargetElement && popoverTargetElement.classList.contains("b3-tooltips")) { popoverTargetElement = undefined; } if (!popoverTargetElement) { - popoverTargetElement = hasClosestByClassName(event.target, "popover__block") as HTMLElement; + popoverTargetElement = hasClosestByClassName(target, "popover__block") as HTMLElement; } - const linkElement = hasClosestByAttribute(event.target, "data-type", "a", true); + const linkElement = hasClosestByAttribute(target, "data-type", "a", true); if (!popoverTargetElement && linkElement && linkElement.getAttribute("data-href")?.startsWith("siyuan://blocks")) { popoverTargetElement = linkElement; } if (!popoverTargetElement) { // 移动到弹窗的 loading 元素上,但经过 settimeout 后 loading 已经被移除了 // https://ld246.com/article/1673596577519/comment/1673767749885#comments - let targetElement = event.target; + let targetElement = target; if (!targetElement.parentElement && event.path && event.path[1]) { targetElement = event.path[1]; } diff --git a/app/src/boot/globalEvent/event.ts b/app/src/boot/globalEvent/event.ts index d6d5ab95c..3a9543932 100644 --- a/app/src/boot/globalEvent/event.ts +++ b/app/src/boot/globalEvent/event.ts @@ -65,12 +65,60 @@ export const initWindowEvent = (app: App) => { globalClick(event); }); - if (isIPad()) { - let time = 0; - document.addEventListener("touchstart", () => { - time = new Date().getTime(); - }, false); - document.addEventListener("touchend", (event) => { + let time = 0; + document.addEventListener("touchstart", (event) => { + time = new Date().getTime(); + // https://github.com/siyuan-note/siyuan/issues/6328 + const target = event.target as HTMLElement; + if (hasClosestByClassName(target, "protyle-icons") || + hasClosestByClassName(target, "item") || + target.classList.contains("protyle-background__icon")) { + return; + } + // 触摸屏背景和嵌入块按钮显示 + const backgroundElement = hasClosestByClassName(target, "protyle-background") + if (backgroundElement) { + if (target.tagName === "IMG" && backgroundElement.firstElementChild.querySelector(".protyle-icons").classList.contains("fn__none")) { + // 文档背景位置调整 + const contentElement = hasClosestByClassName(backgroundElement, "protyle-content"); + if (!contentElement) { + return; + } + contentElement.style.overflow = "hidden" + const y = event.touches[0].clientY; + const documentSelf = document; + const height = (target as HTMLImageElement).naturalHeight * target.clientWidth / (target as HTMLImageElement).naturalWidth - target.clientHeight; + let originalPositionY = parseFloat(target.style.objectPosition.substring(7)) || 50; + if (target.style.objectPosition.endsWith("px")) { + originalPositionY = -parseInt(target.style.objectPosition.substring(7)) / height * 100; + } + + documentSelf.ontouchmove = (moveEvent) => { + + target.style.objectPosition = `center ${((y - moveEvent.touches[0].clientY) / height * 100 + originalPositionY).toFixed(2)}%`; + }; + documentSelf.ontouchend = () => { + contentElement.style.overflow = "" + documentSelf.ontouchmove = null; + documentSelf.ontouchstart = null; + documentSelf.ondragstart = null; + documentSelf.onselectstart = null; + documentSelf.onselect = null; + }; + } else { + backgroundElement.classList.toggle("protyle-background--mobileshow"); + } + return; + } + const embedBlockElement = hasClosestByAttribute(target, "data-type", "NodeBlockQueryEmbed"); + if (embedBlockElement) { + embedBlockElement.firstElementChild.classList.toggle("protyle-icons--show"); + return; + } + }, false); + document.addEventListener("touchend", (event) => { + if (isIPad()) { + // https://github.com/siyuan-note/siyuan/issues/9113 if (globalTouchEnd(event, undefined, time, app)) { event.stopImmediatePropagation(); event.preventDefault(); @@ -103,6 +151,6 @@ export const initWindowEvent = (app: App) => { event.preventDefault(); return; } - }, false); - } + } + }, false); }; diff --git a/app/src/mobile/util/touch.ts b/app/src/mobile/util/touch.ts index 591982a13..bf09a57d7 100644 --- a/app/src/mobile/util/touch.ts +++ b/app/src/mobile/util/touch.ts @@ -162,7 +162,6 @@ export const handleTouchStart = (event: TouchEvent) => { } }; - let previousClientX: number; export const handleTouchMove = (event: TouchEvent) => { const target = event.target as HTMLElement; diff --git a/app/src/protyle/header/Background.ts b/app/src/protyle/header/Background.ts index 085b3ae41..35e1c5172 100644 --- a/app/src/protyle/header/Background.ts +++ b/app/src/protyle/header/Background.ts @@ -131,76 +131,49 @@ export class Background { this.tagsElement = this.element.querySelector(".b3-chips") as HTMLElement; this.iconElement = this.element.querySelector(".protyle-background__icon") as HTMLElement; this.imgElement = this.element.firstElementChild.firstElementChild as HTMLImageElement; - if (isTouchDevice()) { - this.imgElement.addEventListener("touchstart", (event: TouchEvent & { target: HTMLElement }) => { - event.preventDefault(); - if (!this.element.firstElementChild.querySelector(".protyle-icons").classList.contains("fn__none")) { - return; - } - const y = event.touches[0].clientY; - const documentSelf = document; - const height = this.imgElement.naturalHeight * this.imgElement.clientWidth / this.imgElement.naturalWidth - this.imgElement.clientHeight; - let originalPositionY = parseFloat(this.imgElement.style.objectPosition.substring(7)) || 50; - if (this.imgElement.style.objectPosition.endsWith("px")) { - originalPositionY = -parseInt(this.imgElement.style.objectPosition.substring(7)) / height * 100; - } - documentSelf.ontouchmove = (moveEvent) => { - this.imgElement.style.objectPosition = `center ${((y - moveEvent.touches[0].clientY) / height * 100 + originalPositionY).toFixed(2)}%`; - event.preventDefault(); - }; - documentSelf.ontouchend = () => { - documentSelf.ontouchmove = null; - documentSelf.ontouchstart = null; - documentSelf.ondragstart = null; - documentSelf.onselectstart = null; - documentSelf.onselect = null; - }; - }); - } else { - this.element.addEventListener("dragover", async (event) => { - event.preventDefault(); - }); - this.element.addEventListener("drop", async (event: DragEvent & { target: HTMLElement }) => { - if (event.dataTransfer.types[0] === "Files" && event.dataTransfer.files[0].type.indexOf("image") !== -1) { - uploadFiles(protyle, [event.dataTransfer.files[0]], undefined, (responseText) => { - const response = JSON.parse(responseText); - const style = `background-image:url("${response.data.succMap[Object.keys(response.data.succMap)[0]]}")`; - this.ial["title-img"] = style; - this.render(this.ial, protyle.block.rootID); - fetchPost("/api/attr/setBlockAttrs", { - id: protyle.block.rootID, - attrs: {"title-img": style} - }); + this.element.addEventListener("dragover", async (event) => { + event.preventDefault(); + }); + this.element.addEventListener("drop", async (event: DragEvent & { target: HTMLElement }) => { + if (event.dataTransfer.types[0] === "Files" && event.dataTransfer.files[0].type.indexOf("image") !== -1) { + uploadFiles(protyle, [event.dataTransfer.files[0]], undefined, (responseText) => { + const response = JSON.parse(responseText); + const style = `background-image:url("${response.data.succMap[Object.keys(response.data.succMap)[0]]}")`; + this.ial["title-img"] = style; + this.render(this.ial, protyle.block.rootID); + fetchPost("/api/attr/setBlockAttrs", { + id: protyle.block.rootID, + attrs: {"title-img": style} }); - } - }); - this.imgElement.addEventListener("mousedown", (event: MouseEvent & { target: HTMLElement }) => { + }); + } + }); + this.imgElement.addEventListener("mousedown", (event: MouseEvent & { target: HTMLElement }) => { + event.preventDefault(); + if (!this.element.firstElementChild.querySelector(".protyle-icons").classList.contains("fn__none")) { + return; + } + const y = event.clientY; + const documentSelf = document; + const height = this.imgElement.naturalHeight * this.imgElement.clientWidth / this.imgElement.naturalWidth - this.imgElement.clientHeight; + let originalPositionY = parseFloat(this.imgElement.style.objectPosition.substring(7)) || 50; + if (this.imgElement.style.objectPosition.endsWith("px")) { + originalPositionY = -parseInt(this.imgElement.style.objectPosition.substring(7)) / height * 100; + } + documentSelf.onmousemove = (moveEvent: MouseEvent) => { + this.imgElement.style.objectPosition = `center ${((y - moveEvent.clientY) / height * 100 + originalPositionY).toFixed(2)}%`; event.preventDefault(); - if (!this.element.firstElementChild.querySelector(".protyle-icons").classList.contains("fn__none")) { - return; - } - const y = event.clientY; - const documentSelf = document; - const height = this.imgElement.naturalHeight * this.imgElement.clientWidth / this.imgElement.naturalWidth - this.imgElement.clientHeight; - let originalPositionY = parseFloat(this.imgElement.style.objectPosition.substring(7)) || 50; - if (this.imgElement.style.objectPosition.endsWith("px")) { - originalPositionY = -parseInt(this.imgElement.style.objectPosition.substring(7)) / height * 100; - } - documentSelf.onmousemove = (moveEvent: MouseEvent) => { - this.imgElement.style.objectPosition = `center ${((y - moveEvent.clientY) / height * 100 + originalPositionY).toFixed(2)}%`; - event.preventDefault(); - }; + }; - documentSelf.onmouseup = () => { - documentSelf.onmousemove = null; - documentSelf.onmouseup = null; - documentSelf.ondragstart = null; - documentSelf.onselectstart = null; - documentSelf.onselect = null; - }; - }); - } + documentSelf.onmouseup = () => { + documentSelf.onmousemove = null; + documentSelf.onmouseup = null; + documentSelf.ondragstart = null; + documentSelf.onselectstart = null; + documentSelf.onselect = null; + }; + }); this.element.querySelector("input").addEventListener("change", (event: InputEvent & { target: HTMLInputElement }) => { diff --git a/app/src/protyle/ui/initUI.ts b/app/src/protyle/ui/initUI.ts index f3b53816f..8fc4a9d01 100644 --- a/app/src/protyle/ui/initUI.ts +++ b/app/src/protyle/ui/initUI.ts @@ -47,27 +47,6 @@ export const initUI = (protyle: IProtyle) => { setEditMode(protyle, protyle.options.mode); document.execCommand("DefaultParagraphSeparator", false, "p"); - // 触摸屏背景和嵌入块按钮显示 - protyle.contentElement.addEventListener("touchstart", (event) => { - // https://github.com/siyuan-note/siyuan/issues/6328 - if (protyle.disabled) { - return; - } - const target = event.target as HTMLElement; - if (hasClosestByClassName(target, "protyle-icons") || - hasClosestByClassName(target, "item") || - target.classList.contains("protyle-background__icon")) { - return; - } - if (hasClosestByClassName(target, "protyle-background")) { - protyle.background.element.classList.toggle("protyle-background--mobileshow"); - return; - } - const embedBlockElement = hasClosestByAttribute(target, "data-type", "NodeBlockQueryEmbed"); - if (embedBlockElement) { - embedBlockElement.firstElementChild.classList.toggle("protyle-icons--show"); - } - }); let wheelTimeout: number; const isMacOS = isMac(); protyle.contentElement.addEventListener("mousewheel", (event: WheelEvent) => {