// code: language=javascript insertSpaces=True tabSize=4 /* Internet Explorer 11 lacks String.startsWith() */ if (!String.prototype.startsWith) { String.prototype.startsWith = function(searchString, position) { position = position || 0; return this.substr(position, searchString.length) === searchString; }; } /* Internet Explorer 8 lacks Array.indexOf */ if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(what, i) { i = i || 0; var L = this.length; while (i < L) { if (this[i] === what) return i; ++i; } return -1; }; } /* Add [].remove */ Array.prototype.remove = function() { var what, a = arguments, L = a.length, ax; while (L && this.length) { what = a[--L]; while ((ax = this.indexOf(what)) !== -1) { this.splice(ax, 1); } } return this; }; function bySortedValue(obj, callback, context) { // get a list of keys, sorted by their value, descending var keys = []; for (var key in obj) keys.push(key); keys.sort(function(a, b) { return obj[b] - obj[a] }); for (var i = 0; i < keys.length; i++) { callback.call(context, keys[i], obj[keys[i]]); } } /* get all checked items in a file browser by its ID */ function get_browser_selected(id) { var unshown_selections = $j(id).data('unshown-selections'); var hex_slash = ($j(id).data('post-action') == 'listdir'); var shown = []; var selected = []; // get the list of selected folders $j.each($j(id.concat(' :input')), function(i, input) { var input = $j(input); shown.push(input.val()); if (input.is(':checked')) { selected.push(input.val()); } }); // remove any items from unshown_selections which the browser has loaded, // then add the remaining to selected $j.each(unshown_selections, function(i, unshown_item) { if (shown.indexOf(unshown_item) != -1) { unshown_selections.remove(unshown_item); } }); $j.each(unshown_selections, function(i, unshown_item) { selected.push(unshown_item); }); // iterate over them again to set .prop('indeterminate', true) as needed $j.each($j(id.concat(' :input')), function(i, input) { var input = $j(input); if (input.is(':checked')) { input.prop('indeterminate', false); } else { // if this item is unchecked var indeterminate = false; var unchecked_path = input.val(); $j.each(selected, function(sel_i, selected_item) { // if selected_item is a child of unchecked_path, it should be set to indeterminate // example: unchecked_path="/root" and selected_item="/root/something/something" if (is_parent_path(unchecked_path, selected_item, hex_slash)) { indeterminate = true; } }); input.prop('indeterminate', indeterminate); } }); return selected; } /* check if all items were selected */ function all_selected(id) { var inputs = $j(id.concat(' :input')); for (let i = 0; i < inputs.length; i++) { if (! $j(inputs[i]).is(':checked')){ return false; } } return true; } function is_parent_path(parent, child, hex_slash) { // ensure one and only one trailing slash if (hex_slash) { // '2f' = utf-8 of '/' in hex var child = child.replace(/(?:2f)+$/, "").concat('2f'); var parent = parent.replace(/(?:2f)+$/, "").concat('2f'); } else { var child = child.replace(/[\/]+$/, "").concat('/'); var parent = parent.replace(/[\/]+$/, "").concat('/'); } if (child == parent) { return false; } return child.startsWith(parent); } /* called when document is ready, this is called */ function init_file_browse(browser_id, snap, geo) { // this tracks which folders are currently trying to fetch contents // to prevent unnecssary API calls var browser_div = $j(browser_id); browser_div.data('processing', []); var post_uri = browser_div.data('post-uri'); var action = browser_div.data('post-action'); if (action == 'listdir') { // loading items from local disk init_from_local_listdir(browser_div); } else { // loading items from restic init_from_restic_browse(action, post_uri, browser_div, snap, geo); } } function hex2str(hex) { var pairs = hex.match(/(..?)/g); var arr = []; $j.each(pairs, function(i, pair) { arr.push(parseInt(pair, 16)); }); return new TextDecoder().decode(new Uint8Array(arr)); }; function init_from_local_listdir(browser_div) { var all_sizes = $j('#settings_tab').data('subpaths') var browser_id = browser_div.attr('id'); var selections = browser_div.data('orig-selections'); browser_div.empty(); // create the main ul where file/folders are displayed var ul = $j('