Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

MediaWiki:Notice.js

MediaWiki interface page

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
(function () {
  function formatRelative(diffMs) {
    var rtf = new Intl.RelativeTimeFormat(mw.config.get('wgUserLanguage') || 'en', {
      numeric: 'auto',
    });

    var sec = Math.round(diffMs / 1000);
    if (Math.abs(sec) < 60) return rtf.format(sec, 'second');

    var min = Math.round(sec / 60);
    if (Math.abs(min) < 60) return rtf.format(min, 'minute');

    var hr = Math.round(min / 60);
    if (Math.abs(hr) < 24) return rtf.format(hr, 'hour');

    var day = Math.round(hr / 24);
    return rtf.format(day, 'day');
  }

  function formatAbsolute(date) {
    if (!date || isNaN(date.getTime())) return '';

    try {
      return new Intl.DateTimeFormat(mw.config.get('wgUserLanguage') || 'en', {
        dateStyle: 'medium',
        timeStyle: 'short',
      }).format(date);
    } catch (e) {
      return '';
    }
  }

  function updateNotice(el) {
    var startRaw = el.getAttribute('data-start');
    var endRaw = el.getAttribute('data-end');
    var mode = el.getAttribute('data-mode') || 'auto';

    var footer = el.querySelector('.js-notice-footer');
    var relEl = el.querySelector('.js-notice-relative');
    var absEl = el.querySelector('.js-notice-absolute');
    var sepEl = el.querySelector('.js-notice-sep');

    var now = Date.now();
    var start = startRaw ? new Date(startRaw) : null;
    var end = endRaw ? new Date(endRaw) : null;

    var hasStart = start && !isNaN(start.getTime());
    var hasEnd = end && !isNaN(end.getTime());

    var rel = '';
    var abs = '';

    if (mode !== 'static') {
      if (hasStart && hasEnd) {
        if (now < start.getTime()) {
          rel = 'Starts ' + formatRelative(start.getTime() - now);
        } else if (now <= end.getTime()) {
          rel = 'In progress';
        } else {
          rel = 'Ended ' + formatRelative(end.getTime() - now);
        }
        abs = formatAbsolute(start) + ' → ' + formatAbsolute(end);
      } else if (hasStart) {
        rel =
          now < start.getTime() ? 'Starts ' + formatRelative(start.getTime() - now) : 'In progress';
        abs = formatAbsolute(start);
      } else if (hasEnd) {
        rel = 'Ends ' + formatRelative(end.getTime() - now);
        abs = formatAbsolute(end);
      }
    }

    if (relEl) relEl.textContent = rel;
    if (absEl) absEl.textContent = abs;

    if (sepEl) {
      sepEl.style.display = rel && abs ? '' : 'none';
    }

    if (footer) {
      footer.classList.toggle('is-empty', !rel && !abs);
    }
  }

  function initNotices() {
    var notices = document.querySelectorAll('.gtw-notice');
    if (!notices.length) return;

    function tick() {
      notices.forEach(updateNotice);
    }

    tick();
    setInterval(tick, 60000);
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initNotices);
  } else {
    initNotices();
  }
})();