// ==UserScript== // @name dmhy tree view // @namespace https://greasyfork.org/zh-CN/scripts/26430-dmhy-tree-view // @license GPL version 3 // @encoding utf-8 // @version 0.31 // @date 2017/01/11 // @modified 2017/05/30 // @description convert plain file list into a tree view for 动漫花园 (share.dmhy.org) // @author TautCony // @require http://cdn.bootcss.com/jquery/3.2.1/jquery.min.js // @require http://cdn.bootcss.com/jstree/3.3.4/jstree.min.js // @resource customCSS http://cdn.bootcss.com/jstree/3.3.3/themes/default/style.min.css // @match *://share.dmhy.org/topics/view/* // @grant GM_addStyle // @grant GM_getResourceText // @downloadURL none // ==/UserScript== var icons = { audio: "https://share.dmhy.org/images/icon/mp3.gif", image: "https://share.dmhy.org/images/icon/jpg.gif", rar: "https://share.dmhy.org/images/icon/rar.gif", text: "https://share.dmhy.org/images/icon/txt.gif", unknown: "https://share.dmhy.org/images/icon/unknown.gif", video: "https://share.dmhy.org/images/icon/mp4.gif", }; var type2Icon = { audio: ["flac", "aac", "wav", "mp3"], image: ["jpg", "bmp", "jpeg", "webp"], rar: ["rar", "zip", "7z"], text: ["txt", "log", "cue", "ass"], video: ["mkv", "mka", "mp4"], }; var Dictionary = (function () { function Dictionary() { this.data = {}; } Dictionary.prototype.add = function (key, value) { if (!(key in this.data)) { this.data[key] = value; } }; Dictionary.prototype.clear = function () { this.data = {}; }; Dictionary.prototype.containsKey = function (key) { return key in this.data; }; Dictionary.prototype.get = function (key) { return this.data[key]; }; Dictionary.prototype.size = function () { return Object.keys(this.data).length; }; Dictionary.prototype.values = function () { return this.data; }; return Dictionary; }()); var FileSize = (function () { function FileSize() { } FileSize.toLength = function (size) { if (size === undefined) { return -1; } size = size.toLowerCase(); var head = ""; var tail = ""; var isNumber = function (c) { return (c >= "0" && c <= "9") || c === "." || c === "-"; }; for (var _i = 0, size_1 = size; _i < size_1.length; _i++) { var c = size_1[_i]; if (isNumber(c)) { head += c; } else { tail += c; } } var value = parseFloat(head); switch (tail) { case "byte": return value; case "bytes": return value; case "kb": return value * Math.pow(2, 10); case "mb": return value * Math.pow(2, 20); case "gb": return value * Math.pow(2, 30); case "tb": return value * Math.pow(2, 40); } return -1; }; FileSize.toSize = function (length) { if (length >= Math.pow(2, 40)) { return this.format(length, 40, "TiB"); } else if (length >= Math.pow(2, 30)) { return this.format(length, 30, "GiB"); } else if (length >= Math.pow(2, 20)) { return this.format(length, 20, "MiB"); } else if (length >= Math.pow(2, 10)) { return this.format(length, 10, "KiB"); } else { return this.format(length, 0, "Bytes"); } }; FileSize.format = function (length, factor, tail) { return (length / Math.pow(2, factor)).toFixed(3).toString() + tail; }; return FileSize; }()); var TreeNode = (function () { function TreeNode(node) { this.getIcon = function (ext) { for (var type in type2Icon) { if (type2Icon[type].indexOf(ext) >= 0) { return icons[type]; } } return icons.unknown; }; this.name = node; this.length = 0; this.childNode = new Dictionary(); } TreeNode.prototype.insert = function (path, size) { var currentNode = this; for (var _i = 0, path_1 = path; _i < path_1.length; _i++) { var node = path_1[_i]; var next = currentNode.childNode.get(node); if (!currentNode.childNode.containsKey(node)) { next = currentNode.add(node, new TreeNode(node)); next.pareneNode = currentNode; } currentNode = next; } currentNode.length = FileSize.toLength(size); return currentNode; }; TreeNode.prototype.toString = function () { return "" + this.name + "" + FileSize.toSize(this.length) + ""; }; TreeNode.prototype.toObject = function () { var ret = {}; ret.children = []; ret.length = 0; ret.text = this.name; ret.state = { opened: true }; var childNodeValues = this.childNode.values(); for (var key in childNodeValues) { if (!childNodeValues.hasOwnProperty(key)) { continue; } var files = []; var value = this.childNode.get(key); if (value.childNode.size() === 0) { files.push(value); } else { var tmp = {}; tmp.children = []; tmp.length = 0; var inner = value.toObject(); for (var _i = 0, _a = inner.children; _i < _a.length; _i++) { var innerNode = _a[_i]; tmp.children.push(innerNode); tmp.length += innerNode.length; } ret.length += tmp.length; value.length = tmp.length; tmp.text = value.toString(); ret.children.push(tmp); } for (var _b = 0, files_1 = files; _b < files_1.length; _b++) { var file = files_1[_b]; var ext = ""; var dotIndex = file.name.lastIndexOf("."); if (dotIndex > 0) { ext = file.name.substr(dotIndex + 1).toLowerCase(); } ret.length += file.length; ret.children.push({ icon: this.getIcon(ext), length: file.length, text: file.toString(), }); } } return ret; }; TreeNode.prototype.add = function (key, value) { this.childNode.add(key, value); return this.childNode.get(key); }; return TreeNode; }()); var GM_getResourceText = GM_getResourceText; var GM_addStyle = GM_addStyle; (function () { if (typeof GM_getResourceText !== "undefined") { GM_addStyle(GM_getResourceText("customCSS")); } else { console.info("%cYou may need to install http://tampermonkey.net/ to use this script.", "color:#e55d67;font-size:1.5em"); return; } $("head").append(""); $("#tabs-1").append(''); $("#tabs-1").append(''); $("#tabs-1").append(''); $(".file_list").css("width", "100%"); $(".file_list").css("max-height", "600px"); var data = new TreeNode("" + $(".topic-title > h3").text() + ""); $(".file_list > ul li").each(function (index, value) { var text = $(value).text(); var line = text.trim().replace(/\t+/i, "\t").split("\t"); switch (line.length) { case 2: var nodes = line[0].split("/"); var size = line[1]; data.insert(nodes, size); break; case 1: //the text should be "More Than 1000 Files" data.insert(line[0].split("/"), ""); break; } }); var options = { contextmenu: { items: { getText: { action: function (selected) { var row = $.jstree.reference(selected.reference).get_node(selected.reference, true); var node = $("#hidden_text"); node.css("display", "block"); node.val(row.find(".filename").text()); node.focus(); document.execCommand("selectAll"); document.execCommand("copy"); document.execCommand("unselect"); node.css("display", "none"); }, label: "Copy", }, remove: { action: function (selected) { var row = $.jstree.reference(selected.reference).get_node(selected.reference, true); row.remove(); }, label: "死ね!", }, }, show_at_node: false, }, core: { data: data.toObject(), }, plugins: ["search", "wholerow", "contextmenu"], }; $($(".file_list").jstree(options)).bind("loaded.jstree", function (loadedEventData) { var isExpended = false; $("#switch").click(function (clickeventData) { if (isExpended) { clickeventData.target.innerHTML = "Expand All"; $(loadedEventData.target).jstree("close_all"); } else { clickeventData.target.innerHTML = "Toggle All"; $(loadedEventData.target).jstree("open_all"); } isExpended = !isExpended; }); var lastVal = ""; $("#search_input").keyup(function (keyupEventData) { var val = keyupEventData.target.value; if (val !== lastVal) { $(loadedEventData.target).jstree(true).search(val); lastVal = val; } }); }); })();