Browse Source

:bug: When the heading block and super block are used together, repeating content if unfolding the heading https://github.com/siyuan-note/siyuan/issues/9435

Daniel 1 year ago
parent
commit
4a832e89f8
2 changed files with 36 additions and 2 deletions
  1. 3 2
      kernel/model/heading.go
  2. 33 0
      kernel/treenode/heading.go

+ 3 - 2
kernel/model/heading.go

@@ -46,7 +46,7 @@ func (tx *Transaction) doFoldHeading(operation *Operation) (ret *TxErr) {
 		return &TxErr{code: TxErrCodeBlockNotFound, id: headingID}
 	}
 
-	children := treenode.HeadingChildren(heading)
+	children := treenode.HeadingChildren4Folding(heading)
 	for _, child := range children {
 		childrenIDs = append(childrenIDs, child.ID)
 		child.SetIALAttr("fold", "1")
@@ -80,7 +80,7 @@ func (tx *Transaction) doUnfoldHeading(operation *Operation) (ret *TxErr) {
 		return &TxErr{code: TxErrCodeBlockNotFound, id: headingID}
 	}
 
-	children := treenode.HeadingChildren(heading)
+	children := treenode.HeadingChildren4Folding(heading)
 	for _, child := range children {
 		child.RemoveIALAttr("heading-fold")
 		child.RemoveIALAttr("fold")
@@ -98,6 +98,7 @@ func (tx *Transaction) doUnfoldHeading(operation *Operation) (ret *TxErr) {
 	}
 	sql.UpsertTreeQueue(tree)
 
+	children = treenode.HeadingChildren(heading)
 	luteEngine := NewLute()
 	operation.RetData = renderBlockDOMByNodes(children, luteEngine)
 	return

+ 33 - 0
kernel/treenode/heading.go

@@ -99,6 +99,39 @@ func GetHeadingFold(nodes []*ast.Node) (ret []*ast.Node) {
 	return
 }
 
+// HeadingChildren4Folding 获取标题下方所属该标题层级的所有节点,如果遇到超级块的话则递归获取超级块下方的所有节点。
+// 折叠和取消折叠要用这个函数单独处理 https://github.com/siyuan-note/siyuan/issues/9435
+func HeadingChildren4Folding(heading *ast.Node) (ret []*ast.Node) {
+	start := heading.Next
+	if nil == start {
+		return
+	}
+	if ast.NodeKramdownBlockIAL == start.Type {
+		start = start.Next // 跳过 heading 的 IAL
+	}
+
+	currentLevel := heading.HeadingLevel
+	for n := start; nil != n; n = n.Next {
+		if ast.NodeHeading == n.Type {
+			if currentLevel >= n.HeadingLevel {
+				break
+			}
+		} else if ast.NodeSuperBlock == n.Type {
+			ast.Walk(n, func(child *ast.Node, entering bool) ast.WalkStatus {
+				if !entering || !child.IsBlock() {
+					return ast.WalkContinue
+				}
+
+				ret = append(ret, child)
+				return ast.WalkContinue
+			})
+			continue
+		}
+		ret = append(ret, n)
+	}
+	return
+}
+
 func HeadingChildren(heading *ast.Node) (ret []*ast.Node) {
 	start := heading.Next
 	if nil == start {