browse-everything 1.0.0.rc1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +71 -0
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +4 -0
  5. data/CONTRIBUTING.md +3 -3
  6. data/LICENSE.txt +205 -22
  7. data/README.md +31 -14
  8. data/Rakefile +0 -9
  9. data/app/assets/javascripts/browse_everything/behavior.js +448 -0
  10. data/app/assets/stylesheets/browse_everything.scss +0 -6
  11. data/app/assets/stylesheets/browse_everything/_browse_everything.scss +2 -116
  12. data/app/assets/stylesheets/browse_everything/_browse_everything_bootstrap3.scss +123 -0
  13. data/app/assets/stylesheets/browse_everything/_browse_everything_bootstrap4.scss +117 -0
  14. data/app/views/browse_everything/_files.html.erb +1 -0
  15. data/app/views/browse_everything/_providers.html.erb +2 -1
  16. data/app/views/browse_everything/index.html.erb +3 -2
  17. data/browse-everything.gemspec +7 -9
  18. data/karma.conf.js +71 -0
  19. data/lib/browse-everything.rb +0 -2
  20. data/lib/browse_everything.rb +11 -5
  21. data/lib/browse_everything/driver/box.rb +10 -3
  22. data/lib/browse_everything/driver/dropbox.rb +25 -9
  23. data/lib/browse_everything/driver/file_system.rb +17 -5
  24. data/lib/browse_everything/driver/google_drive.rb +2 -1
  25. data/lib/browse_everything/driver/s3.rb +18 -2
  26. data/lib/browse_everything/retriever.rb +7 -2
  27. data/lib/browse_everything/version.rb +1 -1
  28. data/lib/generators/browse_everything/install_generator.rb +1 -7
  29. data/lib/generators/browse_everything/templates/browse_everything_providers.yml.example +1 -0
  30. data/spec/javascripts/behavior_spec.js +1 -3
  31. data/spec/javascripts/helpers/jquery.js +11008 -0
  32. data/spec/javascripts/karma_spec.rb +16 -0
  33. data/spec/lib/browse_everything/browser_spec.rb +5 -3
  34. data/spec/lib/browse_everything/driver/dropbox_spec.rb +20 -1
  35. data/spec/lib/browse_everything_spec.rb +7 -0
  36. data/spec/spec_helper.rb +8 -1
  37. data/spec/support/capybara.rb +0 -5
  38. data/spec/test_app_templates/Gemfile.extra +7 -0
  39. data/spec/test_app_templates/lib/generators/test_app_generator.rb +7 -1
  40. metadata +69 -82
  41. data/.travis.yml +0 -27
  42. data/app/assets/javascripts/browse_everything/behavior.js.coffee +0 -342
  43. data/app/helpers/font_awesome_version_helper.rb +0 -17
  44. data/lib/generators/browse_everything/assets_generator.rb +0 -13
  45. data/lib/generators/browse_everything/templates/browse_everything.scss +0 -6
  46. data/spec/javascripts/jasmine_spec.rb +0 -21
  47. data/spec/javascripts/support/jasmine.yml +0 -124
  48. data/spec/javascripts/support/jasmine_helper.rb +0 -16
