Edge Local File Enhancer

Enhance the experience of viewing local files on Edge.

当前为 2023-10-20 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Edge Local File Enhancer
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1.2
  5. // @description Enhance the experience of viewing local files on Edge.
  6. // @author PRO
  7. // @match file:///*/
  8. // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABt0lEQVR42oxStZoWQRCs2cXdHTLcHZ6EjAwnQWIkJyQlRt4Cd3d3d1n5d7q7ju1zv/q+mh6taQsk8fn29kPDRo87SDMQcNAUJgIQkBjdAoRKdXjm2mOH0AqS+PlkP8sfp0h93iu/PDji9s2FzSSJVg5ykZqWgfGRr9rAAAQiDFoB1OfyESZEB7iAI0lHwLREQBcQQKqo8p+gNUCguwCNAAUQAcFOb0NNGjT+BbUC2YsHZpWLhC6/m0chqIoM1LKbQIIBwlTQE1xAo9QDGDPYf6rkTpPc92gCUYVJAZjhyZltJ95f3zuvLYRGWWCUNkDL2333McBh4kaLlxg+aTmyL7c2xTjkN4Bt7oE3DBP/3SRz65R/bkmBRPGzcRNHYuzMjaj+fdnaFoJUEdTSXfaHbe7XNnMPyqryPcmfY+zURaAB7SHk9cXSH4fQ5rojgCAVIuqCNWgRhLYLhJB4k3iZfIPtnQiCpjAzeBIRXMA6emAqoEbQSoDdGxFUrxS1AYcpaNbBgyQBGJEOnYOeENKR/iAd1npusI4C75/c3539+nbUjOgZV5CkAU27df40lH+agUdIuA/EAgDmZnwZlhDc0wAAAABJRU5ErkJggg==
  9. // @grant none
  10. // @license gpl-3.0
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15. // Helper functions
  16. const path = location.href;
  17. if (!path.startsWith("file:///") || !path.endsWith("/")) return;
  18. const debug = false;
  19. const log = debug ? console.log.bind(console, "[ELFE]") : () => {};
  20. const $ = document.querySelector.bind(document);
  21. const $$ = document.querySelectorAll.bind(document);
  22. const getModifier = (e) => (e.ctrlKey << 3 | e.shiftKey << 2 | e.altKey << 1 | e.metaKey);
  23. const hasModifier = (e, test = 0b1111) => Boolean(getModifier(e) & test);
  24.  
  25. // CSS
  26. const header = $("h1#header");
  27. const css = document.createElement("style");
  28. css.id = "elfe-css";
  29. css.textContent = `
  30. html { scroll-behavior: smooth; }
  31. h1#header > a { color: initial; text-decoration: none; transition: color 0.2s ease-in-out; }
  32. h1#header > a:hover { color: -webkit-link; }
  33. table { margin: 0.5rem 0; width: auto; }
  34. table td, table th { padding: 0.3rem 0.5rem; vertical-align: middle; }
  35. #parentDir { padding: 0 0.5em 0; }
  36. thead th { border-left: 1px solid gray; border-right: 1px solid gray; }
  37. thead th, tbody tr { transition: background-color 0.2s ease-in-out; cursor: pointer; }
  38. thead th:hover, tbody tr:hover { background-color: #333333; }
  39. tbody tr.selected { background-color: #4d4d4d; }
  40. `;
  41. $("head").appendChild(css);
  42.  
  43. // Navigation
  44. $("div#parentDirLinkBox").style.display = "none";
  45. const delimeter = header.textContent.includes("\\") ? "\\" : "/";
  46. const split = header.textContent.split(delimeter);
  47. log(split);
  48. const parts = split.slice(0, -1);
  49. header.innerHTML = '<a href="../" id="parentDir">↑</a>'
  50. + parts.map((part, i) =>
  51. `<a href="${parts.slice(0, i + 1).join(delimeter)}${delimeter}">${part}</a>`
  52. ).join(delimeter) + delimeter + split.slice(-1)[0];
  53.  
  54. // Table
  55. const rows = $$("tbody tr");
  56. rows.forEach(row => {
  57. row.addEventListener("click", e => {
  58. if (hasModifier(e)) return; // Try to be none-intrusive
  59. row.querySelector("a").click();
  60. });
  61. });
  62. $$("td").forEach(td => {
  63. td.title = td.getAttribute("data-value") || td.textContent;
  64. });
  65.  
  66. // Shortcuts
  67. const parentDir = $("#parentDir");
  68. const count = rows.length;
  69. var selected = 0;
  70. function select(i) {
  71. rows[selected].classList.remove("selected");
  72. selected = i;
  73. rows[selected].classList.add("selected");
  74. rows[selected].scrollIntoView({ block: "center" });
  75. }
  76. function delta(d) {
  77. select((selected + d + count) % count);
  78. }
  79. document.addEventListener("keydown", e => {
  80. switch (e.key) {
  81. case "ArrowUp":
  82. e.preventDefault();
  83. if (e.altKey && parentDir) { // Go to parent directory
  84. parentDir.click();
  85. break;
  86. }
  87. if (e.ctrlKey) { // Scroll up
  88. window.scrollBy({ top: -window.innerHeight / 2});
  89. break;
  90. }
  91. if (count == 0) break;
  92. if (e.shiftKey) { // Select top
  93. select(0);
  94. break;
  95. }
  96. // Select previous
  97. delta(-1);
  98. break;
  99. case "ArrowDown":
  100. e.preventDefault();
  101. if (e.ctrlKey) { // Scroll down
  102. window.scrollBy({ top: window.innerHeight / 2});
  103. break;
  104. }
  105. if (count == 0) break;
  106. if (e.shiftKey) { // Select bottom
  107. select(count - 1);
  108. break;
  109. }
  110. // Select next
  111. delta(1);
  112. break;
  113. case "ArrowLeft":
  114. if (hasModifier(e)) break; // Try to be none-intrusive
  115. history.back(); break;
  116. case "ArrowRight":
  117. if (hasModifier(e)) break;
  118. history.forward(); break;
  119. case "Enter": {
  120. e.preventDefault();
  121. if (count == 0) break;
  122. const link = rows[selected].querySelector("a");
  123. link.dispatchEvent(new MouseEvent("click", { // Pass modifiers
  124. "altKey": e.altKey, // Download
  125. "ctrlKey": e.ctrlKey, // Open in new tab (background)
  126. "shiftKey": e.shiftKey, // Open in new window
  127. }));
  128. break;
  129. }
  130. default: break;
  131. }
  132. });
  133. })();