mirror of
https://github.com/siyuan-note/siyuan.git
synced 2026-01-06 16:58:49 +01:00
Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
8e60de66ee
8 changed files with 93 additions and 23 deletions
|
|
@ -319,6 +319,13 @@ func moveBlock(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
currentBt := treenode.GetBlockTree(id)
|
||||
if nil == currentBt {
|
||||
ret.Code = -1
|
||||
ret.Msg = "block not found [id=" + id + "]"
|
||||
return
|
||||
}
|
||||
|
||||
var parentID, previousID string
|
||||
if nil != arg["parentID"] {
|
||||
parentID = arg["parentID"].(string)
|
||||
|
|
@ -340,6 +347,19 @@ func moveBlock(c *gin.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
var targetBt *treenode.BlockTree
|
||||
if "" != previousID {
|
||||
targetBt = treenode.GetBlockTree(previousID)
|
||||
} else if "" != parentID {
|
||||
targetBt = treenode.GetBlockTree(parentID)
|
||||
}
|
||||
|
||||
if nil == targetBt {
|
||||
ret.Code = -1
|
||||
ret.Msg = "target block not found [id=" + parentID + "]"
|
||||
return
|
||||
}
|
||||
|
||||
transactions := []*model.Transaction{
|
||||
{
|
||||
DoOperations: []*model.Operation{
|
||||
|
|
@ -356,8 +376,10 @@ func moveBlock(c *gin.Context) {
|
|||
model.PerformTransactions(&transactions)
|
||||
model.FlushTxQueue()
|
||||
|
||||
ret.Data = transactions
|
||||
broadcastTransactions(transactions)
|
||||
model.ReloadProtyle(currentBt.RootID)
|
||||
if currentBt.RootID != targetBt.RootID {
|
||||
model.ReloadProtyle(targetBt.RootID)
|
||||
}
|
||||
}
|
||||
|
||||
func appendBlock(c *gin.Context) {
|
||||
|
|
|
|||
|
|
@ -477,4 +477,5 @@ func ServeAPI(ginServer *gin.Engine) {
|
|||
ginServer.Handle("POST", "/api/ui/reloadAttributeView", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, reloadAttributeView)
|
||||
ginServer.Handle("POST", "/api/ui/reloadProtyle", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, reloadProtyle)
|
||||
ginServer.Handle("POST", "/api/ui/reloadFiletree", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, reloadFiletree)
|
||||
ginServer.Handle("POST", "/api/ui/reloadTag", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, reloadTag)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,13 @@ import (
|
|||
"github.com/siyuan-note/siyuan/kernel/util"
|
||||
)
|
||||
|
||||
func reloadTag(c *gin.Context) {
|
||||
ret := gulu.Ret.NewResult()
|
||||
defer c.JSON(http.StatusOK, ret)
|
||||
|
||||
util.PushReloadTag()
|
||||
}
|
||||
|
||||
func reloadFiletree(c *gin.Context) {
|
||||
ret := gulu.Ret.NewResult()
|
||||
defer c.JSON(http.StatusOK, ret)
|
||||
|
|
|
|||
|
|
@ -728,7 +728,7 @@ func FindReplace(keyword, replacement string, replaceTypes map[string]bool, ids
|
|||
return ast.WalkContinue
|
||||
}
|
||||
|
||||
replaceNodeTextMarkTextContent(n, method, keyword, escapedKey, replacement, r, "em")
|
||||
replaceNodeTextMarkTextContent(n, method, keyword, escapedKey, replacement, r, "em", luteEngine)
|
||||
if "" == n.TextMarkTextContent {
|
||||
unlinks = append(unlinks, n)
|
||||
mergeSamePreNext(n)
|
||||
|
|
@ -738,7 +738,7 @@ func FindReplace(keyword, replacement string, replaceTypes map[string]bool, ids
|
|||
return ast.WalkContinue
|
||||
}
|
||||
|
||||
replaceNodeTextMarkTextContent(n, method, keyword, escapedKey, replacement, r, "strong")
|
||||
replaceNodeTextMarkTextContent(n, method, keyword, escapedKey, replacement, r, "strong", luteEngine)
|
||||
if "" == n.TextMarkTextContent {
|
||||
unlinks = append(unlinks, n)
|
||||
mergeSamePreNext(n)
|
||||
|
|
@ -748,7 +748,7 @@ func FindReplace(keyword, replacement string, replaceTypes map[string]bool, ids
|
|||
return ast.WalkContinue
|
||||
}
|
||||
|
||||
replaceNodeTextMarkTextContent(n, method, keyword, escapedKey, replacement, r, "kbd")
|
||||
replaceNodeTextMarkTextContent(n, method, keyword, escapedKey, replacement, r, "kbd", luteEngine)
|
||||
if "" == n.TextMarkTextContent {
|
||||
unlinks = append(unlinks, n)
|
||||
}
|
||||
|
|
@ -757,7 +757,7 @@ func FindReplace(keyword, replacement string, replaceTypes map[string]bool, ids
|
|||
return ast.WalkContinue
|
||||
}
|
||||
|
||||
replaceNodeTextMarkTextContent(n, method, keyword, escapedKey, replacement, r, "mark")
|
||||
replaceNodeTextMarkTextContent(n, method, keyword, escapedKey, replacement, r, "mark", luteEngine)
|
||||
if "" == n.TextMarkTextContent {
|
||||
unlinks = append(unlinks, n)
|
||||
mergeSamePreNext(n)
|
||||
|
|
@ -767,7 +767,7 @@ func FindReplace(keyword, replacement string, replaceTypes map[string]bool, ids
|
|||
return ast.WalkContinue
|
||||
}
|
||||
|
||||
replaceNodeTextMarkTextContent(n, method, keyword, escapedKey, replacement, r, "s")
|
||||
replaceNodeTextMarkTextContent(n, method, keyword, escapedKey, replacement, r, "s", luteEngine)
|
||||
if "" == n.TextMarkTextContent {
|
||||
unlinks = append(unlinks, n)
|
||||
mergeSamePreNext(n)
|
||||
|
|
@ -777,7 +777,7 @@ func FindReplace(keyword, replacement string, replaceTypes map[string]bool, ids
|
|||
return ast.WalkContinue
|
||||
}
|
||||
|
||||
replaceNodeTextMarkTextContent(n, method, keyword, escapedKey, replacement, r, "sub")
|
||||
replaceNodeTextMarkTextContent(n, method, keyword, escapedKey, replacement, r, "sub", luteEngine)
|
||||
if "" == n.TextMarkTextContent {
|
||||
unlinks = append(unlinks, n)
|
||||
}
|
||||
|
|
@ -786,7 +786,7 @@ func FindReplace(keyword, replacement string, replaceTypes map[string]bool, ids
|
|||
return ast.WalkContinue
|
||||
}
|
||||
|
||||
replaceNodeTextMarkTextContent(n, method, keyword, escapedKey, replacement, r, "sup")
|
||||
replaceNodeTextMarkTextContent(n, method, keyword, escapedKey, replacement, r, "sup", luteEngine)
|
||||
if "" == n.TextMarkTextContent {
|
||||
unlinks = append(unlinks, n)
|
||||
}
|
||||
|
|
@ -795,16 +795,18 @@ func FindReplace(keyword, replacement string, replaceTypes map[string]bool, ids
|
|||
return ast.WalkContinue
|
||||
}
|
||||
|
||||
replaceNodeTextMarkTextContent(n, method, keyword, escapedKey, replacement, r, "tag")
|
||||
replaceNodeTextMarkTextContent(n, method, keyword, escapedKey, replacement, r, "tag", luteEngine)
|
||||
if "" == n.TextMarkTextContent {
|
||||
unlinks = append(unlinks, n)
|
||||
}
|
||||
|
||||
util.PushReloadTag()
|
||||
} else if n.IsTextMarkType("u") {
|
||||
if !replaceTypes["u"] {
|
||||
return ast.WalkContinue
|
||||
}
|
||||
|
||||
replaceNodeTextMarkTextContent(n, method, keyword, escapedKey, replacement, r, "u")
|
||||
replaceNodeTextMarkTextContent(n, method, keyword, escapedKey, replacement, r, "u", luteEngine)
|
||||
if "" == n.TextMarkTextContent {
|
||||
unlinks = append(unlinks, n)
|
||||
mergeSamePreNext(n)
|
||||
|
|
@ -853,7 +855,7 @@ func FindReplace(keyword, replacement string, replaceTypes map[string]bool, ids
|
|||
return ast.WalkContinue
|
||||
}
|
||||
|
||||
replaceNodeTextMarkTextContent(n, method, keyword, escapedKey, replacement, r, "text")
|
||||
replaceNodeTextMarkTextContent(n, method, keyword, escapedKey, replacement, r, "text", luteEngine)
|
||||
if "" == n.TextMarkTextContent {
|
||||
unlinks = append(unlinks, n)
|
||||
mergeSamePreNext(n)
|
||||
|
|
@ -935,7 +937,7 @@ func FindReplace(keyword, replacement string, replaceTypes map[string]bool, ids
|
|||
return
|
||||
}
|
||||
|
||||
func replaceNodeTextMarkTextContent(n *ast.Node, method int, keyword, escapedKey string, replacement string, r *regexp.Regexp, typ string) {
|
||||
func replaceNodeTextMarkTextContent(n *ast.Node, method int, keyword, escapedKey string, replacement string, r *regexp.Regexp, typ string, luteEngine *lute.Lute) {
|
||||
if 0 == method {
|
||||
if strings.Contains(typ, "tag") {
|
||||
keyword = strings.TrimPrefix(keyword, "#")
|
||||
|
|
@ -945,10 +947,45 @@ func replaceNodeTextMarkTextContent(n *ast.Node, method int, keyword, escapedKey
|
|||
if strings.HasPrefix(replacement, "#") && strings.HasSuffix(replacement, "#") {
|
||||
replacement = strings.TrimPrefix(replacement, "#")
|
||||
replacement = strings.TrimSuffix(replacement, "#")
|
||||
} else { // 将标签转换为纯文本
|
||||
} else {
|
||||
// 将标签转换为纯文本
|
||||
|
||||
if "tag" == n.TextMarkType { // 没有其他类型,仅是标签时直接转换
|
||||
n.InsertBefore(&ast.Node{Type: ast.NodeText, Tokens: []byte(n.TextMarkTextContent)})
|
||||
content := n.TextMarkTextContent
|
||||
if strings.Contains(content, escapedKey) {
|
||||
content = strings.ReplaceAll(content, escapedKey, replacement)
|
||||
} else if strings.Contains(content, keyword) {
|
||||
content = strings.ReplaceAll(content, keyword, replacement)
|
||||
}
|
||||
|
||||
tree := parse.Inline("", []byte(content), luteEngine.ParseOptions)
|
||||
if nil == tree.Root.FirstChild {
|
||||
return
|
||||
}
|
||||
parse.NestedInlines2FlattedSpans(tree, false)
|
||||
|
||||
var replaceNodes []*ast.Node
|
||||
var defIDs []string
|
||||
for rNode := tree.Root.FirstChild.FirstChild; nil != rNode; rNode = rNode.Next {
|
||||
replaceNodes = append(replaceNodes, rNode)
|
||||
if blockRefID, _, _ := treenode.GetBlockRef(rNode); "" != blockRefID {
|
||||
defIDs = append(defIDs, blockRefID)
|
||||
}
|
||||
}
|
||||
|
||||
for _, rNode := range replaceNodes {
|
||||
n.InsertBefore(rNode)
|
||||
}
|
||||
n.TextMarkTextContent = ""
|
||||
|
||||
for _, defID := range defIDs {
|
||||
bt := treenode.GetBlockTree(defID)
|
||||
if nil == bt {
|
||||
continue
|
||||
}
|
||||
|
||||
task.AppendAsyncTaskWithDelay(task.SetDefRefCount, util.SQLFlushInterval, refreshRefCount, bt.RootID, defID)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ func RemoveTag(label string) (err error) {
|
|||
updateNodes := map[string]*ast.Node{}
|
||||
for treeID, blocks := range treeBlocks {
|
||||
util.PushEndlessProgress("[" + treeID + "]")
|
||||
tree, e := LoadTreeByBlockID(treeID)
|
||||
tree, e := LoadTreeByBlockIDWithReindex(treeID)
|
||||
if nil != e {
|
||||
util.ClearPushProgress(100)
|
||||
return e
|
||||
|
|
@ -154,7 +154,7 @@ func RenameTag(oldLabel, newLabel string) (err error) {
|
|||
|
||||
for treeID, blocks := range treeBlocks {
|
||||
util.PushEndlessProgress("[" + treeID + "]")
|
||||
tree, e := LoadTreeByBlockID(treeID)
|
||||
tree, e := LoadTreeByBlockIDWithReindex(treeID)
|
||||
if nil != e {
|
||||
util.ClearPushProgress(100)
|
||||
return e
|
||||
|
|
|
|||
|
|
@ -178,8 +178,6 @@ var (
|
|||
)
|
||||
|
||||
func LoadTreeByBlockIDWithReindex(id string) (ret *parse.Tree, err error) {
|
||||
// 仅提供给 getBlockInfo 接口使用
|
||||
|
||||
if "" == id {
|
||||
logging.LogWarnf("block id is empty")
|
||||
return nil, ErrTreeNotFound
|
||||
|
|
@ -192,8 +190,9 @@ func LoadTreeByBlockIDWithReindex(id string) (ret *parse.Tree, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// 尝试从文件系统加载
|
||||
searchTreeInFilesystem(id)
|
||||
// 尝试从文件系统加载并建立索引
|
||||
indexTreeInFilesystem(id)
|
||||
|
||||
bt = treenode.GetBlockTree(id)
|
||||
if nil == bt {
|
||||
if "dev" == util.Mode {
|
||||
|
|
@ -243,7 +242,7 @@ func loadTreeByBlockTree(bt *treenode.BlockTree) (ret *parse.Tree, err error) {
|
|||
|
||||
var searchTreeLimiter = rate.NewLimiter(rate.Every(3*time.Second), 1)
|
||||
|
||||
func searchTreeInFilesystem(rootID string) {
|
||||
func indexTreeInFilesystem(rootID string) {
|
||||
if !searchTreeLimiter.Allow() {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ func QueryTagSpansByKeyword(keyword string, limit int) (ret []*Span) {
|
|||
contentLikes := ""
|
||||
for _, k := range keywords {
|
||||
if contentLikes != "" {
|
||||
contentLikes += " OR "
|
||||
contentLikes += " AND "
|
||||
}
|
||||
contentLikes += "content LIKE '%" + k + "%'"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -182,6 +182,10 @@ func PushReloadFiletree() {
|
|||
BroadcastByType("filetree", "reloadFiletree", 0, "", nil)
|
||||
}
|
||||
|
||||
func PushReloadTag() {
|
||||
BroadcastByType("main", "reloadTag", 0, "", nil)
|
||||
}
|
||||
|
||||
type BlockStatResult struct {
|
||||
RuneCount int `json:"runeCount"`
|
||||
WordCount int `json:"wordCount"`
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue