simditor-rails 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,228 @@
1
+
2
+ class Uploader extends Module
3
+
4
+ @count: 0
5
+
6
+ opts:
7
+ url: ''
8
+ params: null
9
+ connectionCount: 3
10
+ leaveConfirm: '正在上传文件,如果离开上传会自动取消'
11
+
12
+ files: [] #files being uploaded
13
+
14
+ queue: [] #files waiting to be uploaded
15
+
16
+ html5: !!(window.File && window.FileList)
17
+
18
+ constructor: (opts = {}) ->
19
+ $.extend(@opts, opts)
20
+ @id = ++ Uploader.count
21
+
22
+ # upload the files in the queue
23
+ @on 'uploadcomplete', (e, file) =>
24
+ @files.splice($.inArray(file, @files), 1)
25
+ if @queue.length > 0 and @files.length < @opts.connectionCount
26
+ @upload @queue.shift()
27
+ else
28
+ @uploading = false
29
+
30
+ # confirm to leave page while uploading
31
+ $(window).on 'beforeunload.uploader-' + @id, (e) =>
32
+ return unless @uploading
33
+
34
+ # for ie
35
+ # TODO firefox can not set the string
36
+ e.originalEvent.returnValue = @opts.leaveConfirm
37
+ # for webkit
38
+ return @opts.leaveConfirm
39
+
40
+ generateId: (->
41
+ id = 0
42
+ return ->
43
+ id += 1
44
+ )()
45
+
46
+ upload: (file, opts = {}) ->
47
+ return unless file?
48
+
49
+ if $.isArray file
50
+ @upload(f, opts) for f in file
51
+ else if $(file).is('input:file') and @html5
52
+ @upload($.makeArray($(file)[0].files), opts)
53
+ else if !file.id or !file.obj
54
+ file = @getFile file
55
+
56
+ return unless file and file.obj
57
+
58
+ $.extend(file, opts)
59
+
60
+ if @files.length >= @opts.connectionCount
61
+ @queue.push file
62
+ return
63
+
64
+ return if @triggerHandler('beforeupload', [file]) == false
65
+
66
+ @files.push file
67
+ if @html5
68
+ @xhrUpload file
69
+ else
70
+ @iframeUpload file
71
+
72
+ @uploading = true
73
+
74
+ getFile: (fileObj) ->
75
+ if fileObj instanceof window.File or fileObj instanceof window.Blob
76
+ name = fileObj.fileName ? fileObj.name
77
+ else if $(fileObj).is('input:file')
78
+ name = $input.val().replace(/.*(\/|\\)/, "")
79
+ fileObj = $(fileObj).clone()
80
+ else
81
+ return null
82
+
83
+ id: @generateId()
84
+ url: @opts.url
85
+ params: @opts.params
86
+ name: name
87
+ size: fileObj.fileSize ? fileObj.size
88
+ ext: if name then name.split('.').pop().toLowerCase() else ''
89
+ obj: fileObj
90
+
91
+ xhrUpload: (file) ->
92
+ formData = new FormData()
93
+ formData.append("upload_file", file.obj)
94
+ formData.append("original_filename", file.name)
95
+ formData.append(k, v) for k, v of file.params if file.params
96
+
97
+ file.xhr = $.ajax
98
+ url: file.url
99
+ data: formData
100
+ processData: false
101
+ contentType: false
102
+ type: 'POST'
103
+ headers:
104
+ 'X-File-Name': encodeURIComponent(file.name)
105
+ xhr: ->
106
+ req = $.ajaxSettings.xhr()
107
+ if req
108
+ req.upload.onprogress = (e) =>
109
+ @progress(e)
110
+ req
111
+ progress: (e) =>
112
+ return unless e.lengthComputable
113
+ @trigger 'uploadprogress', [file, e.loaded, e.total]
114
+ error: (xhr, status, err) =>
115
+ @trigger 'uploaderror', [file, xhr, status]
116
+ success: (result) =>
117
+ @trigger 'uploadprogress', [file, file.size, file.size]
118
+ @trigger 'uploadsuccess', [file, result]
119
+ complete: (xhr, status) =>
120
+ @trigger 'uploadcomplete', [file, xhr.responseText]
121
+
122
+ iframeUpload: (file) ->
123
+ file.iframe = $('iframe', {
124
+ src: 'javascript:false;',
125
+ name: 'uploader-' + file.id
126
+ }).hide()
127
+ .appendTo(document.body)
128
+
129
+ file.form = $('<form/>', {
130
+ method: 'post',
131
+ enctype: 'multipart/form-data',
132
+ action: file.url,
133
+ target: file.iframe[0].name
134
+ }).hide()
135
+ .append(file.obj)
136
+ .appendTo(document.body)
137
+
138
+ if file.params
139
+ for k, v of file.params
140
+ $('<input/>', {
141
+ type: 'hidden',
142
+ name: k,
143
+ value: v
144
+ }).appendTo(form)
145
+
146
+ file.iframe.on 'load', =>
147
+ # when we remove iframe from dom
148
+ # the request stops, but in IE load
149
+ # event fires
150
+ return unless iframe.parent().length > 0
151
+
152
+ iframeDoc = iframe[0].contentDocument
153
+
154
+ # In Opera event is fired second time
155
+ # when body.innerHTML changed from false
156
+ # to server response approx. after 1 sec
157
+ # when we upload file with iframe
158
+ return if iframeDoc and iframeDoc.body and iframeDoc.body.innerHTML == "false"
159
+
160
+ # 当返回的JSON中存在html片段时,需要做这个hack
161
+ # json-response是一个script标签
162
+ # TODO: 简化服务器端的操作
163
+ responseEl = iframeDoc.getElementById('json-response')
164
+ json = if responseEl then responseEl.innerHTML else iframeDoc.body.innerHTML
165
+
166
+ try
167
+ result = $.parseJSON json
168
+ catch error
169
+ @trigger 'uploaderror', [file, null, 'parsererror']
170
+ result = {}
171
+
172
+ if result.success
173
+ @trigger 'uploadsuccess', [file, result]
174
+
175
+ @trigger 'uploadcomplete', [file, result]
176
+ file.iframe.remove()
177
+
178
+ file.form.submit().remove()
179
+
180
+ cancel: (file) ->
181
+ unless file.id
182
+ for f in @files
183
+ if f.id == file
184
+ file = f
185
+ break
186
+
187
+ @trigger 'uploadcancel', [file]
188
+
189
+ if @html5
190
+ # abort xhr will trigger complete event automatically
191
+ file.xhr.abort() if file.xhr
192
+ file.xhr = null
193
+ else
194
+ file.iframe
195
+ .attr('src', 'javascript:false;')
196
+ .remove()
197
+ @trigger 'uploadcomplete', [file]
198
+
199
+ readImageFile: (fileObj, callback) ->
200
+ return unless $.isFunction callback
201
+
202
+ img = new Image()
203
+ img.onload = ->
204
+ callback img
205
+ img.onerror = ->
206
+ callback()
207
+
208
+ if window.FileReader && FileReader.prototype.readAsDataURL && /^image/.test(fileObj.type)
209
+ fileReader = new FileReader()
210
+ fileReader.onload = (e) ->
211
+ img.src = e.target.result
212
+ fileReader.readAsDataURL fileObj
213
+ else
214
+ callback()
215
+
216
+ destroy: ->
217
+ @queue.length = 0
218
+ @cancel file for file in @files
219
+ $(window).off '.uploader-' + @id
220
+ $(document).off '.uploader-' + @id
221
+
222
+
223
+
224
+ window.Uploader = Uploader
225
+
226
+
227
+
228
+
@@ -0,0 +1,3 @@
1
+ //= require simditor/module
2
+ //= require simditor/uploader
3
+ //= require simditor/simditor