diff --git a/app/appearance/langs/en_US.json b/app/appearance/langs/en_US.json index 45e92baf6..1b76222fe 100644 --- a/app/appearance/langs/en_US.json +++ b/app/appearance/langs/en_US.json @@ -170,7 +170,6 @@ "mergeCell": "Merge Cell", "cancelMerged": "Cancel cell merge", "useDefaultWidth": "Use Default Column Width", - "crossPageUse": "Tips for using multiple selections across pages: click at the start position, and after scrolling the page, at the end position ${}", "type": "Type", "searchType": "Type (searches in the enabled types below, the filter option in the global search overrides this setting)", "searchAttr": "Attribute (search not only in the content, but also in the following enabled attributes)", diff --git a/app/appearance/langs/es_ES.json b/app/appearance/langs/es_ES.json index 4d727f215..5bd980b9b 100644 --- a/app/appearance/langs/es_ES.json +++ b/app/appearance/langs/es_ES.json @@ -170,7 +170,6 @@ "mergeCell": "Merge Cell", "cancelMerged": "Cancelar fusión de celda", "useDefaultWidth": "Usar el ancho de columna por defecto", - "crossPageUse": "Consejos para utilizar selecciones múltiples a través de las páginas: haga clic en la posición inicial y, después de desplazarse por la página, en la posición final ${}", "type": "Tipo", "searchType": "Tipos (busque en los tipos habilitados a continuación, la opción de filtro en la búsqueda global anula esta configuración)", "searchAttr": "Atributo (busca no sólo en el contenido, sino también en los siguientes atributos habilitados)", diff --git a/app/appearance/langs/fr_FR.json b/app/appearance/langs/fr_FR.json index 61b3ec64d..f803ed269 100644 --- a/app/appearance/langs/fr_FR.json +++ b/app/appearance/langs/fr_FR.json @@ -170,7 +170,6 @@ "mergeCell": "Fusionner la cellule", "cancelMerged": "Annuler la fusion de cellules", "useDefaultWidth": "Utiliser la largeur de colonne par défaut", - "crossPageUse": "Conseils pour utiliser plusieurs sélections sur plusieurs pages : cliquez à la position de départ et, après avoir fait défiler la page, à la position de fin ${}", "type": "Type", "searchType": "Types (recherche dans les types activés ci-dessous, l'option de filtre dans la recherche globale remplace ce paramètre)", "searchAttr": "Attribut (recherche non seulement dans le contenu, mais aussi dans les attributs activés suivants)", diff --git a/app/appearance/langs/zh_CHT.json b/app/appearance/langs/zh_CHT.json index f4badb075..be7298d96 100644 --- a/app/appearance/langs/zh_CHT.json +++ b/app/appearance/langs/zh_CHT.json @@ -170,7 +170,6 @@ "mergeCell": "合併單元格", "cancelMerged": "拆分單元格", "useDefaultWidth": "使用預設列寬", - "crossPageUse": "跨頁多選使用提示:在開始位置單擊,滾動頁面以後在結束位置 ${}", "type": "類型", "searchType": "類型(在以下啟用的類型中進行搜索,全局搜索中的過濾選項會覆蓋該設置)", "searchAttr": "屬性(不僅在內容中進行搜索,同時也會在以下啟用的屬性中搜索)", diff --git a/app/appearance/langs/zh_CN.json b/app/appearance/langs/zh_CN.json index 2ef3aa475..53a39aeee 100644 --- a/app/appearance/langs/zh_CN.json +++ b/app/appearance/langs/zh_CN.json @@ -170,7 +170,6 @@ "mergeCell": "合并单元格", "cancelMerged": "拆分单元格", "useDefaultWidth": "使用默认列宽", - "crossPageUse": "跨页多选使用提示:在开始位置单击,滚动页面以后在结束位置 ${}", "type": "类型", "searchType": "类型(在以下启用的类型中进行搜索,全局搜索中的过滤选项会覆盖该设置)", "searchAttr": "属性(不仅在内容中进行搜索,同时也会在以下启用的属性中搜索)", diff --git a/app/src/protyle/scroll/event.ts b/app/src/protyle/scroll/event.ts index 71f583633..426a1397b 100644 --- a/app/src/protyle/scroll/event.ts +++ b/app/src/protyle/scroll/event.ts @@ -33,9 +33,6 @@ export const scrollEvent = (protyle: IProtyle, element: HTMLElement) => { if (!window.siyuan.dragElement) { // https://ld246.com/article/1649638389841 hideElements(["gutter"], protyle); } - if (!protyle.selectElement.classList.contains("fn__none")) { - showMessage(window.siyuan.languages.crossPageUse.replace("${}", updateHotkeyTip("⇧Click")), 9000); - } const panelContextElement = protyle.breadcrumb?.element.parentElement.querySelector('[data-type="context"]'); if (panelContextElement && !panelContextElement.classList.contains("ft__primary")) { diff --git a/app/src/protyle/scroll/index.ts b/app/src/protyle/scroll/index.ts index ff98daade..88bd2403d 100644 --- a/app/src/protyle/scroll/index.ts +++ b/app/src/protyle/scroll/index.ts @@ -11,7 +11,7 @@ export class Scroll { private parentElement: HTMLElement; private inputElement: HTMLInputElement; public lastScrollTop: number; - public keepLazyLoad: boolean; + public keepLazyLoad: boolean; // 保持加载内容 constructor(protyle: IProtyle) { this.parentElement = document.createElement("div"); diff --git a/app/src/protyle/wysiwyg/index.ts b/app/src/protyle/wysiwyg/index.ts index 93f5da5de..01db45617 100644 --- a/app/src/protyle/wysiwyg/index.ts +++ b/app/src/protyle/wysiwyg/index.ts @@ -434,6 +434,8 @@ export class WYSIWYG { let mouseElement: Element; let moveCellElement: HTMLElement; + let startFirstElement: Element; + let endLastElement: Element; documentSelf.onmousemove = (moveEvent: MouseEvent) => { const moveTarget = moveEvent.target as HTMLElement; // table cell select @@ -555,7 +557,14 @@ export class WYSIWYG { mouseElement = newMouseElement; } hideElements(["select"], protyle); - let firstElement = document.elementFromPoint(newLeft - 1, newTop); + let firstElement + if (moveEvent.clientY > y) { + firstElement = startFirstElement || document.elementFromPoint(newLeft - 1, newTop); + endLastElement = undefined + } else { + firstElement = document.elementFromPoint(newLeft - 1, newTop); + startFirstElement = undefined; + } if (!firstElement) { return; } @@ -565,6 +574,9 @@ export class WYSIWYG { if (!firstElement || firstElement.classList.contains("protyle-wysiwyg")) { return; } + if (moveEvent.clientY > y && !startFirstElement) { + startFirstElement = firstElement; + } const firstBlockElement = hasClosestBlock(firstElement); if (!firstBlockElement) { return; @@ -572,15 +584,16 @@ export class WYSIWYG { let selectElements: Element[] = []; let currentElement: Element | boolean = firstBlockElement; let hasJump = false; + const selectBottom = endLastElement ? endLastElement.getBoundingClientRect().bottom : (newTop + newHeight) while (currentElement) { if (currentElement && !currentElement.classList.contains("protyle-attr")) { const currentRect = currentElement.getBoundingClientRect(); - if (currentRect.height > 0 && currentRect.top < newTop + newHeight && currentRect.left < newLeft + newWidth) { + if (currentRect.height > 0 && currentRect.top < selectBottom && currentRect.left < newLeft + newWidth) { if (hasJump) { // 父节点的下个节点在选中范围内才可使用父节点作为选中节点 if (currentElement.nextElementSibling && !currentElement.nextElementSibling.classList.contains("protyle-attr")) { const nextRect = currentElement.nextElementSibling.getBoundingClientRect(); - if (nextRect.top < newTop + newHeight && nextRect.left < newLeft + newWidth) { + if (nextRect.top < selectBottom && nextRect.left < newLeft + newWidth) { selectElements = [currentElement]; currentElement = currentElement.nextElementSibling; hasJump = false; @@ -613,6 +626,7 @@ export class WYSIWYG { hasJump = true; } } + endLastElement = selectElements[selectElements.length - 1] if (selectElements.length === 1 && !selectElements[0].classList.contains("list") && !selectElements[0].classList.contains("bq") && !selectElements[0].classList.contains("sb")) { // 只有一个 p 时不选中 protyle.selectElement.style.backgroundColor = "transparent"; @@ -632,6 +646,8 @@ export class WYSIWYG { documentSelf.ondragstart = null; documentSelf.onselectstart = null; documentSelf.onselect = null; + startFirstElement = undefined; + endLastElement = undefined; protyle.selectElement.classList.add("fn__none"); protyle.selectElement.removeAttribute("style"); if (!protyle.disabled && tableBlockElement) { @@ -1116,8 +1132,8 @@ export class WYSIWYG { } protyle.hint.render(protyle); event.clipboardData.setData("text/plain", protyle.lute.BlockDOM2StdMd(html).trimEnd()); // 需要 trimEnd,否则 \n 会导致 https://github.com/siyuan-note/siyuan/issues/6218 - event.clipboardData.setData("text/html", protyle.lute.BlockDOM2HTML(html)); - event.clipboardData.setData("text/siyuan", html); + event.clipboardData.setData("text/html", protyle.lute.BlockDOM2HTML(html)); + event.clipboardData.setData("text/siyuan", html); }); let beforeContextmenuRange: Range;