From 873f0f7c10e2f5ab584e080cc0bf5e85cd662a2b Mon Sep 17 00:00:00 2001
From: Rich Hildebrand <rich.hildebrand@gmail.com>
Date: Tue, 25 Feb 2014 11:35:21 -0500
Subject: [PATCH 1/3] Added a test for allowFuture = false

No change to existing functionality. Just testing existing behavior.
---
 test/index.html      | 24 ++++++++++++++++++++++++
 test/test_helpers.js | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+)

diff --git a/test/index.html b/test/index.html
index 225f5be..09e7434 100644
--- a/test/index.html
+++ b/test/index.html
@@ -190,6 +190,12 @@
       <li><abbr id="testMillisSettings9" class="tomillis" title="120"></abbr> [120 sec]</li>
     </ul>
 
+    <h2>Future</h2>
+
+    <ul>
+      <li><abbr id="testAllowFutureFalse1" class="doNotAllowFuture" title="2012-01-01T09:24:17Z">(you shouldn't see this)</abbr></li>
+    </ul>
+
     <h2>Disposal</h2>
     <p><abbr class="disposal disposed"></abbr></p>
     <p><abbr class="disposal notDisposed"></abbr></p>
@@ -243,6 +249,10 @@
       $("abbr.tonumbers").each(toWords);
       unloadNumbers();
 
+      loadDoNotAllowFuture();
+      $("abbr.doNotAllowFuture").timeago();
+      unloadDoNotAllowFuture();
+
       setupDisposal();
 
       loadYoungOldYears();
@@ -595,6 +605,20 @@
         ok($("#testNullSpaces1").html().match(/^2minutesago$/), "Settings correctly applied");
       });
 
+      module("Do Not Allow Future");
+
+      // if allowFuture is false, then a minute into the future is altually reported as a minute in the past.
+      // we did not want to alter the current behavior and break backwards compatability
+      test("allow future false with a future date moves time backwards", function () {
+        equal($("#testAllowFutureFalse1").html(), "2 years ago");
+      });
+
+      module("Allow Future");
+
+      // test("allow future false with a future date moves time backwards", function () {
+      //   ok($("#testAllowFutureFalse1").html().match(/years ago$/));
+      // });
+
       module("Disposal");
 
       asyncTest("disposal", function() {
diff --git a/test/test_helpers.js b/test/test_helpers.js
index 501de1b..7add8ab 100644
--- a/test/test_helpers.js
+++ b/test/test_helpers.js
@@ -131,3 +131,35 @@ function loadYoungOldYears() {
     years: function(value) { return (value < 21) ? "%d young years" : "%d old years"; }
   });
 }
+
+function loadDoNotAllowFuture() {
+  var mockDateToUse = "2010-01-01";
+  $.timeago.settings.allowFuture = false;
+  enableMockedDate(mockDateToUse);
+}
+
+function unloadDoNotAllowFuture() {
+  $.timeago.settings.allowFuture = true;
+  disableMockedDate();
+}
+
+function enableMockedDate(dateToReturn) {
+  var mockDate = dateToReturn;
+  window.NativeDate = Date;
+  window.Date = function () {
+    if(arguments.length === 0) {
+      return new window.NativeDate(mockDate);
+    } else if(arguments.length === 1) {
+      return new window.NativeDate(arguments[0]);
+    } else  if(arguments.length === 7) {
+      return new window.NativeDate(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6]);
+    } else {
+      throw "Mocking Date with this number of parameters is not implemented.";
+    }
+  }
+}
+
+function disableMockedDate() {
+  window.Date = window.NativeDate;
+  delete window.NativeDate;
+}
\ No newline at end of file

From 9d6c2c6b64d43af65215779a059d05ee816b39aa Mon Sep 17 00:00:00 2001
From: Rich Hildebrand <rich.hildebrand@gmail.com>
Date: Tue, 25 Feb 2014 13:53:37 -0500
Subject: [PATCH 2/3] Added "allowPast" setting.

---
 jquery.timeago.js    | 12 ++++++++++++
 test/index.html      | 41 ++++++++++++++++++++++++++++++++++-------
 test/test_helpers.js | 14 ++++++++++++++
 3 files changed, 60 insertions(+), 7 deletions(-)

diff --git a/jquery.timeago.js b/jquery.timeago.js
index cecfaeb..49aa267 100644
--- a/jquery.timeago.js
+++ b/jquery.timeago.js
@@ -39,6 +39,7 @@
   $.extend($.timeago, {
     settings: {
       refreshMillis: 60000,
+      allowPast: true,
       allowFuture: false,
       localeTitle: false,
       cutoff: 0,
@@ -47,6 +48,7 @@
         prefixFromNow: null,
         suffixAgo: "ago",
         suffixFromNow: "from now",
+        inPast: 'any moment now',
         seconds: "less than a minute",
         minute: "about a minute",
         minutes: "%d minutes",
@@ -62,7 +64,12 @@
         numbers: []
       }
     },
+
     inWords: function(distanceMillis) {
+      if(!this.settings.allowPast && ! this.settings.allowFuture) {
+          throw 'timeago allowPast and allowFuture settings can not both be set to false.';
+      }
+
       var $l = this.settings.strings;
       var prefix = $l.prefixAgo;
       var suffix = $l.suffixAgo;
@@ -73,6 +80,10 @@
         }
       }
 
+      if(!this.settings.allowPast && distanceMillis >= 0) {
+        return this.settings.strings.inPast;
+      }
+
       var seconds = Math.abs(distanceMillis) / 1000;
       var minutes = seconds / 60;
       var hours = minutes / 60;
@@ -101,6 +112,7 @@
       if ($l.wordSeparator === undefined) { separator = " "; }
       return $.trim([prefix, words, suffix].join(separator));
     },
