@@ -4,18 +4,22 @@ import UploadNode from "./UploadNode.vue";
44import { ExtensionAttributesSpec , WithRequiredOptions } from "@/form/components/fields/editor/types" ;
55import { ContentUploadManager } from "@/content/ContentUploadManager" ;
66import { Plugin , Transaction } from "@tiptap/pm/state" ;
7- import { ReplaceStep } from "@tiptap/pm/transform" ;
87import { Form } from "@/form/Form" ;
9-
8+ import { FormEditorUploadData } from "@/content/types" ;
9+ import { Fragment , Slice } from "@tiptap/pm/model" ;
10+ import { getAllNodesAfterUpdate } from "@/form/components/fields/editor/utils/tiptap/getAllNodesAfterUpdate" ;
11+ import { FormUploadFieldValueData } from "@/types" ;
1012
1113
1214export type UploadNodeAttributes = {
1315 'data-key' : string ,
16+ 'data-value' ?: FormEditorUploadData ,
1417 isImage : boolean ,
1518}
1619
1720export type UploadOptions = {
1821 uploadManager : ContentUploadManager < Form > ,
22+ locale : string | null
1923}
2024
2125export const Upload : WithRequiredOptions < Node < UploadOptions > > = Node . create < UploadOptions > ( {
@@ -27,11 +31,27 @@ export const Upload: WithRequiredOptions<Node<UploadOptions>> = Node.create<Uplo
2731
2832 isolating : true ,
2933
34+ draggable : true ,
35+
3036 priority : 150 ,
3137
3238 addAttributes ( ) : ExtensionAttributesSpec < UploadNodeAttributes > {
3339 return {
3440 'data-key' : { } ,
41+ 'data-value' : {
42+ parseHTML ( element ) {
43+ return element . hasAttribute ( 'data-value' )
44+ ? JSON . parse ( element . getAttribute ( 'data-value' ) )
45+ : null ;
46+ } ,
47+ renderHTML ( attributes : UploadNodeAttributes ) {
48+ return {
49+ 'data-value' : attributes [ 'data-value' ]
50+ ? JSON . stringify ( attributes [ 'data-value' ] )
51+ : null
52+ } ;
53+ } ,
54+ } ,
3555 isImage : {
3656 default : false ,
3757 parseHTML : element => element . matches ( 'x-sharp-image' ) ,
@@ -61,7 +81,9 @@ export const Upload: WithRequiredOptions<Node<UploadOptions>> = Node.create<Uplo
6181 addCommands ( ) {
6282 return {
6383 insertUpload : ( { id, nativeFile, type, pos } ) => ( { commands, tr } ) => {
64- id ??= this . options . uploadManager . newUpload ( nativeFile ) ;
84+ id ??= this . options . uploadManager . newUpload ( this . options . locale , {
85+ file : { nativeFile } as FormUploadFieldValueData , // auto upload with this file
86+ } ) ;
6587
6688 return commands . insertContentAt ( pos ?? tr . selection . to , {
6789 type : Upload . name ,
@@ -74,9 +96,64 @@ export const Upload: WithRequiredOptions<Node<UploadOptions>> = Node.create<Uplo
7496 }
7597 } ,
7698
99+ onUpdate ( { transaction, appendedTransactions } ) {
100+ this . options . uploadManager . syncUploads (
101+ this . options . locale ,
102+ getAllNodesAfterUpdate ( this . name , transaction , appendedTransactions )
103+ . map ( node => node . attrs [ 'data-key' ] ) ,
104+ )
105+ } ,
106+
77107
78108 addProseMirrorPlugins ( ) {
109+ const { name, options } = this ;
110+
79111 return [
112+ new Plugin ( {
113+ props : {
114+ transformCopied ( slice : Slice ) {
115+ if ( ! slice . content . content . find ( n => n . type . name === name ) ) {
116+ return slice ;
117+ }
118+ return new Slice (
119+ Fragment . fromArray (
120+ slice . content . content . map ( node => {
121+ if ( node . type . name === name ) {
122+ return node . type . create ( {
123+ ...node . attrs ,
124+ 'data-key' : null ,
125+ 'data-value' : options . uploadManager . getUpload ( node . attrs [ 'data-key' ] ) ,
126+ } )
127+ }
128+ return node ;
129+ } )
130+ ) ,
131+ slice . openStart ,
132+ slice . openEnd
133+ ) ;
134+ } ,
135+ transformPasted ( slice : Slice ) {
136+ if ( ! slice . content . content . find ( n => n . type . name === name ) ) {
137+ return slice ;
138+ }
139+ return new Slice (
140+ Fragment . fromArray (
141+ slice . content . content . map ( node => {
142+ if ( node . type . name === name && node . attrs [ 'data-key' ] == null ) {
143+ return node . type . create ( {
144+ 'data-key' : options . uploadManager . newUpload ( options . locale , node . attrs [ 'data-value' ] ) ,
145+ isImage : node . attrs . isImage ,
146+ } ) ;
147+ }
148+ return node ;
149+ } )
150+ ) ,
151+ slice . openStart ,
152+ slice . openEnd
153+ )
154+ } ,
155+ }
156+ } ) ,
80157 new Plugin ( {
81158 props : {
82159 handlePaste : ( view , event ) => {
0 commit comments