how long ago

replaces all dates with the time from that date

目前为 2024-05-15 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name how long ago
  3. // @version 2
  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. `${Math.floor(days / 7)} week${days >= 14 ? "s" : ""}${
  99. days / 7 == Math.floor(days / 7)
  100. ? ""
  101. : ` ${days % 7} day${days % 7 == 1 ? "" : "s"}`
  102. }`
  103. )
  104. return temp
  105. }
  106. window.x = [...x]
  107. return (
  108. //`0 ${time[x.length - 1]}s` ||
  109. "today"
  110. )
  111. }
  112. function getdate(date) {
  113. const tonum = {
  114. january: 1,
  115. february: 2,
  116. march: 3,
  117. april: 4,
  118. may: 5,
  119. june: 6,
  120. july: 7,
  121. august: 8,
  122. september: 9,
  123. october: 10,
  124. november: 11,
  125. december: 12,
  126. jan: 1,
  127. feb: 2,
  128. mar: 3,
  129. apr: 4,
  130. jun: 6,
  131. jul: 7,
  132. aug: 8,
  133. sep: 9,
  134. oct: 10,
  135. nov: 11,
  136. dec: 12,
  137. }
  138.  
  139. function f(reg) {
  140. reg = String(reg).replaceAll(/^\/|\/[gimsueyx]*$/g, "")
  141. ;[
  142. ["d2", "\\d{2}(?:rd|th|nd|st)?"],
  143. ["d4", "\\d{4}(?:rd|th|nd|st)?"],
  144. ["d12", "\\d{1,2}(?:rd|th|nd|st)?"],
  145. [
  146. "monthname",
  147. "(?:jan(?:uary)?|feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|may|june?|july?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)",
  148. ],
  149. ["space", "[^a-z0-9.]"],
  150. ["start", "(?<![\\d\\w/])"],
  151. ["end", "(?![\\d\\w])"],
  152. ].forEach(([a, s]) => {
  153. reg = reg.replaceAll(a, s)
  154. })
  155. return new RegExp(reg, "i")
  156. }
  157.  
  158. function d({ day, month, year, string }) {
  159. day = Number(day.match(/\d+/)[0])
  160. month = tonum[month?.toLowerCase?.()] || Number(month)
  161. if (!month) return
  162. if (day > 31) return
  163. year = Number(
  164. year.length == 2
  165. ? String(new Date().getFullYear()).substring(0, 2) + year
  166. : year
  167. )
  168. var today = new Date()
  169. today.setHours(0, 0, 0, 0)
  170. var ms = today - new Date(year, month - 1, day)
  171. return {
  172. day,
  173. month,
  174. year,
  175. string,
  176. ms: Math.abs(ms),
  177. isago: ms > 0,
  178. }
  179. }
  180. var temp
  181. if (
  182. (temp = date.match(f(/start(monthname|d12)space+(d12)sapce*'(d4|d2)end/)))
  183. )
  184. return d({
  185. day: temp[2],
  186. month: temp[1],
  187. year: temp[3],
  188. string: temp[0],
  189. })
  190. if ((temp = date.match(f(/start(d12)([\/\-])(d12)\2(d4|d2)end/))))
  191. return d({
  192. day: temp[3],
  193. month: temp[1],
  194. year: temp[4],
  195. string: temp[0],
  196. })
  197.  
  198. if ((temp = date.match(f(/start(d12)([\/\-])(d12)\2(d4|d2)end/))))
  199. return d({
  200. day: temp[3],
  201. month: temp[1],
  202. year: temp[4],
  203. string: temp[0],
  204. })
  205.  
  206. if ((temp = date.match(f(/start(d4)([\/\-])(d12)\2(d12)end/))))
  207. return d({
  208. day: temp[4],
  209. month: temp[3],
  210. year: temp[1],
  211. string: temp[0],
  212. })
  213.  
  214. if ((temp = date.match(f(/start(monthname)space*(d12)space+(d4)end/))))
  215. return d({
  216. day: temp[2],
  217. month: temp[1],
  218. year: temp[3],
  219. string: temp[0],
  220. })
  221.  
  222. if ((temp = date.match(f(/start(monthname)(d12)(d4)end/))))
  223. return d({
  224. day: temp[2],
  225. month: temp[1],
  226. year: temp[3],
  227. string: temp[0],
  228. })
  229.  
  230. if ((temp = date.match(f(/start(d12)(monthname)(d4)end/))))
  231. return d({
  232. day: temp[1],
  233. month: temp[2],
  234. year: temp[3],
  235. string: temp[0],
  236. })
  237.  
  238. if ((temp = date.match(f(/start(d4)(monthname)(d12)end/))))
  239. return d({
  240. day: temp[3],
  241. month: temp[2],
  242. year: temp[1],
  243. string: temp[0],
  244. })
  245.  
  246. if ((temp = date.match(f(/start(d12)space*(monthname)space*(d4)end/))))
  247. return d({
  248. day: temp[1],
  249. month: temp[2],
  250. year: temp[3],
  251. string: temp[0],
  252. })
  253. if ((temp = date.match(f(/start(d4)space*(monthname)space*(d12)end/))))
  254. return d({
  255. day: temp[3],
  256. month: temp[2],
  257. year: temp[1],
  258. string: temp[0],
  259. })
  260. if ((temp = date.match(f(/start(monthname)space*(d12)end/))))
  261. return d({
  262. day: temp[2],
  263. month: temp[1],
  264. year: new Date().getFullYear(),
  265. string: temp[0],
  266. })
  267. }