browse-everything 1.0.0.rc1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.circleci/config.yml +71 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +4 -0
- data/CONTRIBUTING.md +3 -3
- data/LICENSE.txt +205 -22
- data/README.md +31 -14
- data/Rakefile +0 -9
- data/app/assets/javascripts/browse_everything/behavior.js +448 -0
- data/app/assets/stylesheets/browse_everything.scss +0 -6
- data/app/assets/stylesheets/browse_everything/_browse_everything.scss +2 -116
- data/app/assets/stylesheets/browse_everything/_browse_everything_bootstrap3.scss +123 -0
- data/app/assets/stylesheets/browse_everything/_browse_everything_bootstrap4.scss +117 -0
- data/app/views/browse_everything/_files.html.erb +1 -0
- data/app/views/browse_everything/_providers.html.erb +2 -1
- data/app/views/browse_everything/index.html.erb +3 -2
- data/browse-everything.gemspec +7 -9
- data/karma.conf.js +71 -0
- data/lib/browse-everything.rb +0 -2
- data/lib/browse_everything.rb +11 -5
- data/lib/browse_everything/driver/box.rb +10 -3
- data/lib/browse_everything/driver/dropbox.rb +25 -9
- data/lib/browse_everything/driver/file_system.rb +17 -5
- data/lib/browse_everything/driver/google_drive.rb +2 -1
- data/lib/browse_everything/driver/s3.rb +18 -2
- data/lib/browse_everything/retriever.rb +7 -2
- data/lib/browse_everything/version.rb +1 -1
- data/lib/generators/browse_everything/install_generator.rb +1 -7
- data/lib/generators/browse_everything/templates/browse_everything_providers.yml.example +1 -0
- data/spec/javascripts/behavior_spec.js +1 -3
- data/spec/javascripts/helpers/jquery.js +11008 -0
- data/spec/javascripts/karma_spec.rb +16 -0
- data/spec/lib/browse_everything/browser_spec.rb +5 -3
- data/spec/lib/browse_everything/driver/dropbox_spec.rb +20 -1
- data/spec/lib/browse_everything_spec.rb +7 -0
- data/spec/spec_helper.rb +8 -1
- data/spec/support/capybara.rb +0 -5
- data/spec/test_app_templates/Gemfile.extra +7 -0
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +7 -1
- metadata +69 -82
- data/.travis.yml +0 -27
- data/app/assets/javascripts/browse_everything/behavior.js.coffee +0 -342
- data/app/helpers/font_awesome_version_helper.rb +0 -17
- data/lib/generators/browse_everything/assets_generator.rb +0 -13
- data/lib/generators/browse_everything/templates/browse_everything.scss +0 -6
- data/spec/javascripts/jasmine_spec.rb +0 -21
- data/spec/javascripts/support/jasmine.yml +0 -124
- 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
|
+
}
|