fb-oo-hook.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. (function(){
  2. var OFFICE_EXT = ["docx","pptx","ppt","xlsx","xls"];
  3. var PREVIEW_BASE = "http://" + location.hostname + ":8080";
  4. var LAST_OPEN = { path: "", ts: 0 };
  5. var OPEN_GUARD_MS = 1200;
  6. function startsWithFiles(p){ return (p || "").toLowerCase().indexOf("/files/") === 0; }
  7. function normalizeFilePath(path){
  8. var p = path || "";
  9. if (!startsWithFiles(p)) return "";
  10. p = p.slice(7);
  11. try { p = decodeURIComponent(p); } catch(e) {}
  12. while (p.length > 0 && p.charAt(0) === "/") p = p.slice(1);
  13. return p;
  14. }
  15. function isOffice(path){
  16. var s = (path || "").toLowerCase();
  17. for (var i = 0; i < OFFICE_EXT.length; i++) {
  18. if (s.endsWith("." + OFFICE_EXT[i])) return true;
  19. }
  20. return false;
  21. }
  22. function encodePathSegments(path){
  23. return (path || "").split("/").map(function(seg){ return encodeURIComponent(seg); }).join("/");
  24. }
  25. function buildRawPath(rel){
  26. var low = (rel || "").toLowerCase();
  27. if (low.indexOf("words/") === 0) {
  28. return "/raw/words/" + encodePathSegments((rel || "").slice(6));
  29. }
  30. if (low.indexOf("excels/") === 0) {
  31. return "/raw/excels/" + encodePathSegments((rel || "").slice(7));
  32. }
  33. return "/raw/files/" + encodePathSegments(rel || "");
  34. }
  35. function buildPreviewUrlFromPath(pathname){
  36. var rel = normalizeFilePath(pathname);
  37. if (!rel || !isOffice(rel)) return "";
  38. var ext = (rel.split(".").pop() || "").toLowerCase();
  39. var rawUrl = PREVIEW_BASE + buildRawPath(rel);
  40. var nonce = Date.now().toString() + "-" + Math.random().toString(16).slice(2, 8);
  41. var mode = (ext === "xlsx" || ext === "xls") ? "edit" : "view";
  42. return PREVIEW_BASE + "/oo-preview.html?url=" + encodeURIComponent(rawUrl) + "&type=" + encodeURIComponent(ext) + "&mode=" + encodeURIComponent(mode) + "&title=" + encodeURIComponent(rel) + "&_fbv=" + encodeURIComponent(nonce);
  43. }
  44. function parentDirPath(pathname){
  45. var p = pathname || "";
  46. if (!startsWithFiles(p)) return "/files/";
  47. var idx = p.lastIndexOf("/");
  48. if (idx <= 6) return "/files/";
  49. return p.slice(0, idx + 1);
  50. }
  51. function openPreviewInNewTab(pathname){
  52. var p = pathname || "";
  53. var u = buildPreviewUrlFromPath(p);
  54. if (!u) return false;
  55. var now = Date.now();
  56. if (LAST_OPEN.path === p && (now - LAST_OPEN.ts) < OPEN_GUARD_MS) return true;
  57. LAST_OPEN.path = p;
  58. LAST_OPEN.ts = now;
  59. var w = window.open(u, "_blank", "noopener");
  60. if (!w) {
  61. // Popup blocked fallback
  62. location.assign(u);
  63. }
  64. return true;
  65. }
  66. function interceptFileClick(){
  67. document.addEventListener("click", function(e){
  68. var a = e.target && e.target.closest && e.target.closest("a[href]");
  69. if (!a) return;
  70. var href = a.getAttribute("href") || "";
  71. if (!href) return;
  72. var pathname = "";
  73. try {
  74. pathname = new URL(href, location.origin).pathname || "";
  75. } catch (err) {
  76. pathname = href;
  77. }
  78. if (!startsWithFiles(pathname)) return;
  79. if (!buildPreviewUrlFromPath(pathname)) return;
  80. e.preventDefault();
  81. e.stopPropagation();
  82. if (e.stopImmediatePropagation) e.stopImmediatePropagation();
  83. openPreviewInNewTab(pathname);
  84. }, true);
  85. }
  86. function maybeJump(){
  87. var p = location.pathname || "";
  88. if (!buildPreviewUrlFromPath(p)) return;
  89. if (location.pathname === "/oo-preview.html") return;
  90. if (openPreviewInNewTab(p)) {
  91. location.replace(parentDirPath(p));
  92. }
  93. }
  94. var pushed = history.pushState;
  95. history.pushState = function(){
  96. pushed.apply(history, arguments);
  97. setTimeout(maybeJump, 0);
  98. };
  99. var replaced = history.replaceState;
  100. history.replaceState = function(){
  101. replaced.apply(history, arguments);
  102. setTimeout(maybeJump, 0);
  103. };
  104. window.addEventListener("popstate", function(){ setTimeout(maybeJump, 0); });
  105. window.addEventListener("hashchange", function(){ setTimeout(maybeJump, 0); });
  106. interceptFileClick();
  107. setTimeout(maybeJump, 0);
  108. })();