From c55c4133658757d6d3784c0bfb453ce8edd86c2a Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sat, 6 Sep 2025 17:10:43 +0800 Subject: [PATCH 1/4] :art: Copy/Cut folded heading changed to copy/cut `Headings and Bottom Blocks` and support multiple headings copy/cut https://github.com/siyuan-note/siyuan/issues/8019 --- kernel/api/block.go | 20 +++++++++++++++++++- kernel/api/router.go | 1 + kernel/model/block.go | 44 ++++++++++++++++++++++++++++++++++++++----- 3 files changed, 59 insertions(+), 6 deletions(-) diff --git a/kernel/api/block.go b/kernel/api/block.go index 55d3132a1..826b92f01 100644 --- a/kernel/api/block.go +++ b/kernel/api/block.go @@ -189,6 +189,20 @@ func getHeadingChildrenIDs(c *gin.Context) { ret.Data = ids } +func appendHeadingChildren(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) + dom := arg["dom"].(string) + model.AppendHeadingChildren(id, dom) +} + func getHeadingChildrenDOM(c *gin.Context) { ret := gulu.Ret.NewResult() defer c.JSON(http.StatusOK, ret) @@ -199,7 +213,11 @@ func getHeadingChildrenDOM(c *gin.Context) { } id := arg["id"].(string) - dom := model.GetHeadingChildrenDOM(id) + removeFoldAttr := false + if nil != arg["removeFoldAttr"] { + removeFoldAttr = arg["removeFoldAttr"].(bool) + } + dom := model.GetHeadingChildrenDOM(id, removeFoldAttr) ret.Data = dom } diff --git a/kernel/api/router.go b/kernel/api/router.go index e6cbf22f8..8e1f8e0f5 100644 --- a/kernel/api/router.go +++ b/kernel/api/router.go @@ -222,6 +222,7 @@ func ServeAPI(ginServer *gin.Engine) { ginServer.Handle("POST", "/api/block/getBlockRelevantIDs", model.CheckAuth, getBlockRelevantIDs) ginServer.Handle("POST", "/api/block/getBlockTreeInfos", model.CheckAuth, getBlockTreeInfos) ginServer.Handle("POST", "/api/block/checkBlockRef", model.CheckAuth, checkBlockRef) + ginServer.Handle("POST", "/api/block/appendHeadingChildren", model.CheckAuth, appendHeadingChildren) ginServer.Handle("POST", "/api/file/getFile", model.CheckAuth, getFile) ginServer.Handle("POST", "/api/file/putFile", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, putFile) diff --git a/kernel/model/block.go b/kernel/model/block.go index d84780af0..34c1eb694 100644 --- a/kernel/model/block.go +++ b/kernel/model/block.go @@ -20,6 +20,7 @@ import ( "bytes" "errors" "fmt" + "slices" "strings" "time" @@ -629,7 +630,35 @@ func GetHeadingChildrenIDs(id string) (ret []string) { return } -func GetHeadingChildrenDOM(id string) (ret string) { +func AppendHeadingChildren(id, childrenDOM string) { + tree, err := LoadTreeByBlockID(id) + if err != nil { + return + } + + heading := treenode.GetNodeInTree(tree, id) + if nil == heading || ast.NodeHeading != heading.Type { + return + } + + luteEngine := util.NewLute() + subTree := luteEngine.BlockDOM2Tree(childrenDOM) + var nodes []*ast.Node + for n := subTree.Root.FirstChild; nil != n; n = n.Next { + nodes = append(nodes, n) + } + + slices.Reverse(nodes) + for _, n := range nodes { + heading.InsertAfter(n) + } + + if err = indexWriteTreeUpsertQueue(tree); err != nil { + return + } +} + +func GetHeadingChildrenDOM(id string, removeFoldAttr bool) (ret string) { tree, err := LoadTreeByBlockID(id) if err != nil { return @@ -650,13 +679,18 @@ func GetHeadingChildrenDOM(id string) (ret string) { return ast.WalkContinue } - n.RemoveIALAttr("heading-fold") - n.RemoveIALAttr("fold") + if removeFoldAttr { + n.RemoveIALAttr("heading-fold") + n.RemoveIALAttr("fold") + } return ast.WalkContinue }) } - heading.RemoveIALAttr("fold") - heading.RemoveIALAttr("heading-fold") + + if removeFoldAttr { + heading.RemoveIALAttr("fold") + heading.RemoveIALAttr("heading-fold") + } luteEngine := util.NewLute() ret = renderBlockDOMByNodes(nodes, luteEngine) From 8ad3cb00ad67adc1ccd6891b930bfef5ae706f35 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sat, 6 Sep 2025 17:11:21 +0800 Subject: [PATCH 2/4] :art: Copy/Cut folded heading changed to copy/cut `Headings and Bottom Blocks` and support multiple headings copy/cut https://github.com/siyuan-note/siyuan/issues/8019 --- kernel/api/block.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/api/block.go b/kernel/api/block.go index 826b92f01..b81d7a845 100644 --- a/kernel/api/block.go +++ b/kernel/api/block.go @@ -213,7 +213,7 @@ func getHeadingChildrenDOM(c *gin.Context) { } id := arg["id"].(string) - removeFoldAttr := false + removeFoldAttr := true if nil != arg["removeFoldAttr"] { removeFoldAttr = arg["removeFoldAttr"].(bool) } From 2a8b47b518358ce7b89ae0169fd2be2d21472d8c Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sat, 6 Sep 2025 17:15:42 +0800 Subject: [PATCH 3/4] :art: Copy/Cut folded heading changed to copy/cut `Headings and Bottom Blocks` and support multiple headings copy/cut https://github.com/siyuan-note/siyuan/issues/8019 --- kernel/api/block.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/api/block.go b/kernel/api/block.go index b81d7a845..5e14a98c9 100644 --- a/kernel/api/block.go +++ b/kernel/api/block.go @@ -199,8 +199,8 @@ func appendHeadingChildren(c *gin.Context) { } id := arg["id"].(string) - dom := arg["dom"].(string) - model.AppendHeadingChildren(id, dom) + childrenDOM := arg["childrenDOM"].(string) + model.AppendHeadingChildren(id, childrenDOM) } func getHeadingChildrenDOM(c *gin.Context) { From 68991a6aef39c5b9e2ed2e9ab7cfe35c3c53d851 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sat, 6 Sep 2025 17:30:35 +0800 Subject: [PATCH 4/4] :art: Copy/Cut folded heading changed to copy/cut `Headings and Bottom Blocks` and support multiple headings copy/cut https://github.com/siyuan-note/siyuan/issues/8019 --- kernel/model/block.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/model/block.go b/kernel/model/block.go index 34c1eb694..ed78bb87a 100644 --- a/kernel/model/block.go +++ b/kernel/model/block.go @@ -672,7 +672,6 @@ func GetHeadingChildrenDOM(id string, removeFoldAttr bool) (ret string) { children := treenode.HeadingChildren(heading) nodes = append(nodes, children...) - // 取消折叠 https://github.com/siyuan-note/siyuan/issues/13232#issuecomment-2535955152 for _, child := range children { ast.Walk(child, func(n *ast.Node, entering bool) ast.WalkStatus { if !entering { @@ -685,6 +684,8 @@ func GetHeadingChildrenDOM(id string, removeFoldAttr bool) (ret string) { } return ast.WalkContinue }) + + child.SetIALAttr("parent-heading", id) } if removeFoldAttr {