how long ago

replaces all dates with the time from that date

  1. // ==UserScript==
  2. // @name how long ago
  3. // @version 8
  4. // @description replaces all dates with the time from that date
  5. // @run-at document-end
  6. // @author rssaromeo
  7. // @license GPLv3
  8. // @match *://*/*
  9. // @include *
  10. // @tag style
  11. // @exclude /^https?:\/\/[^\/]*livereload.net\/files\/ffopen\/index\.html$/
  12. // @exclude /^https?:\/\/[^\/]*stackblitz.com/
  13. // @exclude /^https?:\/\/[^\/]*webcontainer.io/
  14. // @exclude /^https?:\/\/[^\/]*regexr.com/
  15. // @exclude /^https?:\/\/[^\/]*regex101.com/
  16. // @exclude *://*/*.mjs
  17. // @exclude *://*/*.js
  18. // @exclude *://*/*.css
  19. // @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=
  20. // @grant none
  21. // @namespace https://greasyfork.org/users/1184528
  22. // ==/UserScript==
  23. const tonum = {
  24. january: 1,
  25. february: 2,
  26. march: 3,
  27. april: 4,
  28. may: 5,
  29. june: 6,
  30. july: 7,
  31. august: 8,
  32. september: 9,
  33. october: 10,
  34. november: 11,
  35. december: 12,
  36. jan: 1,
  37. feb: 2,
  38. mar: 3,
  39. apr: 4,
  40. jun: 6,
  41. jul: 7,
  42. aug: 8,
  43. sep: 9,
  44. oct: 10,
  45. nov: 11,
  46. dec: 12,
  47. }
  48. const cache = loadlib("cache")
  49. const replacements = [
  50. [
  51. "monthname",
  52. "(?:jan(?:uary)?|feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|may|june?|july?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)",
  53. ],
  54. [
  55. "month",
  56. "(?:\\d{1,2}|(?:jan(?:uary)?|feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|may|june?|july?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?))",
  57. ],
  58. ["day", "\\d{1,2}(?:rd|th|nd|st)?"],
  59. ["year", "\\d{4}(?:rd|th|nd|st)?"],
  60. ["space", "[^a-z0-9.]"],
  61. ["start", "(?<![\\d\\w])"],
  62. ["end", "(?![\\d\\w])"],
  63. ["d2", "\\d{2}(?:rd|th|nd|st)?"],
  64. ["d4", "\\d{4}(?:rd|th|nd|st)?"],
  65. ["d12", "\\d{1,2}(?:rd|th|nd|st)?"],
  66. ]
  67. const formats = [
  68. { regex: "start(month)space(day),?space(year)end", order: [2, 1, 3] },
  69. { regex: "start(year)[-/](month)[-/](day)end", order: [3, 2, 1] },
  70. ].map(({ regex, order }) => {
  71. replacements.forEach(([pattern, replacement]) => {
  72. regex = regex.replaceAll(pattern, replacement)
  73. })
  74. return { regex: new RegExp(regex, "gi"), order }
  75. })
  76.  
  77. const datecache = new cache()
  78. function replaceDates(text) {
  79. if (datecache.has(text)) {
  80. return datecache.get()
  81. }
  82. // if (text.includes("\u202e\u202d]")) {
  83. // return datecache.set(text)
  84. // }
  85. for (var { regex, order } of formats) {
  86. if (regex.test(text)) {
  87. text = text.replace(regex, (fullstr, ...data) => {
  88. var pos = text.indexOf(fullstr) + fullstr.length
  89. if (text.substring(pos, pos + 3) == "\u202e\u202d]") {
  90. // prevent infinite loops
  91. return fullstr
  92. }
  93. var o = order.map((e) => data[e - 1])
  94. return getstr(createDateObject(...o, fullstr))
  95. })
  96. }
  97. }
  98. return datecache.set(text)
  99. }
  100.  
  101. loadlib("textjack")(function (text) {
  102. var newtext = text
  103. newtext = replaceDates(text)
  104. if (newtext !== text) {
  105. return newtext
  106. }
  107. return text
  108. })
  109.  
  110. function createDateObject(day, month, year, string) {
  111. day = parseInt(day, 10)
  112. month = tonum[month.toLowerCase()] || parseInt(month, 10)
  113. year = parseInt(year, 10)
  114. if (year < 100) year += 2000
  115.  
  116. if (!month || day > 31) return null
  117.  
  118. const date = new Date(year, month - 1, day)
  119. const today = new Date()
  120. today.setHours(0, 0, 0, 0)
  121. const ms = today - date
  122.  
  123. return {
  124. // day,
  125. // month,
  126. // year,
  127. string,
  128. ms: Math.abs(ms),
  129. isago: ms > 0,
  130. }
  131. }
  132.  
  133. function howlongago(ms) {
  134. const units = [
  135. { name: "year", ms: 31536000000 },
  136. { name: "week", ms: 604800000 },
  137. { name: "day", ms: 86400000 },
  138. { name: "hour", ms: 3600000 },
  139. { name: "minute", ms: 60000 },
  140. { name: "second", ms: 1000 },
  141. ]
  142.  
  143. let result = []
  144. for (const unit of units) {
  145. const value = Math.floor(ms / unit.ms)
  146. if (value > 0) {
  147. result.push(`${value} ${unit.name}${value !== 1 ? "s" : ""}`)
  148. ms %= unit.ms
  149. }
  150. if (result.length >= 2) break
  151. }
  152.  
  153. return result.length ? result.join(" ") : "today"
  154. }
  155.  
  156. function getstr(x) {
  157. return `[${howlongago(x.ms)} ${
  158. howlongago(x.ms) == "today" ? "" : x.isago ? "ago" : "until"
  159. } ${x.string}\u202e\u202d]`
  160. }
  161.  
  162. // document.querySelector("#yDmH0d > c-wiz > div > div.ToWKne > c-wiz > div.caTGn > c-wiz > div.iggndc > c-wiz > div > div > div > div.rlWbvd > div.gLXQIf > div.LYeNu").innerHTML="oct 21 0202 ****"