Greasy Fork 支持简体中文。

Letterboxd Formated Runtime

Replaces the original runtime with a formated one

  1. // ==UserScript==
  2. // @name Letterboxd Formated Runtime
  3. // @namespace https://github.com/Tetrax-10
  4. // @description Replaces the original runtime with a formated one
  5. // @icon https://tetrax-10.github.io/letterboxd-custom-images/assets/icon.png
  6. // @license MIT
  7. // @version 1.1
  8. // @match *://*.letterboxd.com/film/*
  9. // @run-at document-start
  10. // ==/UserScript==
  11.  
  12. ;(async () => {
  13. async function waitForElement(selector, timeout = null, nthElement = 1) {
  14. // wait till document body loads
  15. while (!document.body) {
  16. await new Promise((resolve) => setTimeout(resolve, 10))
  17. }
  18.  
  19. nthElement -= 1
  20.  
  21. return new Promise((resolve) => {
  22. if (document.querySelectorAll(selector)?.[nthElement]) {
  23. return resolve(document.querySelectorAll(selector)?.[nthElement])
  24. }
  25.  
  26. const observer = new MutationObserver(async () => {
  27. if (document.querySelectorAll(selector)?.[nthElement]) {
  28. resolve(document.querySelectorAll(selector)?.[nthElement])
  29. observer.disconnect()
  30. } else {
  31. if (timeout) {
  32. async function timeOver() {
  33. return new Promise((resolve) => {
  34. setTimeout(() => {
  35. observer.disconnect()
  36. resolve(false)
  37. }, timeout)
  38. })
  39. }
  40. resolve(await timeOver())
  41. }
  42. }
  43. })
  44.  
  45. observer.observe(document.body, {
  46. childList: true,
  47. subtree: true,
  48. })
  49. })
  50. }
  51.  
  52. function formatTimeString(timeStr) {
  53. // Extract hours and minutes using regex
  54. const match = timeStr.match(/(\d+)h\s(\d+)m/)
  55.  
  56. if (!match) return "" // If the input string does not match the pattern
  57.  
  58. const hours = parseInt(match[1], 10)
  59. const minutes = parseInt(match[2], 10)
  60.  
  61. // If hours is 0, return an empty string
  62. if (hours === 0) {
  63. return ""
  64. }
  65.  
  66. // Build the result string
  67. let result = ""
  68.  
  69. // Format hours
  70. result += hours === 1 ? "1 hr" : `${hours} hrs`
  71.  
  72. // Format minutes if more than 0
  73. if (minutes > 0) {
  74. result += ` ${minutes} min${minutes > 1 ? "s" : ""}`
  75. }
  76.  
  77. return result
  78. }
  79.  
  80. const runtimeSelector = ".text-footer-extra.duration-extra[data-original-title]"
  81. const runtime = await waitForElement(runtimeSelector)
  82. const formatedRuntime = runtime.dataset.originalTitle || ""
  83.  
  84. const reFormatedRuntime = formatTimeString(formatedRuntime)
  85.  
  86. if (reFormatedRuntime) {
  87. runtime.dataset.originalTitle = runtime.innerText
  88. runtime.innerText = reFormatedRuntime
  89. }
  90. })()