]> OzVa Git service - ozva-cloud/commitdiff
refactor: no inline scripts in HTML (#391)
authorNeed4Swede <57847545+need4swede@users.noreply.github.com>
Fri, 31 May 2024 00:51:59 +0000 (17:51 -0700)
committerGitHub <noreply@github.com>
Fri, 31 May 2024 00:51:59 +0000 (08:51 +0800)
* Moved 'ready' func call from index.html

Inline script moved to index.js

* Moved <script> out from index.html

* moved inline-styling to css

* minor formatting changes

* changed ratio from const to let

* refactor

* fix tests

---------

Co-authored-by: sigoden <sigoden@gmail.com>
assets/index.css
assets/index.html
assets/index.js
tests/assets.rs
tests/fixtures.rs
tests/utils.rs

index bcc1f50966a0d1048f4f09d77d4670ab2272dac6..9ad9092d64e9abe6ec1a9768e48de7238ae2025b 100644 (file)
@@ -229,8 +229,8 @@ body {
 }
 
 .user-btn {
-    display: flex;
-    align-items: center;
+  display: flex;
+  align-items: center;
 }
 
 .user-name {
index 3fdcb3f27999fd37575b4eab3a182d26e13aadb5..667da48d37bd6927b5d5402e42d2fd966024ce68 100644 (file)
@@ -6,10 +6,6 @@
   <meta name="viewport" content="width=device-width" />
   <link rel="icon" type="image/x-icon" href="__ASSETS_PREFIX__favicon.ico">
   <link rel="stylesheet" href="__ASSETS_PREFIX__index.css">
-  <script>
-    DATA = __INDEX_DATA__
-  </script>
-  <script src="__ASSETS_PREFIX__index.js"></script>
 </head>
 
 <body>
@@ -74,7 +70,8 @@
             d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z" />
         </svg>
       </div>
-      <input id="search" title="Searching for folders or files" name="q" type="text" maxlength="128" autocomplete="off" tabindex="1">
+      <input id="search" title="Searching for folders or files" name="q" type="text" maxlength="128" autocomplete="off"
+        tabindex="1">
       <input type="submit" hidden />
     </form>
     <div class="toolbox-right">
       <textarea id="editor" class="editor hidden" aria-label="Editor" cols="10"></textarea>
     </div>
   </div>
-  <script>
-    window.addEventListener("DOMContentLoaded", ready);
-  </script>
+  <template id="index-data">__INDEX_DATA__</template>
+  <script src="__ASSETS_PREFIX__index.js"></script>
 </body>
 
 </html>
\ No newline at end of file
index 11983057eb25149d0d01ff567b36c7c26bf82b66..b35500be4b18802fbb1c4198562aab6c641cf91f 100644 (file)
@@ -29,6 +29,11 @@ var DUFS_MAX_UPLOADINGS = 1;
  */
 var DATA;
 
+/**
+ * @type {string}
+ */
+var DIR_EMPTY_NOTE;
+
 /**
  * @type {PARAMS}
  * @typedef {object} PARAMS
@@ -45,8 +50,6 @@ const IFRAME_FORMATS = [
   ".mp3", ".ogg", ".wav", ".m4a",
 ];
 
-const dirEmptyNote = PARAMS.q ? 'No results' : DATA.dir_exists ? 'Empty folder' : 'Folder will be created when a file is uploaded';
-
 const ICONS = {
   dir: `<svg height="16" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M13 4H7V3c0-.66-.31-1-1-1H1c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zM6 4H1V3h5v1z"></path></svg>`,
   symlinkFile: `<svg height="16" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M8.5 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h10c.55 0 1-.45 1-1V4.5L8.5 1zM11 14H1V2h7l3 3v9zM6 4.5l4 3-4 3v-2c-.98-.02-1.84.22-2.55.7-.71.48-1.19 1.25-1.45 2.3.02-1.64.39-2.88 1.13-3.73.73-.84 1.69-1.27 2.88-1.27v-2H6z"></path></svg>`,
@@ -97,8 +100,22 @@ let $userBtn;
  */
 let $userName;
 
-function ready() {
-  $pathsTable = document.querySelector(".paths-table")
+// Produce table when window loads
+window.addEventListener("DOMContentLoaded", async () => {
+  const $indexData = document.getElementById('index-data');
+  if (!$indexData) {
+    alert("No data");
+    return;
+  }
+
+  DATA = JSON.parse($indexData.innerHTML);
+  DIR_EMPTY_NOTE = PARAMS.q ? 'No results' : DATA.dir_exists ? 'Empty folder' : 'Folder will be created when a file is uploaded';
+
+  await ready();
+});
+
+async function ready() {
+  $pathsTable = document.querySelector(".paths-table");
   $pathsTableHead = document.querySelector(".paths-table thead");
   $pathsTableBody = document.querySelector(".paths-table tbody");
   $uploadersTable = document.querySelector(".uploaders-table");
@@ -109,25 +126,24 @@ function ready() {
 
   addBreadcrumb(DATA.href, DATA.uri_prefix);
 
-  if (DATA.kind == "Index") {
+  if (DATA.kind === "Index") {
     document.title = `Index of ${DATA.href} - Dufs`;
     document.querySelector(".index-page").classList.remove("hidden");
 
-    setupIndexPage();
-  } else if (DATA.kind == "Edit") {
+    await setupIndexPage();
+  } else if (DATA.kind === "Edit") {
     document.title = `Edit ${DATA.href} - Dufs`;
-    document.querySelector(".editor-page").classList.remove("hidden");;
+    document.querySelector(".editor-page").classList.remove("hidden");
 
-    setupEditorPage();
-  } else if (DATA.kind == "View") {
+    await setupEditorPage();
+  } else if (DATA.kind === "View") {
     document.title = `View ${DATA.href} - Dufs`;
-    document.querySelector(".editor-page").classList.remove("hidden");;
+    document.querySelector(".editor-page").classList.remove("hidden");
 
-    setupEditorPage();
+    await setupEditorPage();
   }
 }
 
-
 class Uploader {
   /**
    *
@@ -221,7 +237,7 @@ class Uploader {
       uploadOffset = parseInt(value) || 0;
     }
     this.uploadOffset = uploadOffset;
-    this.ajax()
+    this.ajax();
   }
 
   progress(event) {
@@ -230,7 +246,7 @@ class Uploader {
     const [speedValue, speedUnit] = formatSize(speed);
     const speedText = `${speedValue} ${speedUnit}/s`;
     const progress = formatPercent(((event.loaded + this.uploadOffset) / this.file.size) * 100);
-    const duration = formatDuration((event.total - event.loaded) / speed)
+    const duration = formatDuration((event.total - event.loaded) / speed);
     this.$uploadStatus.innerHTML = `<span style="width: 80px;">${speedText}</span><span>${progress} ${duration}</span>`;
     this.uploaded = event.loaded;
     this.lastUptime = now;
@@ -274,7 +290,7 @@ Uploader.runQueue = async () => {
   if (!Uploader.auth) {
     Uploader.auth = true;
     try {
-      await checkAuth()
+      await checkAuth();
     } catch {
       Uploader.auth = false;
     }
@@ -319,7 +335,7 @@ function addBreadcrumb(href, uri_prefix) {
   }
 }
 
-function setupIndexPage() {
+async function setupIndexPage() {
   if (DATA.allow_archive) {
     const $download = document.querySelector(".download");
     $download.href = baseUrl() + "?zip";
@@ -335,11 +351,11 @@ function setupIndexPage() {
   }
 
   if (DATA.auth) {
-    setupAuth();
+    await setupAuth();
   }
 
   if (DATA.allow_search) {
-    setupSearch()
+    setupSearch();
   }
 
   renderPathsTableHead();
@@ -402,7 +418,7 @@ function renderPathsTableBody() {
       addPath(DATA.paths[i], i);
     }
   } else {
-    $emptyFolder.textContent = dirEmptyNote;
+    $emptyFolder.textContent = DIR_EMPTY_NOTE;
     $emptyFolder.classList.remove("hidden");
   }
 }
@@ -414,7 +430,7 @@ function renderPathsTableBody() {
  */
 function addPath(file, index) {
   const encodedName = encodedStr(file.name);
-  let url = newUrl(file.name)
+  let url = newUrl(file.name);
   let actionDelete = "";
   let actionDownload = "";
   let actionMove = "";
@@ -455,7 +471,7 @@ function addPath(file, index) {
     ${actionMove}
     ${actionDelete}
     ${actionEdit}
-  </td>`
+  </td>`;
 
   $pathsTableBody.insertAdjacentHTML("beforeend", `
 <tr id="addPath${index}">
@@ -468,7 +484,7 @@ function addPath(file, index) {
   <td class="cell-mtime">${formatMtime(file.mtime)}</td>
   <td class="cell-size">${formatSize(file.size).join(" ")}</td>
   ${actionCell}
-</tr>`)
+</tr>`);
 }
 
 function setupDropzone() {
@@ -480,7 +496,7 @@ function setupDropzone() {
   });
   document.addEventListener("drop", async e => {
     if (!e.dataTransfer.items[0].webkitGetAsEntry) {
-      const files = e.dataTransfer.files.filter(v => v.size > 0);
+      const files = Array.from(e.dataTransfer.files).filter(v => v.size > 0);
       for (const file of files) {
         new Uploader(file, []).upload();
       }
@@ -490,12 +506,12 @@ function setupDropzone() {
       for (let i = 0; i < len; i++) {
         entries.push(e.dataTransfer.items[i].webkitGetAsEntry());
       }
-      addFileEntries(entries, [])
+      addFileEntries(entries, []);
     }
   });
 }
 
-function setupAuth() {
+async function setupAuth() {
   if (DATA.user) {
     $userBtn.classList.remove("hidden");
     $userName.textContent = DATA.user;
@@ -504,7 +520,7 @@ function setupAuth() {
     $loginBtn.classList.remove("hidden");
     $loginBtn.addEventListener("click", async () => {
       try {
-        await checkAuth()
+        await checkAuth();
         location.reload();
       } catch (err) {
         alert(err.message);
@@ -585,7 +601,7 @@ async function setupEditorPage() {
       await doDeletePath(name, url, () => {
         location.href = location.href.split("/").slice(0, -1).join("/");
       });
-    })
+    });
 
     const $saveBtn = document.querySelector(".save-btn");
     $saveBtn.classList.remove("hidden");
@@ -599,7 +615,7 @@ async function setupEditorPage() {
     const url = baseUrl();
     const ext = extName(baseName(url));
     if (IFRAME_FORMATS.find(v => v === ext)) {
-      $notEditable.insertAdjacentHTML("afterend", `<iframe src="${url}" sandbox width="100%" height="${window.innerHeight - 100}px"></iframe>`)
+      $notEditable.insertAdjacentHTML("afterend", `<iframe src="${url}" sandbox width="100%" height="${window.innerHeight - 100}px"></iframe>`);
     } else {
       $notEditable.classList.remove("hidden");
       $notEditable.textContent = "Cannot edit because file is too large or binary.";
@@ -616,8 +632,8 @@ async function setupEditorPage() {
       $editor.value = await res.text();
     } else {
       const bytes = await res.arrayBuffer();
-      const dataView = new DataView(bytes)
-      const decoder = new TextDecoder(encoding)
+      const dataView = new DataView(bytes);
+      const decoder = new TextDecoder(encoding);
       $editor.value = decoder.decode(dataView);
     }
   } catch (err) {
@@ -638,10 +654,10 @@ async function deletePath(index) {
     DATA.paths[index] = null;
     if (!DATA.paths.find(v => !!v)) {
       $pathsTable.classList.add("hidden");
-      $emptyFolder.textContent = dirEmptyNote;
+      $emptyFolder.textContent = DIR_EMPTY_NOTE;
       $emptyFolder.classList.remove("hidden");
     }
-  })
+  });
 }
 
 async function doDeletePath(name, url, cb) {
@@ -674,13 +690,13 @@ async function movePath(index) {
 }
 
 async function doMovePath(fileUrl) {
-  const fileUrlObj = new URL(fileUrl)
+  const fileUrlObj = new URL(fileUrl);
 
   const prefix = DATA.uri_prefix.slice(0, -1);
 
   const filePath = decodeURIComponent(fileUrlObj.pathname.slice(prefix.length));
 
-  let newPath = prompt("Enter new path", filePath)
+  let newPath = prompt("Enter new path", filePath);
   if (!newPath) return;
   if (!newPath.startsWith("/")) newPath = "/" + newPath;
   if (filePath === newPath) return;
@@ -803,7 +819,7 @@ function baseUrl() {
 }
 
 function baseName(url) {
-  return decodeURIComponent(url.split("/").filter(v => v.length > 0).slice(-1)[0])
+  return decodeURIComponent(url.split("/").filter(v => v.length > 0).slice(-1)[0]);
 }
 
 function extName(filename) {
@@ -830,7 +846,7 @@ function getPathSvg(path_type) {
 }
 
 function formatMtime(mtime) {
-  if (!mtime) return ""
+  if (!mtime) return "";
   const date = new Date(mtime);
   const year = date.getFullYear();
   const month = padZero(date.getMonth() + 1, 2);
@@ -841,17 +857,17 @@ function formatMtime(mtime) {
 }
 
 function padZero(value, size) {
-  return ("0".repeat(size) + value).slice(-1 * size)
+  return ("0".repeat(size) + value).slice(-1 * size);
 }
 
 function formatSize(size) {
-  if (size == null) return [0, "B"]
+  if (size == null) return [0, "B"];
   const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
   if (size == 0) return [0, "B"];
   const i = parseInt(Math.floor(Math.log(size) / Math.log(1024)));
-  ratio = 1
+  let ratio = 1;
   if (i >= 3) {
-    ratio = 100
+    ratio = 100;
   }
   return [Math.round(size * ratio / Math.pow(1024, i), 2) / ratio, sizes[i]];
 }
@@ -860,7 +876,7 @@ function formatDuration(seconds) {
   seconds = Math.ceil(seconds);
   const h = Math.floor(seconds / 3600);
   const m = Math.floor((seconds - h * 3600) / 60);
-  const s = seconds - h * 3600 - m * 60
+  const s = seconds - h * 3600 - m * 60;
   return `${padZero(h, 2)}:${padZero(m, 2)}:${padZero(s, 2)}`;
 }
 
@@ -889,8 +905,8 @@ function getEncoding(contentType) {
   if (/charset/i.test(charset)) {
     let encoding = charset.split("=")[1];
     if (encoding) {
-      return encoding.toLowerCase()
+      return encoding.toLowerCase();
     }
   }
-  return 'utf-8'
+  return 'utf-8';
 }
index 3e6a155ff1e36ef75d9d1a14c46eccb06c327403..964f3fc57ace7b4b7a3c2aced732f9254e01444b 100644 (file)
@@ -115,7 +115,7 @@ fn assets_override(tmpdir: TempDir, port: u16) -> Result<(), Error> {
     let url = format!("http://localhost:{port}");
     let resp = reqwest::blocking::get(&url)?;
     assert!(resp.text()?.starts_with(&format!(
-        "/__dufs_v{}__/index.js;DATA",
+        "/__dufs_v{}__/index.js;<template id=\"index-data\">",
         env!("CARGO_PKG_VERSION")
     )));
     let resp = reqwest::blocking::get(&url)?;
index 906563a91bc845a266f47168f288461e008d7825..f86347232872565b433a27fc712803aaa1c72040 100644 (file)
@@ -65,7 +65,7 @@ pub fn tmpdir() -> TempDir {
         if *directory == DIR_ASSETS {
             tmpdir
                 .child(format!("{}{}", directory, "index.html"))
-                .write_str("__ASSETS_PREFIX__index.js;DATA = __INDEX_DATA__")
+                .write_str("__ASSETS_PREFIX__index.js;<template id=\"index-data\">__INDEX_DATA__</template>")
                 .unwrap();
         } else {
             for file in FILES {
index 590ab78626fb2967c59aaa6a61d4d441a0acd35e..1bccefa2d675fd0d7765323078e7a2310b6de7c6 100644 (file)
@@ -62,8 +62,18 @@ pub fn encode_uri(v: &str) -> String {
 #[allow(dead_code)]
 pub fn retrieve_json(content: &str) -> Option<Value> {
     let lines: Vec<&str> = content.lines().collect();
-    let line = lines.iter().find(|v| v.contains("DATA ="))?;
-    let line_col = line.find("DATA =").unwrap() + 6;
-    let value: Value = line[line_col..].parse().unwrap();
+    let start_tag = "<template id=\"index-data\">";
+    let end_tag = "</template>";
+
+    let line = lines.iter().find(|v| v.contains(start_tag))?;
+
+    let start_index = line.find(start_tag)?;
+    let start_content_index = start_index + start_tag.len();
+
+    let end_index = line[start_content_index..].find(end_tag)?;
+    let end_content_index = start_content_index + end_index;
+
+    let value = line[start_content_index..end_content_index].parse().ok()?;
+
     Some(value)
 }