<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -81,6 +81,7 @@ Contributors:
 
 * Justin Palmer (&quot;Caged&quot;)
 * Nik Wakelin (&quot;codetocustomer&quot;)
+* Sebastien Grosjean (&quot;ZenCocoon&quot;)
 
 
 Download:</diff>
      <filename>README.markdown</filename>
    </modified>
    <modified>
      <diff>@@ -2,11 +2,6 @@ THINGS TODO (mostly in order of importance)
 
 * Optimize for IE
 
-* Limit the previous/next buttons to selectable months (between `earliest`
-  and `latest`)
-
-* Elegant way to drag to months before and after the displayed calendars
-
 * More localizations
   
 * Prettier initial styles, especially for non-Safari browsers</diff>
      <filename>TODO</filename>
    </modified>
    <modified>
      <diff>@@ -112,6 +112,7 @@
     &lt;ul&gt;
       &lt;li&gt;&lt;a href=&quot;http://alternateidea.com&quot;&gt;Justin Palmer (&amp;ldquo;Caged&amp;rdquo;)&lt;/a&gt;&lt;/li&gt;
       &lt;li&gt;&lt;a href=&quot;http://codetocustomer.com/blog&quot;&gt;Nik Wakelin (&amp;ldquo;codetocustomer&amp;rdquo;)&lt;/a&gt;&lt;/li&gt;
+      &lt;li&gt;&lt;a href=&quot;http://zencocoon.com&quot;&gt;S&#233;bastien Grosjean (&amp;ldquo;ZenCocoon&amp;rdquo;)&lt;/a&gt;&lt;/li&gt;
     &lt;/ul&gt;
     &lt;h2&gt;Contact:&lt;/h2&gt;
     &lt;p&gt;</diff>
      <filename>example/example.html</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-/* Timeframe, version 0.2
+/* Timeframe, version 0.3
  * (c) 2008 Stephen Celis
  *
  * Freely distributable under the terms of an MIT-style license. 
@@ -18,7 +18,7 @@ var Locale = $H({
 var Timeframes = [];
 
 var Timeframe = Class.create({
-  Version: '0.2',
+  Version: '0.3',
 
   initialize: function(element, options) {
     Timeframes.push(this);
@@ -33,6 +33,11 @@ var Timeframe = Class.create({
     this.format       = this.options.get('format')     || Locale.get('format');
     this.weekOffset   = this.options.get('weekOffset') || Locale.get('weekOffset');
     this.maxRange = this.options.get('maxRange');
+    
+    this.firstDayId = element.id + '_firstday';
+    this.lastDayId = element.id + '_lastday';
+    
+    this.scrollerDelay = 0.5;
 
     this.buttons = $H({
       previous: $H({ label: '&amp;larr;', element: $(this.options.get('previousButton')) }),
@@ -86,6 +91,10 @@ var Timeframe = Class.create({
     this.element.down('div#' + this.element.id + '_container').insert(calendar);
     this.calendars.push(calendar);
     this.months = this.calendars.length;
+    
+    this.element.select('td').first().id = this.firstDayId;
+    this.element.select('td').last().id = this.lastDayId;
+    
     return this;
   },
 
@@ -98,6 +107,11 @@ var Timeframe = Class.create({
   populate: function() {
     var month = this.date.neutral();
     month.setDate(1);
+    
+    this.earliest === null || this.earliest &lt; month ?
+      this.buttons.get('previous').get('element').removeClassName('disabled') :
+      this.buttons.get('previous').get('element').addClassName('disabled');
+    
     this.calendars.each(function(calendar) {
       var caption = calendar.select('caption').first();
       caption.update(this.monthNames[month.getMonth()] + ' ' + month.getFullYear());
@@ -127,6 +141,11 @@ var Timeframe = Class.create({
 
       month.setMonth(month.getMonth() + 1);
     }.bind(this));
+    
+    this.latest === null || this.latest &gt; month.setDate(-1) ?
+      this.buttons.get('next').get('element').removeClassName('disabled') :
+      this.buttons.get('next').get('element').addClassName('disabled');
+    
     return this;
   },
 
@@ -274,11 +293,13 @@ var Timeframe = Class.create({
   handleButtonClick: function(event, element) {
     var el;
     var movement = this.months &gt; 1 ? this.months - 1 : 1;
-    if (element.hasClassName('next'))
-      this.date.setMonth(this.date.getMonth() + movement);
-    else if (element.hasClassName('previous'))
-      this.date.setMonth(this.date.getMonth() - movement);
-    else if (element.hasClassName('today'))
+    if (element.hasClassName('next')) {
+      if (!this.buttons.get('next').get('element').hasClassName('disabled'))
+        this.date.setMonth(this.date.getMonth() + movement);
+    } else if (element.hasClassName('previous')) {
+      if (!this.buttons.get('previous').get('element').hasClassName('disabled'))
+        this.date.setMonth(this.date.getMonth() - movement);
+    } else if (element.hasClassName('today'))
       this.date = new Date();
     else if (element.hasClassName('reset'))
       this.reset();
@@ -329,9 +350,26 @@ var Timeframe = Class.create({
     if (!this.dragging)
       this.toggleClearButton(event);
     else if (event.findElement('span.clear span.active'));
-    else if (el = event.findElement('td.selectable'))
+    else if (el = event.findElement('td.selectable')) {
+      if (el.id == this.lastDayId) {
+        this.timer = window.setInterval(function() {
+          if (!this.buttons.get('next').get('element').hasClassName('disabled')) {
+            this.date.setMonth(this.date.getMonth() + 1);
+            this.populate().refreshRange();
+          }
+        }.bind(this), this.scrollerDelay * 1000);
+      } else if (el.id == this.firstDayId) {
+        this.timer = window.setInterval(function() {
+          if (!this.buttons.get('previous').get('element').hasClassName('disabled')) {
+            this.date.setMonth(this.date.getMonth() - 1);
+            this.populate().refreshRange();
+          }
+        }.bind(this), this.scrollerDelay * 1000);
+      } else {
+        window.clearInterval(this.timer);
+      }
       this.extendRange(el.date);
-    else this.toggleClearButton(event);
+    } else this.toggleClearButton(event);
   },
 
   toggleClearButton: function(event) {
@@ -385,6 +423,8 @@ var Timeframe = Class.create({
       this.dragging = false;
       if (event.findElement('span.clear span.active'))
         this.clearRange();
+      if (this.timer)
+        clearInterval(this.timer);
     }
     this.mousedown = false;
     this.refreshRange();</diff>
      <filename>timeframe.js</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>0e138f78b531a74b916418ed6ea7f445ba1e8877</id>
    </parent>
  </parents>
  <author>
    <name>Sebastien Grosjean</name>
    <email>public@zencocoon.com</email>
  </author>
  <url>http://github.com/stephencelis/timeframe/commit/f71a3f35bf858e634146d50dea431300fed671b8</url>
  <id>f71a3f35bf858e634146d50dea431300fed671b8</id>
  <committed-date>2009-03-28T01:29:01-07:00</committed-date>
  <authored-date>2009-03-28T01:29:01-07:00</authored-date>
  <message>Limit the previous/next buttons to selectable months (between  and ). Add an elegant way to drag to months before and after the displayed calendars by rolling over the first or last day of the visible calendar while in selection mode.</message>
  <tree>870364a95970d28e795a78cf3ffd36ed12725267</tree>
  <committer>
    <name>Sebastien Grosjean</name>
    <email>public@zencocoon.com</email>
  </committer>
</commit>
