From d517065f45430375c7160241ac8194fb4fc0d305 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Wed, 27 Mar 2024 11:32:35 +0800 Subject: [PATCH 01/87] :art: fix https://github.com/siyuan-note/siyuan/issues/10763 --- app/src/protyle/render/av/action.ts | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/app/src/protyle/render/av/action.ts b/app/src/protyle/render/av/action.ts index 70b0c36fbd..3d962c31bf 100644 --- a/app/src/protyle/render/av/action.ts +++ b/app/src/protyle/render/av/action.ts @@ -320,12 +320,18 @@ export const avContextmenu = (protyle: IProtyle, rowElement: HTMLElement, positi } menu.addItem({ icon: "iconBefore", - type: "readonly", label: `
-${window.siyuan.languages.insertRowBefore.replace("${x}", '')} +${window.siyuan.languages.insertRowBefore.replace("${x}", '')}
`, bind(element) { const inputElement = element.querySelector("input"); + element.addEventListener("click", () => { + if (document.activeElement.isSameNode(inputElement)) { + return; + } + insertRows(blockElement, protyle, parseInt(inputElement.value), rowElements[0].previousElementSibling.getAttribute("data-id")); + menu.close(); + }) inputElement.addEventListener("keydown", (event: KeyboardEvent) => { if (!event.isComposing && event.key === "Enter") { insertRows(blockElement, protyle, parseInt(inputElement.value), rowElements[0].previousElementSibling.getAttribute("data-id")); @@ -336,12 +342,18 @@ ${window.siyuan.languages.insertRowBefore.replace("${x}", ' -${window.siyuan.languages.insertRowAfter.replace("${x}", '')} +${window.siyuan.languages.insertRowAfter.replace("${x}", '')} `, bind(element) { const inputElement = element.querySelector("input"); + element.addEventListener("click", () => { + if (document.activeElement.isSameNode(inputElement)) { + return; + } + insertRows(blockElement, protyle, parseInt(inputElement.value), rowElements[0].getAttribute("data-id")); + menu.close(); + }); inputElement.addEventListener("keydown", (event: KeyboardEvent) => { if (!event.isComposing && event.key === "Enter") { insertRows(blockElement, protyle, parseInt(inputElement.value), rowElements[0].getAttribute("data-id")); From 284ec21b3be7496fae9b78c9b31462bbd8c51365 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Wed, 27 Mar 2024 11:45:09 +0800 Subject: [PATCH 02/87] :art: fix https://github.com/siyuan-note/siyuan/issues/10753 --- app/src/assets/scss/component/_menu.scss | 2 ++ app/src/protyle/breadcrumb/index.ts | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/src/assets/scss/component/_menu.scss b/app/src/assets/scss/component/_menu.scss index f8ceaadd06..10380fcafd 100644 --- a/app/src/assets/scss/component/_menu.scss +++ b/app/src/assets/scss/component/_menu.scss @@ -120,6 +120,8 @@ white-space: break-spaces; line-height: 26px; margin: 8px 0; + // 移动端面包屑过长 + word-wrap: break-word; } &__icon { diff --git a/app/src/protyle/breadcrumb/index.ts b/app/src/protyle/breadcrumb/index.ts index 6fa4a03488..8ecc8e543c 100644 --- a/app/src/protyle/breadcrumb/index.ts +++ b/app/src/protyle/breadcrumb/index.ts @@ -31,6 +31,7 @@ import {emitOpenMenu} from "../../plugin/EventBus"; import {isInAndroid, isIPad, isMac, updateHotkeyTip} from "../util/compatibility"; import {resize} from "../util/resize"; import {listIndent, listOutdent} from "../wysiwyg/list"; +import {escapeAttr, escapeHtml} from "../../util/escape"; export class Breadcrumb { public element: HTMLElement; @@ -243,7 +244,7 @@ ${padHTML} menu.addItem({ current: isCurrent, icon: getIconByType(item.type, item.subType), - label: item.name, + label: escapeHtml(item.name), click() { zoomOut({protyle, id: item.id, focusId: id}); } @@ -618,7 +619,7 @@ ${padHTML} } else { html += ` - ${item.name} + ${escapeHtml(item.name)} `; } if (index !== response.data.length - 1) { From 65d677984f230e3de906cf51342b9ba6de740d39 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Wed, 27 Mar 2024 18:35:19 +0800 Subject: [PATCH 03/87] :art: fix https://github.com/siyuan-note/siyuan/issues/10773 --- app/src/boot/globalEvent/keydown.ts | 2 +- app/src/card/openCard.ts | 82 +++++++++++++++++++++-------- 2 files changed, 62 insertions(+), 22 deletions(-) diff --git a/app/src/boot/globalEvent/keydown.ts b/app/src/boot/globalEvent/keydown.ts index c9c85d2f46..fd9a014b7a 100644 --- a/app/src/boot/globalEvent/keydown.ts +++ b/app/src/boot/globalEvent/keydown.ts @@ -368,7 +368,7 @@ const editKeydown = (app: App, event: KeyboardEvent) => { } if (!isFileFocus && matchHotKey(window.siyuan.config.keymap.editor.general.spaceRepetition.custom, event)) { fetchPost("/api/riff/getTreeRiffDueCards", {rootID: protyle.block.rootID}, (response) => { - openCardByData(app, response.data, "doc", protyle.block.rootID, protyle.title.editElement.textContent || window.siyuan.languages.untitled); + openCardByData(app, response.data, "doc", protyle.block.rootID, protyle.title?.editElement.textContent || window.siyuan.languages.untitled); }); event.preventDefault(); return true; diff --git a/app/src/card/openCard.ts b/app/src/card/openCard.ts index ccd6b8cbb2..bd30967932 100644 --- a/app/src/card/openCard.ts +++ b/app/src/card/openCard.ts @@ -13,6 +13,9 @@ import {escapeHtml} from "../util/escape"; /// #if !MOBILE import {openFile} from "../editor/util"; /// #endif +/// #if !BROWSER +import {ipcRenderer} from "electron"; +/// #endif import * as dayjs from "dayjs"; import {getDisplayName, movePathTo} from "../util/pathName"; import {App} from "../index"; @@ -84,8 +87,8 @@ export const genCardHTML = (options: {
-
- +
+
`; /// #endif @@ -406,7 +409,7 @@ export const bindCardEvent = async (options: { /// #if MOBILE menu.fullscreen(); /// #else - const rect = target.getBoundingClientRect(); + const rect = moreElement.getBoundingClientRect(); menu.open({ x: rect.left, y: rect.bottom @@ -417,25 +420,62 @@ export const bindCardEvent = async (options: { /// #if !MOBILE const sticktabElement = hasClosestByAttribute(target, "data-type", "sticktab"); if (sticktabElement) { - openFile({ - app: options.app, - position: "right", - custom: { - icon: "iconRiffCard", - title: window.siyuan.languages.spaceRepetition, - data: { - cardsData: options.cardsData, - index, - cardType: filterElement.getAttribute("data-cardtype") as TCardType, - id: docId, - title: options.title - }, - id: "siyuan-card" - }, + const stickMenu = new Menu(); + stickMenu.addItem({ + icon: "iconLayoutRight", + label: window.siyuan.languages.insertRight, + click() { + openFile({ + app: options.app, + position: "right", + custom: { + icon: "iconRiffCard", + title: window.siyuan.languages.spaceRepetition, + data: { + cardsData: options.cardsData, + index, + cardType: filterElement.getAttribute("data-cardtype") as TCardType, + id: docId, + title: options.title + }, + id: "siyuan-card" + }, + }); + options.dialog.destroy(); + } + }); + /// #if !BROWSER + stickMenu.addItem({ + icon: "iconOpenWindow", + label: window.siyuan.languages.openByNewWindow, + click() { + const json = { + "title": window.siyuan.languages.spaceRepetition, + "icon": "iconRiffCard", + "instance": "Tab", + "children": { + "instance": "Custom", + "customModelType": "siyuan-card", + "customModelData": { + "cardType": filterElement.getAttribute("data-cardtype"), + "id": docId, + "title": options.title + } + } + }; + ipcRenderer.send(Constants.SIYUAN_OPEN_WINDOW, { + // 需要 encode, 否则 https://github.com/siyuan-note/siyuan/issues/9343 + url: `${window.location.protocol}//${window.location.host}/stage/build/app/window.html?v=${Constants.SIYUAN_VERSION}&json=${encodeURIComponent(JSON.stringify(json))}` + }); + options.dialog.destroy(); + } + }); + /// #endif + const rect = sticktabElement.getBoundingClientRect(); + stickMenu.open({ + x: rect.left, + y: rect.bottom }); - if (options.dialog) { - options.dialog.destroy(); - } event.stopPropagation(); event.preventDefault(); return; From 92c72694bb00658c5354ff6c7574ae4c37b07d5b Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Wed, 27 Mar 2024 19:58:37 +0800 Subject: [PATCH 04/87] :bug: Fix insertBlock API argument check https://ld246.com/article/1711525429788 --- kernel/api/block_op.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/kernel/api/block_op.go b/kernel/api/block_op.go index 0839d21293..051e03ae5a 100644 --- a/kernel/api/block_op.go +++ b/kernel/api/block_op.go @@ -364,20 +364,26 @@ func insertBlock(c *gin.Context) { var parentID, previousID, nextID string if nil != arg["parentID"] { parentID = arg["parentID"].(string) - if util.InvalidIDPattern(parentID, ret) { - return + if "" != parentID { + if util.InvalidIDPattern(parentID, ret) { + return + } } } if nil != arg["previousID"] { previousID = arg["previousID"].(string) - if util.InvalidIDPattern(previousID, ret) { - return + if "" != previousID { + if util.InvalidIDPattern(previousID, ret) { + return + } } } if nil != arg["nextID"] { nextID = arg["nextID"].(string) - if util.InvalidIDPattern(nextID, ret) { - return + if "" != nextID { + if util.InvalidIDPattern(nextID, ret) { + return + } } } From 57d2cd14f02b054f374da8f5cc953a1d4c4ecb90 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Wed, 27 Mar 2024 20:11:04 +0800 Subject: [PATCH 05/87] :art: fix https://github.com/siyuan-note/siyuan/issues/10716 --- app/src/protyle/scroll/index.ts | 5 ++++- app/src/protyle/util/onGet.ts | 13 ++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/app/src/protyle/scroll/index.ts b/app/src/protyle/scroll/index.ts index 25a01e9ed3..8c1d9487b4 100644 --- a/app/src/protyle/scroll/index.ts +++ b/app/src/protyle/scroll/index.ts @@ -78,7 +78,7 @@ export class Scroll { }); } - public updateIndex(protyle: IProtyle, id: string) { + public updateIndex(protyle: IProtyle, id: string, cb?:(index: number) => void) { fetchPost("/api/block/getBlockIndex", {id}, (response) => { if (!response.data) { return; @@ -86,6 +86,9 @@ export class Scroll { const inputElement = protyle.scroll.element.querySelector(".b3-slider") as HTMLInputElement; inputElement.value = response.data; protyle.scroll.element.setAttribute("aria-label", `Blocks ${response.data}/${protyle.block.blockCount}`); + if (cb) { + cb(response.data); + } }); } diff --git a/app/src/protyle/util/onGet.ts b/app/src/protyle/util/onGet.ts index 0a789f426f..f73ed6757c 100644 --- a/app/src/protyle/util/onGet.ts +++ b/app/src/protyle/util/onGet.ts @@ -254,11 +254,14 @@ const setHTML = (options: { } if (options.scrollAttr && !protyle.scroll.element.classList.contains("fn__none") && !protyle.element.classList.contains("fn__none")) { // 使用动态滚动条定位到最后一个块,重启后无法触发滚动事件,需要再次更新 index - protyle.scroll.updateIndex(protyle, options.scrollAttr.startId); - // https://github.com/siyuan-note/siyuan/issues/8224 - if (protyle.contentElement.scrollHeight <= protyle.contentElement.clientHeight) { - showMessage(window.siyuan.languages.scrollGetMore); - } + protyle.scroll.updateIndex(protyle, options.scrollAttr.startId, (index) => { + // https://github.com/siyuan-note/siyuan/issues/8224 + // https://github.com/siyuan-note/siyuan/issues/10716 + if (index > 1 && protyle.block.blockCount > 1 && protyle.contentElement.scrollHeight <= protyle.contentElement.clientHeight) { + showMessage(window.siyuan.languages.scrollGetMore); + } + }); + } protyle.app.plugins.forEach(item => { item.eventBus.emit("loaded-protyle", protyle); // 准备废弃 From 53b62fe5f43277a3a612fcbc596fcd2efb21c4ba Mon Sep 17 00:00:00 2001 From: Vanessa Date: Wed, 27 Mar 2024 20:24:15 +0800 Subject: [PATCH 06/87] :art: fix https://github.com/siyuan-note/siyuan/issues/10766 --- app/src/mobile/editor.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/mobile/editor.ts b/app/src/mobile/editor.ts index 055946fe05..f2d70e6611 100644 --- a/app/src/mobile/editor.ts +++ b/app/src/mobile/editor.ts @@ -94,5 +94,8 @@ export const openMobileFileById = (app: App, id: string, action = [Constants.CB_ (document.getElementById("toolbarName") as HTMLInputElement).value = data.data.rootTitle === window.siyuan.languages.untitled ? "" : data.data.rootTitle; setEditor(); closePanel(); + app.plugins.forEach(item => { + item.eventBus.emit("switch-protyle", {protyle: window.siyuan.mobile.editor.protyle}); + }); }); }; From 24c59dd0956874df7f5d7e8aa057896f296d8290 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Wed, 27 Mar 2024 20:42:09 +0800 Subject: [PATCH 07/87] :bug: Fix insertBlock API argument check https://ld246.com/article/1711525429788 --- kernel/api/block_op.go | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/kernel/api/block_op.go b/kernel/api/block_op.go index 051e03ae5a..829c266a00 100644 --- a/kernel/api/block_op.go +++ b/kernel/api/block_op.go @@ -222,13 +222,13 @@ func moveBlock(c *gin.Context) { var parentID, previousID string if nil != arg["parentID"] { parentID = arg["parentID"].(string) - if util.InvalidIDPattern(parentID, ret) { + if "" != parentID && util.InvalidIDPattern(parentID, ret) { return } } if nil != arg["previousID"] { previousID = arg["previousID"].(string) - if util.InvalidIDPattern(previousID, ret) { + if "" != previousID && util.InvalidIDPattern(previousID, ret) { return } @@ -364,26 +364,20 @@ func insertBlock(c *gin.Context) { var parentID, previousID, nextID string if nil != arg["parentID"] { parentID = arg["parentID"].(string) - if "" != parentID { - if util.InvalidIDPattern(parentID, ret) { - return - } + if "" != parentID && util.InvalidIDPattern(parentID, ret) { + return } } if nil != arg["previousID"] { previousID = arg["previousID"].(string) - if "" != previousID { - if util.InvalidIDPattern(previousID, ret) { - return - } + if "" != previousID && util.InvalidIDPattern(parentID, ret) { + return } } if nil != arg["nextID"] { nextID = arg["nextID"].(string) - if "" != nextID { - if util.InvalidIDPattern(nextID, ret) { - return - } + if "" != nextID && util.InvalidIDPattern(parentID, ret) { + return } } From 611f6e2da0451a77efad5f8d30305217eacefdfb Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Wed, 27 Mar 2024 22:15:52 +0800 Subject: [PATCH 08/87] :art: The outline item in the outline panel supports dragging to adjust the level and position https://github.com/siyuan-note/siyuan/issues/7957 --- kernel/api/block_op.go | 48 ++++++++++++++++++ kernel/api/router.go | 1 + kernel/model/outline.go | 97 +++++++++++++++++++++++++++++++++++++ kernel/model/transaction.go | 2 + 4 files changed, 148 insertions(+) diff --git a/kernel/api/block_op.go b/kernel/api/block_op.go index 829c266a00..0e0b32cdea 100644 --- a/kernel/api/block_op.go +++ b/kernel/api/block_op.go @@ -32,6 +32,54 @@ import ( "github.com/siyuan-note/siyuan/kernel/util" ) +func moveOutlineHeading(c *gin.Context) { + ret := gulu.Ret.NewResult() + defer c.JSON(http.StatusOK, ret) + + arg, ok := util.JsonArg(c, ret) + if !ok { + return + } + + id := arg["id"].(string) + if util.InvalidIDPattern(id, ret) { + return + } + + var parentID, previousID string + if nil != arg["parentID"] { + parentID = arg["parentID"].(string) + if "" != parentID && util.InvalidIDPattern(parentID, ret) { + return + } + } + if nil != arg["previousID"] { + previousID = arg["previousID"].(string) + if "" != previousID && util.InvalidIDPattern(previousID, ret) { + return + } + } + + transactions := []*model.Transaction{ + { + DoOperations: []*model.Operation{ + { + Action: "moveOutlineHeading", + ID: id, + PreviousID: previousID, + ParentID: parentID, + }, + }, + }, + } + + model.PerformTransactions(&transactions) + model.WaitForWritingFiles() + + ret.Data = transactions + broadcastTransactions(transactions) +} + func appendDailyNoteBlock(c *gin.Context) { ret := gulu.Ret.NewResult() defer c.JSON(http.StatusOK, ret) diff --git a/kernel/api/router.go b/kernel/api/router.go index e42551a04d..0b6e89593c 100644 --- a/kernel/api/router.go +++ b/kernel/api/router.go @@ -188,6 +188,7 @@ func ServeAPI(ginServer *gin.Engine) { ginServer.Handle("POST", "/api/block/updateBlock", model.CheckAuth, model.CheckReadonly, updateBlock) ginServer.Handle("POST", "/api/block/deleteBlock", model.CheckAuth, model.CheckReadonly, deleteBlock) ginServer.Handle("POST", "/api/block/moveBlock", model.CheckAuth, model.CheckReadonly, moveBlock) + ginServer.Handle("POST", "/api/block/moveOutlineHeading", model.CheckAuth, model.CheckReadonly, moveOutlineHeading) ginServer.Handle("POST", "/api/block/foldBlock", model.CheckAuth, model.CheckReadonly, foldBlock) ginServer.Handle("POST", "/api/block/unfoldBlock", model.CheckAuth, model.CheckReadonly, unfoldBlock) ginServer.Handle("POST", "/api/block/setBlockReminder", model.CheckAuth, model.CheckReadonly, setBlockReminder) diff --git a/kernel/model/outline.go b/kernel/model/outline.go index ea8ba9a0d3..9d519821a5 100644 --- a/kernel/model/outline.go +++ b/kernel/model/outline.go @@ -26,6 +26,103 @@ import ( "github.com/siyuan-note/siyuan/kernel/util" ) +func (tx *Transaction) doMoveOutlineHeading(operation *Operation) (ret *TxErr) { + headingID := operation.ID + previousID := operation.PreviousID + parentID := operation.ParentID + + if headingID == parentID || headingID == previousID { + return + } + + tree, err := tx.loadTree(headingID) + if nil != err { + return &TxErr{code: TxErrCodeBlockNotFound, id: headingID} + } + + heading := treenode.GetNodeInTree(tree, headingID) + if nil == heading { + return &TxErr{code: TxErrCodeBlockNotFound, id: headingID} + } + + headings := []*ast.Node{} + ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus { + if entering && ast.NodeHeading == n.Type && !n.ParentIs(ast.NodeBlockquote) { + headings = append(headings, n) + } + return ast.WalkContinue + }) + + headingChildren := treenode.HeadingChildren(heading) + if "" != previousID { + previousHeading := treenode.GetNodeInTree(tree, previousID) + if nil == previousHeading { + return &TxErr{code: TxErrCodeBlockNotFound, id: previousID} + } + + targetNode := previousHeading + previousHeadingChildren := treenode.HeadingChildren(previousHeading) + if 0 < len(previousHeadingChildren) { + for _, child := range previousHeadingChildren { + targetNode = child + if child.ID == headingID { + break + } + } + } + + diffLevel := heading.HeadingLevel - previousHeading.HeadingLevel + heading.HeadingLevel = previousHeading.HeadingLevel + + for i := len(headingChildren) - 1; i >= 0; i-- { + child := headingChildren[i] + if ast.NodeHeading == child.Type { + child.HeadingLevel -= diffLevel + } + targetNode.InsertAfter(child) + } + targetNode.InsertAfter(heading) + } else if "" != parentID { + parentHeading := treenode.GetNodeInTree(tree, parentID) + if nil == parentHeading { + return &TxErr{code: TxErrCodeBlockNotFound, id: parentID} + } + + targetNode := parentHeading + parentHeadingChildren := treenode.HeadingChildren(parentHeading) + if 0 < len(parentHeadingChildren) { + for _, child := range parentHeadingChildren { + targetNode = child + if child.ID == headingID { + break + } + } + } + + diffLevel := heading.HeadingLevel - parentHeading.HeadingLevel + heading.HeadingLevel = parentHeading.HeadingLevel + 1 + if 6 < heading.HeadingLevel { + heading.HeadingLevel = 6 + } + + for i := len(headingChildren) - 1; i >= 0; i-- { + child := headingChildren[i] + if ast.NodeHeading == child.Type { + child.HeadingLevel -= diffLevel + } + targetNode.InsertAfter(child) + } + targetNode.InsertAfter(heading) + } else { + return + } + + if err = tx.writeTree(tree); nil != err { + return + } + return +} + func Outline(rootID string) (ret []*Path, err error) { time.Sleep(util.FrontendQueueInterval) WaitForWritingFiles() diff --git a/kernel/model/transaction.go b/kernel/model/transaction.go index 88c356d2e8..5d2e07f162 100644 --- a/kernel/model/transaction.go +++ b/kernel/model/transaction.go @@ -195,6 +195,8 @@ func performTx(tx *Transaction) (ret *TxErr) { ret = tx.doDelete(op) case "move": ret = tx.doMove(op) + case "moveOutlineHeading": + ret = tx.doMoveOutlineHeading(op) case "append": ret = tx.doAppend(op) case "appendInsert": From f2f112cebe8fe74bbefeef1b1f879d3e5565037f Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Wed, 27 Mar 2024 22:26:47 +0800 Subject: [PATCH 09/87] :art: The outline item in the outline panel supports dragging to adjust the level and position https://github.com/siyuan-note/siyuan/issues/7957 --- kernel/model/outline.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/kernel/model/outline.go b/kernel/model/outline.go index 9d519821a5..464bc0ebb1 100644 --- a/kernel/model/outline.go +++ b/kernel/model/outline.go @@ -64,13 +64,17 @@ func (tx *Transaction) doMoveOutlineHeading(operation *Operation) (ret *TxErr) { previousHeadingChildren := treenode.HeadingChildren(previousHeading) if 0 < len(previousHeadingChildren) { for _, child := range previousHeadingChildren { - targetNode = child if child.ID == headingID { break } + targetNode = child } } + if targetNode == heading.Previous { + return + } + diffLevel := heading.HeadingLevel - previousHeading.HeadingLevel heading.HeadingLevel = previousHeading.HeadingLevel @@ -92,10 +96,16 @@ func (tx *Transaction) doMoveOutlineHeading(operation *Operation) (ret *TxErr) { parentHeadingChildren := treenode.HeadingChildren(parentHeading) if 0 < len(parentHeadingChildren) { for _, child := range parentHeadingChildren { - targetNode = child if child.ID == headingID { break } + targetNode = child + } + } + + if targetNode == heading.Previous { + if parentHeading.HeadingLevel < heading.HeadingLevel { + return } } From 1f70336b41aaed7c7ea8112246946b2582798024 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Wed, 27 Mar 2024 22:30:44 +0800 Subject: [PATCH 10/87] :art: The outline item in the outline panel supports dragging to adjust the level and position https://github.com/siyuan-note/siyuan/issues/7957 --- kernel/model/outline.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kernel/model/outline.go b/kernel/model/outline.go index 464bc0ebb1..027fad24bd 100644 --- a/kernel/model/outline.go +++ b/kernel/model/outline.go @@ -72,7 +72,9 @@ func (tx *Transaction) doMoveOutlineHeading(operation *Operation) (ret *TxErr) { } if targetNode == heading.Previous { - return + if previousHeading.HeadingLevel >= heading.HeadingLevel { + return + } } diffLevel := heading.HeadingLevel - previousHeading.HeadingLevel From 0b20f85793176858ebbadd71b346242681644b98 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Wed, 27 Mar 2024 22:50:03 +0800 Subject: [PATCH 11/87] :art: The outline item in the outline panel supports dragging to adjust the level and position https://github.com/siyuan-note/siyuan/issues/7957 --- kernel/model/outline.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/kernel/model/outline.go b/kernel/model/outline.go index 027fad24bd..2f367c33e1 100644 --- a/kernel/model/outline.go +++ b/kernel/model/outline.go @@ -84,6 +84,9 @@ func (tx *Transaction) doMoveOutlineHeading(operation *Operation) (ret *TxErr) { child := headingChildren[i] if ast.NodeHeading == child.Type { child.HeadingLevel -= diffLevel + if 6 < child.HeadingLevel { + child.HeadingLevel = 6 + } } targetNode.InsertAfter(child) } @@ -111,7 +114,7 @@ func (tx *Transaction) doMoveOutlineHeading(operation *Operation) (ret *TxErr) { } } - diffLevel := heading.HeadingLevel - parentHeading.HeadingLevel + diffLevel := 1 heading.HeadingLevel = parentHeading.HeadingLevel + 1 if 6 < heading.HeadingLevel { heading.HeadingLevel = 6 @@ -120,7 +123,10 @@ func (tx *Transaction) doMoveOutlineHeading(operation *Operation) (ret *TxErr) { for i := len(headingChildren) - 1; i >= 0; i-- { child := headingChildren[i] if ast.NodeHeading == child.Type { - child.HeadingLevel -= diffLevel + child.HeadingLevel += diffLevel + if 6 < child.HeadingLevel { + child.HeadingLevel = 6 + } } targetNode.InsertAfter(child) } From 5c6dec485fc8c6b9c40c896af7d8afe11928b2ce Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Wed, 27 Mar 2024 23:04:42 +0800 Subject: [PATCH 12/87] :art: Improve the handling of empty values in database multi-field sorting https://github.com/siyuan-note/siyuan/issues/10758 --- kernel/av/table.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/kernel/av/table.go b/kernel/av/table.go index 0930b01eb9..9d7ef8f99b 100644 --- a/kernel/av/table.go +++ b/kernel/av/table.go @@ -173,25 +173,25 @@ func (table *Table) SortRows(attrView *AttributeView) { } } - includeUneditedRows := map[string]bool{} + editedValRows := map[string]bool{} for i, row := range table.Rows { for _, colIndexSort := range colIndexSorts { val := table.Rows[i].Cells[colIndexSort.Index].Value - if !val.IsEdited() { - // 如果该行的某个列的值是未编辑的,则该行不参与排序 - includeUneditedRows[row.ID] = true + if val.IsEdited() { + // 如果该行某列的值已经编辑过,则该行可参与排序 + editedValRows[row.ID] = true break } } } - // 将包含未编辑的行和全部已编辑的行分开排序 + // 将未编辑的行和已编辑的行分开排序 var uneditedRows, editedRows []*TableRow for _, row := range table.Rows { - if _, ok := includeUneditedRows[row.ID]; ok { - uneditedRows = append(uneditedRows, row) - } else { + if _, ok := editedValRows[row.ID]; ok { editedRows = append(editedRows, row) + } else { + uneditedRows = append(uneditedRows, row) } } From 58f79964ff7aa221363044a8665dd8bcbbdacbca Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Thu, 28 Mar 2024 09:23:29 +0800 Subject: [PATCH 13/87] :art: Improve the handling of empty values in database multi-field sorting https://github.com/siyuan-note/siyuan/issues/10758 --- kernel/av/sort.go | 48 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/kernel/av/sort.go b/kernel/av/sort.go index 681ea7fc7d..ad6b6d1a4e 100644 --- a/kernel/av/sort.go +++ b/kernel/av/sort.go @@ -48,13 +48,21 @@ func (value *Value) Compare(other *Value, attrView *AttributeView) int { } case KeyTypeText: if nil != value.Text && nil != other.Text { + if "" == value.Text.Content { + if "" == other.Text.Content { + return 0 + } + return 1 + } else if "" == other.Text.Content { + return -1 + } return strings.Compare(value.Text.Content, other.Text.Content) } case KeyTypeNumber: if nil != value.Number && nil != other.Number { if value.Number.IsNotEmpty { if !other.Number.IsNotEmpty { - return 1 + return -1 } if value.Number.Content > other.Number.Content { @@ -65,17 +73,17 @@ func (value *Value) Compare(other *Value, attrView *AttributeView) int { } return 0 } else { - if other.Number.IsNotEmpty { - return -1 + if !other.Number.IsNotEmpty { + return 0 } - return 0 + return 1 } } case KeyTypeDate: if nil != value.Date && nil != other.Date { if value.Date.IsNotEmpty { if !other.Date.IsNotEmpty { - return 1 + return -1 } if value.Date.Content > other.Date.Content { return 1 @@ -85,10 +93,10 @@ func (value *Value) Compare(other *Value, attrView *AttributeView) int { } return 0 } else { - if other.Date.IsNotEmpty { - return -1 + if !other.Date.IsNotEmpty { + return 0 } - return 0 + return 1 } } case KeyTypeCreated: @@ -140,14 +148,38 @@ func (value *Value) Compare(other *Value, attrView *AttributeView) int { } case KeyTypeURL: if nil != value.URL && nil != other.URL { + if "" == value.URL.Content { + if "" == other.URL.Content { + return 0 + } + return 1 + } else if "" == other.URL.Content { + return -1 + } return strings.Compare(value.URL.Content, other.URL.Content) } case KeyTypeEmail: if nil != value.Email && nil != other.Email { + if "" == value.Email.Content { + if "" == other.Email.Content { + return 0 + } + return 1 + } else if "" == other.Email.Content { + return -1 + } return strings.Compare(value.Email.Content, other.Email.Content) } case KeyTypePhone: if nil != value.Phone && nil != other.Phone { + if "" == value.Phone.Content { + if "" == other.Phone.Content { + return 0 + } + return 1 + } else if "" == other.Phone.Content { + return -1 + } return strings.Compare(value.Phone.Content, other.Phone.Content) } case KeyTypeMAsset: From d2c0f57ceb64148570b0512a2de6df2ee9e59b20 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Thu, 28 Mar 2024 10:05:06 +0800 Subject: [PATCH 14/87] :art: fix https://github.com/siyuan-note/siyuan/issues/10712 --- app/src/assets/scss/business/_av.scss | 2 +- app/src/protyle/render/av/cell.ts | 52 +++++++++++++++++---------- 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/app/src/assets/scss/business/_av.scss b/app/src/assets/scss/business/_av.scss index 54d6b958b6..2698076b86 100644 --- a/app/src/assets/scss/business/_av.scss +++ b/app/src/assets/scss/business/_av.scss @@ -225,7 +225,7 @@ &__cell { box-sizing: border-box; position: relative; - padding: 5px; + padding: 5px 8px; flex-shrink: 0; border-right: 1px solid var(--b3-theme-surface-lighter); overflow: hidden; diff --git a/app/src/protyle/render/av/cell.ts b/app/src/protyle/render/av/cell.ts index 0e144aaf1d..d53a450957 100644 --- a/app/src/protyle/render/av/cell.ts +++ b/app/src/protyle/render/av/cell.ts @@ -13,6 +13,23 @@ import {genAVValueHTML} from "./blockAttr"; import {Constants} from "../../../constants"; import {hintRef} from "../../hint/extend"; +const renderCellURL = (urlContent: string) => { + let host = urlContent; + let suffix = "" + try { + const urlObj = new URL(urlContent); + host = urlObj.host; + suffix = urlObj.href.replace(urlObj.origin, "") + if (suffix.length > 12) { + suffix = suffix.substring(0, 4) + "..." + suffix.substring(suffix.length - 6); + } + } catch (e) { + // 不是 url 地址 + } + // https://github.com/siyuan-note/siyuan/issues/9291 + return `${host}${suffix}`; +}; + export const getCellText = (cellElement: HTMLElement | false) => { if (!cellElement) { return ""; @@ -48,7 +65,7 @@ export const genCellValueByElement = (colType: TAVCol, cellElement: HTMLElement) } else if (["text", "block", "url", "phone", "email", "template"].includes(colType)) { const textElement = cellElement.querySelector(".av__celltext") as HTMLElement; cellValue[colType as "text"] = { - content: textElement.textContent + content: colType === "url" ? textElement.dataset.href : textElement.textContent }; if (colType === "block" && textElement.dataset.id) { cellValue.block.id = textElement.dataset.id; @@ -319,8 +336,10 @@ export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[], type } } const style = `style="padding-top: 6.5px;position:absolute;left: ${cellRect.left}px;top: ${cellRect.top}px;width:${Math.max(cellRect.width, 25)}px;height: ${height}px"`; - if (["text", "url", "email", "phone", "block", "template"].includes(type)) { + if (["text", "email", "phone", "block", "template"].includes(type)) { html = ``; + } else if (type === "url") { + html = ``; } else if (type === "number") { html = ``; } else { @@ -512,7 +531,7 @@ export const updateCellsValue = (protyle: IProtyle, nodeElement: HTMLElement, va text += getCellText(item) + ((cellElements[elementIndex + 1] && item.nextElementSibling && item.nextElementSibling.isSameNode(cellElements[elementIndex + 1])) ? "\t" : "\n\n"); const oldValue = genCellValueByElement(type, item); if (elementIndex === 0 || !cellElements[elementIndex - 1].isSameNode(item.previousElementSibling)) { - json.push([]); + json.push([]); } json[json.length - 1].push(oldValue); // relation 为全部更新,以下类型为添加 @@ -600,14 +619,10 @@ export const renderCell = (cellValue: IAVCellValue) => { let text = ""; if (["text", "template"].includes(cellValue.type)) { text = `${cellValue ? (cellValue[cellValue.type as "text"].content || "") : ""}`; - } else if (["url", "email", "phone"].includes(cellValue.type)) { - const urlContent = cellValue ? cellValue[cellValue.type as "url"].content : ""; - // https://github.com/siyuan-note/siyuan/issues/9291 - let urlAttr = ""; - if (cellValue.type === "url") { - urlAttr = ` data-href="${urlContent}"`; - } - text = `${urlContent}`; + } else if (["email", "phone"].includes(cellValue.type)) { + text = `${cellValue ? cellValue[cellValue.type as "email"].content : ""}`; + } else if ("url" === cellValue.type) { + text = renderCellURL(cellValue?.url?.content || "") } else if (cellValue.type === "block") { if (cellValue?.isDetached) { text = `${cellValue.block.content || ""} @@ -680,14 +695,15 @@ const renderRollup = (cellValue: IAVCellValue) => { let text = ""; if (["text"].includes(cellValue.type)) { text = cellValue ? (cellValue[cellValue.type as "text"].content || "") : ""; - } else if (["url", "email", "phone"].includes(cellValue.type)) { - const urlContent = cellValue ? cellValue[cellValue.type as "url"].content : ""; + } else if (["email", "phone"].includes(cellValue.type)) { + const emailContent = cellValue ? cellValue[cellValue.type as "email"].content : ""; + if (emailContent) { + text = `${emailContent}`; + } + } else if ("url" === cellValue.type) { + const urlContent = cellValue?.url?.content || "" if (urlContent) { - let urlAttr = ""; - if (cellValue.type === "url") { - urlAttr = ` data-href="${urlContent}"`; - } - text = `${urlContent}`; + text = renderCellURL(urlContent); } } else if (cellValue.type === "block") { if (cellValue?.isDetached) { From 8540113527a15d5af2e784cb9b208a77bbaeab69 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Thu, 28 Mar 2024 10:35:02 +0800 Subject: [PATCH 15/87] :art: Improve response details for auth check https://ld246.com/article/1711591523782 --- kernel/model/session.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/model/session.go b/kernel/model/session.go index 80dbdcd9f4..d3d80dc264 100644 --- a/kernel/model/session.go +++ b/kernel/model/session.go @@ -242,7 +242,7 @@ func CheckAuth(c *gin.Context) { return } - c.JSON(http.StatusUnauthorized, map[string]interface{}{"code": -1, "msg": "Auth failed"}) + c.JSON(http.StatusUnauthorized, map[string]interface{}{"code": -1, "msg": "Auth failed [header: Authorization]"}) c.Abort() return } @@ -255,7 +255,7 @@ func CheckAuth(c *gin.Context) { return } - c.JSON(http.StatusUnauthorized, map[string]interface{}{"code": -1, "msg": "Auth failed"}) + c.JSON(http.StatusUnauthorized, map[string]interface{}{"code": -1, "msg": "Auth failed [query: token]"}) c.Abort() return } @@ -285,7 +285,7 @@ func CheckAuth(c *gin.Context) { return } - c.JSON(http.StatusUnauthorized, map[string]interface{}{"code": -1, "msg": "Auth failed"}) + c.JSON(http.StatusUnauthorized, map[string]interface{}{"code": -1, "msg": "Auth failed [session]"}) c.Abort() return } From df6ee063a372eed73f4434358f3e24b32cef55c1 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Thu, 28 Mar 2024 11:08:42 +0800 Subject: [PATCH 16/87] :lipstick: fix https://github.com/siyuan-note/siyuan/issues/10731 --- app/src/protyle/gutter/index.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/src/protyle/gutter/index.ts b/app/src/protyle/gutter/index.ts index 83a2f96f72..9c7fa4c1d4 100644 --- a/app/src/protyle/gutter/index.ts +++ b/app/src/protyle/gutter/index.ts @@ -2139,10 +2139,12 @@ data-type="fold"> Date: Thu, 28 Mar 2024 11:27:02 +0800 Subject: [PATCH 17/87] :art: Automatically loads and indexes from the file system when a block is not found https://github.com/siyuan-note/siyuan/issues/10772 --- kernel/model/tree.go | 60 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/kernel/model/tree.go b/kernel/model/tree.go index 659b323aa9..aede8e6c5a 100644 --- a/kernel/model/tree.go +++ b/kernel/model/tree.go @@ -18,8 +18,8 @@ package model import ( "errors" - "github.com/siyuan-note/siyuan/kernel/task" "io/fs" + "os" "path" "path/filepath" "strings" @@ -31,6 +31,8 @@ import ( "github.com/siyuan-note/filelock" "github.com/siyuan-note/logging" "github.com/siyuan-note/siyuan/kernel/filesys" + "github.com/siyuan-note/siyuan/kernel/sql" + "github.com/siyuan-note/siyuan/kernel/task" "github.com/siyuan-note/siyuan/kernel/treenode" "github.com/siyuan-note/siyuan/kernel/util" ) @@ -162,10 +164,64 @@ func LoadTreeByBlockID(id string) (ret *parse.Tree, err error) { return } - return nil, ErrBlockNotFound + // 尝试从文件系统加载 + searchTreeInFilesystem(id) + bt = treenode.GetBlockTree(id) + if nil == bt { + return nil, ErrTreeNotFound + } } luteEngine := util.NewLute() ret, err = filesys.LoadTree(bt.BoxID, bt.Path, luteEngine) return } + +func searchTreeInFilesystem(rootID string) { + msdID := util.PushMsg(Conf.language(45), 7000) + defer util.PushClearMsg(msdID) + + var treePath string + filepath.Walk(util.DataDir, func(path string, info fs.FileInfo, err error) error { + if info.IsDir() { + if strings.HasPrefix(info.Name(), ".") { + return filepath.SkipDir + } + return nil + } + + if !strings.HasSuffix(info.Name(), ".sy") { + return nil + } + + baseName := filepath.Base(path) + if rootID+".sy" != baseName { + return nil + } + + treePath = path + return filepath.SkipAll + }) + + if "" == treePath { + return + } + + boxID := strings.TrimPrefix(treePath, util.DataDir) + boxID = boxID[1:] + boxID = boxID[:strings.Index(boxID, string(os.PathSeparator))] + treePath = strings.TrimPrefix(treePath, util.DataDir) + treePath = strings.TrimPrefix(treePath, string(os.PathSeparator)) + treePath = strings.TrimPrefix(treePath, boxID) + treePath = filepath.ToSlash(treePath) + + tree, err := filesys.LoadTree(boxID, treePath, util.NewLute()) + if nil != err { + logging.LogErrorf("load tree [%s] failed: %s", treePath, err) + return + } + + treenode.IndexBlockTree(tree) + sql.IndexTreeQueue(tree) + sql.WaitForWritingDatabase() +} From 50eef7d1e620d12e2f5906dc95d320c2ba65eb01 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Thu, 28 Mar 2024 11:35:09 +0800 Subject: [PATCH 18/87] :art: Automatically loads and indexes from the file system when a block is not found https://github.com/siyuan-note/siyuan/issues/10772 --- kernel/model/tree.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/model/tree.go b/kernel/model/tree.go index aede8e6c5a..54f98d8500 100644 --- a/kernel/model/tree.go +++ b/kernel/model/tree.go @@ -181,6 +181,7 @@ func searchTreeInFilesystem(rootID string) { msdID := util.PushMsg(Conf.language(45), 7000) defer util.PushClearMsg(msdID) + logging.LogWarnf("searching tree on filesystem [rootID=%s]", rootID) var treePath string filepath.Walk(util.DataDir, func(path string, info fs.FileInfo, err error) error { if info.IsDir() { @@ -204,6 +205,7 @@ func searchTreeInFilesystem(rootID string) { }) if "" == treePath { + logging.LogErrorf("tree not found on filesystem [rootID=%s]", rootID) return } @@ -224,4 +226,5 @@ func searchTreeInFilesystem(rootID string) { treenode.IndexBlockTree(tree) sql.IndexTreeQueue(tree) sql.WaitForWritingDatabase() + logging.LogInfof("reindexed tree by filesystem [rootID=%s]", rootID) } From 35969c4bdfccfd48cdd716cdbdde5eab2970fcb0 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Thu, 28 Mar 2024 11:35:38 +0800 Subject: [PATCH 19/87] :art: fix https://github.com/siyuan-note/siyuan/issues/10702 --- app/src/protyle/wysiwyg/keydown.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/protyle/wysiwyg/keydown.ts b/app/src/protyle/wysiwyg/keydown.ts index e229ec3147..feec26d010 100644 --- a/app/src/protyle/wysiwyg/keydown.ts +++ b/app/src/protyle/wysiwyg/keydown.ts @@ -519,10 +519,10 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => { // 向上/下滚动一屏 if (!event.altKey && !event.shiftKey && isNotCtrl(event) && (event.key === "PageUp" || event.key === "PageDown")) { if (event.key === "PageUp") { - protyle.contentElement.scrollTop = protyle.contentElement.scrollTop - protyle.contentElement.clientHeight; + protyle.contentElement.scrollTop = protyle.contentElement.scrollTop - protyle.contentElement.clientHeight + 60; protyle.scroll.lastScrollTop = protyle.contentElement.scrollTop + 1; } else { - protyle.contentElement.scrollTop = protyle.contentElement.scrollTop + protyle.contentElement.clientHeight; + protyle.contentElement.scrollTop = protyle.contentElement.scrollTop + protyle.contentElement.clientHeight - 60; protyle.scroll.lastScrollTop = protyle.contentElement.scrollTop - 1; } const contentRect = protyle.contentElement.getBoundingClientRect(); From 62cc60c93436638c34359c16436cc41c8f6a760c Mon Sep 17 00:00:00 2001 From: Vanessa Date: Thu, 28 Mar 2024 16:36:37 +0800 Subject: [PATCH 20/87] =?UTF-8?q?:art:=20=E8=AF=B4=E6=98=AF=E5=90=8E?= =?UTF-8?q?=E7=AB=AF=E5=BC=84=20https://github.com/siyuan-note/siyuan/issu?= =?UTF-8?q?es/10753?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/protyle/breadcrumb/index.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/src/protyle/breadcrumb/index.ts b/app/src/protyle/breadcrumb/index.ts index 8ecc8e543c..6fa4a03488 100644 --- a/app/src/protyle/breadcrumb/index.ts +++ b/app/src/protyle/breadcrumb/index.ts @@ -31,7 +31,6 @@ import {emitOpenMenu} from "../../plugin/EventBus"; import {isInAndroid, isIPad, isMac, updateHotkeyTip} from "../util/compatibility"; import {resize} from "../util/resize"; import {listIndent, listOutdent} from "../wysiwyg/list"; -import {escapeAttr, escapeHtml} from "../../util/escape"; export class Breadcrumb { public element: HTMLElement; @@ -244,7 +243,7 @@ ${padHTML} menu.addItem({ current: isCurrent, icon: getIconByType(item.type, item.subType), - label: escapeHtml(item.name), + label: item.name, click() { zoomOut({protyle, id: item.id, focusId: id}); } @@ -619,7 +618,7 @@ ${padHTML} } else { html += ` - ${escapeHtml(item.name)} + ${item.name} `; } if (index !== response.data.length - 1) { From 42967694efde3352242b6803eb0bccef6f8867a0 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Thu, 28 Mar 2024 16:57:24 +0800 Subject: [PATCH 21/87] :bug: Breadcrumb XSS https://github.com/siyuan-note/siyuan/issues/10753 --- kernel/model/blockinfo.go | 3 +++ kernel/util/misc.go | 23 +++++++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/kernel/model/blockinfo.go b/kernel/model/blockinfo.go index 5b3ac3cc4d..44c9111d42 100644 --- a/kernel/model/blockinfo.go +++ b/kernel/model/blockinfo.go @@ -366,6 +366,7 @@ func buildBlockBreadcrumb(node *ast.Node, excludeTypes []string) (ret []*BlockPa name = util.EscapeHTML(box.Name) + util.EscapeHTML(hPath) } else if ast.NodeAttributeView == parent.Type { name = treenode.GetAttributeViewName(parent.AttributeViewID) + name = util.EscapeHTML(name) } else { if "" == name { if ast.NodeListItem == parent.Type { @@ -373,6 +374,7 @@ func buildBlockBreadcrumb(node *ast.Node, excludeTypes []string) (ret []*BlockPa } else { name = gulu.Str.SubStr(renderBlockText(parent, excludeTypes), maxNameLen) } + name = util.EscapeHTML(name) } if ast.NodeHeading == parent.Type { headingLevel = parent.HeadingLevel @@ -389,6 +391,7 @@ func buildBlockBreadcrumb(node *ast.Node, excludeTypes []string) (ret []*BlockPa if ast.NodeListItem == parent.Type { if "" == name { name = gulu.Str.SubStr(renderBlockText(fc, excludeTypes), maxNameLen) + name = util.EscapeHTML(name) } } diff --git a/kernel/util/misc.go b/kernel/util/misc.go index b15015c95c..6ef47299f2 100644 --- a/kernel/util/misc.go +++ b/kernel/util/misc.go @@ -42,11 +42,26 @@ func RemoveElem[T any](s []T, index int) []T { return append(s[:index], s[index+1:]...) } -func EscapeHTML(s string) string { - if ContainsSubStr(s, []string{"&", "'", "<", ">", """, " "}) { - return s +func EscapeHTML(s string) (ret string) { + ret = s + if "" == strings.TrimSpace(ret) { + return } - return html.EscapeString(s) + + ret = strings.ReplaceAll(ret, "&", "__@amp__") + ret = strings.ReplaceAll(ret, "'", "__@39__") + ret = strings.ReplaceAll(ret, "<", "__@lt__") + ret = strings.ReplaceAll(ret, ">", "__@gt__") + ret = strings.ReplaceAll(ret, """, "__@34__") + ret = strings.ReplaceAll(ret, " ", "__@13__") + ret = html.EscapeString(ret) + ret = strings.ReplaceAll(ret, "__@amp__", "&") + ret = strings.ReplaceAll(ret, "__@39__", "'") + ret = strings.ReplaceAll(ret, "__@lt__", "<") + ret = strings.ReplaceAll(ret, "__@gt__", ">") + ret = strings.ReplaceAll(ret, "__@34__", """) + ret = strings.ReplaceAll(ret, "__@13__", " ") + return } func Reverse(s string) string { From da6ba8694897f33cdd2c391e1c15eefdebc6bbea Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Thu, 28 Mar 2024 16:59:50 +0800 Subject: [PATCH 22/87] :bug: Breadcrumb XSS https://github.com/siyuan-note/siyuan/issues/10753 --- kernel/model/blockinfo.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/kernel/model/blockinfo.go b/kernel/model/blockinfo.go index 44c9111d42..aabb5b91e5 100644 --- a/kernel/model/blockinfo.go +++ b/kernel/model/blockinfo.go @@ -361,12 +361,11 @@ func buildBlockBreadcrumb(node *ast.Node, excludeTypes []string) (ret []*BlockPa fc = fc.Next } - name := util.EscapeHTML(parent.IALAttr("name")) + name := parent.IALAttr("name") if ast.NodeDocument == parent.Type { - name = util.EscapeHTML(box.Name) + util.EscapeHTML(hPath) + name = box.Name + hPath } else if ast.NodeAttributeView == parent.Type { name = treenode.GetAttributeViewName(parent.AttributeViewID) - name = util.EscapeHTML(name) } else { if "" == name { if ast.NodeListItem == parent.Type { @@ -374,7 +373,6 @@ func buildBlockBreadcrumb(node *ast.Node, excludeTypes []string) (ret []*BlockPa } else { name = gulu.Str.SubStr(renderBlockText(parent, excludeTypes), maxNameLen) } - name = util.EscapeHTML(name) } if ast.NodeHeading == parent.Type { headingLevel = parent.HeadingLevel @@ -391,15 +389,15 @@ func buildBlockBreadcrumb(node *ast.Node, excludeTypes []string) (ret []*BlockPa if ast.NodeListItem == parent.Type { if "" == name { name = gulu.Str.SubStr(renderBlockText(fc, excludeTypes), maxNameLen) - name = util.EscapeHTML(name) } } name = strings.ReplaceAll(name, editor.Caret, "") + name = util.EscapeHTML(name) if add { ret = append([]*BlockPath{{ ID: id, - Name: util.EscapeHTML(name), + Name: name, Type: parent.Type.String(), SubType: treenode.SubTypeAbbr(parent), }}, ret...) @@ -418,9 +416,10 @@ func buildBlockBreadcrumb(node *ast.Node, excludeTypes []string) (ret []*BlockPa if ast.NodeHeading == b.Type && headingLevel > b.HeadingLevel { name = gulu.Str.SubStr(renderBlockText(b, excludeTypes), maxNameLen) + name = util.EscapeHTML(name) ret = append([]*BlockPath{{ ID: b.ID, - Name: util.EscapeHTML(name), + Name: name, Type: b.Type.String(), SubType: treenode.SubTypeAbbr(b), }}, ret...) From 34fcbacea2f58181d5c0ea7b2c4f3fff5cb80df6 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Thu, 28 Mar 2024 18:26:35 +0800 Subject: [PATCH 23/87] :art: https://github.com/siyuan-note/siyuan/issues/10712 --- app/src/block/popover.ts | 17 ++++++++++++----- app/src/protyle/render/av/cell.ts | 2 ++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/app/src/block/popover.ts b/app/src/block/popover.ts index e91512bada..5affab758c 100644 --- a/app/src/block/popover.ts +++ b/app/src/block/popover.ts @@ -33,12 +33,19 @@ export const initBlockPopover = (app: App) => { if (textElement.scrollWidth > textElement.clientWidth + 2) { tip = getCellText(aElement); } - } else if (aElement.dataset.wrap !== "true" && event.target.dataset.type !== "block-more" && !hasClosestByClassName(event.target, "block__icon")) { - aElement.style.overflow = "auto"; - if (aElement.scrollWidth > aElement.clientWidth + 2) { - tip = getCellText(aElement); + } else { + if (aElement.firstElementChild.getAttribute("data-type") === "url") { + if (aElement.firstElementChild.textContent.indexOf("...") > -1) { + tip = aElement.firstElementChild.getAttribute("data-href"); + } + } + if (!tip && aElement.dataset.wrap !== "true" && event.target.dataset.type !== "block-more" && !hasClosestByClassName(event.target, "block__icon")) { + aElement.style.overflow = "auto"; + if (aElement.scrollWidth > aElement.clientWidth + 2) { + tip = getCellText(aElement); + } + aElement.style.overflow = ""; } - aElement.style.overflow = ""; } } if (!tip) { diff --git a/app/src/protyle/render/av/cell.ts b/app/src/protyle/render/av/cell.ts index d53a450957..396f2deacd 100644 --- a/app/src/protyle/render/av/cell.ts +++ b/app/src/protyle/render/av/cell.ts @@ -40,6 +40,8 @@ export const getCellText = (cellElement: HTMLElement | false) => { textElements.forEach(item => { if (item.querySelector(".av__cellicon")) { cellText += `${item.firstChild.textContent} → ${item.lastChild.textContent}, `; + } else if (item.getAttribute("data-type") === "url") { + cellText = item.getAttribute("data-href") + ", "; } else if (item.getAttribute("data-type") !== "block-more") { cellText += item.textContent + ", "; } From e7d1210ec9e285a6806eecbad3ca0805c7cb2069 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Thu, 28 Mar 2024 21:27:31 +0800 Subject: [PATCH 24/87] :art: Improve av https://ld246.com/article/1711613722864 --- kernel/model/attribute_view.go | 43 ++++++++++++++-------------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index ff356fb4c3..70c4a481a9 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -901,7 +901,7 @@ func renderAttributeViewTable(attrView *av.AttributeView, view *av.View, query s continue } - if treenode.GetBlockTree(blockID) == nil { + if nil == treenode.GetBlockTree(blockID) { notFound = append(notFound, blockID) } } @@ -1985,6 +1985,10 @@ func addAttributeViewBlock(avID, blockID, previousBlockID, addingBlockID string, blockValues := attrView.GetBlockKeyValues() for _, blockValue := range blockValues.Values { if blockValue.Block.ID == addingBlockID { + if !isDetached { + // 重复绑定一下,比如剪切数据库块的场景需要 + bindBlockAv0(tx, avID, blockID, node, tree) + } return } } @@ -2074,31 +2078,7 @@ func addAttributeViewBlock(avID, blockID, previousBlockID, addingBlockID string, } if !isDetached { - attrs := parse.IAL2Map(node.KramdownIAL) - - if "" == attrs[av.NodeAttrNameAvs] { - attrs[av.NodeAttrNameAvs] = avID - } else { - avIDs := strings.Split(attrs[av.NodeAttrNameAvs], ",") - avIDs = append(avIDs, avID) - avIDs = gulu.Str.RemoveDuplicatedElem(avIDs) - attrs[av.NodeAttrNameAvs] = strings.Join(avIDs, ",") - } - - avNames := getAvNames(attrs[av.NodeAttrNameAvs]) - if "" != avNames { - attrs[av.NodeAttrViewNames] = avNames - } - - if nil != tx { - if err = setNodeAttrsWithTx(tx, node, tree, attrs); nil != err { - return - } - } else { - if err = setNodeAttrs(node, tree, attrs); nil != err { - return - } - } + bindBlockAv0(tx, avID, blockID, node, tree) } for _, view := range attrView.Views { @@ -3036,6 +3016,11 @@ func bindBlockAv(tx *Transaction, avID, blockID string) { return } + bindBlockAv0(tx, avID, blockID, node, tree) + return +} + +func bindBlockAv0(tx *Transaction, avID, blockID string, node *ast.Node, tree *parse.Tree) { attrs := parse.IAL2Map(node.KramdownIAL) if "" == attrs[av.NodeAttrNameAvs] { attrs[av.NodeAttrNameAvs] = avID @@ -3046,6 +3031,12 @@ func bindBlockAv(tx *Transaction, avID, blockID string) { attrs[av.NodeAttrNameAvs] = strings.Join(avIDs, ",") } + avNames := getAvNames(attrs[av.NodeAttrNameAvs]) + if "" != avNames { + attrs[av.NodeAttrViewNames] = avNames + } + + var err error if nil != tx { err = setNodeAttrsWithTx(tx, node, tree, attrs) } else { From d85cece8a305f8df11aad2caff7d694f66ea1ef3 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Thu, 28 Mar 2024 21:43:44 +0800 Subject: [PATCH 25/87] :art: https://github.com/siyuan-note/siyuan/issues/10783 --- app/src/menus/workspace.ts | 132 ++++++++++++++++++++++--------------- 1 file changed, 78 insertions(+), 54 deletions(-) diff --git a/app/src/menus/workspace.ts b/app/src/menus/workspace.ts index 582a5e3e9b..d136688aba 100644 --- a/app/src/menus/workspace.ts +++ b/app/src/menus/workspace.ts @@ -26,6 +26,80 @@ import {App} from "../index"; import {isBrowser} from "../util/functions"; import {openRecentDocs} from "../business/openRecentDocs"; +const editLayout = (layoutName?: string) => { + const dialog = new Dialog({ + positionId: Constants.DIALOG_SAVEWORKSPACE, + title: layoutName ? window.siyuan.languages.edit : window.siyuan.languages.save, + content: `
+ +
+
+
+
+ +
`, + width: "520px", + }); + dialog.element.setAttribute("data-key", Constants.DIALOG_SAVEWORKSPACE); + const btnsElement = dialog.element.querySelectorAll(".b3-button"); + const inputElement = dialog.element.querySelector("input"); + inputElement.select(); + inputElement.focus(); + dialog.bindInput(inputElement, () => { + btnsElement[1].dispatchEvent(new CustomEvent("click")); + }); + btnsElement[0].addEventListener("click", () => { + dialog.destroy(); + }); + btnsElement[1].addEventListener("click", () => { + const value = inputElement.value; + if (!value) { + showMessage(window.siyuan.languages["_kernel"]["142"]); + return; + } + dialog.destroy(); + if (layoutName) { + window.siyuan.storage[Constants.LOCAL_LAYOUTS].find((layoutItem: ISaveLayout) => { + if (layoutItem.name === layoutName) { + layoutItem.name = value; + layoutItem.layout = getAllLayout(); + setStorageVal(Constants.LOCAL_LAYOUTS, window.siyuan.storage[Constants.LOCAL_LAYOUTS]); + return true; + } + }); + return; + } + const hadName = window.siyuan.storage[Constants.LOCAL_LAYOUTS].find((item: ISaveLayout) => { + if (item.name === value) { + + confirmDialog(window.siyuan.languages.save, window.siyuan.languages.exportTplTip, () => { + item.layout = getAllLayout(); + setStorageVal(Constants.LOCAL_LAYOUTS, window.siyuan.storage[Constants.LOCAL_LAYOUTS]); + }); + return true; + } + }); + if (hadName) { + return; + } + window.siyuan.storage[Constants.LOCAL_LAYOUTS].push({ + name: value, + layout: getAllLayout() + }); + setStorageVal(Constants.LOCAL_LAYOUTS, window.siyuan.storage[Constants.LOCAL_LAYOUTS]); + }); + btnsElement[2].addEventListener("click", () => { + window.siyuan.storage[Constants.LOCAL_LAYOUTS].find((layoutItem: ISaveLayout, index: number) => { + if (layoutItem.name === layoutName) { + window.siyuan.storage[Constants.LOCAL_LAYOUTS].splice(index, 1); + setStorageVal(Constants.LOCAL_LAYOUTS, window.siyuan.storage[Constants.LOCAL_LAYOUTS]); + return true; + } + }); + dialog.destroy(); + }); +} + const togglePinDock = (dock: Dock, icon: string) => { return { label: `${dock.pin ? window.siyuan.languages.unpin : window.siyuan.languages.pin}`, @@ -226,51 +300,7 @@ export const workspaceMenu = (app: App, rect: DOMRect) => { iconHTML: "", label: window.siyuan.languages.save, click() { - const saveDialog = new Dialog({ - title: window.siyuan.languages.save, - content: `
- -
-
-
- -
`, - width: "520px", - }); - saveDialog.element.setAttribute("data-key", Constants.DIALOG_SAVEWORKSPACE); - const btnsElement = saveDialog.element.querySelectorAll(".b3-button"); - saveDialog.bindInput(saveDialog.element.querySelector("input"), () => { - btnsElement[1].dispatchEvent(new CustomEvent("click")); - }); - btnsElement[0].addEventListener("click", () => { - saveDialog.destroy(); - }); - btnsElement[1].addEventListener("click", () => { - const value = saveDialog.element.querySelector("input").value; - if (!value) { - showMessage(window.siyuan.languages["_kernel"]["142"]); - return; - } - const hadName = window.siyuan.storage[Constants.LOCAL_LAYOUTS].find((item: ISaveLayout) => { - if (item.name === value) { - saveDialog.destroy(); - confirmDialog(window.siyuan.languages.save, window.siyuan.languages.exportTplTip, () => { - item.layout = getAllLayout(); - setStorageVal(Constants.LOCAL_LAYOUTS, window.siyuan.storage[Constants.LOCAL_LAYOUTS]); - }); - return true; - } - }); - if (hadName) { - return; - } - window.siyuan.storage[Constants.LOCAL_LAYOUTS].push({ - name: value, - layout: getAllLayout() - }); - setStorageVal(Constants.LOCAL_LAYOUTS, window.siyuan.storage[Constants.LOCAL_LAYOUTS]); - saveDialog.destroy(); - }); + editLayout(); } }]; if (window.siyuan.storage[Constants.LOCAL_LAYOUTS].length > 0) { @@ -279,21 +309,15 @@ export const workspaceMenu = (app: App, rect: DOMRect) => { window.siyuan.storage[Constants.LOCAL_LAYOUTS].forEach((item: ISaveLayout) => { layoutSubMenu.push({ iconHTML: "", - action: "iconCloseRound", + action: "iconEdit", label: item.name, bind(menuElement) { menuElement.addEventListener("click", (event) => { if (hasClosestByClassName(event.target as Element, "b3-menu__action")) { event.preventDefault(); event.stopPropagation(); - window.siyuan.storage[Constants.LOCAL_LAYOUTS].find((layoutItem: ISaveLayout, index: number) => { - if (layoutItem.name === item.name) { - menuElement.remove(); - window.siyuan.storage[Constants.LOCAL_LAYOUTS].splice(index, 1); - setStorageVal(Constants.LOCAL_LAYOUTS, window.siyuan.storage[Constants.LOCAL_LAYOUTS]); - return true; - } - }); + editLayout(item.name); + window.siyuan.menus.menu.remove(); return; } fetchPost("/api/system/setUILayout", {layout: item.layout}, () => { From 5bc96e05aa4fd3cf410c9a2906aa76526def408e Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Thu, 28 Mar 2024 21:54:23 +0800 Subject: [PATCH 26/87] :art: Automatically loads and indexes from the file system when a block is not found https://github.com/siyuan-note/siyuan/issues/10772 --- kernel/model/tree.go | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/model/tree.go b/kernel/model/tree.go index 54f98d8500..93079df21c 100644 --- a/kernel/model/tree.go +++ b/kernel/model/tree.go @@ -225,6 +225,5 @@ func searchTreeInFilesystem(rootID string) { treenode.IndexBlockTree(tree) sql.IndexTreeQueue(tree) - sql.WaitForWritingDatabase() logging.LogInfof("reindexed tree by filesystem [rootID=%s]", rootID) } From 5f12f31adc554f168c61b5d4b16c15ada5cd460d Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Thu, 28 Mar 2024 23:16:04 +0800 Subject: [PATCH 27/87] :art: Improve data sync conflict generation https://github.com/siyuan-note/siyuan/issues/10784 --- kernel/go.mod | 16 ++++++++-------- kernel/go.sum | 32 ++++++++++++++++---------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/kernel/go.mod b/kernel/go.mod index c6407434fe..4b1ff38d4a 100644 --- a/kernel/go.mod +++ b/kernel/go.mod @@ -45,18 +45,18 @@ require ( github.com/mssola/useragent v1.0.0 github.com/olahol/melody v1.1.4 github.com/open-spaced-repetition/go-fsrs v1.2.0 - github.com/panjf2000/ants/v2 v2.9.0 + github.com/panjf2000/ants/v2 v2.9.1 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/radovskyb/watcher v1.0.7 github.com/rqlite/sql v0.0.0-20240102050638-e741e9f54197 github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 github.com/sashabaranov/go-openai v1.20.2 github.com/shirou/gopsutil/v3 v3.24.2 - github.com/siyuan-note/dejavu v0.0.0-20240323004223-25eaaad1f650 + github.com/siyuan-note/dejavu v0.0.0-20240328150019-caf931b7a455 github.com/siyuan-note/encryption v0.0.0-20231219001248-1e028a4d13b4 github.com/siyuan-note/eventbus v0.0.0-20240318125243-801c98e8f025 github.com/siyuan-note/filelock v0.0.0-20240128091141-94d7bb3e0772 - github.com/siyuan-note/httpclient v0.0.0-20240323002956-eaba148a7247 + github.com/siyuan-note/httpclient v0.0.0-20240328145713-1035acaa5f8a github.com/siyuan-note/logging v0.0.0-20231208035918-61f884c854f0 github.com/siyuan-note/riff v0.0.0-20240315100323-cc554b704bcc github.com/spf13/cast v1.6.0 @@ -81,7 +81,7 @@ require ( github.com/andybalholm/brotli v1.1.0 // indirect github.com/andybalholm/cascadia v1.3.2 // indirect github.com/asaskevich/EventBus v0.0.0-20200907212545-49d423059eef // indirect - github.com/aws/aws-sdk-go v1.50.32 // indirect + github.com/aws/aws-sdk-go v1.51.9 // indirect github.com/bytedance/sonic v1.11.2 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect @@ -99,7 +99,7 @@ require ( github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/golang/glog v1.2.0 // indirect - github.com/google/pprof v0.0.0-20240320155624-b11c3daa6f07 // indirect + github.com/google/pprof v0.0.0-20240327155427-868f304927ed // indirect github.com/google/uuid v1.6.0 // indirect github.com/gopherjs/gopherjs v1.17.2 // indirect github.com/gorilla/context v1.1.2 // indirect @@ -128,12 +128,12 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/onsi/ginkgo/v2 v2.17.0 // indirect + github.com/onsi/ginkgo/v2 v2.17.1 // indirect github.com/otiai10/gosseract/v2 v2.4.1 // indirect github.com/pelletier/go-toml/v2 v2.1.1 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect - github.com/qiniu/go-sdk/v7 v7.19.0 // indirect + github.com/qiniu/go-sdk/v7 v7.19.1 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/quic-go v0.42.0 // indirect github.com/refraction-networking/utls v1.6.3 // indirect @@ -157,7 +157,7 @@ require ( go.uber.org/mock v0.4.0 // indirect golang.org/x/arch v0.7.0 // indirect golang.org/x/crypto v0.21.0 // indirect - golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81 // indirect + golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect golang.org/x/net v0.22.0 // indirect golang.org/x/sync v0.6.0 // indirect golang.org/x/sys v0.18.0 // indirect diff --git a/kernel/go.sum b/kernel/go.sum index 94ead279fe..755dfc5357 100644 --- a/kernel/go.sum +++ b/kernel/go.sum @@ -48,8 +48,8 @@ github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de h1:FxWPpzIjnTlhP github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de/go.mod h1:DCaWoUhZrYW9p1lxo/cm8EmUOOzAPSEZNGF2DK1dJgw= github.com/asaskevich/EventBus v0.0.0-20200907212545-49d423059eef h1:2JGTg6JapxP9/R33ZaagQtAM4EkkSYnIAlOG5EI8gkM= github.com/asaskevich/EventBus v0.0.0-20200907212545-49d423059eef/go.mod h1:JS7hed4L1fj0hXcyEejnW57/7LCetXggd+vwrRnYeII= -github.com/aws/aws-sdk-go v1.50.32 h1:POt81DvegnpQKM4DMDLlHz1CO6OBnEoQ1gRhYFd7QRY= -github.com/aws/aws-sdk-go v1.50.32/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.51.9 h1:w6ZlyFX7l4+ZNVPmWw7LwOHSaBDDQuP22l1gh7OYu7w= +github.com/aws/aws-sdk-go v1.51.9/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= github.com/bytedance/sonic v1.11.2 h1:ywfwo0a/3j9HR8wsYGWsIWl2mvRsI950HyoxiBERw5A= @@ -168,8 +168,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20240320155624-b11c3daa6f07 h1:57oOH2Mu5Nw16KnZAVLdlUjmPH/TSYCKTJgG0OVfX0Y= -github.com/google/pprof v0.0.0-20240320155624-b11c3daa6f07/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/pprof v0.0.0-20240327155427-868f304927ed h1:n8QtJTrwsv3P7dNxPaMeNkMcxvUpqocsHLr8iDLGlQI= +github.com/google/pprof v0.0.0-20240327155427-868f304927ed/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -279,8 +279,8 @@ github.com/olahol/melody v1.1.4/go.mod h1:GgkTl6Y7yWj/HtfD48Q5vLKPVoZOH+Qqgfa7Cv github.com/olekukonko/tablewriter v0.0.0-20180506121414-d4647c9c7a84/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/onsi/ginkgo/v2 v2.17.0 h1:kdnunFXpBjbzN56hcJHrXZ8M+LOkenKA7NnBzTNigTI= -github.com/onsi/ginkgo/v2 v2.17.0/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= +github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= +github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo= github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0= github.com/open-spaced-repetition/go-fsrs v1.2.0 h1:cHCggDk/gEsQGyXybWn1NchrvSSzTknaN1fTpI9ihhI= @@ -289,8 +289,8 @@ github.com/otiai10/gosseract/v2 v2.4.1 h1:G8AyBpXEeSlcq8TI85LH/pM5SXk8Djy2GEXisg github.com/otiai10/gosseract/v2 v2.4.1/go.mod h1:1gNWP4Hgr2o7yqWfs6r5bZxAatjOIdqWxJLWsTsembk= github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs= github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM= -github.com/panjf2000/ants/v2 v2.9.0 h1:SztCLkVxBRigbg+vt0S5QvF5vxAbxbKt09/YfAJ0tEo= -github.com/panjf2000/ants/v2 v2.9.0/go.mod h1:7ZxyxsqE4vvW0M7LSD8aI3cKwgFhBHbxnlN8mDqHa1I= +github.com/panjf2000/ants/v2 v2.9.1 h1:Q5vh5xohbsZXGcD6hhszzGqB7jSSc2/CRr3QKIga8Kw= +github.com/panjf2000/ants/v2 v2.9.1/go.mod h1:7ZxyxsqE4vvW0M7LSD8aI3cKwgFhBHbxnlN8mDqHa1I= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= @@ -308,8 +308,8 @@ github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:Om github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/qiniu/dyn v1.3.0/go.mod h1:E8oERcm8TtwJiZvkQPbcAh0RL8jO1G0VXJMW3FAWdkk= -github.com/qiniu/go-sdk/v7 v7.19.0 h1:k3AzDPil8QHIQnki6xXt4YRAjE52oRoBUXQ4bV+Wc5U= -github.com/qiniu/go-sdk/v7 v7.19.0/go.mod h1:nqoYCNo53ZlGA521RvRethvxUDvXKt4gtYXOwye868w= +github.com/qiniu/go-sdk/v7 v7.19.1 h1:dHgC/UcWLJLEyddknDb9sulKEMCB2jZeamj9mAbCR/Y= +github.com/qiniu/go-sdk/v7 v7.19.1/go.mod h1:nqoYCNo53ZlGA521RvRethvxUDvXKt4gtYXOwye868w= github.com/qiniu/x v1.10.5/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= @@ -353,16 +353,16 @@ github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFR github.com/shurcooL/gofontwoff v0.0.0-20181114050219-180f79e6909d h1:lvCTyBbr36+tqMccdGMwuEU+hjux/zL6xSmf5S9ITaA= github.com/shurcooL/gofontwoff v0.0.0-20181114050219-180f79e6909d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= github.com/simplereach/timeutils v1.2.0/go.mod h1:VVbQDfN/FHRZa1LSqcwo4kNZ62OOyqLLGQKYB3pB0Q8= -github.com/siyuan-note/dejavu v0.0.0-20240323004223-25eaaad1f650 h1:9JNpROqJ7qI9Gh2uYQBe9bauDzlJdEb7M8cN13D6a20= -github.com/siyuan-note/dejavu v0.0.0-20240323004223-25eaaad1f650/go.mod h1:KaDNYNjshJqls1vWdoP3CKRTw/3tWssrKMu9CInWu0k= +github.com/siyuan-note/dejavu v0.0.0-20240328150019-caf931b7a455 h1:kXWWeY/neMFUd+xGXbYRgr5/FS38fu19YrceIUkeQHc= +github.com/siyuan-note/dejavu v0.0.0-20240328150019-caf931b7a455/go.mod h1:mwmUY/MnbbwH5tktbsTRGVIPvaznK296eBXEdkwN10s= github.com/siyuan-note/encryption v0.0.0-20231219001248-1e028a4d13b4 h1:kJaw5L/evyW6LcB9IQT8PR4ppx8JVqOFP9Ix3rfwSrc= github.com/siyuan-note/encryption v0.0.0-20231219001248-1e028a4d13b4/go.mod h1:UYcCCY+0wh+GmUoDOaO63j1sV5lgy7laLAk1XhEiUis= github.com/siyuan-note/eventbus v0.0.0-20240318125243-801c98e8f025 h1:crQmKw5vZz3MljAP/xKMWY/rksMX634jJK9kcsOIbkw= github.com/siyuan-note/eventbus v0.0.0-20240318125243-801c98e8f025/go.mod h1:1/nGgthl89FPA7GzAcEWKl6zRRnfgyTjzLZj9bW7kuw= github.com/siyuan-note/filelock v0.0.0-20240128091141-94d7bb3e0772 h1:ceX49LJmN8FMwWpkCkZIV9dHG4Ya2ZMrhu9T6VyDiKs= github.com/siyuan-note/filelock v0.0.0-20240128091141-94d7bb3e0772/go.mod h1:CYJQjSyKYLhEJJC+5I+R4uNcpyW0X2CaUYwMVbkelDk= -github.com/siyuan-note/httpclient v0.0.0-20240323002956-eaba148a7247 h1:C9El7Df3SWiBNei0ThztkJK/+FmFdIVzJRHz+3ZZ8lo= -github.com/siyuan-note/httpclient v0.0.0-20240323002956-eaba148a7247/go.mod h1:VBH3FUilz0ERt/R4+RMV8S3B/JBd6GwcFzZ3GLnljFU= +github.com/siyuan-note/httpclient v0.0.0-20240328145713-1035acaa5f8a h1:j2yijr6BUHvjfOox/CWMbsmm8xyiNcINpAIgwnKQxvk= +github.com/siyuan-note/httpclient v0.0.0-20240328145713-1035acaa5f8a/go.mod h1:aVuWsPZDrH8X/Js3leXJJTUL7xmaQEfIyDBqe0VdZAQ= github.com/siyuan-note/logging v0.0.0-20231208035918-61f884c854f0 h1:+XjUr9UMXsczdO2bGA72p/k9wa2ShPb8ybi7CDBJ7HQ= github.com/siyuan-note/logging v0.0.0-20231208035918-61f884c854f0/go.mod h1:6mRFtAAvYPn3cDzqvyv+t8BVPGqpONDMMb5ywOhY1D4= github.com/siyuan-note/riff v0.0.0-20240315100323-cc554b704bcc h1:/xkXmPKwQZRnpJYW2WBv0VAGQeRaGN72KUqAZiar60Q= @@ -442,8 +442,8 @@ golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81 h1:6R2FC06FonbXQ8pK11/PDFY6N6LWlf9KlzibaCapmqc= -golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ= +golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw= +golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ= golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8= golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= From 9147d626a8a0f78263a66bdb3d7d47b022c123eb Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Thu, 28 Mar 2024 23:16:40 +0800 Subject: [PATCH 28/87] :art: Improve exit when syncing --- kernel/model/repository.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/model/repository.go b/kernel/model/repository.go index 6ae130469f..5620da6902 100644 --- a/kernel/model/repository.go +++ b/kernel/model/repository.go @@ -1331,8 +1331,10 @@ func syncRepo(exit, byHand bool) (dataChanged bool, err error) { processSyncMergeResult(exit, byHand, mergeResult, trafficStat, "a", elapsed) - // 首次数据同步执行完成后再执行索引订正 Index fixing should not be performed before data synchronization https://github.com/siyuan-note/siyuan/issues/10761 - checkIndex() + if !exit { + // 首次数据同步执行完成后再执行索引订正 Index fixing should not be performed before data synchronization https://github.com/siyuan-note/siyuan/issues/10761 + checkIndex() + } return } From 4c230372421c6886e5e758a6cd5070695973e40e Mon Sep 17 00:00:00 2001 From: Vanessa Date: Thu, 28 Mar 2024 23:34:11 +0800 Subject: [PATCH 29/87] :art: https://github.com/siyuan-note/siyuan/issues/10690 --- app/src/block/popover.ts | 2 +- app/src/protyle/render/av/cell.ts | 10 ++++++++-- app/src/protyle/util/insertHTML.ts | 24 ++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/app/src/block/popover.ts b/app/src/block/popover.ts index 5affab758c..55ee973351 100644 --- a/app/src/block/popover.ts +++ b/app/src/block/popover.ts @@ -34,7 +34,7 @@ export const initBlockPopover = (app: App) => { tip = getCellText(aElement); } } else { - if (aElement.firstElementChild.getAttribute("data-type") === "url") { + if (aElement.firstElementChild?.getAttribute("data-type") === "url") { if (aElement.firstElementChild.textContent.indexOf("...") > -1) { tip = aElement.firstElementChild.getAttribute("data-href"); } diff --git a/app/src/protyle/render/av/cell.ts b/app/src/protyle/render/av/cell.ts index 396f2deacd..36375fb83b 100644 --- a/app/src/protyle/render/av/cell.ts +++ b/app/src/protyle/render/av/cell.ts @@ -3,7 +3,7 @@ import {hasClosestBlock, hasClosestByClassName} from "../../util/hasClosest"; import {openMenuPanel} from "./openMenuPanel"; import {updateAttrViewCellAnimation} from "./action"; import {isNotCtrl} from "../../util/compatibility"; -import {objEquals} from "../../../util/functions"; +import {isDynamicRef, objEquals} from "../../../util/functions"; import {fetchPost} from "../../../util/fetch"; import {focusBlock, focusByRange} from "../../util/selection"; import * as dayjs from "dayjs"; @@ -402,7 +402,13 @@ export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[], type focusByRange(protyle.toolbar.range); cellElements[0].classList.add("av__cell--select"); addDragFill(cellElements[0]); - hintRef(inputElement.value.substring(2), protyle, "av"); + let textPlain = inputElement.value; + if (isDynamicRef(textPlain)) { + textPlain = textPlain.substring(2, 22 + 2) + } else { + textPlain = textPlain.substring(2) + } + hintRef(textPlain, protyle, "av"); avMaskElement?.remove(); event.preventDefault(); event.stopPropagation(); diff --git a/app/src/protyle/util/insertHTML.ts b/app/src/protyle/util/insertHTML.ts index 56ec30365e..6d1630336b 100644 --- a/app/src/protyle/util/insertHTML.ts +++ b/app/src/protyle/util/insertHTML.ts @@ -135,6 +135,30 @@ const processAV = (range: Range, html: string, protyle: IProtyle, blockElement: } return; } + const contenteditableElement = getContenteditableElement(tempElement.content.firstElementChild); + if (contenteditableElement && contenteditableElement.childNodes.length === 1 && contenteditableElement.firstElementChild?.getAttribute("data-type") === "block-ref") { + const selectCellElement = blockElement.querySelector(".av__cell--select") as HTMLElement + if (selectCellElement) { + const avID = blockElement.dataset.avId; + const sourceId = contenteditableElement.firstElementChild.getAttribute("data-id"); + const previousID = selectCellElement.dataset.blockId; + transaction(protyle, [{ + action: "replaceAttrViewBlock", + avID, + previousID, + nextID: sourceId, + isDetached: false, + }], [{ + action: "replaceAttrViewBlock", + avID, + previousID: sourceId, + nextID: previousID, + isDetached: selectCellElement.dataset.detached === "true", + }]); + return; + } + } + const text = protyle.lute.BlockDOM2EscapeMarkerContent(html); const cellsElement: HTMLElement[] = Array.from(blockElement.querySelectorAll(".av__cell--select")); const rowsElement = blockElement.querySelector(".av__row--select"); From 13332781c96f11a34961f5b087e3246fca521ae6 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Fri, 29 Mar 2024 09:47:40 +0800 Subject: [PATCH 30/87] :rotating_light: --- app/electron/main.js | 2 +- app/src/config/keymap.ts | 2 +- app/src/config/util/snippets.ts | 4 ++-- app/src/menus/workspace.ts | 2 +- app/src/protyle/render/av/action.ts | 2 +- app/src/protyle/render/av/cell.ts | 12 ++++++------ app/src/protyle/util/insertHTML.ts | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/app/electron/main.js b/app/electron/main.js index bcd1566847..acc66a135b 100644 --- a/app/electron/main.js +++ b/app/electron/main.js @@ -1041,7 +1041,7 @@ app.whenReady().then(() => { return; } if (globalShortcut.isRegistered(shortcut)) { - globalShortcut.unregister(shortcut) + globalShortcut.unregister(shortcut); } if (index === 0) { globalShortcut.register(shortcut, () => { diff --git a/app/src/config/keymap.ts b/app/src/config/keymap.ts index 78ab596d06..51ca3d15ed 100644 --- a/app/src/config/keymap.ts +++ b/app/src/config/keymap.ts @@ -186,7 +186,7 @@ export const keymap = { }, _setkeymap(app: App) { const data: Config.IKeymap = JSON.parse(JSON.stringify(Constants.SIYUAN_KEYMAP)); - const oldToggleWin = window.siyuan.config.keymap.general.toggleWin.custom + const oldToggleWin = window.siyuan.config.keymap.general.toggleWin.custom; keymap.element.querySelectorAll("label.b3-list-item input").forEach((item) => { const keys = item.getAttribute("data-key").split(Constants.ZWSP); const newHotkey = item.getAttribute("data-value"); diff --git a/app/src/config/util/snippets.ts b/app/src/config/util/snippets.ts index 403e3a8883..e365eea62b 100644 --- a/app/src/config/util/snippets.ts +++ b/app/src/config/util/snippets.ts @@ -171,7 +171,7 @@ export const openSnippets = () => { }, (searchResponse) => { dialog.element.querySelectorAll(`.fn__flex-1 > div > [data-type="${inputItem.dataset.type}"]`).forEach((snipeetPanel: Element) => { snipeetPanel.classList.add("fn__none"); - }) + }); searchResponse.data.snippets.forEach((snippetItem: ISnippet) => { if (snippetItem.type === inputItem.dataset.type) { dialog.element.querySelector(`[data-id="${snippetItem.id}"]`).classList.remove("fn__none"); @@ -180,7 +180,7 @@ export const openSnippets = () => { }); } }); - }) + }); }); }; diff --git a/app/src/menus/workspace.ts b/app/src/menus/workspace.ts index d136688aba..9679ed3942 100644 --- a/app/src/menus/workspace.ts +++ b/app/src/menus/workspace.ts @@ -98,7 +98,7 @@ const editLayout = (layoutName?: string) => { }); dialog.destroy(); }); -} +}; const togglePinDock = (dock: Dock, icon: string) => { return { diff --git a/app/src/protyle/render/av/action.ts b/app/src/protyle/render/av/action.ts index 3d962c31bf..10d36a7199 100644 --- a/app/src/protyle/render/av/action.ts +++ b/app/src/protyle/render/av/action.ts @@ -331,7 +331,7 @@ ${window.siyuan.languages.insertRowBefore.replace("${x}", ' { if (!event.isComposing && event.key === "Enter") { insertRows(blockElement, protyle, parseInt(inputElement.value), rowElements[0].previousElementSibling.getAttribute("data-id")); diff --git a/app/src/protyle/render/av/cell.ts b/app/src/protyle/render/av/cell.ts index 36375fb83b..c444bc3897 100644 --- a/app/src/protyle/render/av/cell.ts +++ b/app/src/protyle/render/av/cell.ts @@ -15,11 +15,11 @@ import {hintRef} from "../../hint/extend"; const renderCellURL = (urlContent: string) => { let host = urlContent; - let suffix = "" + let suffix = ""; try { const urlObj = new URL(urlContent); host = urlObj.host; - suffix = urlObj.href.replace(urlObj.origin, "") + suffix = urlObj.href.replace(urlObj.origin, ""); if (suffix.length > 12) { suffix = suffix.substring(0, 4) + "..." + suffix.substring(suffix.length - 6); } @@ -404,9 +404,9 @@ export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[], type addDragFill(cellElements[0]); let textPlain = inputElement.value; if (isDynamicRef(textPlain)) { - textPlain = textPlain.substring(2, 22 + 2) + textPlain = textPlain.substring(2, 22 + 2); } else { - textPlain = textPlain.substring(2) + textPlain = textPlain.substring(2); } hintRef(textPlain, protyle, "av"); avMaskElement?.remove(); @@ -630,7 +630,7 @@ export const renderCell = (cellValue: IAVCellValue) => { } else if (["email", "phone"].includes(cellValue.type)) { text = `${cellValue ? cellValue[cellValue.type as "email"].content : ""}`; } else if ("url" === cellValue.type) { - text = renderCellURL(cellValue?.url?.content || "") + text = renderCellURL(cellValue?.url?.content || ""); } else if (cellValue.type === "block") { if (cellValue?.isDetached) { text = `${cellValue.block.content || ""} @@ -709,7 +709,7 @@ const renderRollup = (cellValue: IAVCellValue) => { text = `${emailContent}`; } } else if ("url" === cellValue.type) { - const urlContent = cellValue?.url?.content || "" + const urlContent = cellValue?.url?.content || ""; if (urlContent) { text = renderCellURL(urlContent); } diff --git a/app/src/protyle/util/insertHTML.ts b/app/src/protyle/util/insertHTML.ts index 6d1630336b..8fb342f47f 100644 --- a/app/src/protyle/util/insertHTML.ts +++ b/app/src/protyle/util/insertHTML.ts @@ -137,7 +137,7 @@ const processAV = (range: Range, html: string, protyle: IProtyle, blockElement: } const contenteditableElement = getContenteditableElement(tempElement.content.firstElementChild); if (contenteditableElement && contenteditableElement.childNodes.length === 1 && contenteditableElement.firstElementChild?.getAttribute("data-type") === "block-ref") { - const selectCellElement = blockElement.querySelector(".av__cell--select") as HTMLElement + const selectCellElement = blockElement.querySelector(".av__cell--select") as HTMLElement; if (selectCellElement) { const avID = blockElement.dataset.avId; const sourceId = contenteditableElement.firstElementChild.getAttribute("data-id"); From b7f49bde1e4afdb2d30c95a8a430a1da8125d1b7 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Fri, 29 Mar 2024 10:08:58 +0800 Subject: [PATCH 31/87] :art: https://github.com/siyuan-note/siyuan/issues/7957 --- app/src/layout/dock/Outline.ts | 55 +++++++++++++++++++++++++++++++++- app/src/types/index.d.ts | 1 + 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/app/src/layout/dock/Outline.ts b/app/src/layout/dock/Outline.ts index 6da086dacf..0bb8c243aa 100644 --- a/app/src/layout/dock/Outline.ts +++ b/app/src/layout/dock/Outline.ts @@ -15,6 +15,7 @@ import {onGet} from "../../protyle/util/onGet"; import {getPreviousBlock} from "../../protyle/wysiwyg/getBlock"; import {App} from "../../index"; import {checkFold} from "../../util/noRelyPCFunction"; +import {transaction} from "../../protyle/wysiwyg/transaction"; export class Outline extends Model { public tree: Tree; @@ -206,7 +207,7 @@ export class Outline extends Model { target = target.parentElement; } }); - + this.bindSort(); if (this.isPreview) { if (this.blockId) { fetchPost("/api/export/preview", { @@ -225,6 +226,58 @@ export class Outline extends Model { } } + private bindSort() { + this.element.addEventListener("mousedown", (event: MouseEvent) => { + const item = hasClosestByClassName(event.target as HTMLElement, "b3-list-item"); + if (!item || item.tagName !== "LI") { + return; + } + const documentSelf = document; + const ghostElement = item.cloneNode(true) as HTMLElement; + document.body.append(ghostElement); + ghostElement.firstElementChild.setAttribute("style", "padding-left:4px"); + ghostElement.setAttribute("style", `opacity:.38;position: fixed; top: ${event.clientY}px; left: ${event.clientX}px; z-index:999997;`); + + documentSelf.ondragstart = () => false; + + documentSelf.onmousemove = (moveEvent: MouseEvent) => { + moveEvent.preventDefault(); + moveEvent.stopPropagation(); + ghostElement.style.top = moveEvent.clientY + "px"; + ghostElement.style.left = moveEvent.clientX + "px"; + }; + + documentSelf.onmouseup = () => { + documentSelf.onmousemove = null; + documentSelf.onmouseup = null; + documentSelf.ondragstart = null; + documentSelf.onselectstart = null; + documentSelf.onselect = null; + ghostElement.remove(); + const selectItem = hasClosestByClassName(event.target as HTMLElement, "b3-list-item"); + if (!selectItem || selectItem.tagName !== "LI") { + return; + } + getAllModels().editor.find(editItem => { + if (editItem.editor.protyle.block.rootID === this.blockId) { + transaction(editItem.editor.protyle, [{ + action: "moveOutlineHeading", + id: item.dataset.blockId, + previousID: selectItem.previousElementSibling?.getAttribute("data-node-id"), + parentID: selectItem.parentElement.previousElementSibling?.getAttribute("data-node-id"), + }], [{ + action: "moveOutlineHeading", + id: item.dataset.blockId, + previousID: item.previousElementSibling?.getAttribute("data-node-id"), + parentID: item.parentElement.previousElementSibling?.getAttribute("data-node-id"), + }]); + return true; + } + }) + }; + }); + } + public updateDocTitle(ial?: IObject) { const docTitleElement = this.headerElement.nextElementSibling as HTMLElement; if (this.type === "pin") { diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts index dfc3cb335b..090aaa31d6 100644 --- a/app/src/types/index.d.ts +++ b/app/src/types/index.d.ts @@ -46,6 +46,7 @@ type TOperation = | "sortAttrViewView" | "setAttrViewPageSize" | "updateAttrViewColRelation" + | "moveOutlineHeading" | "updateAttrViewColRollup" | "hideAttrViewName" type TBazaarType = "templates" | "icons" | "widgets" | "themes" | "plugins" From 73d232bafbd760a83b37bd60aaffbda8f9fefbea Mon Sep 17 00:00:00 2001 From: Vanessa Date: Fri, 29 Mar 2024 11:03:53 +0800 Subject: [PATCH 32/87] :art: https://github.com/siyuan-note/siyuan/issues/7957 --- app/src/assets/scss/component/_list.scss | 2 +- app/src/layout/dock/Outline.ts | 34 +++++++++++++++++++----- app/src/util/Tree.ts | 2 ++ 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/app/src/assets/scss/component/_list.scss b/app/src/assets/scss/component/_list.scss index 2923482c12..d9508f7574 100644 --- a/app/src/assets/scss/component/_list.scss +++ b/app/src/assets/scss/component/_list.scss @@ -7,7 +7,7 @@ &--background .b3-list-item { border-radius: var(--b3-border-radius); - &:hover:not(.b3-list-item--focus), + &:hover:not(.b3-list-item--focus):not(.dragover):not(.dragover__top):not(.dragover__bottom), &--focus:not(.dragover) { background-color: var(--b3-list-hover); } diff --git a/app/src/layout/dock/Outline.ts b/app/src/layout/dock/Outline.ts index 0bb8c243aa..108062f0b6 100644 --- a/app/src/layout/dock/Outline.ts +++ b/app/src/layout/dock/Outline.ts @@ -99,7 +99,7 @@ export class Outline extends Model {
-
`; +
`; this.element = options.tab.panelElement.lastElementChild as HTMLElement; this.headerElement = options.tab.panelElement.firstElementChild as HTMLElement; this.tree = new Tree({ @@ -233,18 +233,35 @@ export class Outline extends Model { return; } const documentSelf = document; + item.style.opacity = "0.38"; const ghostElement = item.cloneNode(true) as HTMLElement; document.body.append(ghostElement); ghostElement.firstElementChild.setAttribute("style", "padding-left:4px"); - ghostElement.setAttribute("style", `opacity:.38;position: fixed; top: ${event.clientY}px; left: ${event.clientX}px; z-index:999997;`); + ghostElement.setAttribute("style", `border-radius: var(--b3-border-radius);background-color: var(--b3-list-hover);position: fixed; top: ${event.clientY}px; left: ${event.clientX}px; z-index:999997;`); documentSelf.ondragstart = () => false; + let selectItem: HTMLElement; documentSelf.onmousemove = (moveEvent: MouseEvent) => { moveEvent.preventDefault(); moveEvent.stopPropagation(); ghostElement.style.top = moveEvent.clientY + "px"; ghostElement.style.left = moveEvent.clientX + "px"; + selectItem = hasClosestByClassName(moveEvent.target as HTMLElement, "b3-list-item") as HTMLElement; + if (!selectItem || selectItem.tagName !== "LI" || selectItem.isSameNode(item) || selectItem.style.position === "fixed" || !this.element.contains(selectItem)) { + return; + } + this.element.querySelectorAll(".dragover__top, .dragover__bottom, .dragover").forEach(item => { + item.classList.remove("dragover__top", "dragover__bottom", "dragover"); + }); + const selectRect = selectItem.getBoundingClientRect(); + if (moveEvent.clientY > selectRect.bottom - 10) { + selectItem.classList.add("dragover__bottom"); + } else if (moveEvent.clientY < selectRect.top + 10) { + selectItem.classList.add("dragover__top"); + } else { + selectItem.classList.add("dragover"); + } }; documentSelf.onmouseup = () => { @@ -254,26 +271,29 @@ export class Outline extends Model { documentSelf.onselectstart = null; documentSelf.onselect = null; ghostElement.remove(); - const selectItem = hasClosestByClassName(event.target as HTMLElement, "b3-list-item"); - if (!selectItem || selectItem.tagName !== "LI") { + item.style.opacity = ""; + this.element.querySelectorAll(".dragover__top, .dragover__bottom, .dragover").forEach(item => { + item.classList.remove("dragover__top", "dragover__bottom", "dragover"); + }); + if (!selectItem) { return; } getAllModels().editor.find(editItem => { if (editItem.editor.protyle.block.rootID === this.blockId) { transaction(editItem.editor.protyle, [{ action: "moveOutlineHeading", - id: item.dataset.blockId, + id: item.dataset.nodeId, previousID: selectItem.previousElementSibling?.getAttribute("data-node-id"), parentID: selectItem.parentElement.previousElementSibling?.getAttribute("data-node-id"), }], [{ action: "moveOutlineHeading", - id: item.dataset.blockId, + id: item.dataset.nodeId, previousID: item.previousElementSibling?.getAttribute("data-node-id"), parentID: item.parentElement.previousElementSibling?.getAttribute("data-node-id"), }]); return true; } - }) + }); }; }); } diff --git a/app/src/util/Tree.ts b/app/src/util/Tree.ts index c6fa75da21..f13d496dd3 100644 --- a/app/src/util/Tree.ts +++ b/app/src/util/Tree.ts @@ -87,6 +87,7 @@ export class Tree { html += `
  • style = `padding-left: ${(item.depth - 1) * 18 + 22}px;margin-right: 2px`; } html += `
  • Date: Fri, 29 Mar 2024 11:55:21 +0800 Subject: [PATCH 33/87] :bug: Fix arg check https://github.com/Yimien/plugin-memos-sync/issues/16 --- kernel/api/block_op.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/api/block_op.go b/kernel/api/block_op.go index 0e0b32cdea..65d9a96a2a 100644 --- a/kernel/api/block_op.go +++ b/kernel/api/block_op.go @@ -418,13 +418,13 @@ func insertBlock(c *gin.Context) { } if nil != arg["previousID"] { previousID = arg["previousID"].(string) - if "" != previousID && util.InvalidIDPattern(parentID, ret) { + if "" != previousID && util.InvalidIDPattern(previousID, ret) { return } } if nil != arg["nextID"] { nextID = arg["nextID"].(string) - if "" != nextID && util.InvalidIDPattern(parentID, ret) { + if "" != nextID && util.InvalidIDPattern(nextID, ret) { return } } From c0a10ab98c24a5c9f6920a796106e154003b37b0 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Fri, 29 Mar 2024 17:09:13 +0800 Subject: [PATCH 34/87] :art: Improve API Token authentication https://github.com/siyuan-note/siyuan/issues/10792 --- kernel/model/session.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/kernel/model/session.go b/kernel/model/session.go index d3d80dc264..1f1ea22734 100644 --- a/kernel/model/session.go +++ b/kernel/model/session.go @@ -235,8 +235,18 @@ func CheckAuth(c *gin.Context) { // 通过 API token (header: Authorization) if authHeader := c.GetHeader("Authorization"); "" != authHeader { + var token string if strings.HasPrefix(authHeader, "Token ") { - token := strings.TrimPrefix(authHeader, "Token ") + token = strings.TrimPrefix(authHeader, "Token ") + } else if strings.HasPrefix(authHeader, "token ") { + token = strings.TrimPrefix(authHeader, "token ") + } else if strings.HasPrefix(authHeader, "Bearer ") { + token = strings.TrimPrefix(authHeader, "Bearer ") + } else if strings.HasPrefix(authHeader, "bearer ") { + token = strings.TrimPrefix(authHeader, "bearer ") + } + + if "" != token { if Conf.Api.Token == token { c.Next() return From fa502ef2c4a907d71dc133b69979c6f7e8609a34 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Fri, 29 Mar 2024 19:42:28 +0800 Subject: [PATCH 35/87] :art: Improve API Token authentication https://github.com/siyuan-note/siyuan/issues/10792 --- app/appearance/langs/en_US.json | 2 +- app/appearance/langs/es_ES.json | 2 +- app/appearance/langs/fr_FR.json | 2 +- app/appearance/langs/zh_CHT.json | 2 +- app/appearance/langs/zh_CN.json | 2 +- app/src/config/about.ts | 2 +- app/src/mobile/settings/about.ts | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/appearance/langs/en_US.json b/app/appearance/langs/en_US.json index 2479b18313..955c6a60d1 100644 --- a/app/appearance/langs/en_US.json +++ b/app/appearance/langs/en_US.json @@ -1079,7 +1079,7 @@ "about11": "Network serving", "about12": "After enabling, other devices in the same LAN will be allowed to access. The application will be closed automatically after modification, please restart manually", "about13": "API token", - "about14": "The token needs to be authenticated when calling the API", + "about14": "The token needs to be authenticated when calling the API
    HTTP request header Authorization: token ${token}", "about17": "Do not enable proxy when set to Direct connection", "about18": "When using a non-loopback address (127.0.0.1/[::1]) please set the Access authorization code first", "checkUpdate": "Check update", diff --git a/app/appearance/langs/es_ES.json b/app/appearance/langs/es_ES.json index 410d08aab7..9d526c571a 100644 --- a/app/appearance/langs/es_ES.json +++ b/app/appearance/langs/es_ES.json @@ -1079,7 +1079,7 @@ "about11": "Red de servicio", "about12": "Después de habilitarlo, se permitirá el acceso a otros dispositivos de la misma LAN. La aplicación se cerrará automáticamente después de la modificación, por favor reinicie manualmente", "about13": "Token API", - "about14": "El token debe ser autentificado al llamar a la API", + "about14": "El token debe ser autentificado al llamar a la API
    Encabezado de solicitud HTTP Authorization: token ${token}", "about17": "No habilite el proxy cuando esté configurado como Conexión directa", "about18": "Cuando se utiliza una dirección sin bucle invertido (127.0.0.1/[::1] ) Primero configure el Código de autorización de acceso", "checkUpdate": "Comprobar actualización", diff --git a/app/appearance/langs/fr_FR.json b/app/appearance/langs/fr_FR.json index cd5ca14cde..63bd467b45 100644 --- a/app/appearance/langs/fr_FR.json +++ b/app/appearance/langs/fr_FR.json @@ -1079,7 +1079,7 @@ "about11": "Service de réseau", "about12": "Après l'activation, les autres appareils du même réseau local seront autorisés à accéder. L'application sera fermée automatiquement après modification, veuillez la redémarrer manuellement.", "about13": "API token", - "about14": "Le token doit être authentifié lors de l'appel de l'API.", + "about14": "Le token doit être authentifié lors de l'appel de l'API
    En-tête de requête HTTP Authorization: token ${token}", "about17": "N'activez pas le proxy lorsqu'il est défini sur Connexion directe.", "about18": "Lors de l'utilisation d'une adresse sans bouclage (127.0.0.1/[::1] ) Veuillez d'abord définir le Accès code d'autorisation", "checkUpdate": "Vérifier la mise à jour", diff --git a/app/appearance/langs/zh_CHT.json b/app/appearance/langs/zh_CHT.json index aa09690577..38fd348205 100644 --- a/app/appearance/langs/zh_CHT.json +++ b/app/appearance/langs/zh_CHT.json @@ -1079,7 +1079,7 @@ "about11": "網路伺服", "about12": "啟用後將允許同一區域網內的其他設備進行存取。修改後會自動關閉應用,請手動重啟", "about13": "API token", - "about14": "調用 API 時需要通過該 token 進行鑒權", + "about14": "調用 API 時需要通過該 token 進行鑒權
    HTTP 請求標頭 Authorization: token ${token}", "about17": "設置為 直接連接 時不啟用代理", "about18": "使用非環回地址(127.0.0.1/[::1])時請先設置訪問授權碼", "checkUpdate": "檢查更新", diff --git a/app/appearance/langs/zh_CN.json b/app/appearance/langs/zh_CN.json index c3e3bb495a..f518894545 100644 --- a/app/appearance/langs/zh_CN.json +++ b/app/appearance/langs/zh_CN.json @@ -1079,7 +1079,7 @@ "about11": "网络伺服", "about12": "启用后将允许同一局域网内的其他设备进行访问。修改后会自动关闭应用,请手动重启", "about13": "API token", - "about14": "调用 API 时需要通过该 token 进行鉴权", + "about14": "调用 API 时需要通过该 token 进行鉴权
    HTTP 请求标头 Authorization: token ${token}", "about17": "设置为 直接连接 时不启用代理", "about18": "使用非环回地址(127.0.0.1/[::1])时请先设置 访问授权码", "checkUpdate": "检查更新", diff --git a/app/src/config/about.ts b/app/src/config/about.ts index 3d3f52d173..dd58986be9 100644 --- a/app/src/config/about.ts +++ b/app/src/config/about.ts @@ -155,7 +155,7 @@ export const about = {
    ${window.siyuan.languages.about13} -
    ${window.siyuan.languages.about14}
    +
    ${window.siyuan.languages.about14.replace("${token}", window.siyuan.config.api.token)}
    diff --git a/app/src/mobile/settings/about.ts b/app/src/mobile/settings/about.ts index b8035e24e2..68e34f4a3d 100644 --- a/app/src/mobile/settings/about.ts +++ b/app/src/mobile/settings/about.ts @@ -131,7 +131,7 @@ export const initAbout = () => { ${window.siyuan.languages.copy}
    -
    ${window.siyuan.languages.about14}
    +
    ${window.siyuan.languages.about14.replace("${token}", window.siyuan.config.api.token)}
    @@ -110,7 +109,6 @@ export const initAbout = () => { ${window.siyuan.languages.import} -
    ${window.siyuan.languages.importDataTip}
    @@ -131,7 +129,7 @@ export const initAbout = () => { ${window.siyuan.languages.copy}
    -
    ${window.siyuan.languages.about14.replace("${token}", window.siyuan.config.api.token)}
    +
    ${window.siyuan.languages.about14.replace("${token}", window.siyuan.config.api.token)}
    +
    -
    - +
    `, width: isMobile() ? "92vw" : "520px", }); diff --git a/app/src/menus/workspace.ts b/app/src/menus/workspace.ts index 9679ed3942..4edd5ed269 100644 --- a/app/src/menus/workspace.ts +++ b/app/src/menus/workspace.ts @@ -34,9 +34,9 @@ const editLayout = (layoutName?: string) => {
    +
    -
    - +
    `, width: "520px", }); From 487e2f980bc9859194bf617a34911c2ee8a9b77d Mon Sep 17 00:00:00 2001 From: Vanessa Date: Sun, 31 Mar 2024 09:39:46 +0800 Subject: [PATCH 61/87] :art: https://github.com/siyuan-note/siyuan/pull/10804 --- app/src/ai/actions.ts | 8 ++++---- app/src/menus/workspace.ts | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/src/ai/actions.ts b/app/src/ai/actions.ts index 0527f85994..19622fdde7 100644 --- a/app/src/ai/actions.ts +++ b/app/src/ai/actions.ts @@ -47,13 +47,13 @@ const editDialog = (customName: string, customMemo: string) => { const customElement = dialog.element.querySelector("textarea"); const btnsElement = dialog.element.querySelectorAll(".b3-button"); dialog.bindInput(customElement, () => { - (btnsElement[1] as HTMLButtonElement).click(); + (btnsElement[2] as HTMLButtonElement).click(); }); customElement.value = customMemo; - btnsElement[0].addEventListener("click", () => { + btnsElement[1].addEventListener("click", () => { dialog.destroy(); }); - btnsElement[1].addEventListener("click", () => { + btnsElement[2].addEventListener("click", () => { window.siyuan.storage[Constants.LOCAL_AI].find((subItem: { name: string, memo: string @@ -67,7 +67,7 @@ const editDialog = (customName: string, customMemo: string) => { }); dialog.destroy(); }); - btnsElement[2].addEventListener("click", () => { + btnsElement[0].addEventListener("click", () => { window.siyuan.storage[Constants.LOCAL_AI].find((subItem: { name: string, memo: string diff --git a/app/src/menus/workspace.ts b/app/src/menus/workspace.ts index 4edd5ed269..a00d8d09d5 100644 --- a/app/src/menus/workspace.ts +++ b/app/src/menus/workspace.ts @@ -46,12 +46,12 @@ const editLayout = (layoutName?: string) => { inputElement.select(); inputElement.focus(); dialog.bindInput(inputElement, () => { - btnsElement[1].dispatchEvent(new CustomEvent("click")); + btnsElement[2].dispatchEvent(new CustomEvent("click")); }); - btnsElement[0].addEventListener("click", () => { + btnsElement[1].addEventListener("click", () => { dialog.destroy(); }); - btnsElement[1].addEventListener("click", () => { + btnsElement[2].addEventListener("click", () => { const value = inputElement.value; if (!value) { showMessage(window.siyuan.languages["_kernel"]["142"]); @@ -88,7 +88,7 @@ const editLayout = (layoutName?: string) => { }); setStorageVal(Constants.LOCAL_LAYOUTS, window.siyuan.storage[Constants.LOCAL_LAYOUTS]); }); - btnsElement[2].addEventListener("click", () => { + btnsElement[0].addEventListener("click", () => { window.siyuan.storage[Constants.LOCAL_LAYOUTS].find((layoutItem: ISaveLayout, index: number) => { if (layoutItem.name === layoutName) { window.siyuan.storage[Constants.LOCAL_LAYOUTS].splice(index, 1); From 8853b9a1923479417b78cffe5f2398faccf78ef5 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Sun, 31 Mar 2024 09:58:50 +0800 Subject: [PATCH 62/87] :art: https://github.com/siyuan-note/siyuan/issues/10789 --- app/src/protyle/render/av/cell.ts | 10 ++++++---- app/src/protyle/wysiwyg/index.ts | 9 +-------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/app/src/protyle/render/av/cell.ts b/app/src/protyle/render/av/cell.ts index c444bc3897..16ebcdd2be 100644 --- a/app/src/protyle/render/av/cell.ts +++ b/app/src/protyle/render/av/cell.ts @@ -18,10 +18,12 @@ const renderCellURL = (urlContent: string) => { let suffix = ""; try { const urlObj = new URL(urlContent); - host = urlObj.host; - suffix = urlObj.href.replace(urlObj.origin, ""); - if (suffix.length > 12) { - suffix = suffix.substring(0, 4) + "..." + suffix.substring(suffix.length - 6); + if (urlObj.protocol.startsWith("http")) { + host = urlObj.host; + suffix = urlObj.href.replace(urlObj.origin, ""); + if (suffix.length > 12) { + suffix = suffix.substring(0, 4) + "..." + suffix.substring(suffix.length - 6); + } } } catch (e) { // 不是 url 地址 diff --git a/app/src/protyle/wysiwyg/index.ts b/app/src/protyle/wysiwyg/index.ts index 831f7dac02..2219bd3121 100644 --- a/app/src/protyle/wysiwyg/index.ts +++ b/app/src/protyle/wysiwyg/index.ts @@ -1983,14 +1983,7 @@ export class WYSIWYG { // 需放在嵌入块之前,否则嵌入块内的引用、链接、pdf 双链无法点击打开 https://ld246.com/article/1630479789513 const blockRefElement = hasClosestByAttribute(event.target, "data-type", "block-ref"); const aElement = hasClosestByAttribute(event.target, "data-type", "a") || hasClosestByAttribute(event.target, "data-type", "url"); - let aLink = ""; - if (aElement) { - if (aElement.classList.contains("av__celltext")) { - aLink = aElement.textContent.trim(); - } else { - aLink = aElement.getAttribute("data-href"); - } - } + const aLink = aElement ? aElement.getAttribute("data-href") : ""; if (blockRefElement || aLink.startsWith("siyuan://blocks/")) { event.stopPropagation(); event.preventDefault(); From cfe93a0acc92eca871fc573a5605475d823f5bb1 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Sun, 31 Mar 2024 11:15:33 +0800 Subject: [PATCH 63/87] :art: https://github.com/siyuan-note/siyuan/issues/10805 --- app/src/protyle/wysiwyg/enter.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/protyle/wysiwyg/enter.ts b/app/src/protyle/wysiwyg/enter.ts index a7567e8e0a..e8ae88dacf 100644 --- a/app/src/protyle/wysiwyg/enter.ts +++ b/app/src/protyle/wysiwyg/enter.ts @@ -17,8 +17,12 @@ import {isIPad, setStorageVal} from "../util/compatibility"; import {mathRender} from "../render/mathRender"; import {isMobile} from "../../util/functions"; import {processRender} from "../util/processCode"; +import {hasClosestByClassName} from "../util/hasClosest"; export const enter = (blockElement: HTMLElement, range: Range, protyle: IProtyle) => { + if (hasClosestByClassName(blockElement, "protyle-wysiwyg__embed")) { + return; + } const disableElement = isNotEditBlock(blockElement); if (!disableElement && blockElement.classList.contains("protyle-wysiwyg--select")) { setLastNodeRange(getContenteditableElement(blockElement), range, false); From 275b4bb98c39a28e2469032a7a2a3611b61eff0a Mon Sep 17 00:00:00 2001 From: Vanessa Date: Sun, 31 Mar 2024 11:47:38 +0800 Subject: [PATCH 64/87] :art: fix https://github.com/siyuan-note/siyuan/issues/10806 --- app/src/boot/globalEvent/keydown.ts | 18 +++++++++++++++++- app/src/protyle/wysiwyg/keydown.ts | 16 ---------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/app/src/boot/globalEvent/keydown.ts b/app/src/boot/globalEvent/keydown.ts index fd9a014b7a..5d120efc61 100644 --- a/app/src/boot/globalEvent/keydown.ts +++ b/app/src/boot/globalEvent/keydown.ts @@ -42,7 +42,7 @@ import {deleteFiles} from "../../editor/deleteFile"; import {escapeHtml} from "../../util/escape"; import {syncGuide} from "../../sync/syncGuide"; import {showPopover} from "../../block/popover"; -import {getStartEndElement} from "../../protyle/wysiwyg/commonHotkey"; +import {getStartEndElement, goEnd, goHome} from "../../protyle/wysiwyg/commonHotkey"; import {getNextFileLi, getPreviousFileLi} from "../../protyle/wysiwyg/getBlock"; import {editor} from "../../config/editor"; import {hintMoveBlock} from "../../protyle/hint/extend"; @@ -400,6 +400,22 @@ const editKeydown = (app: App, event: KeyboardEvent) => { if (target.tagName !== "TABLE" && ["INPUT", "TEXTAREA"].includes(target.tagName)) { return false; } + // ctrl+home 光标移动到顶 + if (!event.altKey && !event.shiftKey && isOnlyMeta(event) && event.key === "Home") { + goHome(protyle); + hideElements(["select"], protyle); + event.stopPropagation(); + event.preventDefault(); + return; + } + // ctrl+end 光标移动到尾 + if (!event.altKey && !event.shiftKey && isOnlyMeta(event) && event.key === "End") { + goEnd(protyle); + hideElements(["select"], protyle); + event.stopPropagation(); + event.preventDefault(); + return; + } if (matchHotKey(window.siyuan.config.keymap.editor.general.exitFocus.custom, event)) { event.preventDefault(); zoomOut({protyle, id: protyle.block.rootID, focusId: protyle.block.id}); diff --git a/app/src/protyle/wysiwyg/keydown.ts b/app/src/protyle/wysiwyg/keydown.ts index feec26d010..9153e74070 100644 --- a/app/src/protyle/wysiwyg/keydown.ts +++ b/app/src/protyle/wysiwyg/keydown.ts @@ -500,22 +500,6 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => { event.preventDefault(); return; } - // ctrl+home 光标移动到顶 - if (!event.altKey && !event.shiftKey && isOnlyMeta(event) && event.key === "Home") { - goHome(protyle); - hideElements(["select"], protyle); - event.stopPropagation(); - event.preventDefault(); - return; - } - // ctrl+end 光标移动到尾 - if (!event.altKey && !event.shiftKey && isOnlyMeta(event) && event.key === "End") { - goEnd(protyle); - hideElements(["select"], protyle); - event.stopPropagation(); - event.preventDefault(); - return; - } // 向上/下滚动一屏 if (!event.altKey && !event.shiftKey && isNotCtrl(event) && (event.key === "PageUp" || event.key === "PageDown")) { if (event.key === "PageUp") { From 353fdc7b29d7a3a686aa8a6eb4d1a819dd745f1e Mon Sep 17 00:00:00 2001 From: Vanessa Date: Sun, 31 Mar 2024 17:51:15 +0800 Subject: [PATCH 65/87] :art: fix https://github.com/siyuan-note/siyuan/issues/10808 --- app/src/protyle/wysiwyg/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/protyle/wysiwyg/index.ts b/app/src/protyle/wysiwyg/index.ts index 2219bd3121..40edf923a7 100644 --- a/app/src/protyle/wysiwyg/index.ts +++ b/app/src/protyle/wysiwyg/index.ts @@ -2095,7 +2095,7 @@ export class WYSIWYG { return; } - if (aElement) { + if (aElement && range.toString() === "") { event.stopPropagation(); event.preventDefault(); let linkAddress = Lute.UnEscapeHTMLStr(aLink); From 6378d1e73837d6f9163ada0c6d0f5524e8eaf470 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Sun, 31 Mar 2024 20:18:34 +0800 Subject: [PATCH 66/87] :art: fix https://github.com/siyuan-note/siyuan/issues/10738 --- app/src/assets/scss/component/_menu.scss | 12 ++++++++ app/src/protyle/render/av/openMenuPanel.ts | 7 ++++- app/src/protyle/render/av/select.ts | 34 +++++++++++++++++----- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/app/src/assets/scss/component/_menu.scss b/app/src/assets/scss/component/_menu.scss index 10380fcafd..35fc29e38b 100644 --- a/app/src/assets/scss/component/_menu.scss +++ b/app/src/assets/scss/component/_menu.scss @@ -284,6 +284,18 @@ } } + &__checked { + width: 22px; + height: 22px; + align-self: center; + margin-left: 8px; + color: var(--b3-theme-on-surface-light); + border-radius: var(--b3-border-radius); + padding: 4px; + box-sizing: border-box; + translate: var(--b3-transition); + } + &__separator { background-color: var(--b3-theme-surface-lighter); height: 1px; diff --git a/app/src/protyle/render/av/openMenuPanel.ts b/app/src/protyle/render/av/openMenuPanel.ts index b11fc064f7..9882172500 100644 --- a/app/src/protyle/render/av/openMenuPanel.ts +++ b/app/src/protyle/render/av/openMenuPanel.ts @@ -32,6 +32,7 @@ import {updateCellsValue} from "./cell"; import {openCalcMenu} from "./calc"; import * as dayjs from "dayjs"; import {confirmDialog} from "../../../dialog/confirmDialog"; +import {escapeAttr} from "../../../util/escape"; export const openMenuPanel = (options: { protyle: IProtyle, @@ -1074,7 +1075,11 @@ export const openMenuPanel = (options: { event.stopPropagation(); break; } else if (type === "addColOptionOrCell") { - addColOptionOrCell(options.protyle, data, options.cellElements, target, menuElement, options.blockElement); + if (target.querySelector(".b3-menu__checked")) { + removeCellOption(options.protyle, data, options.cellElements, menuElement.querySelector(`.b3-chips .b3-chip[data-content="${escapeAttr(target.dataset.name)}"]`), options.blockElement); + } else { + addColOptionOrCell(options.protyle, data, options.cellElements, target, menuElement, options.blockElement); + } window.siyuan.menus.menu.remove(); event.preventDefault(); event.stopPropagation(); diff --git a/app/src/protyle/render/av/select.ts b/app/src/protyle/render/av/select.ts index d4fe699f83..d8c92133e6 100644 --- a/app/src/protyle/render/av/select.ts +++ b/app/src/protyle/render/av/select.ts @@ -9,15 +9,21 @@ import {genAVValueHTML} from "./blockAttr"; import {escapeAttr} from "../../../util/escape"; import {genCellValueByElement, getTypeByCellElement} from "./cell"; -const filterSelectHTML = (key: string, options: { name: string, color: string }[]) => { +const filterSelectHTML = (key: string, options: { name: string, color: string }[], selected: string[] = []) => { let html = ""; let hasMatch = false; + if (selected.length === 0) { + document.querySelectorAll(".av__panel .b3-chips .b3-chip").forEach((item: HTMLElement) => { + selected.push(item.dataset.content); + }); + } + const checkedName = document.querySelector('.av__panel .b3-menu__item--current[data-type="addColOptionOrCell"]')?.getAttribute("data-name") || "" if (options) { options.forEach(item => { if (!key || (key.toLowerCase().indexOf(item.name.toLowerCase()) > -1 || item.name.toLowerCase().indexOf(key.toLowerCase()) > -1)) { - html += ``; } if (key === item.name) { @@ -33,6 +40,7 @@ const filterSelectHTML = (key: string, options: { name: string, color: string }[ }); } if (!hasMatch && key) { + html = html.replace('class="b3-menu__item b3-menu__item--current"', 'class="b3-menu__item"'); const colorIndex = (options?.length || 0) % 13 + 1; html = `${html}`; - } else { + } else if (html.indexOf("b3-menu__item--current") === -1) { if (key) { - html = html.replace(`class="b3-menu__item" data-name="${key}"` , `class="b3-menu__item b3-menu__item--current" data-name="${key}"`); + html = html.replace(`class="b3-menu__item" data-name="${key}"`, `class="b3-menu__item b3-menu__item--current" data-name="${key}"`); } else { - html = html.replace('class="b3-menu__item"' , 'class="b3-menu__item b3-menu__item--current"'); + html = html.replace('class="b3-menu__item"', 'class="b3-menu__item b3-menu__item--current"'); } } return html; @@ -113,6 +121,12 @@ export const removeCellOption = (protyle: IProtyle, data: IAV, cellElements: HTM } }); transaction(protyle, doOperations, undoOperations); + Array.from(document.querySelectorAll(".av__panel .b3-menu__item")).find((item: HTMLElement) => { + if (item.dataset.name === target.dataset.content) { + item.querySelector(".b3-menu__checked")?.remove(); + return true; + } + }) target.remove(); }; @@ -413,7 +427,11 @@ export const bindSelectEvent = (protyle: IProtyle, data: IAV, menuElement: HTMLE if (!currentElement) { currentElement = menuElement.querySelector(".b3-menu__item--current"); } - addColOptionOrCell(protyle, data, cellElements, currentElement, menuElement, blockElement); + if (currentElement.querySelector(".b3-menu__checked")) { + removeCellOption(protyle, data, cellElements, menuElement.querySelector(`.b3-chips .b3-chip[data-content="${escapeAttr(currentElement.dataset.name)}"]`), blockElement); + } else { + addColOptionOrCell(protyle, data, cellElements, currentElement, menuElement, blockElement); + } } else if (event.key === "Backspace" && inputElement.value === "") { removeCellOption(protyle, data, cellElements, inputElement.previousElementSibling as HTMLElement, blockElement); } @@ -562,7 +580,9 @@ export const getSelectHTML = (data: IAVTable, cellElements: HTMLElement[]) => { }); let selectedHTML = ""; + const selected: string[] = [] genCellValueByElement(colData.type, cellElements[0]).mSelect?.forEach((item) => { + selected.push(item.content) selectedHTML += `
    ${item.content}
    `; }); @@ -571,6 +591,6 @@ export const getSelectHTML = (data: IAVTable, cellElements: HTMLElement[]) => { ${selectedHTML} -
    ${filterSelectHTML("", colData.options)}
    +
    ${filterSelectHTML("", colData.options, selected)}
    `; }; From 5aabda4b37c84bf092b8bb28575a1ddcc8c836ae Mon Sep 17 00:00:00 2001 From: Vanessa Date: Sun, 31 Mar 2024 20:27:29 +0800 Subject: [PATCH 67/87] :recycle: b3-menu__checked --- app/src/menus/Menu.ts | 3 +++ app/src/protyle/render/av/col.ts | 2 +- app/src/protyle/render/av/select.ts | 8 ++++---- app/src/types/index.d.ts | 1 + 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/app/src/menus/Menu.ts b/app/src/menus/Menu.ts index ba8318b66c..6184569c8e 100644 --- a/app/src/menus/Menu.ts +++ b/app/src/menus/Menu.ts @@ -224,6 +224,9 @@ export class MenuItem { if (options.action) { html += ``; } + if (options.checked) { + html += '' + } this.element.innerHTML = html; } diff --git a/app/src/protyle/render/av/col.ts b/app/src/protyle/render/av/col.ts index 7273ded8a4..4ba4bd57b4 100644 --- a/app/src/protyle/render/av/col.ts +++ b/app/src/protyle/render/av/col.ts @@ -854,7 +854,7 @@ const genUpdateColItem = (type: TAVCol, oldType: TAVCol, name: string) => { return ``; }; diff --git a/app/src/protyle/render/av/select.ts b/app/src/protyle/render/av/select.ts index d8c92133e6..873f29d114 100644 --- a/app/src/protyle/render/av/select.ts +++ b/app/src/protyle/render/av/select.ts @@ -301,15 +301,15 @@ export const setColOption = (protyle: IProtyle, data: IAV, target: HTMLElement, menu.addSeparator(); Array.from(Array(13).keys()).forEach(index => { menu.addItem({ - accelerator: parseInt(color) === index + 1 ? '' : undefined, + checked: parseInt(color) === index + 1, iconHTML: "", label: `A`, click(element) { - if (element.lastElementChild.classList.contains("b3-menu__accelerator")) { + if (element.lastElementChild.classList.contains("b3-menu__checked")) { return; } - element.parentElement.querySelector(".b3-menu__accelerator")?.remove(); - element.insertAdjacentHTML("beforeend", ''); + element.parentElement.querySelector(".b3-menu__checked")?.remove(); + element.insertAdjacentHTML("beforeend", ''); transaction(protyle, [{ action: "updateAttrViewColOption", id: colId, diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts index 090aaa31d6..c18a87edc0 100644 --- a/app/src/types/index.d.ts +++ b/app/src/types/index.d.ts @@ -708,6 +708,7 @@ interface IModels { } interface IMenu { + checked?: boolean, iconClass?: string, label?: string, click?: (element: HTMLElement, event: MouseEvent) => boolean | void | Promise From 2713afd7c9c436d3dffaa76f2e52fa7070910e7a Mon Sep 17 00:00:00 2001 From: Vanessa Date: Sun, 31 Mar 2024 23:29:32 +0800 Subject: [PATCH 68/87] :recycle: b3-menu__checked --- app/src/protyle/render/av/row.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/protyle/render/av/row.ts b/app/src/protyle/render/av/row.ts index 62e4c7122f..d4a437aa9a 100644 --- a/app/src/protyle/render/av/row.ts +++ b/app/src/protyle/render/av/row.ts @@ -250,7 +250,7 @@ export const setPageSize = (options: { menu.addItem({ iconHTML: "", label: "10", - accelerator: currentPageSize === "10" ? '' : undefined, + checked: currentPageSize === "10", click() { updatePageSize({ currentPageSize, @@ -263,7 +263,7 @@ export const setPageSize = (options: { }); menu.addItem({ iconHTML: "", - accelerator: currentPageSize === "25" ? '' : undefined, + checked: currentPageSize === "25", label: "25", click() { updatePageSize({ @@ -277,7 +277,7 @@ export const setPageSize = (options: { }); menu.addItem({ iconHTML: "", - accelerator: currentPageSize === "50" ? '' : undefined, + checked: currentPageSize === "50", label: "50", click() { updatePageSize({ @@ -291,7 +291,7 @@ export const setPageSize = (options: { }); menu.addItem({ iconHTML: "", - accelerator: currentPageSize === "100" ? '' : undefined, + checked: currentPageSize === "100", label: "100", click() { updatePageSize({ From 5e7d2341f407d351e4f96fdc712608fb7dd712b6 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sun, 31 Mar 2024 23:01:00 +0800 Subject: [PATCH 69/87] :art: Add comments https://github.com/siyuan-note/siyuan/issues/10800#issuecomment-2028788064 --- kernel/model/search.go | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/model/search.go b/kernel/model/search.go index 4ab66416b0..b29ae1ab30 100644 --- a/kernel/model/search.go +++ b/kernel/model/search.go @@ -424,6 +424,7 @@ func FindReplace(keyword, replacement string, replaceTypes map[string]bool, ids if 0 != groupBy { // 按文档分组后不支持替换 Need to be reminded that replacement operations are not supported after grouping by doc https://github.com/siyuan-note/siyuan/issues/10161 + // 因为分组条件传入以后搜索只能命中文档块,会导致 全部替换 失效 err = errors.New(Conf.Language(221)) return } From c559ac45bedde2ac5f654bc86312b39dd0d8610f Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sun, 31 Mar 2024 23:32:00 +0800 Subject: [PATCH 70/87] :art: Template supports numerical calculations when using rollup https://github.com/siyuan-note/siyuan/issues/10810 --- kernel/model/attribute_view.go | 7 +++++++ kernel/treenode/node.go | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 70c4a481a9..ec66f5c339 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -811,6 +811,13 @@ func renderTemplateCol(ial map[string]string, flashcard *Flashcard, rowValues [] dataModel[rowValue.Key.Name] = v.Number.Content } else if av.KeyTypeDate == v.Type { dataModel[rowValue.Key.Name] = time.UnixMilli(v.Date.Content) + } else if av.KeyTypeRollup == v.Type { + if 0 < len(v.Rollup.Contents) && av.KeyTypeNumber == v.Rollup.Contents[0].Type { + // 模板使用汇总时支持数字计算 + // Template supports numerical calculations when using rollup https://github.com/siyuan-note/siyuan/issues/10810 + // 汇总数字时仅取第一个数字填充模板 + dataModel[rowValue.Key.Name] = v.Rollup.Contents[0].Number.Content + } } else { dataModel[rowValue.Key.Name] = v.String() } diff --git a/kernel/treenode/node.go b/kernel/treenode/node.go index 8be45db601..19cbb41fa9 100644 --- a/kernel/treenode/node.go +++ b/kernel/treenode/node.go @@ -1081,6 +1081,11 @@ func renderTemplateCol(ial map[string]string, rowValues []*av.KeyValues, tplCont dataModel[rowValue.Key.Name] = v.Number.Content } else if av.KeyTypeDate == v.Type { dataModel[rowValue.Key.Name] = time.UnixMilli(v.Date.Content) + } else if av.KeyTypeRollup == v.Type { + if 0 < len(v.Rollup.Contents) && av.KeyTypeNumber == v.Rollup.Contents[0].Type { + // 汇总数字时仅取第一个数字填充模板 + dataModel[rowValue.Key.Name] = v.Rollup.Contents[0].Number.Content + } } else { dataModel[rowValue.Key.Name] = v.String() } From 8f2fa0acd8127be0e0b18a5ee274b25c8db018f4 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Sun, 31 Mar 2024 23:41:05 +0800 Subject: [PATCH 71/87] :art: https://github.com/siyuan-note/siyuan/issues/10783 --- app/src/menus/workspace.ts | 42 ++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/app/src/menus/workspace.ts b/app/src/menus/workspace.ts index a00d8d09d5..a727b7e21b 100644 --- a/app/src/menus/workspace.ts +++ b/app/src/menus/workspace.ts @@ -34,9 +34,10 @@ const editLayout = (layoutName?: string) => {
    -
    +
    - +
    +
    `, width: "520px", }); @@ -46,12 +47,37 @@ const editLayout = (layoutName?: string) => { inputElement.select(); inputElement.focus(); dialog.bindInput(inputElement, () => { - btnsElement[2].dispatchEvent(new CustomEvent("click")); + btnsElement[3].dispatchEvent(new CustomEvent("click")); + }); + btnsElement[0].addEventListener("click", () => { + window.siyuan.storage[Constants.LOCAL_LAYOUTS].find((layoutItem: ISaveLayout, index: number) => { + if (layoutItem.name === layoutName) { + window.siyuan.storage[Constants.LOCAL_LAYOUTS].splice(index, 1); + setStorageVal(Constants.LOCAL_LAYOUTS, window.siyuan.storage[Constants.LOCAL_LAYOUTS]); + return true; + } + }); + dialog.destroy(); }); btnsElement[1].addEventListener("click", () => { dialog.destroy(); }); btnsElement[2].addEventListener("click", () => { + const value = inputElement.value; + if (!value) { + showMessage(window.siyuan.languages["_kernel"]["142"]); + return; + } + dialog.destroy(); + window.siyuan.storage[Constants.LOCAL_LAYOUTS].find((layoutItem: ISaveLayout) => { + if (layoutItem.name === layoutName) { + layoutItem.name = value; + setStorageVal(Constants.LOCAL_LAYOUTS, window.siyuan.storage[Constants.LOCAL_LAYOUTS]); + return true; + } + }); + }); + btnsElement[3].addEventListener("click", () => { const value = inputElement.value; if (!value) { showMessage(window.siyuan.languages["_kernel"]["142"]); @@ -88,16 +114,6 @@ const editLayout = (layoutName?: string) => { }); setStorageVal(Constants.LOCAL_LAYOUTS, window.siyuan.storage[Constants.LOCAL_LAYOUTS]); }); - btnsElement[0].addEventListener("click", () => { - window.siyuan.storage[Constants.LOCAL_LAYOUTS].find((layoutItem: ISaveLayout, index: number) => { - if (layoutItem.name === layoutName) { - window.siyuan.storage[Constants.LOCAL_LAYOUTS].splice(index, 1); - setStorageVal(Constants.LOCAL_LAYOUTS, window.siyuan.storage[Constants.LOCAL_LAYOUTS]); - return true; - } - }); - dialog.destroy(); - }); }; const togglePinDock = (dock: Dock, icon: string) => { From 207330be7ab917a5f4f02a6dab84ebaf10d5ab30 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Sun, 31 Mar 2024 23:41:45 +0800 Subject: [PATCH 72/87] :rotating_light: --- app/src/menus/Menu.ts | 2 +- app/src/menus/workspace.ts | 1 - app/src/protyle/render/av/select.ts | 8 ++++---- app/src/protyle/wysiwyg/keydown.ts | 2 -- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/app/src/menus/Menu.ts b/app/src/menus/Menu.ts index 6184569c8e..bf434f5b02 100644 --- a/app/src/menus/Menu.ts +++ b/app/src/menus/Menu.ts @@ -225,7 +225,7 @@ export class MenuItem { html += ``; } if (options.checked) { - html += '' + html += ''; } this.element.innerHTML = html; } diff --git a/app/src/menus/workspace.ts b/app/src/menus/workspace.ts index a727b7e21b..aa19929558 100644 --- a/app/src/menus/workspace.ts +++ b/app/src/menus/workspace.ts @@ -97,7 +97,6 @@ const editLayout = (layoutName?: string) => { } const hadName = window.siyuan.storage[Constants.LOCAL_LAYOUTS].find((item: ISaveLayout) => { if (item.name === value) { - confirmDialog(window.siyuan.languages.save, window.siyuan.languages.exportTplTip, () => { item.layout = getAllLayout(); setStorageVal(Constants.LOCAL_LAYOUTS, window.siyuan.storage[Constants.LOCAL_LAYOUTS]); diff --git a/app/src/protyle/render/av/select.ts b/app/src/protyle/render/av/select.ts index 873f29d114..c4ca82982f 100644 --- a/app/src/protyle/render/av/select.ts +++ b/app/src/protyle/render/av/select.ts @@ -17,7 +17,7 @@ const filterSelectHTML = (key: string, options: { name: string, color: string }[ selected.push(item.dataset.content); }); } - const checkedName = document.querySelector('.av__panel .b3-menu__item--current[data-type="addColOptionOrCell"]')?.getAttribute("data-name") || "" + const checkedName = document.querySelector('.av__panel .b3-menu__item--current[data-type="addColOptionOrCell"]')?.getAttribute("data-name") || ""; if (options) { options.forEach(item => { if (!key || @@ -126,7 +126,7 @@ export const removeCellOption = (protyle: IProtyle, data: IAV, cellElements: HTM item.querySelector(".b3-menu__checked")?.remove(); return true; } - }) + }); target.remove(); }; @@ -580,9 +580,9 @@ export const getSelectHTML = (data: IAVTable, cellElements: HTMLElement[]) => { }); let selectedHTML = ""; - const selected: string[] = [] + const selected: string[] = []; genCellValueByElement(colData.type, cellElements[0]).mSelect?.forEach((item) => { - selected.push(item.content) + selected.push(item.content); selectedHTML += `
    ${item.content}
    `; }); diff --git a/app/src/protyle/wysiwyg/keydown.ts b/app/src/protyle/wysiwyg/keydown.ts index 9153e74070..47f55268e9 100644 --- a/app/src/protyle/wysiwyg/keydown.ts +++ b/app/src/protyle/wysiwyg/keydown.ts @@ -47,8 +47,6 @@ import { downSelect, duplicateBlock, getStartEndElement, - goEnd, - goHome, upSelect } from "./commonHotkey"; import {enterBack, fileAnnotationRefMenu, linkMenu, refMenu, setFold, tagMenu, zoomOut} from "../../menus/protyle"; From 85da3928beb1cd6719caae08a1230550b1c578d1 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sun, 31 Mar 2024 23:58:46 +0800 Subject: [PATCH 73/87] :bug: Attribute panel - Database template custom attributes not shown Fix https://github.com/siyuan-note/siyuan/issues/10812 --- kernel/model/attribute_view.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index ec66f5c339..5be4f36c9a 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -417,7 +417,7 @@ func GetBlockAttributeViewKeys(blockID string) (ret []*BlockAttributeViewKeys) { ial := map[string]string{} block := getRowBlockValue(keyValues) if nil != block && !block.IsDetached { - ial = GetBlockAttrsWithoutWaitWriting(block.ID) + ial = GetBlockAttrsWithoutWaitWriting(block.BlockID) } kv.Values[0].Template.Content = renderTemplateCol(ial, flashcard, keyValues, kv.Key.Template) From adcd4acda74046e47049fa0a797fde56282af183 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Mon, 1 Apr 2024 09:45:04 +0800 Subject: [PATCH 74/87] :memo: https://github.com/siyuan-note/siyuan/issues/10783#issuecomment-2028810246 --- app/appearance/langs/en_US.json | 1 + app/appearance/langs/es_ES.json | 1 + app/appearance/langs/fr_FR.json | 1 + app/appearance/langs/zh_CHT.json | 1 + app/appearance/langs/zh_CN.json | 1 + app/src/menus/workspace.ts | 2 +- 6 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/appearance/langs/en_US.json b/app/appearance/langs/en_US.json index 420303b5e5..a3f5478ded 100644 --- a/app/appearance/langs/en_US.json +++ b/app/appearance/langs/en_US.json @@ -1,4 +1,5 @@ { + "updateLayout": "Update layout", "dndFolderTip": "Please note that ${x} only inserts the file:// hyperlink and does not copy the file", "removeCol": "Are you sure you want to delete the ${x} column in the database?", "video": "Video", diff --git a/app/appearance/langs/es_ES.json b/app/appearance/langs/es_ES.json index 5e2198a73d..ec6a82453d 100644 --- a/app/appearance/langs/es_ES.json +++ b/app/appearance/langs/es_ES.json @@ -1,4 +1,5 @@ { + "updateLayout": "Actualizar diseño", "dndFolderTip": "Tenga en cuenta que ${x} solo inserta el hipervínculo file:// y no copia el archivo", "removeCol": "¿Está seguro de que desea eliminar la columna ${x} en la base de datos?", "vídeo": "Vídeo", diff --git a/app/appearance/langs/fr_FR.json b/app/appearance/langs/fr_FR.json index 30cf4ad67c..7722e10adc 100644 --- a/app/appearance/langs/fr_FR.json +++ b/app/appearance/langs/fr_FR.json @@ -1,4 +1,5 @@ { + "updateLayout": "Mettre à jour la mise en page", "dndFolderTip": "Veuillez noter que ${x} insère uniquement le lien hypertexte file:// et ne copie pas le fichier", "removeCol": "Êtes-vous sûr de vouloir supprimer la colonne ${x} de la base de données ?", "video": "Vidéo", diff --git a/app/appearance/langs/zh_CHT.json b/app/appearance/langs/zh_CHT.json index 7b705464ff..ef6d10ba78 100644 --- a/app/appearance/langs/zh_CHT.json +++ b/app/appearance/langs/zh_CHT.json @@ -1,4 +1,5 @@ { + "updateLayout": "更新版面配置", "dndFolderTip": "請注意 ${x} 僅插入 file:// 超鏈接,不複製檔案", "removeCol": "確定刪除資料庫中的 ${x} 欄位?", "video": "影片", diff --git a/app/appearance/langs/zh_CN.json b/app/appearance/langs/zh_CN.json index 916fe3aeed..ad825b794e 100644 --- a/app/appearance/langs/zh_CN.json +++ b/app/appearance/langs/zh_CN.json @@ -1,4 +1,5 @@ { + "updateLayout": "更新布局", "dndFolderTip": "请注意 ${x} 仅插入 file:// 超链接,不复制文件", "removeCol": "确定删除数据库中的 ${x} 列?", "video": "视频", diff --git a/app/src/menus/workspace.ts b/app/src/menus/workspace.ts index aa19929558..eac18d7d30 100644 --- a/app/src/menus/workspace.ts +++ b/app/src/menus/workspace.ts @@ -37,7 +37,7 @@ const editLayout = (layoutName?: string) => {
    - + `, width: "520px", }); From 1f5715201f7f9852e038fbf1cbfd4d0958964725 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Mon, 1 Apr 2024 10:13:21 +0800 Subject: [PATCH 75/87] :art: https://github.com/siyuan-note/siyuan/issues/10813 --- app/src/assets/scss/protyle/_wysiwyg.scss | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/app/src/assets/scss/protyle/_wysiwyg.scss b/app/src/assets/scss/protyle/_wysiwyg.scss index da586ecb9e..0472d1bae7 100644 --- a/app/src/assets/scss/protyle/_wysiwyg.scss +++ b/app/src/assets/scss/protyle/_wysiwyg.scss @@ -241,6 +241,15 @@ color: var(--b3-protyle-inline-fileref-color); } + span[data-type~="block-ref"], + span[data-type~="file-annotation-ref"] { + cursor: pointer; + + &:hover { + opacity: 1; + } + } + &.render-node { min-height: 32px; @@ -590,8 +599,6 @@ .protyle-wysiwyg[data-readonly="false"] { span[data-type~="inline-math"], span[data-type~="tag"], - span[data-type~="block-ref"], - span[data-type~="file-annotation-ref"], .protyle-action__language, .img > span:nth-child(2), .render-node { @@ -602,11 +609,6 @@ background-color: var(--b3-theme-surface-lighter); } - span[data-type~="block-ref"]:hover, - span[data-type~="file-annotation-ref"]:hover { - opacity: 1; - } - .code-block .protyle-action { -webkit-user-modify: read-only; From 763e541598cf8fd457345f81098862d1e1793483 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Mon, 1 Apr 2024 11:09:59 +0800 Subject: [PATCH 76/87] :bug: Export PDF error when containing HTML block https://github.com/siyuan-note/siyuan/issues/10814 --- kernel/go.mod | 2 +- kernel/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/go.mod b/kernel/go.mod index 4b1ff38d4a..eaec2ca4bc 100644 --- a/kernel/go.mod +++ b/kernel/go.mod @@ -9,7 +9,7 @@ require ( github.com/88250/clipboard v0.1.5 github.com/88250/epub v0.0.0-20230830085737-c19055cd1f48 github.com/88250/gulu v1.2.3-0.20240324024901-3c1bb82cba30 - github.com/88250/lute v1.7.7-0.20240324154522-5bad50e3dd45 + github.com/88250/lute v1.7.7-0.20240401030317-1d8358d96fd5 github.com/88250/pdfcpu v0.3.14-0.20230401044135-c7369a99720c github.com/88250/vitess-sqlparser v0.0.0-20210205111146-56a2ded2aba1 github.com/ClarkThan/ahocorasick v0.0.0-20231011042242-30d1ef1347f4 diff --git a/kernel/go.sum b/kernel/go.sum index 755dfc5357..03c9ddbb4f 100644 --- a/kernel/go.sum +++ b/kernel/go.sum @@ -10,8 +10,8 @@ github.com/88250/go-sqlite3 v1.14.13-0.20231214121541-e7f54c482950 h1:Pa5hMiBceT github.com/88250/go-sqlite3 v1.14.13-0.20231214121541-e7f54c482950/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/88250/gulu v1.2.3-0.20240324024901-3c1bb82cba30 h1:IeE4DVRWnVpcbMj7gGZoSMiBWs3h/ihiyOmualS1Mas= github.com/88250/gulu v1.2.3-0.20240324024901-3c1bb82cba30/go.mod h1:MUfzyfmbPrRDZLqxc7aPrVYveatTHRfoUa5TynPS0i8= -github.com/88250/lute v1.7.7-0.20240324154522-5bad50e3dd45 h1:GWH+7dINO/u7juoqpKN6HbCFFaIqSuGjIzQ2jWCoIRc= -github.com/88250/lute v1.7.7-0.20240324154522-5bad50e3dd45/go.mod h1:VDAzL8b+oCh+e3NAlmwwLzC53ten0rZlS8NboB7ljtk= +github.com/88250/lute v1.7.7-0.20240401030317-1d8358d96fd5 h1:It+2SGISoKRaYun/658xi7tFLt4MeHw1L2/uD+eBW7Y= +github.com/88250/lute v1.7.7-0.20240401030317-1d8358d96fd5/go.mod h1:VDAzL8b+oCh+e3NAlmwwLzC53ten0rZlS8NboB7ljtk= github.com/88250/pdfcpu v0.3.14-0.20230401044135-c7369a99720c h1:Dl/8S9iLyPMTElnWIBxmjaLiWrkI5P4a21ivwAn5pU0= github.com/88250/pdfcpu v0.3.14-0.20230401044135-c7369a99720c/go.mod h1:S5YT38L/GCjVjmB4PB84PymA1qfopjEhfhTNQilLpv4= github.com/88250/vitess-sqlparser v0.0.0-20210205111146-56a2ded2aba1 h1:48T899JQDwyyRu9yXHePYlPdHtpJfrJEUGBMH3SMBWY= From 7408cfb7dac06f0f1cb6e5cfd4ffb707b642841e Mon Sep 17 00:00:00 2001 From: Vanessa Date: Mon, 1 Apr 2024 11:51:24 +0800 Subject: [PATCH 77/87] :art: fix https://github.com/siyuan-note/siyuan/issues/10816 --- app/src/boot/globalEvent/keydown.ts | 6 ++--- app/src/protyle/gutter/index.ts | 22 +++++++++-------- app/src/protyle/util/paste.ts | 37 ++++++++++++++++++++++++++++- 3 files changed, 50 insertions(+), 15 deletions(-) diff --git a/app/src/boot/globalEvent/keydown.ts b/app/src/boot/globalEvent/keydown.ts index 5d120efc61..67fc76a499 100644 --- a/app/src/boot/globalEvent/keydown.ts +++ b/app/src/boot/globalEvent/keydown.ts @@ -76,6 +76,7 @@ import {historyKeydown} from "../../history/keydown"; import {zoomOut} from "../../menus/protyle"; import {openSearchAV} from "../../protyle/render/av/relation"; import * as dayjs from "dayjs"; +import {getPlainText} from "../../protyle/util/paste"; const switchDialogEvent = (app: App, event: MouseEvent) => { event.preventDefault(); @@ -488,10 +489,7 @@ const editKeydown = (app: App, event: KeyboardEvent) => { selectsElement.push(nodeElement); } selectsElement.forEach(item => { - // 不能使用 [contenteditable="true"], 否则嵌入块无法复制 - item.querySelectorAll("[spellcheck]").forEach(editItem => { - html += editItem.textContent + "\n"; - }); + html += getPlainText(item) + "\n"; }); copyPlainText(html.trimEnd()); } else { diff --git a/app/src/protyle/gutter/index.ts b/app/src/protyle/gutter/index.ts index 9c7fa4c1d4..32c42f9580 100644 --- a/app/src/protyle/gutter/index.ts +++ b/app/src/protyle/gutter/index.ts @@ -9,7 +9,14 @@ import {getIconByType} from "../../editor/getIcon"; import {enterBack, iframeMenu, setFold, tableMenu, videoMenu, zoomOut} from "../../menus/protyle"; import {MenuItem} from "../../menus/Menu"; import {copySubMenu, openAttr, openWechatNotify} from "../../menus/commonMenuItem"; -import {copyPlainText, isMac, isOnlyMeta, openByMobile, updateHotkeyTip, writeText} from "../util/compatibility"; +import { + copyPlainText, + isMac, + isOnlyMeta, + openByMobile, + updateHotkeyTip, + writeText +} from "../util/compatibility"; import { transaction, turnsIntoOneTransaction, @@ -47,6 +54,7 @@ import {emitOpenMenu} from "../../plugin/EventBus"; import {insertAttrViewBlockAnimation} from "../render/av/row"; import {avContextmenu} from "../render/av/action"; import {openSearchAV} from "../render/av/relation"; +import {getPlainText} from "../util/paste"; export class Gutter { public element: HTMLElement; @@ -749,10 +757,8 @@ export class Gutter { accelerator: window.siyuan.config.keymap.editor.general.copyPlainText.custom, click() { let html = ""; - selectsElement.forEach(item => { - item.querySelectorAll("[spellcheck]").forEach(editItem => { - html += editItem.textContent + "\n"; - }); + selectsElement.forEach((item: HTMLElement) => { + html += getPlainText(item) + "\n"; }); copyPlainText(html.trimEnd()); focusBlock(selectsElement[0]); @@ -1223,11 +1229,7 @@ export class Gutter { label: window.siyuan.languages.copyPlainText, accelerator: window.siyuan.config.keymap.editor.general.copyPlainText.custom, click() { - let text = ""; - nodeElement.querySelectorAll("[spellcheck]").forEach(item => { - text += item.textContent + "\n"; - }); - copyPlainText(text.trimEnd()); + copyPlainText(getPlainText(nodeElement as HTMLElement).trimEnd()); focusBlock(nodeElement); } }, { diff --git a/app/src/protyle/util/paste.ts b/app/src/protyle/util/paste.ts index e12ea5bee0..b2f8c03669 100644 --- a/app/src/protyle/util/paste.ts +++ b/app/src/protyle/util/paste.ts @@ -15,7 +15,42 @@ import {insertHTML} from "./insertHTML"; import {scrollCenter} from "../../util/highlightById"; import {hideElements} from "../ui/hideElements"; import {avRender} from "../render/av/render"; -import {cellScrollIntoView} from "../render/av/cell"; +import {cellScrollIntoView, getCellText} from "../render/av/cell"; + +export const getPlainText = (blockElement: HTMLElement, isNested = false) => { + let text = "" + const dataType = blockElement.dataset.type + if ("NodeHTMLBlock" === dataType) { + text += Lute.UnEscapeHTMLStr(blockElement.querySelector("protyle-html").getAttribute("data-content")) + } else if ("NodeAttributeView" === dataType) { + blockElement.querySelectorAll(".av__row").forEach(rowElement => { + rowElement.querySelectorAll(".av__cell").forEach((cellElement: HTMLElement) => { + text += getCellText(cellElement) + " "; + }) + text += "\n"; + }) + text = text.trimEnd() + } else if ("NodeThematicBreak" === dataType) { + text += "---"; + } else if ("NodeIFrame" === dataType || "NodeWidget" === dataType) { + text += blockElement.querySelector("iframe").getAttribute("src") + } else if ("NodeVideo" === dataType) { + text += blockElement.querySelector("video").getAttribute("src") + } else if ("NodeAudio" === dataType) { + text += blockElement.querySelector("audio").getAttribute("src") + } else if (blockElement.classList.contains("render-node")) { + // 需在嵌入块后,代码块前 + text += Lute.UnEscapeHTMLStr(blockElement.getAttribute("data-content")) + } else if (["NodeHeading", "NodeParagraph", "NodeCodeBlock", "NodeTable"].includes(dataType)) { + text += blockElement.querySelector("[spellcheck]").textContent; + } else if (!isNested && ["NodeBlockquote", "NodeList", "NodeSuperBlock", "NodeListItem"].includes(dataType)) { + blockElement.querySelectorAll("[data-node-id]").forEach((item: HTMLElement) => { + const nestedText = getPlainText(item, true); + text += nestedText ? nestedText + "\n" : ""; + }) + } + return text; +} export const pasteEscaped = async (protyle: IProtyle, nodeElement: Element) => { try { From a3be3aea337c108ff0dee79876fa5f7826250fdc Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Mon, 1 Apr 2024 16:57:57 +0800 Subject: [PATCH 78/87] :art: Improve database rollup number calculation https://github.com/siyuan-note/siyuan/issues/10822 --- kernel/av/value.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/kernel/av/value.go b/kernel/av/value.go index 6e80d1ec07..3901084d4b 100644 --- a/kernel/av/value.go +++ b/kernel/av/value.go @@ -716,7 +716,7 @@ func (r *ValueRollup) RenderContents(calc *RollupCalc, destKey *Key) { case CalcOperatorSum: sum := 0.0 for _, v := range r.Contents { - if nil != v.Number { + if KeyTypeNumber == v.Type && nil != v.Number && v.Number.IsNotEmpty { sum += v.Number.Content } } @@ -725,7 +725,7 @@ func (r *ValueRollup) RenderContents(calc *RollupCalc, destKey *Key) { sum := 0.0 count := 0 for _, v := range r.Contents { - if nil != v.Number { + if KeyTypeNumber == v.Type && nil != v.Number && v.Number.IsNotEmpty { sum += v.Number.Content count++ } @@ -736,7 +736,7 @@ func (r *ValueRollup) RenderContents(calc *RollupCalc, destKey *Key) { case CalcOperatorMedian: var numbers []float64 for _, v := range r.Contents { - if nil != v.Number { + if KeyTypeNumber == v.Type && nil != v.Number && v.Number.IsNotEmpty { numbers = append(numbers, v.Number.Content) } } @@ -747,7 +747,7 @@ func (r *ValueRollup) RenderContents(calc *RollupCalc, destKey *Key) { case CalcOperatorMin: minVal := math.MaxFloat64 for _, v := range r.Contents { - if nil != v.Number { + if KeyTypeNumber == v.Type && nil != v.Number && v.Number.IsNotEmpty { if v.Number.Content < minVal { minVal = v.Number.Content } @@ -757,7 +757,7 @@ func (r *ValueRollup) RenderContents(calc *RollupCalc, destKey *Key) { case CalcOperatorMax: maxVal := -math.MaxFloat64 for _, v := range r.Contents { - if nil != v.Number { + if KeyTypeNumber == v.Type && nil != v.Number && v.Number.IsNotEmpty { if v.Number.Content > maxVal { maxVal = v.Number.Content } @@ -768,7 +768,7 @@ func (r *ValueRollup) RenderContents(calc *RollupCalc, destKey *Key) { minVal := math.MaxFloat64 maxVal := -math.MaxFloat64 for _, v := range r.Contents { - if nil != v.Number { + if KeyTypeNumber == v.Type && nil != v.Number && v.Number.IsNotEmpty { if v.Number.Content < minVal { minVal = v.Number.Content } From 8ae601f9ea115b14af59891700c2d9346ba5c0cb Mon Sep 17 00:00:00 2001 From: Vanessa Date: Mon, 1 Apr 2024 17:33:18 +0800 Subject: [PATCH 79/87] :art: fix https://github.com/siyuan-note/siyuan/issues/10817 --- app/src/protyle/util/paste.ts | 41 ++++++++++++++++++++++++++++++ app/src/protyle/wysiwyg/index.ts | 23 +++++------------ app/src/protyle/wysiwyg/keydown.ts | 7 ++++- 3 files changed, 54 insertions(+), 17 deletions(-) diff --git a/app/src/protyle/util/paste.ts b/app/src/protyle/util/paste.ts index b2f8c03669..a3088e552b 100644 --- a/app/src/protyle/util/paste.ts +++ b/app/src/protyle/util/paste.ts @@ -16,6 +16,47 @@ import {scrollCenter} from "../../util/highlightById"; import {hideElements} from "../ui/hideElements"; import {avRender} from "../render/av/render"; import {cellScrollIntoView, getCellText} from "../render/av/cell"; +import {getContenteditableElement} from "../wysiwyg/getBlock"; + +export const getTextStar = (blockElement: HTMLElement) => { + const dataType = blockElement.dataset.type + let refText = "" + if (["NodeHeading", "NodeParagraph"].includes(dataType)) { + refText = getContenteditableElement(blockElement).innerHTML; + } else { + if ("NodeHTMLBlock" === dataType) { + refText = "HTML" + } else if ("NodeAttributeView" === dataType) { + refText = blockElement.querySelector(".av__title").textContent || window.siyuan.languages.database + } else if ("NodeThematicBreak" === dataType) { + refText = window.siyuan.languages.line + } else if ("NodeIFrame" === dataType) { + refText = "IFrame" + } else if ("NodeWidget" === dataType) { + refText = window.siyuan.languages.widget + } else if ("NodeVideo" === dataType) { + refText = window.siyuan.languages.video + } else if ("NodeAudio" === dataType) { + refText = window.siyuan.languages.audio + } else if (["NodeCodeBlock", "NodeTable"].includes(dataType)) { + refText = getPlainText(blockElement); + } else if (blockElement.classList.contains("render-node")) { + // 需在嵌入块后,代码块前 + refText += blockElement.dataset.subtype || Lute.UnEscapeHTMLStr(blockElement.getAttribute("data-content")); + } else if (["NodeBlockquote", "NodeList", "NodeSuperBlock", "NodeListItem"].includes(dataType)) { + Array.from(blockElement.querySelectorAll("[data-node-id]")).find((item: HTMLElement) => { + if (!["NodeBlockquote", "NodeList", "NodeSuperBlock", "NodeListItem"].includes(item.getAttribute("data-type"))) { + refText = getTextStar(blockElement.querySelector("[data-node-id]")); + return true; + } + }) + if (refText) { + return refText + } + } + } + return refText + ` *`; +} export const getPlainText = (blockElement: HTMLElement, isNested = false) => { let text = "" diff --git a/app/src/protyle/wysiwyg/index.ts b/app/src/protyle/wysiwyg/index.ts index 40edf923a7..99918141aa 100644 --- a/app/src/protyle/wysiwyg/index.ts +++ b/app/src/protyle/wysiwyg/index.ts @@ -1,4 +1,4 @@ -import {paste} from "../util/paste"; +import {getTextStar, paste} from "../util/paste"; import { hasClosestBlock, hasClosestByAttribute, @@ -269,32 +269,23 @@ export class WYSIWYG { selectElements[0].parentElement.classList.contains("list") && // 反链复制列表项 https://github.com/siyuan-note/siyuan/issues/6555 selectElements[0].parentElement.childElementCount - 1 === selectElements.length) { if (isRefText) { - const cloneElement = selectElements[0].parentElement.cloneNode(true) as HTMLElement; - const cloneEditElement = getContenteditableElement(cloneElement); - if (cloneEditElement) { - cloneEditElement.insertAdjacentHTML("beforeend", ` *`); - } - html = cloneElement.outerHTML; - selectElements[0].removeAttribute("data-reftext"); + html = getTextStar(selectElements[0].parentElement) } else { html = selectElements[0].parentElement.outerHTML; } } else { - selectElements.forEach((item, index) => { + selectElements.forEach((item: HTMLElement, index) => { // 复制列表项中的块会变为复制列表项,因此不能使用 getTopAloneElement https://github.com/siyuan-note/siyuan/issues/8925 if (isRefText && index === 0) { - const cloneElement = item.cloneNode(true) as HTMLElement; - const cloneEditElement = getContenteditableElement(cloneElement); - if (cloneEditElement) { - cloneEditElement.insertAdjacentHTML("beforeend", ` *`); - } - html += removeEmbed(cloneElement); - selectElements[0].removeAttribute("data-reftext"); + html += getTextStar(item) + "\n\n"; } else { html += removeEmbed(item); } }); } + if (isRefText) { + selectElements[0].removeAttribute("data-reftext"); + } } else if (selectAVElement) { const cellElements: Element[] = Array.from(nodeElement.querySelectorAll(".av__cell--active, .av__cell--select")) || []; if (cellElements.length === 0) { diff --git a/app/src/protyle/wysiwyg/keydown.ts b/app/src/protyle/wysiwyg/keydown.ts index 47f55268e9..9470381b2f 100644 --- a/app/src/protyle/wysiwyg/keydown.ts +++ b/app/src/protyle/wysiwyg/keydown.ts @@ -919,7 +919,12 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => { writeText(`${content.trim()} ((${nodeElement.getAttribute("data-node-id")} "*"))`); }); } else { - nodeElement.setAttribute("data-reftext", "true"); + const selectElements = protyle.wysiwyg.element.querySelectorAll(".protyle-wysiwyg--select"); + if (selectElements.length > 0) { + selectElements[0].setAttribute("data-reftext", "true"); + } else { + nodeElement.setAttribute("data-reftext", "true"); + } focusByRange(getEditorRange(nodeElement)); document.execCommand("copy"); } From 04a06c36291131475bd3cb9b848c3eb65ee1653c Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Mon, 1 Apr 2024 17:52:22 +0800 Subject: [PATCH 80/87] :art: Data history supports querying in all notebooks Fix https://github.com/siyuan-note/siyuan/issues/10788 --- app/appearance/langs/en_US.json | 1 + app/appearance/langs/es_ES.json | 1 + app/appearance/langs/fr_FR.json | 1 + app/appearance/langs/zh_CHT.json | 1 + app/appearance/langs/zh_CN.json | 1 + app/src/history/history.ts | 11 ++++++++++- 6 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/appearance/langs/en_US.json b/app/appearance/langs/en_US.json index a3f5478ded..51308eed09 100644 --- a/app/appearance/langs/en_US.json +++ b/app/appearance/langs/en_US.json @@ -436,6 +436,7 @@ "autoDownloadUpdatePkgTip": "After enabling, it will automatically check the version update every two hours. If there is an updated version, it will automatically download the installation package and prompt for installation", "downloaded": "Downloaded", "allOp": "All operations", + "allNotebooks": "All Notebooks", "historyClean": "clean", "historyUpdate": "update", "historyDelete": "delete", diff --git a/app/appearance/langs/es_ES.json b/app/appearance/langs/es_ES.json index ec6a82453d..bcc880e051 100644 --- a/app/appearance/langs/es_ES.json +++ b/app/appearance/langs/es_ES.json @@ -436,6 +436,7 @@ "autoDownloadUpdatePkgTip": "Después de abrir, verificará automáticamente la actualización de la versión cada dos horas. Si hay una versión actualizada, descargará automáticamente el paquete de instalación y solicitará la instalación", "downloaded": "Descargado", "allOp": "Todas las operaciones", + "allNotebooks": "Todos los cuadernos", "historyClean": "limpiar (clean)", "historyUpdate": "actualizar (update)", "historyDelete": "eliminar (delete)", diff --git a/app/appearance/langs/fr_FR.json b/app/appearance/langs/fr_FR.json index 7722e10adc..e22cc14e8a 100644 --- a/app/appearance/langs/fr_FR.json +++ b/app/appearance/langs/fr_FR.json @@ -436,6 +436,7 @@ "autoDownloadUpdatePkgTip": "Après l'ouverture, il vérifiera automatiquement la mise à jour de la version toutes les deux heures. S'il existe une version mise à jour, il téléchargera automatiquement le package d'installation et demandera l'installation", "downloaded": "Téléchargé", "allOp": "Toutes les opérations", + "allNotebooks": "Tous les cahiers", "historyClean": "nettoyer (clean)", "historyUpdate": "mettre à jour (update)", "historyDelete": "supprimer (delete)", diff --git a/app/appearance/langs/zh_CHT.json b/app/appearance/langs/zh_CHT.json index ef6d10ba78..1a11d5862f 100644 --- a/app/appearance/langs/zh_CHT.json +++ b/app/appearance/langs/zh_CHT.json @@ -436,6 +436,7 @@ "autoDownloadUpdatePkgTip": "啟用後會每隔兩小時自動檢查版本更新,如果有更新版本則自動下載安裝檔並提示安裝", "downloaded": "已下載", "allOp": "所有操作", + "allNotebooks": "所有筆記本", "historyClean": "清理  (clean)", "historyUpdate": "更新  (update)", "historyDelete": "刪除  (delete)", diff --git a/app/appearance/langs/zh_CN.json b/app/appearance/langs/zh_CN.json index ad825b794e..7a346ecd11 100644 --- a/app/appearance/langs/zh_CN.json +++ b/app/appearance/langs/zh_CN.json @@ -436,6 +436,7 @@ "autoDownloadUpdatePkgTip": "启用后会每隔两小时自动检查版本更新,如果有更新版本则自动下载安装包并提示安装", "downloaded": "已下载", "allOp": "所有操作", + "allNotebooks": "所有笔记本", "historyClean": "清理  (clean)", "historyUpdate": "更新  (update)", "historyDelete": "删除  (delete)", diff --git a/app/src/history/history.ts b/app/src/history/history.ts index fc1ca08007..c20f59c0d4 100644 --- a/app/src/history/history.ts +++ b/app/src/history/history.ts @@ -303,7 +303,16 @@ export const openHistory = (app: App) => { return; } - let notebookSelectHTML = ""; + let existLocalHistoryNoteID = false; + window.siyuan.notebooks.forEach((item) => { + if (!item.closed) { + if (item.id === window.siyuan.storage[Constants.LOCAL_HISTORYNOTEID]) { + existLocalHistoryNoteID = true; + } + } + }); + + let notebookSelectHTML = ``; window.siyuan.notebooks.forEach((item) => { if (!item.closed) { notebookSelectHTML += ` `; From 4c4d3ed84f567af00384edb1af2aced969343c3b Mon Sep 17 00:00:00 2001 From: Vanessa Date: Mon, 1 Apr 2024 18:08:00 +0800 Subject: [PATCH 81/87] :art: fix https://github.com/siyuan-note/siyuan/issues/10814 --- app/src/protyle/export/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/protyle/export/index.ts b/app/src/protyle/export/index.ts index 97da14d344..fff2477600 100644 --- a/app/src/protyle/export/index.ts +++ b/app/src/protyle/export/index.ts @@ -105,6 +105,7 @@ const renderPDF = async (id: string) => { + ${themeStyle} ${window.siyuan.languages.export} PDF