public/js/script.js   F
last analyzed

Complexity

Total Complexity 154
Complexity/F 1.62

Size

Lines of Code 820
Function Count 95

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 154
eloc 511
c 0
b 0
f 0
dl 0
loc 820
rs 2
mnd 59
bc 59
fnc 95
bpm 0.621
cpm 1.621
noi 33

39 Functions

Rating   Name   Duplication   Size   Complexity  
A script.js ➔ setOpenFolders 0 12 2
A script.js ➔ clearSelected 0 7 1
A script.js ➔ updateSelectedStyle 0 8 2
F script.js ➔ toggleMobileTree 0 6 18
C script.js ➔ toggleSelected 0 15 11
A script.js ➔ toggleActions 0 23 3
A script.js ➔ getSelectedItems 0 6 2
A script.js ➔ getPreviousDir 0 4 1
A script.js ➔ goTo 0 4 2
B script.js ➔ performLfmRequest 0 25 6
A script.js ➔ getOneSelectedElement 0 4 2
A script.js ➔ defaultParameters 0 6 1
C script.js ➔ generatePaginationHTML 0 75 11
A script.js ➔ getUrlParam 0 5 2
A script.js ➔ displayErrorResponse 0 7 2
A script.js ➔ trash 0 7 3
A script.js ➔ usingTinymce4AndColorbox 0 3 1
A script.js ➔ createPagination 0 31 4
F script.js ➔ loadItems 0 98 15
A script.js ➔ usingWysiwygEditor 0 3 1
A script.js ➔ rename 0 8 2
A script.js ➔ crop 0 4 1
A script.js ➔ usingTinymce5 0 3 1
A script.js ➔ usingCkeditor3 0 3 1
A script.js ➔ resize 0 4 1
A script.js ➔ createFolder 0 4 1
A script.js ➔ dialog 0 10 3
A script.js ➔ download 0 16 4
F script.js ➔ use 0 100 23
A script.js ➔ usingFckeditor2 0 3 1
A script.js ➔ usingTinymce3 0 3 1
A script.js ➔ loading 0 3 1
A script.js ➔ confirm 0 5 1
D script.js ➔ preview 0 59 12
A script.js ➔ notImp 0 3 1
A script.js ➔ move 0 4 2
B script.js ➔ loadFolders 0 7 6
A script.js ➔ open 0 3 1
A script.js ➔ notify 0 3 1

How to fix   Complexity   

Complexity