+
     parse: function(iso8601) {
       var s = $.trim(iso8601);
       s = s.replace(/\.\d+/,""); // remove milliseconds
diff --git a/test/index.html b/test/index.html
index 09e7434..ddb24c6 100644
--- a/test/index.html
+++ b/test/index.html
@@ -190,12 +190,19 @@
       <li><abbr id="testMillisSettings9" class="tomillis" title="120"></abbr> [120 sec]</li>
     </ul>
 
-    <h2>Future</h2>
+    <h2>Do Not Allow Future</h2>
 
     <ul>
       <li><abbr id="testAllowFutureFalse1" class="doNotAllowFuture" title="2012-01-01T09:24:17Z">(you shouldn't see this)</abbr></li>
     </ul>
 
+    <h2>Do Not Allow Past</h2>
+
+    <ul>
+      <li><abbr id="testAllowPastFalse1" class="doNotAllowPast" title="2008-01-01T09:24:17Z">(you shouldn't see this)</abbr></li>
+      <li><abbr id="testAllowPastAndFutureFalse" title="2008-01-01T09:24:17Z"></abbr></li>
+    </ul>
+
     <h2>Disposal</h2>
     <p><abbr class="disposal disposed"></abbr></p>
     <p><abbr class="disposal notDisposed"></abbr></p>
@@ -253,6 +260,10 @@
       $("abbr.doNotAllowFuture").timeago();
       unloadDoNotAllowFuture();
 
+      loadDoNotAllowPast();
+      $("abbr.doNotAllowPast").timeago();
+      unloadDoNotAllowPast();
+
       setupDisposal();
 
       loadYoungOldYears();
@@ -605,19 +616,35 @@
         ok($("#testNullSpaces1").html().match(/^2minutesago$/), "Settings correctly applied");
       });
 
-      module("Do Not Allow Future");
+      module("Allow Future and Past");
 
-      // if allowFuture is false, then a minute into the future is altually reported as a minute in the past.
+      // if allowFuture is false, then a minute into the future is actually reported as a minute in the past.
       // we did not want to alter the current behavior and break backwards compatability
       test("allow future false with a future date moves time backwards", function () {
         equal($("#testAllowFutureFalse1").html(), "2 years ago");
       });
 
-      module("Allow Future");
+      test("allow future false with a future date moves time backwards", function () {
+        equal($("#testAllowPastFalse1").html(), "in the past");
+      });
 
-      // test("allow future false with a future date moves time backwards", function () {
-      //   ok($("#testAllowFutureFalse1").html().match(/years ago$/));
-      // });
+      test("throws if allowPast and allowFuture are both false", function () {
+        // setup
+        var origAllowFuture = $.timeago.settings.allowFuture;
+        var origAllowPast = $.timeago.settings.allowPast;
+        $.timeago.settings.allowFuture = false;
+        $.timeago.settings.allowPast = false;
+
+        try {
+          throws(function () {
+            $("#testAllowPastAndFutureFalse").timeago();
+          });
+        } finally {
+          // teardown
+          $.timeago.settings.allowFuture = origAllowFuture;
+          $.timeago.settings.allowPast = origAllowPast;
+        }
+      });
 
       module("Disposal");
 
diff --git a/test/test_helpers.js b/test/test_helpers.js
index 7add8ab..2438c3f 100644
--- a/test/test_helpers.js
+++ b/test/test_helpers.js
@@ -143,6 +143,20 @@ function unloadDoNotAllowFuture() {
   disableMockedDate();
 }
 
+function loadDoNotAllowPast() {
+  var mockDateToUse = "2010-01-01";
+  $.timeago.settings.allowFuture = true;
+  $.timeago.settings.allowPast = false;
+  $.timeago.settings.strings.inPast = "in the past";
+  enableMockedDate(mockDateToUse);
+}
+
+function unloadDoNotAllowPast() {
+  $.timeago.settings.allowFuture = true;
+  $.timeago.settings.allowPast = true;
+  disableMockedDate();
+}
+
 function enableMockedDate(dateToReturn) {
   var mockDate = dateToReturn;
   window.NativeDate = Date;

From d0e161a164815e1817080b5c9b6f692da6924554 Mon Sep 17 00:00:00 2001
From: Rich Hildebrand <rich.hildebrand@gmail.com>
Date: Tue, 25 Feb 2014 13:53:50 -0500
Subject: [PATCH 3/3] Added docs for "allowPast" setting.

---
 index.html | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/index.html b/index.html
index 14e033b..9df6513 100644
--- a/index.html
+++ b/index.html
@@ -116,6 +116,15 @@ jQuery.timeago(jQuery("abbr#some_id")); //=> &quot;<span id="prog_element"></spa
       <pre>
 jQuery.timeago.settings.allowFuture = true;</pre>
 
+      <p class="how">
+        To disable timestamps in the past, use the <tt>allowPast</tt> setting.
+        This setting is set to true by default. When set to false, if the time is in the past then instead of displaying a message like "5 minutes ago" a static message will be displayed.
+        The staic message displayed can be configured with the <tt>strings.inPast</tt> setting:
+      </p>
+      <pre>
+jQuery.timeago.settings.strings.inPast = "time has elapsed";
+jQuery.timeago.settings.allowPast = false;</pre>
+
       <h3>Excusez-moi?</h3>
       <p>
         Yes, timeago has locale/i18n/language support.  Here are some <a href="https://github.com/rmm5t/jquery-timeago/tree/master/locales">configuration examples</a>.  Please submit a <a href="https://github.com/rmm5t/jquery-timeago">GitHub pull request</a> for corrections or additional languages.