Project

General

Profile

1
function plugin(UIkit) {
2

    
3
    if (plugin.installed) {
4
        return;
5
    }
6

    
7
    var {$, ajax, on} = UIkit.util;
8

    
9
    UIkit.component('upload', {
10

    
11
        props: {
12
            allow: String,
13
            clsDragover: String,
14
            concurrent: Number,
15
            dataType: String,
16
            mime: String,
17
            msgInvalidMime: String,
18
            msgInvalidName: String,
19
            multiple: Boolean,
20
            name: String,
21
            params: Object,
22
            type: String,
23
            url: String
24
        },
25

    
26
        defaults: {
27
            allow: false,
28
            clsDragover: 'uk-dragover',
29
            concurrent: 1,
30
            dataType: undefined,
31
            mime: false,
32
            msgInvalidMime: 'Invalid File Type: %s',
33
            msgInvalidName: 'Invalid File Name: %s',
34
            multiple: false,
35
            name: 'files[]',
36
            params: {},
37
            type: 'POST',
38
            url: '',
39
            abort: null,
40
            beforeAll: null,
41
            beforeSend: null,
42
            complete: null,
43
            completeAll: null,
44
            error: null,
45
            fail(msg) {
46
                alert(msg);
47
            },
48
            load: null,
49
            loadEnd: null,
50
            loadStart: null,
51
            progress: null
52
        },
53

    
54
        events: {
55

    
56
            change(e) {
57

    
58
                if (!$(e.target).is('input[type="file"]')) {
59
                    return;
60
                }
61

    
62
                e.preventDefault();
63

    
64
                if (e.target.files) {
65
                    this.upload(e.target.files);
66
                }
67

    
68
                e.target.value = '';
69
            },
70

    
71
            drop(e) {
72
                e.preventDefault();
73
                e.stopPropagation();
74

    
75
                var transfer = e.originalEvent.dataTransfer;
76

    
77
                if (!transfer || !transfer.files) {
78
                    return;
79
                }
80

    
81
                this.$el.removeClass(this.clsDragover);
82

    
83
                this.upload(transfer.files);
84
            },
85

    
86
            dragenter(e) {
87
                e.preventDefault();
88
                e.stopPropagation();
89
            },
90

    
91
            dragover(e) {
92
                e.preventDefault();
93
                e.stopPropagation();
94
                this.$el.addClass(this.clsDragover);
95
            },
96

    
97
            dragleave(e) {
98
                e.preventDefault();
99
                e.stopPropagation();
100
                this.$el.removeClass(this.clsDragover);
101
            }
102

    
103
        },
104

    
105
        methods: {
106

    
107
            upload(files) {
108

    
109
                if (!files.length) {
110
                    return;
111
                }
112

    
113
                this.$el.trigger('upload', [files]);
114

    
115
                for (var i = 0; i < files.length; i++) {
116

    
117
                    if (this.allow) {
118
                        if (!match(this.allow, files[i].name)) {
119
                            this.fail(this.msgInvalidName.replace(/%s/, this.allow));
120
                            return;
121
                        }
122
                    }
123

    
124
                    if (this.mime) {
125
                        if (!match(this.mime, files[i].type)) {
126
                            this.fail(this.msgInvalidMime.replace(/%s/, this.mime));
127
                            return;
128
                        }
129
                    }
130

    
131
                }
132

    
133
                if (!this.multiple) {
134
                    files = [files[0]];
135
                }
136

    
137
                this.beforeAll && this.beforeAll(this, files);
138

    
139
                var chunks = chunk(files, this.concurrent),
140
                    upload = files => {
141

    
142
                        var data = new FormData();
143

    
144
                        files.forEach(file => data.append(this.name, file));
145

    
146
                        for (var key in this.params) {
147
                            data.append(key, this.params[key]);
148
                        }
149

    
150
                        ajax({
151
                            data,
152
                            url: this.url,
153
                            type: this.type,
154
                            dataType: this.dataType,
155
                            beforeSend: this.beforeSend,
156
                            complete: [this.complete, (xhr, status) => {
157
                                if (chunks.length) {
158
                                    upload(chunks.shift());
159
                                } else {
160
                                    this.completeAll && this.completeAll(xhr);
161
                                }
162

    
163
                                if (status === 'abort') {
164
                                    this.abort && this.abort(xhr);
165
                                }
166
                            }],
167
                            cache: false,
168
                            contentType: false,
169
                            processData: false,
170
                            xhr: () => {
171
                                var xhr = $.ajaxSettings.xhr();
172
                                xhr.upload && this.progress && on(xhr.upload, 'progress', this.progress);
173
                                ['loadStart', 'load', 'loadEnd', 'error', 'abort'].forEach(type => this[type] && on(xhr, type.toLowerCase(), this[type]));
174
                                return xhr;
175
                            }
176
                        })
177

    
178
                    };
179

    
180
                upload(chunks.shift());
181

    
182
            }
183

    
184
        }
185

    
186
    });
187

    
188
    function match(pattern, path) {
189
        return path.match(new RegExp(`^${pattern.replace(/\//g, '\\/').replace(/\*\*/g, '(\\/[^\\/]+)*').replace(/\*/g, '[^\\/]+').replace(/((?!\\))\?/g, '$1.')}$`, 'i'));
190
    }
191

    
192
    function chunk(files, size) {
193
        var chunks = [];
194
        for (var i = 0; i < files.length; i += size) {
195
            var chunk = [];
196
            for (var j = 0; j < size; j++) {
197
                chunk.push(files[i+j]);
198
            }
199
            chunks.push(chunk);
200
        }
201
        return chunks;
202
    }
203

    
204
}
205

    
206
if (!BUNDLED && typeof window !== 'undefined' && window.UIkit) {
207
    window.UIkit.use(plugin);
208
}
209

    
210
export default plugin;
(5-5/5)