@@ -3,11 +3,19 @@ window.NoteView = Backbone.View.extend
3
3
events :
4
4
" click .editor-toolbar .edit a" : " toggleEditView"
5
5
" click .editor-toolbar .preview a" : " togglePreviewView"
6
+ " click #note-upload-image" : " browseUpload"
7
+ " click .insert-codes a" : " appendCodesFromHint"
8
+ " click .pickup-emoji" : " pickupEmoji"
6
9
7
10
initialize : (opts ) ->
8
11
@parentView = opts .parentView
12
+ @ initDropzone ()
13
+ @ initContentImageZoom ()
14
+ @ initCloseWarning ()
15
+ @ initComponents ()
9
16
$ (" <div id='preview' class='markdown' style='display:none;'></div>" ).insertAfter ( $ (' #note_body' ) )
10
17
18
+
11
19
toggleEditView : (e ) ->
12
20
$ (e .target ).parent ().addClass (' active' )
13
21
$ (' .preview a' ).parent ().removeClass (' active' )
@@ -25,3 +33,191 @@ window.NoteView = Backbone.View.extend
25
33
$ (' #preview' ).html (data)
26
34
false
27
35
false
36
+
37
+ initDropzone : ->
38
+ self = @
39
+ editor = $ (" textarea.note-editor" )
40
+ editor .wrap " <div class=\" note-editor-dropzone\" ></div>"
41
+
42
+ editor_dropzone = $ (' .note-editor-dropzone' )
43
+ editor_dropzone .on ' paste' , (event ) =>
44
+ self .handlePaste (event)
45
+
46
+ dropzone = editor_dropzone .dropzone (
47
+ url : " /photos"
48
+ dictDefaultMessage : " "
49
+ clickable : true
50
+ paramName : " file"
51
+ maxFilesize : 20
52
+ uploadMultiple : false
53
+ headers :
54
+ " X-CSRF-Token" : $ (" meta[name=\" csrf-token\" ]" ).attr (" content" )
55
+ previewContainer : false
56
+ processing : ->
57
+ $ (" .div-dropzone-alert" ).alert " close"
58
+ self .showUploading ()
59
+ dragover : ->
60
+ editor .addClass " div-dropzone-focus"
61
+ return
62
+ dragleave : ->
63
+ editor .removeClass " div-dropzone-focus"
64
+ return
65
+ drop : ->
66
+ editor .removeClass " div-dropzone-focus"
67
+ editor .focus ()
68
+ return
69
+ success : (header , res ) ->
70
+ self .appendImageFromUpload ([res .url ])
71
+ return
72
+ error : (temp , msg ) ->
73
+ App .alert (msg)
74
+ return
75
+ totaluploadprogress : (num ) ->
76
+ return
77
+ sending : ->
78
+ return
79
+ queuecomplete : ->
80
+ self .restoreUploaderStatus ()
81
+ return
82
+ )
83
+
84
+ initComponents : ->
85
+ # 绑定文本框 tab 按键事件
86
+ $ (" textarea.note-editor" ).unbind " keydown.tab"
87
+ $ (" textarea.note-editor" ).bind " keydown.tab" , " tab" , (el ) =>
88
+ return @ insertSpaces (el)
89
+
90
+ $ (" textarea.note-editor" ).autogrow ()
91
+
92
+ uploadFile : (item , filename ) ->
93
+ self = @
94
+ formData = new FormData ()
95
+ formData .append " file" , item, filename
96
+ $ .ajax
97
+ url : ' /photos'
98
+ type : " POST"
99
+ data : formData
100
+ dataType : " JSON"
101
+ processData : false
102
+ contentType : false
103
+ beforeSend : ->
104
+ self .showUploading ()
105
+ success : (e , status , res ) ->
106
+ self .appendImageFromUpload ([res .responseJSON .url ])
107
+ self .restoreUploaderStatus ()
108
+ error : (res ) ->
109
+ App .alert (" 上传失败" )
110
+ self .restoreUploaderStatus ()
111
+ complete : ->
112
+ self .restoreUploaderStatus ()
113
+
114
+ handlePaste : (e ) ->
115
+ self = @
116
+ pasteEvent = e .originalEvent
117
+ if pasteEvent .clipboardData and pasteEvent .clipboardData .items
118
+ image = self .isImage (pasteEvent)
119
+ if image
120
+ e .preventDefault ()
121
+ self .uploadFile image .getAsFile (), " image.png"
122
+
123
+ isImage : (data ) ->
124
+ i = 0
125
+ while i < data .clipboardData .items .length
126
+ item = data .clipboardData .items [i]
127
+ if item .type .indexOf (" image" ) isnt - 1
128
+ return item
129
+ i++
130
+ return false
131
+
132
+ browseUpload : (e ) ->
133
+ $ (" .note-editor" ).focus ()
134
+ $ (' .note-editor-dropzone' ).click ()
135
+ return false
136
+
137
+ showUploading : () ->
138
+ $ (" #note-upload-image" ).hide ()
139
+ if $ (" #note-upload-image" ).parent ().find (" span.loading" ).length == 0
140
+ $ (" #note-upload-image" ).before (" <span class='loading'><i class='fa fa-circle-o-notch fa-spin'></i></span>" )
141
+
142
+ restoreUploaderStatus : ->
143
+ $ (" #note-upload-image" ).parent ().find (" span.loading" ).remove ()
144
+ $ (" #note-upload-image" ).show ()
145
+
146
+ appendImageFromUpload : (srcs ) ->
147
+ src_merged = " "
148
+ for src in srcs
149
+ src_merged = " \n "
150
+ @ insertString (src_merged)
151
+ return false
152
+
153
+ initContentImageZoom : () ->
154
+ exceptClasses = [" emoji" , " twemoji" ]
155
+ imgEls = $ (" .markdown img" )
156
+ for el in imgEls
157
+ if exceptClasses .indexOf ($ (el).attr (" class" )) == - 1
158
+ $ (el).wrap (" <a href='#{ $ (el).attr (" src" )} ' class='zoom-image' data-action='zoom'></a>" )
159
+
160
+ # Bind click event
161
+ if App .turbolinks || App .mobile
162
+ $ (' a.zoom-image' ).attr (" target" ," _blank" )
163
+ else
164
+ $ (' a.zoom-image' ).fluidbox
165
+ overlayColor : " #FFF"
166
+ closeTrigger : [ {
167
+ selector : ' window'
168
+ event : ' scroll'
169
+ } ]
170
+ true
171
+
172
+ initCloseWarning : () ->
173
+ text = $ (" textarea.closewarning" )
174
+ return false if text .length == 0
175
+ msg = " 离开本页面将丢失未保存页面!" if ! msg
176
+ $ (" input[type=submit]" ).click ->
177
+ $ (window ).unbind (" beforeunload" )
178
+ text .change ->
179
+ if text .val ().length > 0
180
+ $ (window ).bind " beforeunload" , (e ) ->
181
+ if $ .browser .msie
182
+ e .returnValue = msg
183
+ else
184
+ return msg
185
+ else
186
+ $ (window ).unbind (" beforeunload" )
187
+
188
+ # 往话题编辑器里面的光标前插入两个空白字符
189
+ insertSpaces : (e ) ->
190
+ @ insertString (' ' )
191
+ return false
192
+
193
+ # 往话题编辑器里面插入代码模版
194
+ appendCodesFromHint : (e ) ->
195
+ link = $ (e .currentTarget )
196
+ language = link .data (" lang" )
197
+ txtBox = $ (" .note-editor" )
198
+ caret_pos = txtBox .caret (' pos' )
199
+ prefix_break = " "
200
+ if txtBox .val ().length > 0
201
+ prefix_break = " \n "
202
+ src_merged = " #{ prefix_break } ```#{ language} \n\n ```\n "
203
+ source = txtBox .val ()
204
+ before_text = source .slice (0 , caret_pos)
205
+ txtBox .val (before_text + src_merged + source .slice (caret_pos+ 1 , source .count ))
206
+ txtBox .caret (' pos' ,caret_pos + src_merged .length - 5 )
207
+ txtBox .focus ()
208
+ txtBox .trigger (' click' )
209
+ return false
210
+
211
+ insertString : (str ) ->
212
+ $target = $ (" .note-editor" )
213
+ start = $target[0 ].selectionStart
214
+ end = $target[0 ].selectionEnd
215
+ $target .val ($target .val ().substring (0 , start) + str + $target .val ().substring (end));
216
+ $target[0 ].selectionStart = $target[0 ].selectionEnd = start + str .length
217
+ $target .focus ()
218
+
219
+ pickupEmoji : () ->
220
+ if ! window ._emojiModal
221
+ window ._emojiModal = new EmojiModalView ()
222
+ window ._emojiModal .show ()
223
+ false
0 commit comments