PageSourceSearch

https://bogront.no/js/drag_drop_import.js?v=5.0.4

js bogront.no collected 2026-10-02 14:19:27 UTC 14,528 bytes, 392 lines download raw bytes

1/* vim: set expandtab sw=4 ts=4 sts=4: */
2
3/* This script handles PMA Drag Drop Import, loaded only when configuration is enabled.*/
4
5/**
6 * Class to handle PMA Drag and Drop Import
7 *      feature
8 */
9var DragDropImport = {
10    /**
11     * @var int, count of total uploads in this view
12     */
13    uploadCount: 0,
14    /**
15     * @var int, count of live uploads
16     */
17    liveUploadCount: 0,
18    /**
19     * @var  string array, allowed extensions
20     */
21    allowedExtensions: ['sql', 'xml', 'ldi', 'mediawiki', 'shp'],
22    /**
23     * @var  string array, allowed extensions for compressed files
24     */
25    allowedCompressedExtensions: ['gz', 'bz2', 'zip'],
26    /**
27     * @var obj array to store message returned by import_status.php
28     */
29    importStatus: [],
30    /**
31     * Checks if any dropped file has valid extension or not
32     *
33     * @param file filename
34     *
35     * @return string, extension for valid extension, '' otherwise
36     */
37    getExtension: function (file) {
38        var arr = file.split('.');
39        var ext = arr[arr.length - 1];
40
41        // check if compressed
42        if (jQuery.inArray(ext.toLowerCase(),
43            DragDropImport.allowedCompressedExtensions) !== -1) {
44            ext = arr[arr.length - 2];
45        }
46
47        // Now check for extension
48        if (jQuery.inArray(ext.toLowerCase(),
49            DragDropImport.allowedExtensions) !== -1) {
50            return ext;
51        }
52        return '';
53    },
54    /**
55     * Shows upload progress for different sql uploads
56     *
57     * @param: hash (string), hash for specific file upload
58     * @param: percent (float), file upload percentage
59     *
60     * @return void
61     */
62    setProgress: function (hash, percent) {
63        $('.pma_sql_import_status div li[data-hash="' + hash + '"]')
64            .children('progress').val(percent);
65    },
66    /**
67     * Function to upload the file asynchronously
68     *
69     * @param formData FormData object for a specific file
70     * @param hash hash of the current file upload
71     *
72     * @return void
73     */
74    sendFileToServer: function (formData, hash) {
75        var uploadURL = './import.php'; // Upload URL
76        var jqXHR = $.ajax({
77            xhr: function () {
78                var xhrobj = $.ajaxSettings.xhr();
79                if (xhrobj.upload) {
80                    xhrobj.upload.addEventListener('progress', function (event) {
81                        var percent = 0;
82                        var position = event.loaded || event.position;
83                        var total = event.total;
84                        if (event.lengthComputable) {
85                            percent = Math.ceil(position / total * 100);
86                        }
87                        // Set progress
88                        DragDropImport.setProgress(hash, percent);
89                    }, false);
90                }
91                return xhrobj;
92            },
93            url: uploadURL,
94            type: 'POST',
95            contentType:false,
96            processData: false,
97            cache: false,
98            data: formData,
99            success: function (data) {
100                DragDropImport.importFinished(hash, false, data.success);
101                if (!data.success) {
102                    DragDropImport.importStatus[DragDropImport.importStatus.length] = {
103                        hash: hash,
104                        message: data.error
105                    };
106                }
107            }
108        });
109
110        // -- provide link to cancel the upload
111        $('.pma_sql_import_status div li[data-hash="' + hash +
112            '"] span.filesize').html('<span hash="' +
113            hash + '" class="pma_drop_file_status" task="cancel">' +
114            Messages.dropImportMessageCancel + '</span>');
115
116        // -- add event listener to this link to abort upload operation
117        $('.pma_sql_import_status div li[data-hash="' + hash +
118            '"] span.filesize span.pma_drop_file_status')
119            .on('click', function () {
120                if ($(this).attr('task') === 'cancel') {
121                    jqXHR.abort();
122                    $(this).html('<span>' + Messages.dropImportMessageAborted + '</span>');
123                    DragDropImport.importFinished(hash, true, false);
124                } else if ($(this).children('span').html() ===
125                    Messages.dropImportMessageFailed) {
126                    // -- view information
127                    var $this = $(this);
128                    $.each(DragDropImport.importStatus,
129                        function (key, value) {
130                            if (value.hash === hash) {
131                                $('.pma_drop_result:visible').remove();
132                                var filename = $this.parent('span').attr('data-filename');
133                                $('body').append('<div class="pma_drop_result"><h2>' +
134                                Messages.dropImportImportResultHeader + ' - ' +
135                                filename + '<span class="close">x</span></h2>' + value.message + '</div>');
136                                $('.pma_drop_result').draggable();  // to make this dialog draggable
137                            }
138                        });
139                }
140            });
141    },
142    /**
143     * Triggered when an object is dragged into the PMA UI
144     *
145     * @param event obj
146     *
147     * @return void
148     */
149    dragEnter : function (event) {
150        // We don't want to prevent users from using
151        // browser's default drag-drop feature on some page(s)
152        if ($('.noDragDrop').length !== 0) {
153            return;
154        }
155
156        event.stopPropagation();
157        event.preventDefault();
158        if (!DragDropImport.hasFiles(event)) {
159            return;
160        }
161        if (CommonParams.get('db') === '') {
162            $('.pma_drop_handler').html(Messages.dropImportSelectDB);
163        } else {
164            $('.pma_drop_handler').html(Messages.dropImportDropFiles);
165        }
166        $('.pma_drop_handler').fadeIn();
167    },
168    /**
169     * Check if dragged element contains Files
170     *
171     * @param event the event object
172     *
173     * @return bool
174     */
175    hasFiles: function (event) {
176        return !(typeof event.originalEvent.dataTransfer.types === 'undefined' ||
177            $.inArray('Files', event.originalEvent.dataTransfer.types) < 0 ||
178            $.inArray(
179                'application/x-moz-nativeimage',
180                event.originalEvent.dataTransfer.types
181            ) >= 0);
182    },
183    /**
184     * Triggered when dragged file is being dragged over PMA UI
185     *
186     * @param event obj
187     *
188     * @return void
189     */
190    dragOver: function (event) {
191        // We don't want to prevent users from using
192        // browser's default drag-drop feature on some page(s)
193        if ($('.noDragDrop').length !== 0) {
194            return;
195        }
196
197        event.stopPropagation();
198        event.preventDefault();
199        if (!DragDropImport.hasFiles(event)) {
200            return;
201        }
202        $('.pma_drop_handler').fadeIn();
203    },
204    /**
205     * Triggered when dragged objects are left
206     *
207     * @param event obj
208     *
209     * @return void
210     */
211    dragLeave: function (event) {
212        // We don't want to prevent users from using
213        // browser's default drag-drop feature on some page(s)
214        if ($('.noDragDrop').length !== 0) {
215            return;
216        }
217        event.stopPropagation();
218        event.preventDefault();
219        var $dropHandler = $('.pma_drop_handler');
220        $dropHandler.clearQueue().stop();
221        $dropHandler.fadeOut();
222        $dropHandler.html(Messages.dropImportDropFiles);
223    },
224    /**
225     * Called when upload has finished
226     *
227     * @param string, unique hash for a certain upload
228     * @param bool, true if upload was aborted
229     * @param bool, status of sql upload, as sent by server
230     *
231     * @return void
232     */
233    importFinished: function (hash, aborted, status) {
234        $('.pma_sql_import_status div li[data-hash="' + hash + '"]')
235            .children('progress').hide();
236        var icon = 'icon ic_s_success';
237        // -- provide link to view upload status
238        if (!aborted) {
239            if (status) {
240                $('.pma_sql_import_status div li[data-hash="' + hash +
241                   '"] span.filesize span.pma_drop_file_status')
242                    .html('<span>' + Messages.dropImportMessageSuccess + '</a>');
243            } else {
244                $('.pma_sql_import_status div li[data-hash="' + hash +
245                   '"] span.filesize span.pma_drop_file_status')
246                    .html('<span class="underline">
246' + Messages.dropImportMessageFailed +
247                   '</a>');
248                icon = 'icon ic_s_error';
249            }
250        } else {
251            icon = 'icon ic_s_notice';
252        }
253        $('.pma_sql_import_status div li[data-hash="' + hash +
254            '"] span.filesize span.pma_drop_file_status')
255            .attr('task', 'info');
256
257        // Set icon
258        $('.pma_sql_import_status div li[data-hash="' + hash + '"]')
259            .prepend('<img src="./themes/dot.gif" title="finished" class="' +
260            icon + '"> ');
261
262        // Decrease liveUploadCount by one
263        $('.pma_import_count').html(--DragDropImport.liveUploadCount);
264        if (!DragDropImport.liveUploadCount) {
265            $('.pma_sql_import_status h2 .close').fadeIn();
266        }
267    },
268    /**
269     * Triggered when dragged objects are dropped to UI
270     * From this function, the AJAX Upload operation is initiated
271     *
272     * @param event object
273     *
274     * @return void
275     */
276    drop: function (event) {
277        // We don't want to prevent users from using
278        // browser's default drag-drop feature on some page(s)
279        if ($('.noDragDrop').length !== 0) {
280            return;
281        }
282
283        var dbname = CommonParams.get('db');
284        var server = CommonParams.get('server');
285
286        // if no database is selected -- no
287        if (dbname !== '') {
288            var files = event.originalEvent.dataTransfer.files;
289            if (!files || files.length === 0) {
290                // No files actually transferred
291                $('.pma_drop_handler').fadeOut();
292                event.stopPropagation();
293                event.preventDefault();
294                return;
295            }
296            $('.pma_sql_import_status').slideDown();
297            for (var i = 0; i < files.length; i++) {
298                var ext  = (DragDropImport.getExtension(files[i].name));
299                var hash = AJAX.hash(++DragDropImport.uploadCount);
300
301                var $sqlImportStatusDiv = $('.pma_sql_import_status div');
302                $sqlImportStatusDiv.append('<li data-hash="' + hash + '">' +
303                    ((ext !== '') ? '' : '<img src="./themes/dot.gif" title="invalid format" class="icon ic_s_notice"> ') +
304                    Functions.escapeHtml(files[i].name) + '<span class="filesize" data-filename="' +
305                    Functions.escapeHtml(files[i].name) + '">' + (files[i].size / 1024).toFixed(2) +
306                    ' kb</span></li>');
307
308                // scroll the UI to bottom
309                $sqlImportStatusDiv.scrollTop(
310                    $sqlImportStatusDiv.scrollTop() + 50
311                );  // 50 hardcoded for now
312
313                if (ext !== '') {
314                    // Increment liveUploadCount by one
315                    $('.pma_import_count').html(++DragDropImport.liveUploadCount);
316                    $('.pma_sql_import_status h2 .close').fadeOut();
317
318                    $('.pma_sql_import_status div li[data-hash="' + hash + '"]')
319                        .append('<br><progress max="100" value="2"></progress>');
320
321                    // uploading
322                    var fd = new FormData();
323                    fd.append('import_file', files[i]);
324                    fd.append('noplugin', Math.random().toString(36).substring(2, 12));
325                    fd.append('db', dbname);
326                    fd.append('server', server);
327                    fd.append('token', CommonParams.get('token'));
328                    fd.append('import_type', 'database');
329                    // todo: method to find the value below
330                    fd.append('MAX_FILE_SIZE', '4194304');
331                    // todo: method to find the value below
332                    fd.append('charset_of_file','utf-8');
333                    // todo: method to find the value below
334                    fd.append('allow_interrupt', 'yes');
335                    fd.append('skip_queries', '0');
336                    fd.append('format',ext);
337                    fd.append('sql_compatibility','NONE');
338                    fd.append('sql_no_auto_value_on_zero','something');
339                    fd.append('ajax_request','true');
340                    fd.append('hash', hash);
341
342                    // init uploading
343                    DragDropImport.sendFileToServer(fd, hash);
344                } else if (!DragDropImport.liveUploadCount) {
345                    $('.pma_sql_import_status h2 .close').fadeIn();
346                }
347            }
348        }
349        $('.pma_drop_handler').fadeOut();
350        event.stopPropagation();
351        event.preventDefault();
352    }
353};
354
355/**
356 * Called when some user drags, dragover, leave
357 *       a file to the PMA UI
358 * @param object Event data
359 * @return void
360 */
361$(document).on('dragenter', DragDropImport.dragEnter);
362$(document).on('dragover', DragDropImport.dragOver);
363$(document).on('dragleave', '.pma_drop_handler', DragDropImport.dragLeave);
364
365// when file is dropped to PMA UI
366$(document).on('drop', 'body', DragDropImport.drop);
367
368// minimizing-maximising the sql ajax upload status
369$(document).on('click', '.pma_sql_import_status h2 .minimize', function () {
370    if ($(this).attr('toggle') === 'off') {
371        $('.pma_sql_import_status div').css('height','270px');
372        $(this).attr('toggle','on');
373        $(this).html('-');  // to minimize
374    } else {
375        $('.pma_sql_import_status div').css('height','0px');
376        $(this).attr('toggle','off');
377        $(this).html('+');  // to maximise
378    }
379});
380
381// closing sql ajax upload status
382$(document).on('click', '.pma_sql_import_status h2 .close', function () {
383    $('.pma_sql_import_status').fadeOut(function () {
384        $('.pma_sql_import_status div').html('');
385        DragDropImport.importStatus = [];  // clear the message array
386    });
387});
388
389// Closing the import result box
390$(document).on('click', '.pma_drop_result h2 .close', function () {
391    $(this).parent('h2').parent('div').remove();
392});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.