Complex classes like public/js/script.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
var lfm_route = location.origin + location.pathname;
2
var show_list;
3
var sort_type = 'alphabetic';
4
var multi_selection_enabled = false;
5
var selected = [];
6
var items = [];
7
8
$.fn.fab = function (options) {
9
  var menu = this;
10
  menu.addClass('fab-wrapper');
11
12
  var toggler = $('<a>')
13
    .addClass('fab-button fab-toggle')
14
    .append($('<i>').addClass('fas fa-plus'))
15
    .click(function () {
16
      menu.toggleClass('fab-expand');
17
    });
18
19
  menu.append(toggler);
20
21
  options.buttons.forEach(function (button) {
22
    toggler.before(
23
      $('<a>').addClass('fab-button fab-action')
24
        .attr('data-label', button.label)
25
        .attr('id', button.attrs.id)
26
        .append($('<i>').addClass(button.icon))
27
        .click(function () {
28
          menu.removeClass('fab-expand');
29
        })
30
    );
31
  });
32
};
33
34
$(document).ready(function () {
35
  $('#fab').fab({
36
    buttons: [
37
      {
38
        icon: 'fas fa-upload',
39
        label: lang['nav-upload'],
0 ignored issues
show
Bug introduced by
The variable lang seems to be never declared. If this is a global, consider adding a /** global: lang */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
40
        attrs: {id: 'upload'}
41
      },
42
      {
43
        icon: 'fas fa-folder',
44
        label: lang['nav-new'],
45
        attrs: {id: 'add-folder'}
46
      }
47
    ]
48
  });
49
50
  actions.reverse().forEach(function (action) {
0 ignored issues
show
Bug introduced by
The variable actions seems to be never declared. If this is a global, consider adding a /** global: actions */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
51
    $('#nav-buttons > ul').prepend(
52
      $('<li>').addClass('nav-item').append(
53
        $('<a>').addClass('nav-link d-none')
54
          .attr('data-action', action.name)
55
          .attr('data-multiple', action.multiple)
56
          .append($('<i>').addClass('fas fa-fw fa-' + action.icon))
57
          .append($('<span>').text(action.label))
58
      )
59
    );
60
  });
61
62
  sortings.forEach(function (sort) {
0 ignored issues
show
Bug introduced by
The variable sortings seems to be never declared. If this is a global, consider adding a /** global: sortings */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
63
    $('#nav-buttons .dropdown-menu').append(
64
      $('<a>').addClass('dropdown-item').attr('data-sortby', sort.by)
65
        .append($('<i>').addClass('fas fa-fw fa-' + sort.icon))
66
        .append($('<span>').text(sort.label))
67
        .click(function() {
68
          sort_type = sort.by;
69
          loadItems();
70
        })
71
    );
72
  });
73
74
  loadFolders();
75
  performLfmRequest('errors')
76
    .done(function (response) {
77
      JSON.parse(response).forEach(function (message) {
78
        $('#alerts').append(
79
          $('<div>').addClass('alert alert-warning')
80
            .append($('<i>').addClass('fas fa-exclamation-circle'))
81
            .append(' ' + message)
82
        );
83
      });
84
    });
85
86
  $(window).on('dragenter', function(){
87
    $('#uploadModal').modal('show');
88
  });
89
90
  if (usingWysiwygEditor()) {
91
    $('#multi_selection_toggle').hide();
92
  }
93
});
94
95
// ======================
96
// ==  Navbar actions  ==
97
// ======================
98
99
$('#multi_selection_toggle').click(function () {
100
  multi_selection_enabled = !multi_selection_enabled;
101
102
  $('#multi_selection_toggle i')
103
    .toggleClass('fa-times', multi_selection_enabled)
104
    .toggleClass('fa-check-double', !multi_selection_enabled);
105
106
  if (!multi_selection_enabled) {
107
    clearSelected();
108
  }
109
});
110
111
$('#to-previous').click(function () {
112
  var previous_dir = getPreviousDir();
113
  if (previous_dir == '') return;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
114
  goTo(previous_dir);
115
});
116
117
function toggleMobileTree(should_display) {
118
  if (should_display === undefined) {
119
    should_display = !$('#tree').hasClass('in');
120
  }
121
  $('#tree').toggleClass('in', should_display);
122
}
123
124
$('#show_tree').click(function (e) {
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
125
  toggleMobileTree();
126
});
127
128
$('#main').click(function (e) {
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
129
  if ($('#tree').hasClass('in')) {
130
    toggleMobileTree(false);
131
  }
132
});
133
134
$(document).on('click', '#add-folder', function () {
135
  dialog(lang['message-name'], '', createFolder);
0 ignored issues
show
Bug introduced by
The variable lang seems to be never declared. If this is a global, consider adding a /** global: lang */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
136
});
137
138
$(document).on('click', '#upload', function () {
139
  $('#uploadModal').modal('show');
140
});
141
142
$(document).on('click', '[data-display]', function() {
143
  show_list = $(this).data('display');
144
  loadItems();
145
});
146
147
$(document).on('click', '[data-action]', function() {
148
  window[$(this).data('action')]($(this).data('multiple') ? getSelectedItems() : getOneSelectedElement());
149
});
150
151
// ==========================
152
// ==  Multiple Selection  ==
153
// ==========================
154
155
function toggleSelected (e) {
156
  if (!multi_selection_enabled) {
157
    selected = [];
158
  }
159
160
  var sequence = $(e.target).closest('a').data('id');
161
  var element_index = selected.indexOf(sequence);
162
  if (element_index === -1) {
163
    selected.push(sequence);
164
  } else {
165
    selected.splice(element_index, 1);
166
  }
167
168
  updateSelectedStyle();
169
}
170
171
function clearSelected () {
172
  selected = [];
173
174
  multi_selection_enabled = false;
175
176
  updateSelectedStyle();
177
}
178
179
function updateSelectedStyle() {
180
  items.forEach(function (item, index) {
181
    $('[data-id=' + index + ']')
182
      .find('.square')
183
      .toggleClass('selected', selected.indexOf(index) > -1);
184
  });
185
  toggleActions();
186
}
187
188
function getOneSelectedElement(orderOfItem) {
189
  var index = orderOfItem !== undefined ? orderOfItem : selected[0];
190
  return items[index];
191
}
192
193
function getSelectedItems() {
194
  return selected.reduce(function (arr_objects, id) {
195
    arr_objects.push(getOneSelectedElement(id));
196
    return arr_objects
197
  }, []);
198
}
199
200
function toggleActions() {
201
  var one_selected = selected.length === 1;
202
  var many_selected = selected.length >= 1;
203
  var only_image = getSelectedItems()
204
    .filter(function (item) { return !item.is_image; })
205
    .length === 0;
206
  var only_file = getSelectedItems()
207
    .filter(function (item) { return !item.is_file; })
208
    .length === 0;
209
210
  $('[data-action=use]').toggleClass('d-none', !(many_selected && only_file));
211
  $('[data-action=rename]').toggleClass('d-none', !one_selected);
212
  $('[data-action=preview]').toggleClass('d-none', !(many_selected && only_file));
213
  $('[data-action=move]').toggleClass('d-none', !many_selected);
214
  $('[data-action=download]').toggleClass('d-none', !(many_selected && only_file));
215
  $('[data-action=resize]').toggleClass('d-none', !(one_selected && only_image));
216
  $('[data-action=crop]').toggleClass('d-none', !(one_selected && only_image));
217
  $('[data-action=trash]').toggleClass('d-none', !many_selected);
218
  $('[data-action=open]').toggleClass('d-none', !one_selected || only_file);
219
  $('#multi_selection_toggle').toggleClass('d-none', usingWysiwygEditor() || !many_selected);
220
  $('#actions').toggleClass('d-none', selected.length === 0);
221
  $('#fab').toggleClass('d-none', selected.length !== 0);
222
}
223
224
// ======================
225
// ==  Folder actions  ==
226
// ======================
227
228
$(document).on('click', '#tree a', function (e) {
229
  goTo($(e.target).closest('a').data('path'));
230
  toggleMobileTree(false);
231
});
232
233
function goTo(new_dir) {
234
  $('#working_dir').val(new_dir);
235
  loadItems();
236
}
237
238
function getPreviousDir() {
239
  var working_dir = $('#working_dir').val();
240
  return working_dir.substring(0, working_dir.lastIndexOf('/'));
241
}
242
243
function setOpenFolders() {
244
  $('#tree [data-path]').each(function (index, folder) {
245
    // close folders that are not parent
246
    var should_open = ($('#working_dir').val() + '/').startsWith($(folder).data('path') + '/');
247
    $(folder).children('i')
248
      .toggleClass('fa-folder-open', should_open)
249
      .toggleClass('fa-folder', !should_open);
250
  });
251
252
  $('#tree .nav-item').removeClass('active');
253
  $('#tree [data-path="' + $('#working_dir').val() + '"]').parent('.nav-item').addClass('active');
254
}
255
256
// ====================
257
// ==  Ajax actions  ==
258
// ====================
259
260
function performLfmRequest(url, parameter, type) {
261
  var data = defaultParameters();
262
263
  if (parameter != null) {
0 ignored issues
show
Best Practice introduced by
Comparing parameter to null using the != operator is not safe. Consider using !== instead.
Loading history...
264
    $.each(parameter, function (key, value) {
265
      data[key] = value;
266
    });
267
  }
268
269
  return $.ajax({
270
    type: 'GET',
271
    beforeSend: function(request) {
272
      var token = getUrlParam('token');
273
      if (token !== null) {
274
        request.setRequestHeader("Authorization", 'Bearer ' + token);
275
      }
276
    },
277
    dataType: type || 'text',
278
    url: lfm_route + '/' + url,
279
    data: data,
280
    cache: false
281
  }).fail(function (jqXHR, textStatus, errorThrown) {
0 ignored issues
show
Unused Code introduced by
The parameter textStatus is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter errorThrown is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
282
    displayErrorResponse(jqXHR);
283
  });
284
}
285
286
function displayErrorResponse(jqXHR) {
287
  var message = JSON.parse(jqXHR.responseText)
288
  if (Array.isArray(message)) {
289
    message = message.join('<br>')
290
  }
291
  notify('<div style="max-height:50vh;overflow: auto;">' + message + '</div>');
292
}
293
294
var refreshFoldersAndItems = function (data) {
295
  loadFolders();
296
  if (data != 'OK') {
297
    data = Array.isArray(data) ? data.join('<br/>') : data;
298
    notify(data);
299
  }
300
};
301
302
var hideNavAndShowEditor = function (data) {
303
  $('#nav-buttons > ul').addClass('d-none');
304
  $('#content').html(data);
305
  $('#pagination').removeClass('preserve_actions_space')
306
  clearSelected();
307
}
308
309
function loadFolders() {
310
  performLfmRequest('folders', {}, 'html')
311
    .done(function (data) {
312
      $('#tree').html(data);
313
      loadItems();
314
    });
315
}
316
317
function generatePaginationHTML(el, args) {
318
  var template = '<li class="page-item"><\/li>';
319
  var linkTemplate = '<a class="page-link"><\/a>';
320
  var currentPage = args.currentPage;
321
  var totalPage = args.totalPage;
322
  var rangeStart = args.rangeStart;
323
  var rangeEnd = args.rangeEnd;
324
  var i;
325
326
  // Disable page range, display all the pages
327
  if (args.pageRange === null) {
328
    for (i = 1; i <= totalPage; i++) {
329
      var button = $(template)
330
        .attr('data-num', i)
331
        .append($(linkTemplate).html(i));
332
      if (i == currentPage) {
333
        button.addClass('active');
334
      }
335
      el.append(button);
336
    }
337
338
    return;
339
  }
340
341
  if (rangeStart <= 3) {
342
    for (i = 1; i < rangeStart; i++) {
343
      var button = $(template)
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable button already seems to be declared on line 329. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
344
        .attr('data-num', i)
345
        .append($(linkTemplate).html(i));
346
      if (i == currentPage) {
347
        button.addClass('active');
348
      }
349
      el.append(button);
350
    }
351
  } else {
352
    var button = $(template)
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable button already seems to be declared on line 329. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
353
      .attr('data-num', 1)
354
      .append($(linkTemplate).html(1));
355
    el.append(button);
356
357
    var button = $(template)
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable button already seems to be declared on line 329. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
358
      .addClass('disabled')
359
      .append($(linkTemplate).html('...'));
360
    el.append(button);
361
  }
362
363
  for (i = rangeStart; i <= rangeEnd; i++) {
364
    var button = $(template)
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable button already seems to be declared on line 329. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
365
      .attr('data-num', i)
366
      .append($(linkTemplate).html(i));
367
    if (i == currentPage) {
368
      button.addClass('active');
369
    }
370
    el.append(button);
371
  }
372
373
  if (rangeEnd >= totalPage - 2) {
374
    for (i = rangeEnd + 1; i <= totalPage; i++) {
375
      var button = $(template)
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable button already seems to be declared on line 329. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
376
        .attr('data-num', i)
377
        .append($(linkTemplate).html(i));
378
      el.append(button);
379
    }
380
  } else {
381
    var button = $(template)
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable button already seems to be declared on line 329. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
382
      .addClass('disabled')
383
      .append($(linkTemplate).html('...'));
384
    el.append(button);
385
386
    var button = $(template)
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable button already seems to be declared on line 329. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
387
      .attr('data-num', totalPage)
388
      .append($(linkTemplate).html(totalPage));
389
    el.append(button);
390
  }
391
}
392
393
function createPagination(paginationSetting) {
394
  var el = $('<ul class="pagination" role="navigation"></ul>');
395
396
  var currentPage = paginationSetting.current_page;
397
  var pageRange = 5;
398
  var totalPage = Math.ceil(paginationSetting.total / paginationSetting.per_page);
399
400
  var rangeStart = currentPage - pageRange;
401
  var rangeEnd = currentPage + pageRange;
402
403
  if (rangeEnd > totalPage) {
404
    rangeEnd = totalPage;
405
    rangeStart = totalPage - pageRange * 2;
406
    rangeStart = rangeStart < 1 ? 1 : rangeStart;
407
  }
408
409
  if (rangeStart <= 1) {
410
    rangeStart = 1;
411
    rangeEnd = Math.min(pageRange * 2 + 1, totalPage);
412
  }
413
414
  generatePaginationHTML(el, {
415
    totalPage: totalPage,
416
    currentPage: currentPage,
417
    pageRange: pageRange,
418
    rangeStart: rangeStart,
419
    rangeEnd: rangeEnd
420
  });
421
422
  $('#pagination').append(el);
423
}
424
425
function loadItems(page) {
426
  loading(true);
427
  performLfmRequest('jsonitems', {show_list: show_list, sort_type: sort_type, page: page || 1}, 'html')
428
    .done(function (data) {
429
      selected = [];
430
      var response = JSON.parse(data);
431
      var working_dir = response.working_dir;
432
      items = response.items;
433
      var hasItems = items.length !== 0;
434
      var hasPaginator = !!response.paginator;
435
      $('#empty').toggleClass('d-none', hasItems);
436
      $('#content').html('').removeAttr('class');
437
      $('#pagination').html('').removeAttr('class');
438
439
      if (hasItems) {
440
        $('#content').addClass(response.display);
441
        $('#pagination').addClass('preserve_actions_space');
442
443
        items.forEach(function (item, index) {
444
          var template = $('#item-template').clone()
445
            .removeAttr('id class')
446
            .attr('data-id', index)
447
            .click(toggleSelected)
448
            .dblclick(function (e) {
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
449
              if (item.is_file) {
450
                use(getSelectedItems());
451
              } else {
452
                goTo(item.url);
453
              }
454
            });
455
456
          if (item.thumb_url) {
457
            var image = $('<div>').css('background-image', 'url("' + item.thumb_url + '?timestamp=' + item.time + '")');
458
          } else {
459
            var icon = $('<div>').addClass('ico');
460
            var image = $('<div>').addClass('mime-icon ico-' + item.icon).append(icon);
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable image already seems to be declared on line 457. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
461
          }
462
463
          template.find('.square').append(image);
464
          template.find('.item_name').text(item.name);
465
          template.find('time').text((new Date(item.time * 1000)).toLocaleString());
466
467
          $('#content').append(template);
468
        });
469
      }
470
471
      if (hasPaginator) {
472
        createPagination(response.paginator);
473
474
        $('#pagination a').on('click', function(event) {
475
          event.preventDefault();
476
477
          loadItems($(this).closest('li')[0].getAttribute('data-num'));
478
479
          return false;
480
        });
481
      }
482
483
      $('#nav-buttons > ul').removeClass('d-none');
484
485
      $('#working_dir').val(working_dir);
486
      console.log('Current working_dir : ' + working_dir);
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
487
      var breadcrumbs = [];
488
      var validSegments = working_dir.split('/').filter(function (e) { return e; });
489
      validSegments.forEach(function (segment, index) {
490
        if (index === 0) {
491
          // set root folder name as the first breadcrumb
492
          breadcrumbs.push($("[data-path='/" + segment + "']").text());
493
        } else {
494
          breadcrumbs.push(segment);
495
        }
496
      });
497
498
      $('#current_folder').text(breadcrumbs[breadcrumbs.length - 1]);
499
      $('#breadcrumbs > ol').html('');
500
      breadcrumbs.forEach(function (breadcrumb, index) {
501
        var li = $('<li>').addClass('breadcrumb-item').text(breadcrumb);
502
503
        if (index === breadcrumbs.length - 1) {
504
          li.addClass('active').attr('aria-current', 'page');
505
        } else {
506
          li.click(function () {
507
            // go to corresponding path
508
            goTo('/' + validSegments.slice(0, 1 + index).join('/'));
509
          });
510
        }
511
512
        $('#breadcrumbs > ol').append(li);
513
      });
514
515
      var atRootFolder = getPreviousDir() == '';
516
      $('#to-previous').toggleClass('d-none invisible-lg', atRootFolder);
517
      $('#show_tree').toggleClass('d-none', !atRootFolder).toggleClass('d-block', atRootFolder);
518
      setOpenFolders();
519
      loading(false);
520
      toggleActions();
521
    });
522
}
523
524
function loading(show_loading) {
525
  $('#loading').toggleClass('d-none', !show_loading);
526
}
527
528
function createFolder(folder_name) {
529
  performLfmRequest('newfolder', {name: folder_name})
530
    .done(refreshFoldersAndItems);
531
}
532
533
// ==================================
534
// ==         File Actions         ==
535
// ==================================
536
537
function rename(item) {
538
  dialog(lang['message-rename'], item.name, function (new_name) {
0 ignored issues
show
Bug introduced by
The variable lang seems to be never declared. If this is a global, consider adding a /** global: lang */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
539
    performLfmRequest('rename', {
540
      file: item.name,
541
      new_name: new_name
542
    }).done(refreshFoldersAndItems);
543
  });
544
}
545
546
function trash(items) {
547
  confirm(lang['message-delete'], function () {
0 ignored issues
show
Bug introduced by
The variable lang seems to be never declared. If this is a global, consider adding a /** global: lang */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
548
    performLfmRequest('delete', {
549
      items: items.map(function (item) { return item.name; })
550
    }).done(refreshFoldersAndItems)
551
  });
552
}
553
554
function crop(item) {
555
  performLfmRequest('crop', {img: item.name})
556
    .done(hideNavAndShowEditor);
557
}
558
559
function resize(item) {
560
  performLfmRequest('resize', {img: item.name})
561
    .done(hideNavAndShowEditor);
562
}
563
564
function download(items) {
565
  items.forEach(function (item, index) {
566
    var data = defaultParameters();
567
568
    data['file'] = item.name;
569
570
    var token = getUrlParam('token');
571
    if (token) {
572
      data['token'] = token;
573
    }
574
575
    setTimeout(function () {
576
      location.href = lfm_route + '/download?' + $.param(data);
577
    }, index * 100);
578
  });
579
}
580
581
function open(item) {
582
  goTo(item.url);
583
}
584
585
function preview(items) {
586
  var carousel = $('#carouselTemplate').clone().attr('id', 'previewCarousel').removeClass('d-none');
587
  var imageTemplate = carousel.find('.carousel-item').clone().removeClass('active');
588
  var indicatorTemplate = carousel.find('.carousel-indicators > li').clone().removeClass('active');
589
  carousel.children('.carousel-inner').html('');
590
  carousel.children('.carousel-indicators').html('');
591
  carousel.children('.carousel-indicators,.carousel-control-prev,.carousel-control-next').toggle(items.length > 1);
592
593
  items.forEach(function (item, index) {
594
    var carouselItem = imageTemplate.clone()
595
      .addClass(index === 0 ? 'active' : '');
596
597
    if (item.thumb_url) {
598
      carouselItem.find('.carousel-image').css('background-image', 'url(\'' + item.url + '?timestamp=' + item.time + '\')');
599
    } else {
600
      carouselItem.find('.carousel-image').css('width', '50vh').append($('<div>').addClass('mime-icon ico-' + item.icon));
601
    }
602
603
    carouselItem.find('.carousel-label').attr('target', '_blank').attr('href', item.url)
604
      .text(item.name)
605
      .append($('<i class="fas fa-external-link-alt ml-2"></i>'));
606
607
    carousel.children('.carousel-inner').append(carouselItem);
608
609
    var carouselIndicator = indicatorTemplate.clone()
610
      .addClass(index === 0 ? 'active' : '')
611
      .attr('data-slide-to', index);
612
    carousel.children('.carousel-indicators').append(carouselIndicator);
613
  });
614
615
616
  // carousel swipe control
617
  var touchStartX = null;
618
619
  carousel.on('touchstart', function (event) {
620
    var e = event.originalEvent;
621
    if (e.touches.length == 1) {
0 ignored issues
show
Best Practice introduced by
Comparing e.touches.length to 1 using the == operator is not safe. Consider using === instead.
Loading history...
622
      var touch = e.touches[0];
623
      touchStartX = touch.pageX;
624
    }
625
  }).on('touchmove', function (event) {
626
    var e = event.originalEvent;
627
    if (touchStartX != null) {
0 ignored issues
show
Best Practice introduced by
Comparing touchStartX to null using the != operator is not safe. Consider using !== instead.
Loading history...
628
      var touchCurrentX = e.changedTouches[0].pageX;
629
      if ((touchCurrentX - touchStartX) > 60) {
630
        touchStartX = null;
631
        carousel.carousel('prev');
632
      } else if ((touchStartX - touchCurrentX) > 60) {
633
        touchStartX = null;
634
        carousel.carousel('next');
635
      }
636
    }
637
  }).on('touchend', function () {
638
    touchStartX = null;
639
  });
640
  // end carousel swipe control
641
642
  notify(carousel);
643
}
644
645
function move(items) {
646
  performLfmRequest('move', { items: items.map(function (item) { return item.name; }) })
647
    .done(refreshFoldersAndItems);
648
}
649
650
function getUrlParam(paramName) {
651
  var reParam = new RegExp('(?:[\?&]|&)' + paramName + '=([^&]+)', 'i');
652
  var match = window.location.search.match(reParam);
653
  return ( match && match.length > 1 ) ? match[1] : null;
654
}
655
656
function use(items) {
657
  function useTinymce3(url) {
658
    if (!usingTinymce3()) { return; }
659
660
    var win = tinyMCEPopup.getWindowArg("window");
0 ignored issues
show
Bug introduced by
The variable tinyMCEPopup seems to be never declared. If this is a global, consider adding a /** global: tinyMCEPopup */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
661
    win.document.getElementById(tinyMCEPopup.getWindowArg("input")).value = url;
662
    if (typeof(win.ImageDialog) != "undefined") {
663
      // Update image dimensions
664
      if (win.ImageDialog.getImageData) {
665
        win.ImageDialog.getImageData();
666
      }
667
668
      // Preview if necessary
669
      if (win.ImageDialog.showPreviewImage) {
670
        win.ImageDialog.showPreviewImage(url);
671
      }
672
    }
673
    tinyMCEPopup.close();
674
  }
675
676
  function useTinymce4AndColorbox(url) {
677
    if (!usingTinymce4AndColorbox()) { return; }
678
679
    parent.document.getElementById(getUrlParam('field_name')).value = url;
0 ignored issues
show
Bug introduced by
The variable parent seems to be never declared. If this is a global, consider adding a /** global: parent */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
680
681
    if(typeof parent.tinyMCE !== "undefined") {
682
      parent.tinyMCE.activeEditor.windowManager.close();
683
    }
684
    if(typeof parent.$.fn.colorbox !== "undefined") {
685
      parent.$.fn.colorbox.close();
686
    }
687
  }
688
689
  function useTinymce5(url){
690
    if (!usingTinymce5()) { return; }
691
692
    parent.postMessage({
0 ignored issues
show
Bug introduced by
The variable parent seems to be never declared. If this is a global, consider adding a /** global: parent */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
693
      mceAction: 'insert',
694
      content: url
695
    });
696
697
    parent.postMessage({ mceAction: 'close' });
698
  }
699
700
  function useCkeditor3(url) {
701
    if (!usingCkeditor3()) { return; }
702
703
    if (window.opener) {
704
      // Popup
705
      window.opener.CKEDITOR.tools.callFunction(getUrlParam('CKEditorFuncNum'), url);
706
    } else {
707
      // Modal (in iframe)
708
      parent.CKEDITOR.tools.callFunction(getUrlParam('CKEditorFuncNum'), url);
0 ignored issues
show
Bug introduced by
The variable parent seems to be never declared. If this is a global, consider adding a /** global: parent */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
709
      parent.CKEDITOR.tools.callFunction(getUrlParam('CKEditorCleanUpFuncNum'));
710
    }
711
  }
712
713
  function useFckeditor2(url) {
714
    if (!usingFckeditor2()) { return; }
715
716
    var p = url;
717
    var w = data['Properties']['Width'];
0 ignored issues
show
Bug introduced by
The variable data seems to be never declared. If this is a global, consider adding a /** global: data */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
718
    var h = data['Properties']['Height'];
719
    window.opener.SetUrl(p,w,h);
720
  }
721
722
  var url = items[0].url;
723
  var callback = getUrlParam('callback');
724
  var useFileSucceeded = true;
725
726
  if (usingWysiwygEditor()) {
727
    useTinymce3(url);
728
729
    useTinymce4AndColorbox(url);
730
731
    useTinymce5(url);
732
733
    useCkeditor3(url);
734
735
    useFckeditor2(url);
736
  } else if (callback && window[callback]) {
737
    window[callback](getSelectedItems());
738
  } else if (callback && parent[callback]) {
0 ignored issues
show
Bug introduced by
The variable parent seems to be never declared. If this is a global, consider adding a /** global: parent */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
739
    parent[callback](getSelectedItems());
740
  } else if (window.opener) { // standalone button or other situations
741
    window.opener.SetUrl(getSelectedItems());
742
  } else {
743
    useFileSucceeded = false;
744
  }
745
746
  if (useFileSucceeded) {
747
    if (window.opener) {
748
      window.close();
749
    }
750
  } else {
751
    console.log('window.opener not found');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
752
    // No editor found, open/download file using browser's default method
753
    window.open(url);
754
  }
755
}
756
//end useFile
757
758
// ==================================
759
// ==     WYSIWYG Editors Check    ==
760
// ==================================
761
762
function usingTinymce3() {
763
  return !!window.tinyMCEPopup;
764
}
765
766
function usingTinymce4AndColorbox() {
767
  return !!getUrlParam('field_name');
768
}
769
770
function usingTinymce5(){
771
    return !!getUrlParam('editor');
772
}
773
774
function usingCkeditor3() {
775
  return !!getUrlParam('CKEditor') || !!getUrlParam('CKEditorCleanUpFuncNum');
776
}
777
778
function usingFckeditor2() {
779
  return window.opener && typeof data != 'undefined' && data['Properties']['Width'] != '';
0 ignored issues
show
Bug introduced by
The variable data seems to be never declared. If this is a global, consider adding a /** global: data */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
780
}
781
782
function usingWysiwygEditor() {
783
  return usingTinymce3() || usingTinymce4AndColorbox() || usingTinymce5() || usingCkeditor3() || usingFckeditor2();
784
}
785
786
// ==================================
787
// ==            Others            ==
788
// ==================================
789
790
function defaultParameters() {
791
  return {
792
    working_dir: $('#working_dir').val(),
793
    type: $('#type').val()
794
  };
795
}
796
797
function notImp() {
798
  notify('Not yet implemented!');
799
}
800
801
function notify(body) {
802
  $('#notify').modal('show').find('.modal-body').html(body);
803
}
804
805
function confirm(body, callback) {
806
  $('#confirm').find('.btn-primary').toggle(callback !== undefined);
807
  $('#confirm').find('.btn-primary').click(callback);
808
  $('#confirm').modal('show').find('.modal-body').html(body);
809
}
810
811
function dialog(title, value, callback) {
812
  $('#dialog').find('input').val(value);
813
  $('#dialog').on('shown.bs.modal', function () {
814
    $('#dialog').find('input').focus();
815
  });
816
  $('#dialog').find('.btn-primary').unbind().click(function (e) {
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
817
    callback($('#dialog').find('input').val());
818
  });
819
  $('#dialog').modal('show').find('.modal-title').text(title);
820
}
821