PageSourceSearch

https://www.dinamobasket.com/core/misc/time-diff.js?v=10.1.6

js dinamobasket.com collected 2026-10-02 10:46:05 UTC 9,803 bytes, 305 lines download raw bytes

1/**
2 * @file
3 * Dynamic time difference formatting.
4 */
5
6((Drupal, once) => {
7  /**
8   * @typedef {object} timeDiffValue
9   *
10   * @prop {number} [year]
11   *   Years count.
12   * @prop {number} [month]
13   *   Months count.
14   * @prop {number} [week]
15   *   Weeks count.
16   * @prop {number} [day]
17   *   Days count.
18   * @prop {number} [hour]
19   *   Hours count.
20   * @prop {number} [minute]
21   *   Minutes count.
22   * @prop {number} [second]
23   *   Seconds count.
24   */
25
26  /**
27   * @typedef {object} timeDiff
28   *
29   * @prop {string} formatted
30   *   A translated string representation of the interval.
31   * @prop {timeDiffValue} value
32   *   The elements composing the time difference interval. Example: { day: 2,
33   *   hour: 2, minute: 32, second: 15 }.
34   */
35
36  /**
37   * List of time intervals.
38   *
39   * @type {object}
40   *
41   * @prop {number} year
42   *   Year duration in seconds.
43   * @prop {number} month
44   *   Month duration in seconds.
45   * @prop {number} week
46   *   Week duration in seconds.
47   * @prop {number} day
48   *   Day duration in seconds.
49   * @prop {number} hour
50   *   Hour duration in seconds.
51   * @prop {number} minute
52   *   Minute duration in seconds.
53   * @prop {number} second
54   *   One second.
55   */
56  const intervals = {
57    year: 31536000,
58    month: 2592000,
59    week: 604800,
60    day: 86400,
61    hour: 3600,
62    minute: 60,
63    second: 1,
64  };
65
66  /**
67   * List of available time intervals names.
68   *
69   * @type {string[]}
70   */
71  const intervalsNames = Object.keys(intervals);
72
73  /**
74   *
75   * @type {WeakMap<HTMLElement, number>}
76   */
77  const timers = new WeakMap();
78
79  /**
80   * @namespace
81   */
82  Drupal.timeDiff = {
83    /**
84     * Fills a HTML5 time element text with a computed time difference string.
85     *
86     * @param {Element} timeElement
87     *   The time DOM element.
88     */
89    show(timeElement) {
90      const timestamp = new Date(
91        timeElement.getAttribute('datetime'),
92      ).getTime();
93      const timeDiffSettings = JSON.parse(
94        timeElement.getAttribute('data-drupal-time-diff'),
95      );
96
97      const now = Date.now();
98      const diff = Math.round((timestamp - now) / 1000);
99      const options = { granularity: timeDiffSettings.granularity };
100      const timeDiff = Drupal.timeDiff.format(diff, options);
101      const format = diff > 0 ? 'future' : 'past';
102      timeElement.textContent = Drupal.formatString(
103        timeDiffSettings.format[format],
104        {
105          '@interval': timeDiff.formatted,
106        },
107      );
108
109      if (timeDiffSettings.refresh > 0) {
110        const refreshInterval = Drupal.timeDiff.refreshInterval(
111          timeDiff.value,
112          timeDiffSettings.refresh,
113          timeDiffSettings.granularity,
114        );
115        clearTimeout(timers.get(timeElement));
116        timers.set(
117          timeElement,
118          setTimeout(Drupal.timeDiff.show, refreshInterval * 1000, timeElement),
119        );
120      }
121    },
122
123    /**
124     * Computes the refresh interval.
125     *
126     * There are cases when the refresh occurs even when it is not needed. For
127     * example if the refresh interval is '10 seconds', the granularity is 2 and
128     * the time difference is '1 hour 32 minutes', there's no need to refresh
129     * every 10 seconds but every 1 minute. This function optimizes the refresh
130     * interval to higher values, if the structure of the time difference
131     * doesn't require refreshing more often.
132     *
133     * @param {timeDiffValue} value
134     *   The time difference object.
135     * @param {number} refresh
136     *   The configured refresh interval in seconds.
137     * @param {number} granularity
138     *   The time difference granularity.
139     *
140     * @return {number}
141     *   The computed refresh interval in seconds.
142     */
143    refreshInterval(value, refresh, granularity) {
144      const units = Object.keys(value);
145      const unitsCount = units.length;
146      const lastUnit = units.pop();
147
148      // If the lowest unit of time difference is 'minute' or greater but the
149      // refresh interval is lower, do not refresh often than the duration of
150      // the lowest unit of time difference.
151      if (lastUnit !== 'second') {
152        // If the time difference value parts count equals the granularity and
153        // lowest unit duration is bigger than the refresh interval, use the
154        // interval duration. For example, if the refresh interval is
155        // '10 seconds', the granularity is 2 and the time difference is
156        // '1 hour 32 minutes', do not refresh every 10 seconds but every one
157        // minute (60 seconds).
158        if (unitsCount === granularity) {
159          intervalsNames.every((interval) => {
160            const duration = intervals[interval];
161            if (interval === lastUnit) {
162              refresh = refresh < duration ? duration : refresh;
163              return false;
164            }
165            return true;
166          });
167          return refresh;
168        }
169        // The time difference value parts count might be smaller than the
170        // granularity when the lowest part is missed because is 0. In this case
171        // the missed part interval duration is used as refresh. For example, if
172        // the refresh is '10 seconds', the granularity is 2 and the time
173        // difference is '59 minutes 59 seconds', on the next refresh the time
174        // difference will be '1 hour' (because minutes are 0, therefore are not
175        // shown) but we want the next refresh to occur, not in one hour, but in
176        // one minute.
177        const lastIntervalIndex = intervalsNames.indexOf(lastUnit);
178        const nextInterval = intervalsNames[lastIntervalIndex + 1];
179        refresh = intervals[nextInterval];
180      }
181      return refresh;
182    },
183
184    /**
185     * Formats a time interval between two timestamps.
186     *
187     * @param {number} diff
188     *   A UNIX timestamps difference in seconds.
189     * @param {object} [options]
190     *   An optional object with additional options.
191     * @param {number} [options.granularity=2]
192     *   An integer value that signals how many different units to display in the
193     *   string. Defaults to 2.
194     * @param {boolean} [options.strict=false]
195     *   A boolean value indicating whether or not, a negative diff should be
196     *   rendered as "0 seconds". If the time difference is negative (i.e. the
197     *   timestamp is in the past) and this option is false (default) the result
198     *   string will be the formatted time difference. If the option is true the
199     *   result string will be "0 seconds".
200     *
201     * @return {timeDiff}
202     *   A time difference type object.
203     */
204    format(diff, options = {}) {
205      // Provide appropriate defaults.
206      options = { granularity: 2, strict: false, ...options };
207
208      if (options.strict && diff < 0) {
209        return {
210          formatted: Drupal.formatPlural(0, '1 second', '@count seconds'),
211          value: { second: 0 },
212        };
213      }
214      diff = Math.abs(diff);
215
216      const output = [];
217      const value = {};
218      let units;
219      let { granularity } = options;
220
221      intervalsNames.every((interval) => {
222        const duration = intervals[interval];
223        units = Math.floor(diff / duration);
224        if (units > 0) {
225          diff %= units * duration;
226          switch (interval) {
227            case 'year':
228              output.push(Drupal.formatPlural(units, '1 year', '@count years'));
229              break;
230            case 'month':
231              output.push(
232                Drupal.formatPlural(units, '1 month', '@count months'),
233              );
234              break;
235            case 'week':
236              output.push(Drupal.formatPlural(units, '1 week', '@count weeks'));
237              break;
238            case 'day':
239              output.push(Drupal.formatPlural(units, '1 day', '@count days'));
240              break;
241            case 'hour':
242              output.push(Drupal.formatPlural(units, '1 hour', '@count hours'));
243              break;
244            case 'minute':
245              output.push(
246                Drupal.formatPlural(units, '1 minute', '@count minutes'),
247              );
248              break;
249            default:
250              output.push(
251                Drupal.formatPlural(units, '1 second', '@count seconds'),
252              );
253          }
254          value[interval] = units;
255
256          granularity -= 1;
257          if (granularity <= 0) {
258            // Limit the granularity of the output.
259            return false;
260          }
261        } else if (output.length > 0) {
262          // Exit if there was previous output but not any output at this level,
263          // to avoid skipping levels and getting output like "1 year 1 second".
264          return false;
265        }
266        return true;
267      });
268
269      if (output.length === 0) {
270        return {
271          formatted: Drupal.formatPlural(0, '1 second', '@count seconds'),
272          value: { second: 0 },
273        };
274      }
275      return { formatted: output.join(' '), value };
276    },
277  };
278
279  /**
280   * Fills all time[data-drupal-time-diff] elements with a refreshing time diff.
281   *
282   * @type {Drupal~behavior}
283   *
284   * @prop {Drupal~behaviorAttach} attach
285   *   Initializes refresh of time differences.
286   *
287   * @prop {Drupal~behaviorDetach} detach
288   *   Clear timers associated with time diff elements.
289   */
290  Drupal.behaviors.timeDiff = {
291    attach(context) {
292      // Replace each <time> element text with a time difference representation.
293      once('time-diff', 'time[data-drupal-time-diff]', context).forEach(
294        Drupal.timeDiff.show,
295      );
296    },
297    detach(context, settings, trigger) {
298      if (trigger === 'unload') {
299        once
300          .remove('time-diff', 'time[data-drupal-time-diff]', context)
301          .forEach((timeElement) => clearTimeout(timers.get(timeElement)));
302      }
303    },
304  };
305})(Drupal, once);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.