diff --git a/4chan_x.user.js b/4chan_x.user.js index 5c9007b86..47e916545 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -3558,11 +3558,11 @@ node: function(post) { var dateEl, diff, utc; dateEl = $('.postInfo > .dateTime', post.el); - utc = dateEl.dataset.utc * 1000; dateEl.title = dateEl.textContent; + utc = dateEl.dataset.utc * 1000; diff = Date.now() - utc; dateEl.textContent = RelativeDates.relative(diff); - RelativeDates.setUpdate(dateEl, diff); + RelativeDates.setUpdate(dateEl, utc, diff); return RelativeDates.flush(); }, relative: function(diff) { @@ -3576,29 +3576,38 @@ }, stale: [], flush: $.debounce($.SECOND, function() { - var dateEl, diff, _i, _len, _ref; + var now, update, _i, _len, _ref; if (d.hidden) { return; } + now = Date.now(); _ref = RelativeDates.stale; for (_i = 0, _len = _ref.length; _i < _len; _i++) { - dateEl = _ref[_i]; - if (d.contains(dateEl)) { - diff = Date.now() - dateEl.dataset.utc * 1000; - dateEl.textContent = RelativeDates.relative(diff); - RelativeDates.setUpdate(dateEl, diff); - } + update = _ref[_i]; + update(now); } RelativeDates.stale = []; clearTimeout(RelativeDates.timeout); return RelativeDates.timeout = setTimeout(RelativeDates.flush, RelativeDates.INTERVAL); }), - setUpdate: function(dateEl, diff) { - var delay; - delay = diff > $.HOUR ? diff % $.HOUR : diff > $.MINUTE ? diff % $.MINUTE : diff % $.SECOND; - return setTimeout((function() { - return RelativeDates.stale.push(dateEl); - }), delay); + setUpdate: function(dateEl, utc, diff) { + var markStale, setOwnTimeout, update; + setOwnTimeout = function(diff) { + var delay; + delay = diff > $.HOUR ? diff % $.HOUR : diff > $.MINUTE ? diff % $.MINUTE : diff % $.SECOND; + return setTimeout(markStale, delay); + }; + update = function(now) { + if (d.contains(dateEl)) { + diff = now - utc; + dateEl.textContent = RelativeDates.relative(diff); + return setOwnTimeout(diff); + } + }; + markStale = function() { + return RelativeDates.stale.push(update); + }; + return setOwnTimeout(diff); } }; diff --git a/script.coffee b/script.coffee index 6acfa8868..7a004c54d 100644 --- a/script.coffee +++ b/script.coffee @@ -2849,17 +2849,18 @@ RelativeDates = node: (post) -> dateEl = $ '.postInfo > .dateTime', post.el - utc = dateEl.dataset.utc * 1000 # convert data-utc to milliseconds - # Show original absolute time as tooltip so users can still know exact times # Since "Time Formatting" runs `node` before us, the title tooltip will # pick up the user-formatted time instead of 4chan time when enabled. dateEl.title = dateEl.textContent + # convert data-utc to milliseconds + utc = dateEl.dataset.utc * 1000 + diff = Date.now() - utc dateEl.textContent = RelativeDates.relative diff - RelativeDates.setUpdate dateEl, diff + RelativeDates.setUpdate dateEl, utc, diff # Main calls @node whenever a DOM node is added (update, inline post, # whatever), so use also this reflow opportunity to flush any other dates @@ -2889,31 +2890,44 @@ RelativeDates = # stuttering won't be noticed), falling back to INTERVAL while the page # is visible. # - # each individual dateTime element will be added to the stale list when it - # needs to change. + # each individual dateTime element will add its update() function to the stale list + # when it to be called. stale: [] flush: $.debounce($.SECOND, -> # no point in changing the dates until the user sees them return if d.hidden - for dateEl in RelativeDates.stale - if d.contains dateEl # not removed from DOM - diff = Date.now() - dateEl.dataset.utc * 1000 - dateEl.textContent = RelativeDates.relative diff - RelativeDates.setUpdate dateEl, diff + + now = Date.now() + update now for update in RelativeDates.stale RelativeDates.stale = [] + + # reset automatic flush clearTimeout RelativeDates.timeout RelativeDates.timeout = setTimeout RelativeDates.flush, RelativeDates.INTERVAL) - # Add element to stale list when the relative date string would change - # diff is in milliseconds between dateEl and now - setUpdate: (dateEl, diff) -> - delay = if diff > $.HOUR - diff % $.HOUR - else if diff > $.MINUTE - diff % $.MINUTE - else - diff % $.SECOND - setTimeout (-> RelativeDates.stale.push dateEl), delay + # create function `update()`, closed over dateEl and diff, that, when called + # from `flush()`, updates the element, and re-calls `setOwnTimeout()` to + # re-add `update()` to the stale list later. + setUpdate: (dateEl, utc, diff) -> + setOwnTimeout = (diff) -> + delay = if diff > $.HOUR + diff % $.HOUR + else if diff > $.MINUTE + diff % $.MINUTE + else + diff % $.SECOND + setTimeout markStale, delay + + update = (now) -> + if d.contains dateEl # not removed from DOM + diff = now - utc + dateEl.textContent = RelativeDates.relative diff + setOwnTimeout diff + + markStale = -> RelativeDates.stale.push update + + # kick off initial timeout with current diff + setOwnTimeout diff FileInfo = init: ->