how long ago

replaces all dates with the time from that date

当前为 2024-07-08 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name how long ago
  3. // @version 3
  4. // @description replaces all dates with the time from that date
  5. // @run-at document-end
  6. // @author You
  7. // @license GPLv3
  8. // @match *://*/*
  9. // @exclude /livereload.net\/files\/ffopen\/index.html$/
  10. // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAMAAABiM0N1AAAAAXNSR0IB2cksfwAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAHJQTFRFAAAAEIijAo2yAI60BYyuF4WaFIifAY6zBI2wB4usGIaZEYigIoiZCIyrE4igG4iYD4mjEomhFoedCoqpDIqnDomlBYyvE4efEYmiDYqlA42xBoytD4mkCYqqGYSUFYidC4qoC4upAo6yCoupDYqmCYur4zowOQAAACZ0Uk5TAO////9vr////1+/D/+/L+/Pf/////+f3///////H4////////+5G91rAAACgUlEQVR4nM2Y22KjIBCGidg1264liZqDadK03X3/V2wNKHMC7MpF/xthHD5mgERAqZhWhfYqH6K+Qf2qNNf625hCoFj9/gblMUi5q5jLkXLCKudgyiRm0FMK82cWJp1fLbV5VmvJbCIc0GCYaFqqlDJgADdBjncqAXYobm1xh72aFMflbysteFfdy2Yi1XGOm5HGBzQ1dq7TzEoxjeNTjQZb7VA3e1c7+ImgasAgQ9+xusNVNZIo5xmOMgihIS2PbCQIiHEUdTvhxCcS/kPomfFI2zHy2PkWmA6aNatIJpKFJyekyy02xh5Y3DI9T4aOT6VhIUrsNTFp1pf79Z4SIIVDegl6IJO6cHiL/GimIZDhgTu/BlYWCQzHMl0zBWT/T3KAhtxOuUB9FtBrpsz0RV4xsjHmW+UCaffcSy/5viMGer0/6HdFNMZBq/vjJL38H9Dqx4Fuy0Em12DbZy+9pGtiDijbglwAehyj11n0tRD3WUBm+lwulE/8h4BuA+iWAQQnteg2Xm63WQLTpnMnpjdge0Mgu/GRPsV4xdjQ94Lfi624fabhDkfUqIKNrM64Q837v8yL0prasepCgrtvw1sJpoqanGEX7b5mQboNW8eawXaWXTMfMGxub472hzWzHSn6Sg2G9+6TAyRruE71s+zAzjWaknoyJCQzwxrghH2k5FDT4eqWunuNxyN9QCGcxVod5oADbYnIUkDTGZEf1xDJnSFteQ3KdsT8zYDMQXcHxsevcLH1TrsABzkNPyA/L7b0jg704viMMlpQI96WsHknCt/3YH0kOEo9zcGkwrFK39ck72rmoehmKqo2RKlilzSy/nJKEV45CT38myJp456fezktHjN5aeMAAAAASUVORK5CYII=
  11. // @grant none
  12. // @namespace https://greasyfork.org/users/1184528
  13. // ==/UserScript==
  14. const a = loadlib("allfuncs")
  15. const newelem = loadlib("newelem")
  16. a(function (elem) {
  17. if (elem.title && !elem.title.includes("\u202e\u202d")) {
  18. let x = elem.title && getdate(elem.title)
  19. if (x) elem.title = elem.title.replace(x.string, getstr(x))
  20. }
  21. if (elem.tagName.toLowerCase() == "relative-time") {
  22. if (!elem.shadowRoot || elem.shadowRoot.innerHTML.includes("\u202e\u202d"))
  23. return
  24. elem = elem.shadowRoot
  25. let x = getdate(elem.innerHTML)
  26. if (!x) return
  27. replaceall(
  28. new RegExp(regescape(x.string)),
  29. (e) =>
  30. newelem("timediff", {
  31. innerHTML: getstr(x),
  32. }),
  33. elem,
  34. ["script", "style", "timediff", "input", "textarea"]
  35. )
  36. return
  37. }
  38.  
  39. if (!elem.innerHTML.includes("\u202e\u202d")) {
  40. let x = getdate(elem.innerHTML)
  41. if (!x) return
  42. replaceall(
  43. new RegExp(regescape(x.string)),
  44. (e) =>
  45. newelem("timediff", {
  46. innerHTML: getstr(x),
  47. }),
  48. elem,
  49. ["script", "style", "timediff", "input", "textarea"]
  50. )
  51. }
  52. function getstr(x) {
  53. return `[${howlongago(
  54. x.ms,
  55. -3,
  56. true
  57. )} ${howlongago(x.ms, -3, true) == "today" ? "" : x.isago ? "ago" : "until"} ${x.string}\u202e\u202d]`
  58. }
  59. }).runonallelems()
  60. function regescape(reg) {
  61. return reg.replaceAll(/[.*+?^${}()|[\]\\]/g, "\\$&")
  62. }
  63. function replaceall(regex, getelem, node = document.body, ignores = []) {
  64. var search, newelement, splitnode, splittext, i, childnode
  65. if (node.nodeType == 3) {
  66. search = node.data.search(regex)
  67. if (search >= 0) {
  68. splitnode = node.splitText(search)
  69. splittext = splitnode.splitText(RegExp.lastMatch.length)
  70. newelement = getelem(splitnode.data)
  71. if (!ignores.includes(newelement.tagName.toLowerCase()))
  72. ignores.push(newelement.tagName.toLowerCase())
  73. splitnode.innerHTML = splitnode.textContent = ""
  74. newelement.appendChild(splitnode)
  75. splittext.parentNode.insertBefore(newelement, splittext)
  76. }
  77. } else if (
  78. node.nodeType == 11 ||
  79. (node.tagName && !ignores.includes(node.tagName.toLowerCase()))
  80. )
  81. for (i = 0; (childnode = node.childNodes[i]); ++i)
  82. replaceall(regex, getelem, childnode, ignores)
  83. }
  84.  
  85. function howlongago(ms, remove = 0, showweeks) {
  86. remove--
  87. var time = ["year", "day", "hour", "minute", "second", "milisecond"]
  88. var x = Object.values(a(ms).fromms().val)
  89. x = x.slice(0, remove)
  90. if (x.find((e) => e !== 0)) {
  91. time.splice(0, x.indexOf(x.find((e) => e !== 0)))
  92. x.splice(0, x.indexOf(x.find((e) => e !== 0)))
  93. var temp = x.map((e, i) => `${e} ${time[i]}${e == 1 ? "" : "s"}`).join(" ")
  94. if (showweeks)
  95. temp = temp.replace(
  96. /(\d+) days?/,
  97. (_, days) =>
  98. `${
  99. Math.floor(days / 7)
  100. ? `${Math.floor(days / 7)} week${days >= 14 ? "s" : ""}`
  101. : ""
  102. }${
  103. days / 7 == Math.floor(days / 7)
  104. ? ""
  105. : ` ${days % 7} day${days % 7 == 1 ? "" : "s"}`
  106. }`
  107. )
  108. return temp
  109. }
  110. window.x = [...x]
  111. return (
  112. //`0 ${time[x.length - 1]}s` ||
  113. "today"
  114. )
  115. }
  116. function getdate(date) {
  117. const tonum = {
  118. january: 1,
  119. february: 2,
  120. march: 3,
  121. april: 4,
  122. may: 5,
  123. june: 6,
  124. july: 7,
  125. august: 8,
  126. september: 9,
  127. october: 10,
  128. november: 11,
  129. december: 12,
  130. jan: 1,
  131. feb: 2,
  132. mar: 3,
  133. apr: 4,
  134. jun: 6,
  135. jul: 7,
  136. aug: 8,
  137. sep: 9,
  138. oct: 10,
  139. nov: 11,
  140. dec: 12,
  141. }
  142.  
  143. function f(reg) {
  144. reg = String(reg).replaceAll(/^\/|\/[gimsueyx]*$/g, "")
  145. ;[
  146. ["d2", "\\d{2}(?:rd|th|nd|st)?"],
  147. ["d4", "\\d{4}(?:rd|th|nd|st)?"],
  148. ["d12", "\\d{1,2}(?:rd|th|nd|st)?"],
  149. [
  150. "monthname",
  151. "(?:jan(?:uary)?|feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|may|june?|july?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)",
  152. ],
  153. ["space", "[^a-z0-9.]"],
  154. ["start", "(?<![\\d\\w/])"],
  155. ["end", "(?![\\d\\w])"],
  156. ].forEach(([a, s]) => {
  157. reg = reg.replaceAll(a, s)
  158. })
  159. return new RegExp(reg, "i")
  160. }
  161.  
  162. function d({ day, month, year, string }) {
  163. day = Number(day.match(/\d+/)[0])
  164. month = tonum[month?.toLowerCase?.()] || Number(month)
  165. if (!month) return
  166. if (day > 31) return
  167. year = Number(
  168. year.length == 2
  169. ? String(new Date().getFullYear()).substring(0, 2) + year
  170. : year
  171. )
  172. var today = new Date()
  173. today.setHours(0, 0, 0, 0)
  174. var ms = today - new Date(year, month - 1, day)
  175. return {
  176. day,
  177. month,
  178. year,
  179. string,
  180. ms: Math.abs(ms),
  181. isago: ms > 0,
  182. }
  183. }
  184. var temp
  185. if (
  186. (temp = date.match(f(/start(monthname|d12)space+(d12)sapce*'(d4|d2)end/)))
  187. )
  188. return d({
  189. day: temp[2],
  190. month: temp[1],
  191. year: temp[3],
  192. string: temp[0],
  193. })
  194. if ((temp = date.match(f(/start(d12)([\/\-])(d12)\2(d4|d2)end/))))
  195. return d({
  196. day: temp[3],
  197. month: temp[1],
  198. year: temp[4],
  199. string: temp[0],
  200. })
  201.  
  202. if ((temp = date.match(f(/start(d12)([\/\-])(d12)\2(d4|d2)end/))))
  203. return d({
  204. day: temp[3],
  205. month: temp[1],
  206. year: temp[4],
  207. string: temp[0],
  208. })
  209.  
  210. if ((temp = date.match(f(/start(d4)([\/\-])(d12)\2(d12)end/))))
  211. return d({
  212. day: temp[4],
  213. month: temp[3],
  214. year: temp[1],
  215. string: temp[0],
  216. })
  217.  
  218. if ((temp = date.match(f(/start(monthname)space*(d12)space+(d4)end/))))
  219. return d({
  220. day: temp[2],
  221. month: temp[1],
  222. year: temp[3],
  223. string: temp[0],
  224. })
  225.  
  226. if ((temp = date.match(f(/start(monthname)(d12)(d4)end/))))
  227. return d({
  228. day: temp[2],
  229. month: temp[1],
  230. year: temp[3],
  231. string: temp[0],
  232. })
  233.  
  234. if ((temp = date.match(f(/start(d12)(monthname)(d4)end/))))
  235. return d({
  236. day: temp[1],
  237. month: temp[2],
  238. year: temp[3],
  239. string: temp[0],
  240. })
  241.  
  242. if ((temp = date.match(f(/start(d4)(monthname)(d12)end/))))
  243. return d({
  244. day: temp[3],
  245. month: temp[2],
  246. year: temp[1],
  247. string: temp[0],
  248. })
  249.  
  250. if ((temp = date.match(f(/start(d12)space*(monthname)space*(d4)end/))))
  251. return d({
  252. day: temp[1],
  253. month: temp[2],
  254. year: temp[3],
  255. string: temp[0],
  256. })
  257. if ((temp = date.match(f(/start(d4)space*(monthname)space*(d12)end/))))
  258. return d({
  259. day: temp[3],
  260. month: temp[2],
  261. year: temp[1],
  262. string: temp[0],
  263. })
  264. if ((temp = date.match(f(/start(monthname)space*(d12)end/))))
  265. return d({
  266. day: temp[2],
  267. month: temp[1],
  268. year: new Date().getFullYear(),
  269. string: temp[0],
  270. })
  271. }