@@ -0,0 +1,448 @@
1
+ 'use strict';
2
+
3
+ $(function () {
4
+ var dialog = $('div#browse-everything');
5
+
6
+ var initialize = function initialize(obj, options) {
7
+ if ($('div#browse-everything').length === 0) {
8
+ // bootstrap 4 needs at least the inner class="modal-dialog" div, or it gets really
9
+ // confused and can't close the dialog.
10
+ dialog = $('<div tabindex="-1" id="browse-everything" class="ev-browser modal fade" aria-live="polite" role="dialog" aria-labelledby="beModalLabel">' + '<div class="modal-dialog modal-lg" role="document"></div>' + '</div>').hide().appendTo('body');
11
+ }
12
+
13
+ dialog.modal({
14
+ backdrop: 'static',
15
+ show: false
16
+ });
17
+ var ctx = {
18
+ opts: $.extend(true, {}, options),
19
+ callbacks: {
20
+ show: $.Callbacks(),
21
+ done: $.Callbacks(),
22
+ cancel: $.Callbacks(),
23
+ fail: $.Callbacks()
24
+ }
25
+ };
26
+ ctx.callback_proxy = {
27
+ show: function show(func) {
28
+ ctx.callbacks.show.add(func);return this;
29
+ },
30
+ done: function done(func) {
31
+ ctx.callbacks.done.add(func);return this;
32
+ },
33
+ cancel: function cancel(func) {
34
+ ctx.callbacks.cancel.add(func);return this;
35
+ },
36
+ fail: function fail(func) {
37
+ ctx.callbacks.fail.add(func);return this;
38
+ }
39
+ };
40
+ $(obj).data('ev-state', ctx);
41
+ return ctx;
42
+ };
43
+
44
+ var toHiddenFields = function toHiddenFields(data) {
45
+ var fields = $.param(data).split('&').map(function (t) {
46
+ return t.replace(/\+/g, ' ').split('=', 2);
47
+ });
48
+ var elements = $(fields).map(function () {
49
+ return $("<input type='hidden'/>").attr('name', decodeURIComponent(this[0])).val(decodeURIComponent(this[1]))[0].outerHTML;
50
+ });
51
+ return $(elements.toArray().join("\n"));
52
+ };
53
+
54
+ var indicateSelected = function indicateSelected() {
55
+ return $('input.ev-url').each(function () {
56
+ return $('*[data-ev-location=\'' + $(this).val() + '\']').addClass('ev-selected');
57
+ });
58
+ };
59
+
60
+ var fileIsSelected = function fileIsSelected(row) {
61
+ var result = false;
62
+ $('input.ev-url').each(function () {
63
+ if (this.value === $(row).data('ev-location')) {
64
+ return result = true;
65
+ }
66
+ });
67
+ return result;
68
+ };
69
+
70
+ var toggleFileSelect = function toggleFileSelect(row) {
71
+ row.toggleClass('ev-selected');
72
+ if (row.hasClass('ev-selected')) {
73
+ selectFile(row);
74
+ } else {
75
+ unselectFile(row);
76
+ }
77
+ return updateFileCount();
78
+ };
79
+
80
+ var selectFile = function selectFile(row) {
81
+ var target_form = $('form.ev-submit-form');
82
+ var file_location = row.data('ev-location');
83
+ var hidden_input = $("<input type='hidden' class='ev-url' name='selected_files[]'/>").val(file_location);
84
+ target_form.append(hidden_input);
85
+ if (!$(row).find('.ev-select-file').prop('checked')) {
86
+ return $(row).find('.ev-select-file').prop('checked', true);
87
+ }
88
+ };
89
+
90
+ var unselectFile = function unselectFile(row) {
91
+ var target_form = $('form.ev-submit-form');
92
+ var file_location = row.data('ev-location');
93
+ $('form.ev-submit-form input[value=\'' + file_location + '\']').remove();
94
+ if ($(row).find('.ev-select-file').prop('checked')) {
95
+ return $(row).find('.ev-select-file').prop('checked', false);
96
+ }
97
+ };
98
+
99
+ var updateFileCount = function updateFileCount() {
100
+ var count = $('input.ev-url').length;
101
+ var files = count === 1 ? "file" : "files";
102
+ return $('.ev-status').html(count + ' ' + files + ' selected');
103
+ };
104
+
105
+ var toggleBranchSelect = function toggleBranchSelect(row) {
106
+ if (row.hasClass('collapsed')) {
107
+ var node_id = row.find('td.ev-file-name a.ev-link').attr('href');
108
+ return $('table#file-list').treetable('expandNode', node_id);
109
+ }
110
+ };
111
+
112
+ var selectAll = function selectAll(rows) {
113
+ return rows.each(function () {
114
+ if ($(this).data('tt-branch')) {
115
+ var box = $(this).find('#select_all')[0];
116
+ $(box).prop('checked', true);
117
+ $(box).prop('value', "1");
118
+ return toggleBranchSelect($(this));
119
+ } else {
120
+ if (!fileIsSelected($(this))) {
121
+ return toggleFileSelect($(this));
122
+ }
123
+ }
124
+ });
125
+ };
126
+
127
+ var selectChildRows = function selectChildRows(row, action) {
128
+ return $('table#file-list tr').each(function () {
129
+ if ($(this).data('tt-parent-id')) {
130
+ var re = RegExp($(row).data('tt-id'), 'i');
131
+ if ($(this).data('tt-parent-id').match(re)) {
132
+ if ($(this).data('tt-branch')) {
133
+ var box = $(this).find('#select_all')[0];
134
+ $(box).prop('value', action);
135
+ if (action === "1") {
136
+ $(box).prop("checked", true);
137
+ var node_id = $(this).find('td.ev-file-name a.ev-link').attr('href');
138
+ return $('table#file-list').treetable('expandNode', node_id);
139
+ } else {
140
+ return $(box).prop("checked", false);
141
+ }
142
+ } else {
143
+ if (action === "1") {
144
+ $(this).addClass('ev-selected');
145
+ if (!fileIsSelected($(this))) {
146
+ selectFile($(this));
147
+ }
148
+ } else {
149
+ $(this).removeClass('ev-selected');
150
+ unselectFile($(this));
151
+ }
152
+ return updateFileCount();
153
+ }
154
+ }
155
+ }
156
+ });
157
+ };
158
+
159
+ var tableSetup = function tableSetup(table) {
160
+ table.treetable({
161
+ expandable: true,
162
+ onNodeCollapse: function onNodeCollapse() {
163
+ var node = this;
164
+ return table.treetable("unloadBranch", node);
165
+ },
166
+ onNodeExpand: function onNodeExpand() {
167
+ var node = this;
168
+ startWait();
169
+ var size = $(node.row).find('td.ev-file-size').text().trim();
170
+ var start = 1;
171
+ var increment = 1;
172
+ if (size.indexOf("MB") > -1) {
173
+ start = 10;
174
+ increment = 5;
175
+ }
176
+ if (size.indexOf("KB") > -1) {
177
+ start = 50;
178
+ increment = 10;
179
+ }
180
+ setProgress(start);
181
+ var progressIntervalID = setInterval(function () {
182
+ start = start + increment;
183
+ if (start > 99) {
184
+ start = 99;
185
+ }
186
+ return setProgress(start);
187
+ }, 2000);
188
+ return setTimeout(function () {
189
+ return loadFiles(node, table, progressIntervalID);
190
+ }, 10);
191
+ }
192
+ });
193
+ $("#file-list tr:first").focus();
194
+ return sizeColumns(table);
195
+ };
196
+
197
+ var sizeColumns = function sizeColumns(table) {
198
+ var full_width = $('.ev-files').width();
199
+ table.width(full_width);
200
+ var set_size = function set_size(selector, pct) {
201
+ return $(selector, table).width(full_width * pct).css('width', full_width * pct).css('max-width', full_width * pct);
202
+ };
203
+ set_size('.ev-file', 0.4);
204
+ set_size('.ev-container', 0.4);
205
+ set_size('.ev-size', 0.1);
206
+ set_size('.ev-kind', 0.3);
207
+ return set_size('.ev-date', 0.2);
208
+ };
209
+
210
+ var loadFiles = function loadFiles(node, table, progressIntervalID) {
211
+ return $.ajax({
212
+ async: true, // Must be false, otherwise loadBranch happens after showChildren?
213
+ url: $('a.ev-link', node.row).attr('href'),
214
+ data: {
215
+ parent: node.row.data('tt-id'),
216
+ accept: dialog.data('ev-state').opts.accept,
217
+ context: dialog.data('ev-state').opts.context
218
+ } }).done(function (html) {
219
+ setProgress('100');
220
+ clearInterval(progressIntervalID);
221
+ var rows = $('tbody tr', $(html));
222
+ table.treetable("loadBranch", node, rows);
223
+ $(node).show();
224
+ sizeColumns(table);
225
+ indicateSelected();
226
+ if ($(node.row).find('#select_all')[0].checked) {
227
+ return selectAll(rows);
228
+ }
229
+ }).always(function () {
230
+ clearInterval(progressIntervalID);
231
+ return stopWait();
232
+ });
233
+ };
234
+
235
+ var setProgress = function setProgress(done) {
236
+ return $('.loading-text').text(done + '% complete');
237
+ };
238
+
239
+ var refreshFiles = function refreshFiles() {
240
+ return $('.ev-providers select').change();
241
+ };
242
+
243
+ var startWait = function startWait() {
244
+ $('.loading-progress').removeClass("hidden");
245
+ $('body').css('cursor', 'wait');
246
+ $("html").addClass("wait");
247
+ $(".ev-browser").addClass("loading");
248
+ return $('.ev-submit').attr('disabled', true);
249
+ };
250
+
251
+ var stopWait = function stopWait() {
252
+ $('.loading-progress').addClass("hidden");
253
+ $('body').css('cursor', 'default');
254
+ $("html").removeClass("wait");
255
+ $(".ev-browser").removeClass("loading");
256
+ return $('.ev-submit').attr('disabled', false);
257
+ };
258
+
259
+ $(window).on('resize', function () {
260
+ return sizeColumns($('table#file-list'));
261
+ });
262
+
263
+ $.fn.browseEverything = function (options) {
264
+ var ctx = $(this).data('ev-state');
265
+ if (ctx == null && options == null) {
266
+ options = $(this).data();
267
+ }
268
+ if (options != null) {
269
+ ctx = initialize(this[0], options);
270
+ $(this).click(function () {
271
+ dialog.data('ev-state', ctx);
272
+ return dialog.load(ctx.opts.route, function () {
273
+ setTimeout(refreshFiles, 500);
274
+ ctx.callbacks.show.fire();
275
+ return dialog.modal('show');
276
+ });
277
+ });
278
+ }
279
+
280
+ if (ctx) {
281
+ return ctx.callback_proxy;
282
+ } else {
283
+ return {
284
+ show: function show() {
285
+ return this;
286
+ },
287
+ done: function done() {
288
+ return this;
289
+ },
290
+ cancel: function cancel() {
291
+ return this;
292
+ },
293
+ fail: function fail() {
294
+ return this;
295
+ }
296
+ };
297
+ }
298
+ };
299
+
300
+ $.fn.browseEverything.toggleCheckbox = function (box) {
301
+ if (box.value === "0") {
302
+ return $(box).prop('value', "1");
303
+ } else {
304
+ return $(box).prop('value', "0");
305
+ }
306
+ };
307
+
308
+ $(document).on('ev.refresh', function (event) {
309
+ return refreshFiles();
310
+ });
311
+
312
+ $(document).on('click', 'button.ev-cancel', function (event) {
313
+ event.preventDefault();
314
+ dialog.data('ev-state').callbacks.cancel.fire();
315
+ return $('.ev-browser').modal('hide');
316
+ });
317
+
318
+ $(document).on('click', 'button.ev-submit', function (event) {
319
+ event.preventDefault();
320
+ $(this).button('loading');
321
+ startWait();
322
+ var main_form = $(this).closest('form');
323
+ var resolver_url = main_form.data('resolver');
324
+ var ctx = dialog.data('ev-state');
325
+ $(main_form).find('input[name=context]').val(ctx.opts.context);
326
+ return $.ajax(resolver_url, {
327
+ type: 'POST',
328
+ dataType: 'json',
329
+ data: main_form.serialize()
330
+ }).done(function (data) {
331
+ if (ctx.opts.target != null) {
332
+ var fields = toHiddenFields({ selected_files: data });
333
+ $(ctx.opts.target).append($(fields));
334
+ }
335
+ return ctx.callbacks.done.fire(data);
336
+ }).fail(function (xhr, status, error) {
337
+ return ctx.callbacks.fail.fire(status, error, xhr.responseText);
338
+ }).always(function () {
339
+ $('body').css('cursor', 'default');
340
+ $('.ev-browser').modal('hide');
341
+ return $('#browse-btn').focus();
342
+ });
343
+ });
344
+
345
+ $(document).on('click', '.ev-files .ev-container a.ev-link', function (event) {
346
+ event.stopPropagation();
347
+ event.preventDefault();
348
+ var row = $(this).closest('tr');
349
+ var action = row.hasClass('expanded') ? 'collapseNode' : 'expandNode';
350
+ var node_id = $(this).attr('href');
351
+ return $('table#file-list').treetable(action, node_id);
352
+ });
353
+
354
+ $(document).on('change', '.ev-providers select', function (event) {
355
+ event.preventDefault();
356
+ startWait();
357
+ return $.ajax({
358
+ url: $(this).val(),
359
+ data: {
360
+ accept: dialog.data('ev-state').opts.accept,
361
+ context: dialog.data('ev-state').opts.context
362
+ } }).done(function (data) {
363
+ $('.ev-files').html(data);
364
+ indicateSelected();
365
+ $('#provider_auth').focus();
366
+ return tableSetup($('table#file-list'));
367
+ }).fail(function (xhr, status, error) {
368
+ if (xhr.responseText.indexOf("Refresh token has expired") > -1) {
369
+ return $('.ev-files').html("Your sessison has expired please clear your cookies.");
370
+ } else {
371
+ return $('.ev-files').html(xhr.responseText);
372
+ }
373
+ }).always(function () {
374
+ return stopWait();
375
+ });
376
+ });
377
+
378
+ $(document).on('click', '.ev-providers a', function (event) {
379
+ $('.ev-providers li').removeClass('ev-selected');
380
+ return $(this).closest('li').addClass('ev-selected');
381
+ });
382
+
383
+ $(document).on('click', '.ev-file a', function (event) {
384
+ event.preventDefault();
385
+ var target = $(this).closest('*[data-ev-location]');
386
+ return toggleFileSelect(target);
387
+ });
388
+
389
+ $(document).on('click', '.ev-auth', function (event) {
390
+ event.preventDefault();
391
+ var auth_win = window.open($(this).attr('href'));
392
+ var check_func = function check_func() {
393
+ if (auth_win.closed) {
394
+ return $('.ev-providers .ev-selected a').click();
395
+ } else {
396
+ return window.setTimeout(check_func, 1000);
397
+ }
398
+ };
399
+ return check_func();
400
+ });
401
+
402
+ $(document).on('change', 'input.ev-select-all', function (event) {
403
+ event.stopPropagation();
404
+ event.preventDefault();
405
+ $.fn.browseEverything.toggleCheckbox(this);
406
+ var action = this.value;
407
+ var row = $(this).closest('tr');
408
+ var node_id = row.find('td.ev-file-name a.ev-link').attr('href');
409
+ if (row.hasClass('collapsed')) {
410
+ return $('table#file-list').treetable('expandNode', node_id);
411
+ } else {
412
+ return selectChildRows(row, action);
413
+ }
414
+ });
415
+
416
+ return $(document).on('change', 'input.ev-select-file', function (event) {
417
+ event.stopPropagation();
418
+ event.preventDefault();
419
+ return toggleFileSelect($(this).closest('tr'));
420
+ });
421
+ });
422
+
423
+ var auto_toggle = function auto_toggle() {
424
+ var triggers = $('*[data-toggle=browse-everything]');
425
+ if (typeof Rails !== 'undefined' && Rails !== null) {
426
+ $.ajaxSetup({
427
+ headers: { 'X-CSRF-TOKEN': (Rails || $.rails).csrfToken() || '' }
428
+ });
429
+ }
430
+
431
+ return triggers.each(function () {
432
+ var ctx = $(this).data('ev-state');
433
+ if (ctx == null) {
434
+ return $(this).browseEverything($(this).data());
435
+ }
436
+ });
437
+ };
438
+
439
+ if (typeof Turbolinks !== 'undefined' && Turbolinks !== null && Turbolinks.supported) {
440
+ // Use turbolinks:load for Turbolinks 5, otherwise use the old way
441
+ if (Turbolinks.BrowserAdapter) {
442
+ $(document).on('turbolinks:load', auto_toggle);
443
+ } else {
444
+ $(document).on('page:change', auto_toggle);
445
+ }
446
+ } else {
447
+ $(document).ready(auto_toggle);
448
+ }
@@ -1,6 +0,0 @@
1
- @import 'bootstrap-sprockets';
2
- @import 'bootstrap';
3
-
4
- @import "font-awesome";
5
-
6
- @import "browse_everything/browse_everything";