@@ -977,35 +977,37 @@ func syncDelete2AttributeView(node *ast.Node) (changedAvIDs []string) {
977977}
978978
979979func (tx * Transaction ) doInsert (operation * Operation ) (ret * TxErr ) {
980- var err error
981- opParentID := operation .ParentID
982- block := treenode .GetBlockTree (opParentID )
983- if nil == block {
984- block = treenode .GetBlockTree (operation .PreviousID )
985- if nil == block {
986- block = treenode .GetBlockTree (operation .NextID )
980+ var bt * treenode.BlockTree
981+ bts := treenode .GetBlockTrees ([]string {operation .ParentID , operation .PreviousID , operation .NextID })
982+ for _ , b := range bts {
983+ if "" != b .ID {
984+ bt = b
985+ break
987986 }
988987 }
989- if nil == block {
990- logging .LogWarnf ("not found block [%s, %s, %s]" , operation .ParentID , operation .PreviousID , operation .NextID )
988+ if nil == bt {
989+ logging .LogWarnf ("not found block tree [%s, %s, %s]" , operation .ParentID , operation .PreviousID , operation .NextID )
991990 util .ReloadUI () // 比如分屏后编辑器状态不一致,这里强制重新载入界面
992991 return
993992 }
994993
995- tree , err := tx .loadTree (block .ID )
994+ var err error
995+ tree , err := tx .loadTreeByBlockTree (bt )
996996 if err != nil {
997- msg := fmt .Sprintf ("load tree [%s] failed: %s" , block .ID , err )
997+ msg := fmt .Sprintf ("load tree [%s] failed: %s" , bt .ID , err )
998998 logging .LogErrorf (msg )
999- return & TxErr {code : TxErrCodeBlockNotFound , id : block .ID }
999+ return & TxErr {code : TxErrCodeBlockNotFound , id : bt .ID }
10001000 }
10011001
10021002 data := strings .ReplaceAll (operation .Data .(string ), editor .FrontEndCaret , "" )
10031003 subTree := tx .luteEngine .BlockDOM2Tree (data )
10041004
1005- p := block .Path
1006- assets := getAssetsDir (filepath .Join (util .DataDir , block .BoxID ), filepath .Dir (filepath .Join (util .DataDir , block .BoxID , p )))
1007- isGlobalAssets := strings .HasPrefix (assets , filepath .Join (util .DataDir , "assets" ))
1008- if ! isGlobalAssets {
1005+ if ! tx .isGlobalAssetsInit {
1006+ tx .assetsDir = getAssetsDir (filepath .Join (util .DataDir , bt .BoxID ), filepath .Dir (filepath .Join (util .DataDir , bt .BoxID , bt .Path )))
1007+ tx .isGlobalAssets = strings .HasPrefix (tx .assetsDir , filepath .Join (util .DataDir , "assets" ))
1008+ tx .isGlobalAssetsInit = true
1009+ }
1010+ if ! tx .isGlobalAssets {
10091011 // 本地资源文件需要移动到用户手动建立的 assets 下 https://github.com/siyuan-note/siyuan/issues/2410
10101012 ast .Walk (subTree .Root , func (n * ast.Node , entering bool ) ast.WalkStatus {
10111013 if ! entering {
@@ -1026,7 +1028,7 @@ func (tx *Transaction) doInsert(operation *Operation) (ret *TxErr) {
10261028 }
10271029
10281030 // 只有全局 assets 才移动到相对 assets
1029- targetP := filepath .Join (assets , filepath .Base (assetPath ))
1031+ targetP := filepath .Join (tx . assetsDir , filepath .Base (assetPath ))
10301032 if e = filelock .Rename (assetPath , targetP ); err != nil {
10311033 logging .LogErrorf ("copy path of asset from [%s] to [%s] failed: %s" , assetPath , targetP , err )
10321034 return ast .WalkContinue
@@ -1035,9 +1037,10 @@ func (tx *Transaction) doInsert(operation *Operation) (ret *TxErr) {
10351037 return ast .WalkContinue
10361038 })
10371039 }
1040+
10381041 insertedNode := subTree .Root .FirstChild
10391042 if nil == insertedNode {
1040- return & TxErr {code : TxErrCodeBlockNotFound , msg : "invalid data tree" , id : block .ID }
1043+ return & TxErr {code : TxErrCodeBlockNotFound , msg : "invalid data tree" , id : bt .ID }
10411044 }
10421045 var remains []* ast.Node
10431046 for remain := insertedNode .Next ; nil != remain ; remain = remain .Next {
@@ -1123,7 +1126,7 @@ func (tx *Transaction) doInsert(operation *Operation) (ret *TxErr) {
11231126 createdUpdated (insertedNode )
11241127 tx .nodes [insertedNode .ID ] = insertedNode
11251128 if err = tx .writeTree (tree ); err != nil {
1126- return & TxErr {code : TxErrCodeWriteTree , msg : err .Error (), id : block .ID }
1129+ return & TxErr {code : TxErrCodeWriteTree , msg : err .Error (), id : bt .ID }
11271130 }
11281131
11291132 // 收集引用的定义块 ID
@@ -1179,8 +1182,6 @@ func (tx *Transaction) doInsert(operation *Operation) (ret *TxErr) {
11791182
11801183 operation .ID = insertedNode .ID
11811184 operation .ParentID = insertedNode .Parent .ID
1182-
1183- checkUpsertInUserGuide (tree )
11841185 return
11851186}
11861187
@@ -1302,8 +1303,6 @@ func (tx *Transaction) doUpdate(operation *Operation) (ret *TxErr) {
13021303 }
13031304 }
13041305 }
1305-
1306- checkUpsertInUserGuide (tree )
13071306 return
13081307}
13091308
@@ -1408,8 +1407,6 @@ func (tx *Transaction) doUpdateUpdated(operation *Operation) (ret *TxErr) {
14081407func (tx * Transaction ) doCreate (operation * Operation ) (ret * TxErr ) {
14091408 tree := operation .Data .(* parse.Tree )
14101409 tx .writeTree (tree )
1411-
1412- checkUpsertInUserGuide (tree )
14131410 return
14141411}
14151412
@@ -1534,8 +1531,12 @@ type Transaction struct {
15341531 DoOperations []* Operation `json:"doOperations"`
15351532 UndoOperations []* Operation `json:"undoOperations"`
15361533
1537- trees map [string ]* parse.Tree
1538- nodes map [string ]* ast.Node
1534+ trees map [string ]* parse.Tree // 事务中变更的树
1535+ nodes map [string ]* ast.Node // 事务中变更的节点
1536+
1537+ isGlobalAssetsInit bool // 是否初始化过全局资源判断
1538+ isGlobalAssets bool // 是否属于全局资源
1539+ assetsDir string // 资源目录路径
15391540
15401541 luteEngine * lute.Lute
15411542 m * sync.Mutex
@@ -1570,6 +1571,8 @@ func (tx *Transaction) commit() (err error) {
15701571 var sources []interface {}
15711572 sources = append (sources , tx )
15721573 util .PushSaveDoc (tree .ID , "tx" , sources )
1574+
1575+ checkUpsertInUserGuide (tree )
15731576 }
15741577 refreshDynamicRefTexts (tx .nodes , tx .trees )
15751578 IncSync ()
@@ -1585,6 +1588,24 @@ func (tx *Transaction) rollback() {
15851588 return
15861589}
15871590
1591+ func (tx * Transaction ) loadTreeByBlockTree (bt * treenode.BlockTree ) (ret * parse.Tree , err error ) {
1592+ if nil == bt {
1593+ return nil , ErrBlockNotFound
1594+ }
1595+
1596+ ret = tx .trees [bt .RootID ]
1597+ if nil != ret {
1598+ return
1599+ }
1600+
1601+ ret , err = filesys .LoadTree (bt .BoxID , bt .Path , tx .luteEngine )
1602+ if err != nil {
1603+ return
1604+ }
1605+ tx .trees [bt .RootID ] = ret
1606+ return
1607+ }
1608+
15881609func (tx * Transaction ) loadTree (id string ) (ret * parse.Tree , err error ) {
15891610 var rootID , box , p string
15901611 bt := treenode .GetBlockTree (id )
0 commit comments