MediaWiki:CentralNotice/Resources/BannerShowHideCountDate.js

From Meta, a Wikimedia project coordination wiki

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)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
<script>
  /* MediaWiki:CentralNotice/Resources/BannerShowHideCountDate.js
   * Determine if a banner should be hidden or displayed based on the
   * contents of the cookie named `hide-cookie-name` and that + `-wait`.
   *
   * Showing a banner entails that a certain number of impressions have
   * already occured in a time period.
   * 
   * hide-cookie-show-count - Number of impressions to show per period
   * hide-cookie-wait-count - Number of impressions to wait per period
   * hide-cookie-wait-delay - Number of second in period
   *
   * Provides CentralNotice alterImpressionData hook
   * Banner may be forced if URL parameter force = 1
   * Counters may be reset if URL parameter reset = 1
   *
   * Flow chart: https://commons.wikimedia.org/wiki/File:CentralNotice_-_wait_cookie_code_flow.png
   */
  (function(mw) {
    var
      /** Total number of impressions seen by this user */
      cookieCount = parseInt($.cookie('{{{hide-cookie-name}}}')) || 0,

      waitData = ($.cookie('{{{hide-cookie-name}}}-wait') || '').split(/[|]/),
      /** This cycle's count of how many impressions we've waited for */
      waitCount = parseInt(waitData[0]) || 0,
      /** Timestamp (ms) until we can show another banner */
      waitUntil = parseInt(waitData[1]) || 0,
      /** Number of impressions seen this cycle */
      waitSeenCount = parseInt(waitData[2]) || 0,

      showLimit = parseInt('{{{hide-cookie-show-count}}}') || 0,
      waitLimit = parseInt('{{{hide-cookie-wait-count}}}') || 0,
      waitDelay = parseInt('{{{hide-cookie-wait-delay}}}') || 0,

      hideBanner = true,
      hideReason = null;

    if (location.search.match(/\breset=1/)) {
      // Reset counters on demand
      cookieCount = 0;
      waitCount = 0;
      waitUntil = 0;
      waitSeenCount = 0;
    }

    var
      pastDate = waitUntil < new Date().getTime(),
      waitForHideImps = waitCount < waitLimit,
      waitForShowImps = waitSeenCount < showLimit;
 
    if (location.search.match(/\bforce=1/)) {
      hideBanner = false;
    } else if (!pastDate) {
      hideReason = 'waitdate';
      waitCount += 1;
    } else if (pastDate && waitForHideImps) {
      hideReason = 'waitimps';
      waitCount += 1;
    } else if (pastDate && !waitForHideImps && waitForShowImps) {
      hideBanner = false;
      waitSeenCount += 1;
      cookieCount += 1;
      
      if (waitSeenCount >= showLimit) {
        waitCount = 0;
        waitSeenCount = 0;
        waitUntil = new Date().getTime() + (waitDelay * 1000);
      }
    } else {
      hideReason = 'waiterr';
      waitCount = 0;
      waitSeenCount = 0;
      waitUntil = new Date().getTime() + (waitDelay * 1000);
    }
    waitData = waitCount + '|' + waitUntil + '|' + waitSeenCount;
 
    // Finish up and store results
    $.cookie('{{{hide-cookie-name}}}', cookieCount, { expires: 365, path: '/' });
    $.cookie('{{{hide-cookie-name}}}-wait', waitData, { expires: 365, path: '/' });
    mw.centralNotice.bannerData.hideResult = hideBanner;
    mw.centralNotice.bannerData.hideReason = hideReason;
    mw.centralNotice.bannerData.cookieCount = cookieCount;
  })(mediaWiki);
 
  mediaWiki.centralNotice.bannerData.alterImpressionData = function( impressionData ) {
    // Returning true from this function indicates the banner was shown
    if (mediaWiki.centralNotice.bannerData.hideReason) {
      impressionData.reason = mediaWiki.centralNotice.bannerData.hideReason;
    }
    if (mediaWiki.centralNotice.bannerData.cookieCount) {
      impressionData.banner_count = mediaWiki.centralNotice.bannerData.cookieCount;
    }
    return !mediaWiki.centralNotice.bannerData.hideResult;
  };
</script>