diff --git a/README.txt b/README.txt
index 5261aac..f8bdf9f 100644
--- a/README.txt
+++ b/README.txt
@@ -61,6 +61,9 @@ Credits:
   copied, thanks mattyoung).
 - The animated preloader icon for the jQuery slider widget in timelapse mode
   was generated by http://preloaders.net.
+- The use of jQuery queuing for the scrollpane animation was inspired by Ben
+  Nadel's blog post http://www.bennadel.com/blog/1864-Experimenting-With-jQuery-s-Queue-And-Dequeue-Methods.htm
+
 
 
 Themes
@@ -243,6 +246,9 @@ Drupal core pager theme variables.
   that build the pager.
 
 Advanced:
+- widget_resize: Determines if the widget width should be calculated
+  dynamically based on the width of the string of the last page/item number.
+  Set to 'false' to keep a fixed width as set by styling. Default: 'true'.
 - slider_action: Determines how the page relocation should be triggered after
   it has been selected through the jQuery slider. Options are: "tickmark"
   (page relocation only occurs after user clicks a tickmark on the slider
diff --git a/pagerer.admin.inc b/pagerer.admin.inc
index 614ed36..93ee56a 100644
--- a/pagerer.admin.inc
+++ b/pagerer.admin.inc
@@ -9,6 +9,8 @@
  * @author   mondrake <mondrake@mondrake.org>
  */
 
+// @todo manage widget_resize
+
 /**
  * Main Pagerer settings admin form.
  */
@@ -28,7 +30,7 @@ function pagerer_settings_form($form, &$form_state) {
   else {
     $js_enabled = FALSE;
     drupal_set_message(
-      t("To enable the jQuery based themes 'pagerer_mini' and 'pagerer_slider', Pagerer requires the 'jQuery update' module to be installed and enabled."),
+      t("To enable the jQuery based themes 'pagerer_mini', 'pagerer_slider' and 'pagerer_scrollpane', Pagerer requires the 'jQuery update' module to be installed and enabled."),
       'status',
       FALSE
     );
@@ -57,11 +59,12 @@ function pagerer_settings_form($form, &$form_state) {
     'none',
     'pagerer_standard',
   );
-  // Mini and Slider are only available with jQuery update installed.
+  // Mini, Slider and Scrollpane are only available with jQuery update installed.
   if ($js_enabled) {
     $options = array_merge($options, array(
         'pagerer_mini',
         'pagerer_slider',
+        'pagerer_scrollpane',
       )
     );
   }
@@ -301,7 +304,7 @@ function pagerer_pane_settings_form($form, &$form_state) {
   else {
     $js_enabled = FALSE;
     drupal_set_message(
-      t("To enable the jQuery elements 'widget' and 'slider' for current page, Pagerer requires the 'jQuery update' module to be installed and enabled."),
+      t("To enable the jQuery elements 'widget', 'slider' and 'scrollpane' for current page, Pagerer requires the 'jQuery update' module to be installed and enabled."),
       'status',
       FALSE
     );
@@ -397,9 +400,10 @@ function pagerer_pane_settings_form($form, &$form_state) {
     '#required' => TRUE,
   );
   $options = array('none', 'normal');
-  // Widget and Slider are only available with jQuery update installed.
+  // Widget, Slider and Scrollpane are only available with jQuery update
+  // installed.
   if ($js_enabled) {
-    $options = array_merge($options, array('widget', 'slider'));
+    $options = array_merge($options, array('widget', 'slider', 'scrollpane'));
   }
   $options = drupal_map_assoc($options);
   $form['display_container']['current_display'] = array(
@@ -407,7 +411,7 @@ function pagerer_pane_settings_form($form, &$form_state) {
     '#title' => t("Current page"),
     '#options' => $options,
     '#default_value' => $v['current_display'],
-    '#description' => t("Select how the current page is rendered in the pager. Options are 'none' (not displayed), 'normal' (as a text), 'widget' (an active input box from where users can enter directly a page to go to), 'slider' (as a slider)."),
+    '#description' => t("Select how the current page is rendered in the pager. Options are 'none' (not displayed), 'normal' (as a text), 'widget' (an active input box for users to enter directly a page to go to), 'slider' (as a slider), 'scrollpane' (as a scrolling pane embedding a full pager)."),
     '#required' => TRUE,
   );
   $options = drupal_map_assoc(array('none', 'after_current', 'first', 'last'));
diff --git a/pagerer.css b/pagerer.css
index 251ea17..8529838 100644
--- a/pagerer.css
+++ b/pagerer.css
@@ -98,6 +98,37 @@ div.pagerer-slider-handle-icon {
   display: inline-block;
 }
 
+/* pagerer scrollpane */
+ul.pager li.pagerer-scrollpane {
+  display: inline-block;
+  padding: 0;
+  vertical-align: middle;
+}
+/* scrollpane viewport */
+ul.pager li.pagerer-scrollpane div.item-list {
+  -moz-border-radius: 6px;
+  -webkit-border-radius: 6px;
+  border: 1px solid;
+  border-radius: 6px;
+  margin: 0;
+  overflow: hidden;
+  padding: 0;
+  position: absolute;
+}
+/* scrollpane embedded pager */
+ul.pager li.pagerer-scrollpane ul.pager {
+  /*border: dashed thin black;*/
+  margin: 0;
+  padding: 0;
+  position: absolute;
+}
+/* scrollpane embedded pager elements */
+ul.pager li.pagerer-scrollpane ul.pager li.pager-current,
+ul.pager li.pagerer-scrollpane ul.pager li.pager-item  {
+  /*border: dashed thin black;*/
+  position: absolute;
+}
+
 /* Admin */
 table.pagerer_admin_panes_config,
 table.pagerer_admin_panes_config tbody,
diff --git a/pagerer.install b/pagerer.install
index 9cda7fc..97f3833 100644
--- a/pagerer.install
+++ b/pagerer.install
@@ -16,8 +16,12 @@
  */
 function pagerer_install() {
   $t = get_t();
-  drupal_set_message($t('The Pagerer module has been installed. Visit <a href="@url">configure</a> for configuration.',
-                     array('@url' => url('admin/config/user-interface/pagerer'))));
+  drupal_set_message(
+    $t(
+      'The Pagerer module has been installed. Visit <a href="@url">configure</a> for configuration.',
+      array('@url' => url('admin/config/user-interface/pagerer'))
+    )
+  );
 }
 
 /**
diff --git a/pagerer.js b/pagerer.js
index 2a4b360..69f35e8 100644
--- a/pagerer.js
+++ b/pagerer.js
@@ -3,23 +3,74 @@
  *
  * Pagerer jquery scripts.
  *
+ * @todo - document
+ * pagererState
+ * path: drupal *request* path inclusive of querystring fragment, no base path
+ * element: integer to distinguish between multiple pagers on one page
+ * quantity: number of page elements in the pager list
+ * total: total number of pages in the query
+ * totalItems: total number of items in the query
+ * current: 0-base index of current page
+ * interval: number of elements per page (1 if display = pages, items per page if display = items/item_ranges
+ * display: pages|items|item_ranges indicates what is displayed in the page element
+ * action:
+ * timelapse:
+ * icons:
+ * tickmarkTitle:
+ * pageTitle:
+ * firstTitle:
+ * lastTitle:
+ * rangeSeparator:
+ *
+ * @todo
+ * Scrollpane -
+ * - acceleration of shift
+ * - goto first/last if not enough elements
+ * - items_ranges anchor width
+ * - left margin in pagererstate useless?
+ * - queue only click to same button
+ * - anchors in views ajax
+ * Slider -
+ * - slider handle width with item ranges
+ * - move spinInterval to settings
  */
 (function ($) {
 
+Drupal.settings.pagerer = {
+  timeoutAction: 0,
+  intervalAction: 0,
+  intervalCount: 0,
+  isRelocating: false,
+}
+
 Drupal.behaviors.pagerer = {
 
   attach: function(context, settings) {
 
     /**
+     * Constants.
+     */
+    var PAGERER_LEFT = -1;
+    var PAGERER_RIGHT = 1;
+
+    /**
      * 'pagerer-page' input box event binding
      */
     $('.pagerer-page', context)
     .ready().each(function(index) {
+      Drupal.settings.pagerer.isRelocating = false;
       this.pagererState = eval('(' + $(this).attr('name') + ');');
+      // Item ranges do not really work on widget.
+      if (this.pagererState.display == 'item_ranges') {
+        this.pagererState.display = 'items';
+      }
       // Adjust width of the input box.
-      $(this).width(String(this.pagererState.total).length + 'em');
+      if (this.pagererState.widgetResize) {
+        $(this).width(String(indexToValue(this.pagererState.total - 1, this.pagererState)).length + 'em');
+      }
     })
     .bind('focus', function(event) {
+      clearDelayedAction();
       this.select();
       $(this).addClass('pagerer-page-has-focus');
     })
@@ -30,52 +81,37 @@ Drupal.behaviors.pagerer = {
       switch(event.keyCode) {
         case 13:
         case 10:
-          // Return key pressed.
-          var newPage;
-          // Determine destination page.
-          if (this.pagererState.display == 'pages') {
-            newPage = isNaN($(this).val()) ? 0 : parseInt($(this).val()) - 1;
-            if (newPage < 0) {
-              newPage = 0;
-            } else if (newPage >= this.pagererState.total) {
-              newPage = this.pagererState.total - 1;
-            }
-          } else {
-            var item = isNaN($(this).val()) ? 0 : parseInt($(this).val()) - 1;
-            if (item < 0) {
-              item = 0;
-            } else if (item >= this.pagererState.total) {
-              item = this.pagererState.total - 1;
-            }
-            newPage = parseInt(item / parseInt(this.pagererState.interval));
+          // Return key pressed, relocate.
+          var targetPage = valueToIndex($(this).val(), this.pagererState);
+          if (targetPage != this.pagererState.current) {
+            pagererRelocate(this, this, targetPage);
           }
-          pagererRelocate(this, this, this.pagererState.path.replace(/pagererpage/, newPage));
           event.stopPropagation();
           event.preventDefault();
           return false;
         case 27:
           // Escape.
-           $(this).val(this.pagererState.current);
+          $(this).val(indexToValue(this.pagererState.current, this.pagererState));
           return false;
         case 38:
           // Up.
-          pagererOffsetWidgetValue(this, -1);
+          widgetOffsetValue(this, -1);
           return false;
         case 40:
           // Down.
-          pagererOffsetWidgetValue(this, 1);
+          widgetOffsetValue(this, 1);
           return false;
         case 33:
           // Page up.
-          pagererOffsetWidgetValue(this, -5);
+          widgetOffsetValue(this, -5);
           return false;
         case 34:
           // Page down.
-          pagererOffsetWidgetValue(this, 5);
+          widgetOffsetValue(this, 5);
           return false;
         case 35:
           // End.
-           $(this).val(this.pagererState.total);
+           $(this).val(indexToValue(this.pagererState.total - 1, this.pagererState));
           return false;
         case 36:
           // Home.
@@ -87,46 +123,48 @@ Drupal.behaviors.pagerer = {
     /**
      * 'pagerer-slider' jQuery UI slider event binding.
      */
-    var actionInterval = 0;
     $('.pagerer-slider', context)
     .ready().each(function(index) {
+      Drupal.settings.pagerer.isRelocating = false;
       this.pagererState = eval('(' + $(this).attr('id') + ');');
 
       // Create slider.
       var sliderBar = $(this);
-      sliderBar.slider({ min : 1, range : 'min', animate: true });
-      var sliderHandle = $(this).find('.ui-slider-handle');
+      sliderBar.slider({
+        min: 0,
+        max: this.pagererState.total - 1,
+        step: 1,
+        value: this.pagererState.current,
+        range: 'min',
+        animate: true,
+      });
 
-      // Adjust slider handle width and current page.
+      // Adjust slider handle dimensions and text.
+      var sliderHandle = sliderBar.find('.ui-slider-handle');
       sliderHandle
-        .width((String(this.pagererState.total).length + 2) + 'em')
+        .css('width', (String(indexToValue(this.pagererState.total - 1, this.pagererState)).length + 2) + 'em')
         .css('height', Math.max(sliderHandle.height(), 16) + 'px')
         .css('line-height', Math.max(sliderHandle.height(), 16) + 'px')
         .css('margin-left', -sliderHandle.width() / 2)
-        .text(this.pagererState.current)
+        .text(indexToValue(this.pagererState.current, this.pagererState))
         .bind('blur', function(event) {
-          if (actionInterval) {
-            clearTimeout(actionInterval);
-          }
-          var sliderBar = $(this).parent();
-          if (!sliderBar[0].pagererState.spinning) {
-            sliderBar[0].pagererState.spinning = true;
-            sliderBar.slider('option', 'value', sliderBar[0].pagererState.current);
-            $(this).text(sliderBar[0].pagererState.current);
-            sliderBar[0].pagererState.spinning = false;
+          clearDelayedAction();
+          var sliderBar = $(this).parent().get(0);
+          if (!sliderBar.pagererState.spinning) {
+            sliderBar.pagererState.spinning = true;
+            $(sliderBar).slider('option', 'value', sliderBar.pagererState.current);
+            $(this).text(indexToValue(sliderBar.pagererState.current, sliderBar.pagererState));
+            sliderBar.pagererState.spinning = false;
           }
         });
 
-      // Adjust slider bar options and width.
+      // Set slider bar dimensions.
       sliderBar
-        .slider('option', 'max', this.pagererState.total)
-        .slider('option', 'value', this.pagererState.current)
-        .slider('option', 'step', this.pagererState.interval)
         .width((this.pagererState.quantity * 3) + 'em')
         .css('margin-left', sliderHandle.width() / 2)
         .css('margin-right', sliderHandle.width() / 2);
 
-      var pixelsPerStep = sliderBar.width() / (this.pagererState.total / this.pagererState.interval);
+      var pixelsPerStep = sliderBar.width() / this.pagererState.total;
       // If autodetection of navigation action, determine whether to
       // use tickmark or timelapse.
       if (this.pagererState.action == 'auto') {
@@ -141,23 +179,21 @@ Drupal.behaviors.pagerer = {
       if (this.pagererState.icons == 'auto' && pixelsPerStep > 3) {
         $(this).parents('.pager').find('.pagerer-slider-control-icon').parent().hide();
       }
-      // Add indication to click on the tickmark to start page
+      // Add information to user to click on the tickmark to start page
       // relocation.
       if (this.pagererState.action == 'tickmark') {
         var title = $(this).attr('title');
-        $(this).attr('title',  title + ' ' + this.pagererState.tickmark_title);
+        $(this).attr('title',  title + ' ' + this.pagererState.tickmarkTitle);
       }
     })
     .bind('slide', function(event, ui) {
-      if (actionInterval) {
-        clearTimeout(actionInterval);
-      }
-      $(this).find('.ui-slider-handle').text(ui.value);
+      clearDelayedAction();
+      $(this).find('.ui-slider-handle').text(indexToValue(ui.value, this.pagererState));
     })
     .bind('slidechange', function(event, ui) {
 
       var sliderHandle = $(this).find('.ui-slider-handle');
-      sliderHandle.text(ui.value);
+      sliderHandle.text(indexToValue(ui.value, this.pagererState));
 
       // If currently sliding the handle via navigation icons,
       // do nothing.
@@ -166,27 +202,20 @@ Drupal.behaviors.pagerer = {
       }
 
       // Determine target page.
-      var currVal = $(this).slider('option', 'value');
-      var newPage;
-      if (this.pagererState.display == 'pages') {
-        newPage = currVal - 1;
-      } else {
-        newPage = parseInt(currVal / parseInt(this.pagererState.interval));
-      }
+      var targetPage = $(this).slider('option', 'value');
 
       // Relocate immediately to target page if no
       // tickmark/timelapse confirmation required.
       if (this.pagererState.action == 'timelapse' && this.pagererState.timelapse == 0) {
         sliderHandle.append("<div class='pagerer-slider-handle-icon'/>");
         var sliderHandleIcon = sliderHandle.find('.pagerer-slider-handle-icon');
-        pagererRelocate(this, sliderHandleIcon, this.pagererState.path.replace(/pagererpage/, newPage));
+        pagererRelocate(this, sliderHandleIcon, targetPage);
         return false;
       }
 
       // Otherwise, add a tickmark or clock icon to the handle text,
       // to be clicked to activate page relocation.
-      var sliderBar = $(this);
-      sliderHandle.text(ui.value + ' ');
+      sliderHandle.text(indexToValue(ui.value, this.pagererState) + ' ');
       if (this.pagererState.action == 'timelapse') {
         sliderHandle.append("<div class='pagerer-slider-handle-icon throbber'/>");
       } else {
@@ -194,28 +223,24 @@ Drupal.behaviors.pagerer = {
       }
 
       // Bind page relocation to mouse clicking on the icon.
+      var sliderBar = this;
       var sliderHandleIcon = sliderHandle.find('.pagerer-slider-handle-icon');
       sliderHandleIcon.bind('mousedown', function(event) {
-        if (actionInterval) {
-          clearTimeout(actionInterval);
-        }
+        clearDelayedAction();
         // Remove icon.
-        $(sliderBar[0]).find('.pagerer-slider-handle-icon').removeClass('throbber');
+        $(sliderBar).find('.pagerer-slider-handle-icon').removeClass('throbber');
         // Relocate.
-        pagererRelocate(sliderBar[0], sliderHandleIcon, sliderBar[0].pagererState.path.replace(/pagererpage/, newPage));
+        pagererRelocate(sliderBar, sliderHandleIcon, targetPage);
         return false;
       });
 
       // Bind page relocation to timeout of timelapse.
       if (this.pagererState.action == 'timelapse') {
-        if (actionInterval) {
-          clearTimeout(actionInterval);
-        }
-        actionInterval = setTimeout(function(){
+        setDelayedAction(function() {
           // Remove icon.
-          $(sliderBar[0]).find('.pagerer-slider-handle-icon').removeClass('ui-icon').removeClass('throbber');
+          $(sliderBar).find('.pagerer-slider-handle-icon').removeClass('ui-icon').removeClass('throbber');
           // Relocate.
-          pagererRelocate(sliderBar[0], sliderHandleIcon, sliderBar[0].pagererState.path.replace(/pagererpage/, newPage));
+          pagererRelocate(sliderBar, sliderHandleIcon, targetPage);
           return false;
         }, this.pagererState.timelapse);
       }
@@ -231,44 +256,543 @@ Drupal.behaviors.pagerer = {
       * slider handle will move continuosly. When mouse is released or moved
       * away from the icon, sliding will stop and the handle status will be
       * processed through slider 'slidechange' event triggered by the
-      * pagererOffsetSliderValue() function.
+      * sliderOffsetValue() function.
       */
     var spinInterval = 0;
     var spinIdleCycles = 0;
     // Spin events.
     $('.pagerer-slider-control-icon', context)
     .bind('mousedown', function(event) {
-      if (actionInterval) {
-        clearTimeout(actionInterval);
-      }
-      var slider = $(this).parents('.pager').find('.pagerer-slider');
-      slider[0].pagererState.spinning = true;
-      var offset = $(this).hasClass('ui-icon-circle-minus') ? -1 : 1;
-      pagererOffsetSliderValue(slider, offset);
+      clearDelayedAction();
+      var slider = $(this).parents('.pager').find('.pagerer-slider').get(0);
+      slider.pagererState.spinning = true;
+      var offset = $(this).hasClass('ui-icon-circle-minus') ? PAGERER_LEFT : PAGERER_RIGHT;
+      sliderOffsetValue(slider, offset);
       spinInterval = setInterval(function(){
         spinIdleCycles++;
         if (spinIdleCycles > 10) {
-          pagererOffsetSliderValue(slider, offset);
+          sliderOffsetValue(slider, offset);
         }
       }, 50);
     })
     .bind('mouseup mouseleave', function() {
-      var slider = $(this).parents('.pager').find('.pagerer-slider');
-      if (slider[0].pagererState.spinning) {
+      var slider = $(this).parents('.pager').find('.pagerer-slider').get(0);
+      if (slider.pagererState.spinning) {
         spinIdleCycles = 0;
         clearInterval(spinInterval);
-        slider[0].pagererState.spinning = false;
-        pagererOffsetSliderValue(slider, 0);
-        slider.find('.ui-slider-handle').focus();
+        slider.pagererState.spinning = false;
+        sliderOffsetValue(slider, 0);
+        $(slider).find('.ui-slider-handle').focus();
+      }
+    });
+
+    /**
+     * 'pagerer-scrollpane' event binding.
+     */
+    $('.pagerer-scrollpane', context)
+    .ready().each(function(index) {
+      Drupal.settings.pagerer.isRelocating = false;
+
+      // Get the scrollpane components, i.e. the viewport, the
+      // pager wrapped within it, and the wrapped pager elements.
+      var viewport = $(this).find('.item-list');
+      var pager = $(this).find('.pager').get(0);
+      var pagerElements = $(this).find('li');
+
+      // Attach state variables to the wrapped pager.
+      pager.pagererState = eval('(' + $(this).attr('id') + ');');
+      $.extend(pager.pagererState, {
+        scrollpane: $(this),
+        viewport: viewport,
+        pagerElementWidth: 0,
+        pagerElementLeftMargin: 0,
+        pagerElementsLeftOverflow: 0,
+        pagerElementsRightOverflow: 0,
+      });
+
+      // Determine pager element width from maximum width possible.
+      var dupe = $(pagerElements[0]).clone();
+      dupe.removeClass('pager-current first last');
+      dupe.addClass('pager-item pagerer-dupe');
+      dupe.text(indexToValue(pager.pagererState.total - 1, pager.pagererState));
+      $(pager).append(dupe);
+      pager.pagererState.pagerElementWidth = Math.ceil($(dupe).outerWidth(true));
+      pager.pagererState.pagerElementLeftMargin = parseInt($(dupe).css('margin-left'))
+      var cellHeight = Math.ceil($(dupe).outerHeight(true));
+      $(pager).find('.pagerer-dupe').remove();
+
+      // Set dimensions.
+      var pagerWidth = pagerElements.length * pager.pagererState.pagerElementWidth;
+      var viewportWidth = Math.min(pager.pagererState.quantity * pager.pagererState.pagerElementWidth, pagerWidth);
+      $(this).css({
+        width: viewportWidth + 'px',
+        height: cellHeight + 'px',
+      });
+      $(viewport).css({
+        width: viewportWidth + 'px',
+        height: cellHeight + 'px',
+      });
+      $(pager).css({
+        width: pagerWidth + 'px',
+        height: cellHeight + 'px',
+      });
+
+      // Allocate input pager elements to pager.
+      var elementLeft = 0;
+      var pagerCurrentElement = 0;
+      pagerElements.each(function(index) {
+        var elementWidth = $(this).outerWidth(true);
+        var elementLeftMargin = pager.pagererState.pagerElementLeftMargin + ((pager.pagererState.pagerElementWidth - elementWidth) / 2);
+        $(this).css('left', elementLeft + 'px');
+        $(this).css('margin-left', elementLeftMargin + 'px');
+        if ($(this).hasClass('pager-current')) {
+          pagerCurrentElement = index;
+        }
+        elementLeft += pager.pagererState.pagerElementWidth;
+      });
+
+      // Set current item in the middle of the viewport.
+      var pagerLeftElement = pagerCurrentElement - Math.floor(pager.pagererState.quantity / 2);
+      if (pagerLeftElement < 0) {
+        pagerLeftElement = 0;
+      } else if (pagerLeftElement >  pagerElements.length - pager.pagererState.quantity) {
+        pagerLeftElement = pagerElements.length - pager.pagererState.quantity;
+      }
+      var pagerLeftOffset = $(pagerElements[pagerLeftElement]).css('left');
+      $(pager).css('left', '-' + pagerLeftOffset);
+
+      // Add elements to the left.
+      pager.pagererState.pagerElementsLeftOverflow = scrollpaneAddPagerElements(
+        pager,
+        PAGERER_LEFT,
+        valueToIndex($(pagerElements[0]).text(), pager.pagererState) - 1,
+        pager.pagererState.quantity,
+        true
+      );
+
+      // Add elements to the right.
+      pagerElements = $(this).find('li');
+      pager.pagererState.pagerElementsRightOverflow = scrollpaneAddPagerElements(
+        pager,
+        PAGERER_RIGHT,
+        valueToIndex($(pagerElements[pagerElements.length - 1]).text(), pager.pagererState) + 1,
+        pager.pagererState.quantity,
+        true
+      );
+
+    });
+
+    /**
+     * todo
+     */
+    $('.pagerer-scrollpane-button', context)
+    .ready().each(function(index) {
+      this.pagererState = {
+        scrollpane: $(this).parents('.pager').get(0),
+        pager: $(this).parents('.pager').find('.pagerer-scrollpane').find('.item-list').find('.pager').get(0),
+      };
+      $(this).button();
+      $(this)
+      .bind('mousedown', function(event) {
+        var button = this;
+        clearDelayedAction();
+        pagererQueueTransition(button.pagererState.pager, function(){scrollpaneButtonProcess(button, 500);}, 510);
+        if ($(button).hasClass('pagerer-previous') || $(button).hasClass('pagerer-next')) {
+          Drupal.settings.pagerer.intervalAction = setInterval(function(){
+            Drupal.settings.pagerer.intervalCount++;
+            if (Drupal.settings.pagerer.intervalCount > 20) {
+              pagererQueueTransition(button.pagererState.pager, function(){scrollpaneButtonProcess(button, 20);}, 30);
+            }
+          }, 25);
+        }
+        event.stopPropagation();
+        event.preventDefault();
+      })
+      .bind('mouseup mouseleave', function(event) {
+        Drupal.settings.pagerer.intervalCount = 0;
+        clearInterval(Drupal.settings.pagerer.intervalAction);
+      })
+    })
+    .load().each(function(index) {
+      // Aligns viewport border color to button style.
+      if ($(this).hasClass('pagerer-first')) {
+        this.pagererState.pager.pagererState.viewport.css({
+          'border-color' : $(this).css('border-color'),
+        });
       }
+      // Set button enable/disabled state.
+      scrollpaneSetButtonState(this);
     });
 
+    /**
+     * Todo.
+     */
+    function scrollpaneButtonProcess(button, duration) {
+      var pager = button.pagererState.pager;
+      var pagerElements = $(pager).find('li');
+      if ($(button).hasClass('pagerer-next')) {
+        // ***** Next - shift left.
+        var last = valueToIndex($(pagerElements[pagerElements.length - 1]).text(), pager.pagererState);
+        if (pager.pagererState.pagerElementsLeftOverflow < pager.pagererState.quantity) {
+          // There's space on the left side to shift pager.
+          if (scrollpaneAddPagerElements(pager, PAGERER_RIGHT, last + 1, 1, true)) {
+            // An element was added to the right, so shift pager to the left.
+            scrollpaneShiftPager(pager, PAGERER_LEFT, 1, duration, +1, -1);
+          } else {
+            // No further elements on the right, end of run.
+            return false;
+          }
+        } else {
+          // No space on the left side to shift pager.
+          if (scrollpaneAddPagerElements(pager, PAGERER_RIGHT, last + 1, 1, false)) {
+            // An element was added to the right, so shift elements to the left.
+            scrollpaneRemovePagerElements(pager, PAGERER_LEFT, 1, false);
+            scrollpaneShiftPagerElements(pager, PAGERER_LEFT, 1, duration, +1, -1);
+          } else {
+            // End of run to the right. If pager allows, shift it.
+            if (pager.pagererState.pagerElementsRightOverflow > 0) {
+              scrollpaneRemovePagerElements(pager, PAGERER_LEFT, 1, true);
+              scrollpaneShiftPager(pager, PAGERER_LEFT, 1, duration, +1, -1);
+            } else {
+              // End of run, can't move.
+              return false;
+            }
+          }
+        }
+        $(button.pagererState.scrollpane).find('.ui-button').each(function() {
+          scrollpaneSetButtonState(this);
+        });
+      } else if ($(button).hasClass('pagerer-previous')) {
+        // ***** Previous - shift right.
+        var first = valueToIndex($(pagerElements[0]).text(), pager.pagererState);
+        if (pager.pagererState.pagerElementsRightOverflow < pager.pagererState.quantity) {
+          // There's space on the right side to shift pager.
+          if (scrollpaneAddPagerElements(pager, PAGERER_LEFT, first - 1, 1, true)) {
+            // An element was added to the left, so shift pager to the right.
+            scrollpaneShiftPager(pager, PAGERER_RIGHT, 1, duration, -1, +1);
+          } else {
+            // No further elements on the left, end of run.
+            return false;
+          }
+        } else {
+          // No space on the right side to shift pager.
+          if (scrollpaneAddPagerElements(pager, PAGERER_LEFT, first - 1, 1, false)) {
+            // An element was added to the left, so shift elements to the right.
+            scrollpaneRemovePagerElements(pager, PAGERER_RIGHT, 1, false);
+            scrollpaneShiftPagerElements(pager, PAGERER_RIGHT, 1, duration, -1, +1);
+          } else {
+            // End of run to the left. If pager allows, shift it.
+            if (pager.pagererState.pagerElementsLeftOverflow > 0) {
+              scrollpaneRemovePagerElements(pager, PAGERER_RIGHT, 1, true);
+              scrollpaneShiftPager(pager, PAGERER_RIGHT, 1, duration, -1, +1);
+            } else {
+              // End of run, can't move.
+              return false;
+            }
+          }
+        }
+        $(button.pagererState.scrollpane).find('.ui-button').each(function() {
+          scrollpaneSetButtonState(this);
+        });
+      } else if ($(button).hasClass('pagerer-first')) {
+        var first = valueToIndex($(pagerElements[0]).text(), pager.pagererState);
+        var fromEl = Math.min((pager.pagererState.quantity * 2), first);
+        var count = fromEl + 1;
+        scrollpaneAddPagerElements(pager, PAGERER_LEFT, fromEl, count, true);
+        scrollpaneShiftPager(pager, PAGERER_RIGHT, pager.pagererState.pagerElementsLeftOverflow, duration, -pager.pagererState.pagerElementsLeftOverflow, pager.pagererState.pagerElementsLeftOverflow);
+        setTimeout(function() {
+//console.log(pager.pagererState.pagerElementsLeftOverflow - pager.pagererState.quantity);
+          scrollpaneRemovePagerElements(pager, PAGERER_RIGHT, pager.pagererState.pagerElementsRightOverflow - pager.pagererState.quantity, true);
+          $(button.pagererState.scrollpane).find('.ui-button').each(function() {
+            scrollpaneSetButtonState(this);
+          });
+        }, duration + 5);
+      } else if ($(button).hasClass('pagerer-last')) {
+        // ***** Last.
+        var last = valueToIndex($(pagerElements[pagerElements.length - 1]).text(), pager.pagererState);
+        var fromEl = Math.max((pager.pagererState.total - (pager.pagererState.quantity * 2) + 1), last);
+        var count = pager.pagererState.total - fromEl + 1;
+        scrollpaneAddPagerElements(pager, PAGERER_RIGHT, fromEl, count, true);
+        pagerElements = $(pager).find('li');
+        scrollpaneShiftPager(pager, PAGERER_LEFT, pagerElements.length - pager.pagererState.pagerElementsLeftOverflow - pager.pagererState.quantity, duration, pager.pagererState.pagerElementsRightOverflow, -pager.pagererState.pagerElementsRightOverflow);
+        setTimeout(function() {
+//console.log(pager.pagererState.pagerElementsLeftOverflow - pager.pagererState.quantity);
+          scrollpaneRemovePagerElements(pager, PAGERER_LEFT, pager.pagererState.pagerElementsLeftOverflow - pager.pagererState.quantity, true);
+          $(button.pagererState.scrollpane).find('.ui-button').each(function() {
+            scrollpaneSetButtonState(this);
+          });
+        }, duration + 5);
+      }
+    }
+
+    /**
+     * Todo.
+     */
+    function scrollpaneAddPagerElements(pager, side, start, count, pagerResize) {
+console.log('add start: ' + pager.pagererState.pagerElementsLeftOverflow + ' ' + pager.pagererState.pagerElementsRightOverflow);
+console.log('side: ' + side + ' count: ' + count + ' start: ' + start);
+      for (var i = 0; i < count; i++) {
+        var pagerElements = $(pager).find('li');
+        if (side == PAGERER_RIGHT) {
+          var last = pagerElements.length - 1;
+          if (valueToIndex($(pagerElements[last]).text(), pager.pagererState) == (pager.pagererState.total - 1)) {
+            break;
+          }
+          var dupe = $(pagerElements[last]).clone();
+          $(pagerElements[last]).removeClass('last');
+          $(dupe).css('left', (parseInt($(dupe).css('left')) + pager.pagererState.pagerElementWidth) + 'px');
+          scrollpaneSetPagerElementHTML(dupe, pager, start + i);
+          $(pager).append(dupe);
+          var elementWidth = $(dupe).outerWidth(true);
+          var elementLeftMargin = pager.pagererState.pagerElementLeftMargin + ((pager.pagererState.pagerElementWidth - elementWidth) / 2);
+          $(dupe).css('margin-left', elementLeftMargin + 'px');
+          pager.pagererState.pagerElementsRightOverflow++;
+        } else if (side == PAGERER_LEFT) {
+          var first = 0;
+          if (valueToIndex($(pagerElements[first]).text(), pager.pagererState) == 0) {
+            break;
+          }
+          var dupe = $(pagerElements[first]).clone();
+          $(pagerElements[first]).removeClass('first');
+          $(dupe).css('left', (parseInt($(dupe).css('left')) - pager.pagererState.pagerElementWidth) + 'px');
+          scrollpaneSetPagerElementHTML(dupe, pager, start - i);
+          $(pager).prepend(dupe);
+          var elementWidth = $(dupe).outerWidth(true);
+          var elementLeftMargin = pager.pagererState.pagerElementLeftMargin + ((pager.pagererState.pagerElementWidth - elementWidth) / 2);
+          $(dupe).css('margin-left', elementLeftMargin + 'px');
+          pager.pagererState.pagerElementsLeftOverflow++;
+        }
+      }
+console.log('add (' + i + '): ' + pager.pagererState.pagerElementsLeftOverflow + ' ' + pager.pagererState.pagerElementsRightOverflow);
+      if (pagerResize) {
+        pagerElements = $(pager).find('li');
+        $(pager).css('width', ((pagerElements.length) * pager.pagererState.pagerElementWidth) + 'px');
+        if (side == PAGERER_LEFT) {
+          $(pager).css({
+            left: (parseInt($(pager).css('left')) - (pager.pagererState.pagerElementWidth * i)) + 'px',
+            '-webkit-transition-property': 'none',
+          });
+          scrollpaneShiftPagerElements(pager, PAGERER_RIGHT, i, 0, 0, 0);
+        }
+      }
+      return i;
+    }
+
+    /**
+     * Todo.
+     */
+    function scrollpaneRemovePagerElements(pager, side, count, pagerResize) {
+//alert('remove start: ' + pager.pagererState.pagerElementsLeftOverflow + ' ' + pager.pagererState.pagerElementsRightOverflow);
+      for (var i = 0; i < count; i++) {
+        var pagerElements = $(pager).find('li');
+        if (side == PAGERER_RIGHT) {
+          $(pagerElements[pagerElements.length - 1]).remove();
+          $(pagerElements[pagerElements.length - 1]).addClass('first');
+          pager.pagererState.pagerElementsRightOverflow--;
+        } else if (side == PAGERER_LEFT) {
+          $(pagerElements[0]).remove();
+          $(pagerElements[0]).addClass('first');
+          pager.pagererState.pagerElementsLeftOverflow--;
+        }
+      }
+//alert('remove (' + i + '); ' + pager.pagererState.pagerElementsLeftOverflow + ' ' + pager.pagererState.pagerElementsRightOverflow);
+      if (pagerResize) {
+        $(pager).css('width', ((pagerElements.length - 1) * pager.pagererState.pagerElementWidth) + 'px');
+        if (side == PAGERER_LEFT) {
+          $(pager).css({
+            left: (parseInt($(pager).css('left')) + (pager.pagererState.pagerElementWidth * count)) + 'px',
+            '-webkit-transition-property': 'none',
+          });
+          scrollpaneShiftPagerElements(pager, PAGERER_LEFT, i, 0, 0, 0);
+        }
+      }
+      return true;
+    }
+
+    /**
+     * Todo.
+     */
+    function scrollpaneShiftPagerElements(pager, direction, count, duration, xxxload, xxxroad) {
+      var pagerElements = $(pager).find('li');
+      pagerElements.each(function(index) {
+        $(this).css({
+          left: (parseInt($(this).css('left')) + (direction * pager.pagererState.pagerElementWidth * count)) + 'px',
+          '-webkit-transition-property': 'left',
+          '-webkit-transition-duration': duration + 'ms'
+        });
+      });
+      pager.pagererState.pagerElementsLeftOverflow += xxxload;
+      pager.pagererState.pagerElementsRightOverflow += xxxroad;
+    }
+
+    /**
+     * Todo.
+     */
+    function scrollpaneShiftPager(pager, direction, count, duration, xxxload, xxxroad) {
+      var left = parseInt($(pager).css('left'));
+      var offset = direction * count * pager.pagererState.pagerElementWidth;
+      $(pager).css({
+        left: (left + offset) + 'px',
+        '-webkit-transition-property': 'left',
+        '-webkit-transition-duration': duration + 'ms',
+      });
+      pager.pagererState.pagerElementsLeftOverflow += xxxload;
+      pager.pagererState.pagerElementsRightOverflow += xxxroad;
+    };
+
+    /**
+     * Todo.
+     */
+    function scrollpaneSetPagerElementHTML(element, pager, targetPage) {
+      if (targetPage == pager.pagererState.current) {
+        $(element[0]).removeClass('pager-item').addClass('pager-current');
+        $(element[0]).text(indexToValue(targetPage, pager.pagererState));
+      } else {
+        $(element[0]).removeClass('pager-current').addClass('pager-item');
+        var anchor = $(element).find('a');
+        if (!anchor.length) {
+          $(element).text('');
+          $(element).append('<a></a>');
+          anchor = $(element).find('a');
+        }
+        anchor[0].href = Drupal.settings.basePath + pager.pagererState.path.replace(/pagererpage/, targetPage);
+        anchor[0].title = Drupal.t('Go to page @number', { '@number': targetPage + 1});
+        $(anchor[0]).text(indexToValue(targetPage, pager.pagererState));
+      }
+    }
+
+    /**
+     * Todo.
+     */
+    function scrollpaneSetButtonState(elem) {
+      if ($(elem).hasClass('pagerer-first') || $(elem).hasClass('pagerer-previous')) {
+        if (elem.pagererState.pager.pagererState.pagerElementsLeftOverflow == 0) {
+          $(elem).mouseup().mouseleave();
+          $(elem).button('disable');
+        } else {
+          $(elem).button('enable');
+        }
+      }
+      if ($(elem).hasClass('pagerer-next') || $(elem).hasClass('pagerer-last')) {
+        if (elem.pagererState.pager.pagererState.pagerElementsRightOverflow == 0) {
+          $(elem).mouseup().mouseleave();
+          $(elem).button('disable');
+        } else {
+          $(elem).button('enable');
+        }
+      }
+    }
+
 
     /**
      * Helper functions
      */
 
     /**
+     * Todo.
+     */
+    function indexToValue(index, state) {
+      switch(state.display) {
+        case 'pages':
+          return index + 1;
+          break;
+
+        case 'items':
+          return (index * state.interval) + 1;
+          break;
+
+        case 'item_ranges':
+          return Drupal.t('@min@separator@max', {
+            '@min': (index * state.interval) + 1,
+            '@separator': state.rangeSeparator,
+            '@max': Math.min(((index + 1) * state.interval), state.totalItems),
+          });
+          break;
+
+      }
+    }
+
+    /**
+     * Todo.
+     */
+    function valueToIndex(value, state) {
+      switch(state.display) {
+        case 'pages':
+          if (isNaN(value)) {
+            return 0;
+          }
+          value = parseInt(value);
+          if (value < 1) {
+            return 0;
+          }
+          if (value > state.total) {
+            value = state.total;
+          }
+          return value - 1;
+          break;
+
+        case 'items':
+          if (isNaN(value)) {
+            return 0;
+          }
+          value = parseInt(value);
+          if (value < 1) {
+            return 0;
+          }
+          if (value > state.totalItems) {
+            value = state.totalItems;
+          }
+          return parseInt((value - 1) / state.interval);
+          break;
+
+        case 'item_ranges':
+          var values = value.split(state.rangeSeparator);
+          value = values[0];
+          if (isNaN(value)) {
+            return 0;
+          }
+          value = parseInt(value);
+          if (value < 1) {
+            return 0;
+          }
+          if (value > state.totalItems) {
+            value = state.totalItems;
+          }
+          return parseInt((value - 1) / state.interval);
+          break;
+
+      }
+    }
+
+    /**
+     * Todo.
+     */
+    function pagererQueueTransition(element, action, delay) {
+        $(element).queue(function(next) {
+          action();
+          next();
+        });
+        $(element).delay(delay);
+    }
+
+    /**
+     * Todo.
+     */
+    function setDelayedAction(action, delay) {
+      clearDelayedAction();
+      Drupal.settings.pagerer.timeoutAction = setTimeout(action, delay);
+    }
+
+    /**
+     * Todo.
+     */
+    function clearDelayedAction() {
+      if (Drupal.settings.pagerer.timeoutAction) {
+        clearTimeout(Drupal.settings.pagerer.timeoutAction);
+      }
+    }
+
+    /**
      * Relocate client browser to target page.
      *
      * Relocation method is decided based on the context of the pager element,
@@ -278,19 +802,23 @@ Drupal.behaviors.pagerer = {
      *  - a page rendered through the admin overlay - BBQ is used
      *  - a normal page - document.location is used
      */
-    function pagererRelocate(element, ajaxAttachElement, path) {
+    function pagererRelocate(element, ajaxAttachElement, targetPage) {
       // Check we are not relocating already.
-      if (element.pagererState.relocating) {
+      if (Drupal.settings.pagerer.isRelocating) {
         return false;
-      } else {
-        element.pagererState.relocating = true;
       }
+      Drupal.settings.pagerer.isRelocating = true;
+
+      // Replace placeholder with page target.
+      var path = element.pagererState.path.replace(/pagererpage/, targetPage);
+
       // Check if element is in Views AJAX context.
-      var viewsAjaxContext = pagererInViewsAjaxContext(element);
+      var viewsAjaxContext = getViewsAjaxContext(element);
       if (viewsAjaxContext) {
         // Element is in Views AJAX context.
-        pagererAttachViewsAjax(ajaxAttachElement, 'doViewsAjax', viewsAjaxContext, path);
+        attachViewsAjax(ajaxAttachElement, 'doViewsAjax', viewsAjaxContext, path);
         $(ajaxAttachElement).trigger('doViewsAjax');
+
       } else if ($(element).parents('#views-live-preview').length) {
         // Element is in Views preview context.
         var base = $(element).attr('id');
@@ -307,42 +835,43 @@ Drupal.behaviors.pagerer = {
       } else if (window.Drupal.overlayChild) {
         // Drupal admin overlay
         window.parent.jQuery.bbq.pushState({'overlay': path});
+
       } else {
         // Normal page
         document.location = Drupal.settings.basePath + path;
+
       }
     };
 
     /**
      * Update widget value.
      */
-    function pagererOffsetWidgetValue(widget, offset) {
-      var widgetValue = isNaN($(widget).val()) ? 1 : parseInt($(widget).val());
-      widgetValue += offset * widget.pagererState.interval;
-      if (widgetValue < 1) {
-        widgetValue = 1;
-      } else if (widgetValue > widget.pagererState.total){
-        widgetValue = widget.pagererState.total;
+    function widgetOffsetValue(element, offset) {
+      var widgetValue = valueToIndex($(element).val(), element.pagererState);
+      var newValue = widgetValue + offset;
+      if (newValue < 0) {
+        newValue = 0;
+      } else if (newValue >= element.pagererState.total) {
+        newValue = element.pagererState.total - 1;
       }
-      $(widget).val(widgetValue);
+      $(element).val(indexToValue(newValue, element.pagererState));
     };
 
     /**
      * Update slider value.
      */
-    function pagererOffsetSliderValue(ui, offset) {
-      var step = ui.slider('option', 'step');
-      var newValue = ui.slider('option', 'value') + (offset * step);
-      var maxValue = ui.slider('option', 'max');
-      if (newValue > 0 && newValue <= maxValue) {
-        ui.slider('option', 'value', newValue);
+    function sliderOffsetValue(element, offset) {
+      var newValue = $(element).slider('option', 'value') + offset;
+      var maxValue = $(element).slider('option', 'max');
+      if (newValue >= 0 && newValue <= maxValue) {
+        $(element).slider('option', 'value', newValue);
       }
     }
 
     /**
      * Views - Check if element is part of an AJAX enabled view.
      */
-    function pagererInViewsAjaxContext(element) {
+    function getViewsAjaxContext(element) {
       if (Drupal.settings && Drupal.settings.views && Drupal.settings.views.ajaxViews) {
         // Loop through active Views Ajax elements.
         for (var i in Drupal.settings.views.ajaxViews) {
@@ -363,7 +892,7 @@ Drupal.behaviors.pagerer = {
     /**
      * Views - Attach Views AJAX behaviour to an element.
      */
-    function pagererAttachViewsAjax(element, event, viewContext, path) {
+    function attachViewsAjax(element, event, viewContext, path) {
 
       // Link to the element.
       var $link = $(element);
diff --git a/pagerer.module b/pagerer.module
index 8eafdfa..27ff68e 100644
--- a/pagerer.module
+++ b/pagerer.module
@@ -77,6 +77,7 @@ function pagerer_theme() {
         'pager_separator'         => 'none',
         'range_separator'         => '-',
         'fl_breakers'             => TRUE,
+        'widget_resize'           => TRUE,
         'slider_action'           => 'tickmark',
         'slider_action_timelapse' => 0,
         'slider_navigation_icons' => 'yes',
@@ -101,6 +102,7 @@ function pagerer_theme() {
         'pager_separator'         => 'none',
         'range_separator'         => '-',
         'fl_breakers'             => TRUE,
+        'widget_resize'           => TRUE,
         'slider_action'           => 'tickmark',
         'slider_action_timelapse' => 0,
         'slider_navigation_icons' => 'yes',
@@ -123,6 +125,7 @@ function pagerer_theme() {
         'pager_separator'         => 'none',
         'range_separator'         => '-',
         'fl_breakers'             => FALSE,
+        'widget_resize'           => TRUE,
         'slider_action'           => 'tickmark',
         'slider_action_timelapse' => 0,
         'slider_navigation_icons' => 'yes',
@@ -145,6 +148,30 @@ function pagerer_theme() {
         'pager_separator'         => 'none',
         'range_separator'         => '-',
         'fl_breakers'             => FALSE,
+        'widget_resize'           => TRUE,
+        'slider_action'           => 'tickmark',
+        'slider_action_timelapse' => 0,
+        'slider_navigation_icons' => 'yes',
+      ),
+    ),
+    'pagerer_scrollpane' => array(
+      'variables' => array(
+        'element'                 => $common_theme['pager']['variables']['element'],
+        'parameters'              => $common_theme['pager']['variables']['parameters'],
+        'quantity'                => $common_theme['pager']['variables']['quantity'],
+        'display'                 => 'pages',
+        'label_display'           => 'none',
+        'current_display'         => 'scrollpane',
+        'total_display'           => 'none',
+        'first_link'              => 'always',
+        'previous_link'           => 'always',
+        'next_link'               => 'always',
+        'last_link'               => 'always',
+        'pager_breaker'           => '…',
+        'pager_separator'         => 'none',
+        'range_separator'         => '-',
+        'fl_breakers'             => FALSE,
+        'widget_resize'           => TRUE,
         'slider_action'           => 'tickmark',
         'slider_action_timelapse' => 0,
         'slider_navigation_icons' => 'yes',
@@ -169,6 +196,7 @@ function pagerer_theme() {
         'pager_breaker'           => '…',
         'pager_separator'         => 'none',
         'range_separator'         => '-',
+        'widget_resize'           => TRUE,
         'slider_action'           => 'tickmark',
         'slider_action_timelapse' => 0,
         'slider_navigation_icons' => 'yes',
@@ -657,6 +685,15 @@ function theme_pagerer_slider($variables) {
 }
 
 /**
+ * This theme displays a scrollpane embedding a full pager.
+ *
+ * Page navigation is managed via a javascript.
+ */
+function theme_pagerer_scrollpane($variables) {
+  return _pagerer_theme_handler('pagerer_scrollpane', $variables);
+}
+
+/**
  * Pagerer's theme handler.
  *
  * Calls to any theme_pagerer_xxx() function are channeled to this handler.
@@ -853,6 +890,11 @@ function _pagerer_theme_handler($theme, $variables) {
       list($pages[$c]['text'], $pages[$c]['text_title']) = _pagerer_get_page_text($variables, $markers, 0);
       break;
 
+    case 'pagerer_scrollpane':
+      // Current.
+      $pages[$c]['interval'] = 0;
+      break;
+
     case 'pagerer_standard':
     default:
       // Neighborhood.
@@ -891,14 +933,16 @@ function _pagerer_theme_handler($theme, $variables) {
     $items[] = _pagerer_itemize_link(
       'first',
       $variables,
-      $markers
+      $markers,
+      ($theme == 'pagerer_scrollpane') ? 'button' : 'anchor'
     );
   }
   if ($variables['previous_link'] == 'always' or ($variables['previous_link'] == 'not_on_first' and $c <> 0)) {
     $items[] = _pagerer_itemize_link(
       'previous',
       $variables,
-      $markers
+      $markers,
+      ($theme == 'pagerer_scrollpane') ? 'button' : 'anchor'
     );
   }
   // 3 - Pages.
@@ -908,14 +952,16 @@ function _pagerer_theme_handler($theme, $variables) {
     $items[] = _pagerer_itemize_link(
       'next',
       $variables,
-      $markers
+      $markers,
+      ($theme == 'pagerer_scrollpane') ? 'button' : 'anchor'
     );
   }
   if ($variables['last_link'] == 'always' or ($variables['last_link'] == 'not_on_last' and $c <> $m)) {
     $items[] = _pagerer_itemize_link(
       'last',
       $variables,
-      $markers
+      $markers,
+      ($theme == 'pagerer_scrollpane') ? 'button' : 'anchor'
     );
   }
   // 5 - Labels.
@@ -1060,7 +1106,7 @@ function _pagerer_itemize_link($scope, $variables, $markers, $type = 'anchor') {
     );
   }
   elseif ($type == 'button') {
-    $li_data = "<button class='pagerer-button pagerer-$scope' title='$text_title'>$text</button>";
+    $li_data = "<div class='pagerer-scrollpane-button pagerer-$scope' title='$text_title'>$text</div>";
   }
   else {
     $li_data = NULL;
@@ -1182,6 +1228,7 @@ function _pagerer_itemize_page_links($variables, $markers, $pages) {
 
           case 'widget':
           case 'slider':
+          case 'scrollpane':
             $items = array_merge($items, _pagerer_itemize_js_element($variables['current_display'], $variables, $markers));
             break;
 
@@ -1270,7 +1317,6 @@ function _pagerer_itemize_page_links($variables, $markers, $pages) {
  *   keys/values
  */
 function _pagerer_get_neighborhood_pages($variables, $markers) {
-  global $pager_limits;
 
   // Prepare for generation loop.
   $i = $markers['pager_first'];
@@ -1318,7 +1364,6 @@ function _pagerer_get_neighborhood_pages($variables, $markers) {
  *   a key 'progressive' set to TRUE is also added as a marker
  */
 function _pagerer_get_progressive_pages($variables, $markers, $pages, $scale_factor, $ratio, $limit = NULL) {
-  global $pager_limits;
 
   // Avoid endless loop in converging series.
   if ($ratio < 1) {
@@ -1563,7 +1608,8 @@ function _pagerer_get_total($variables, $markers) {
  * enabled element.
  *
  * @param string $element_type
- *   'widget' for an active input box, 'slider' for a jquery ui slider
+ *   'widget' for an active input box, 'slider' for a jquery ui slider,
+ *   'scrollpane' for a scrolling pager
  * @param array $variables
  *   theme's variables
  * @param array $markers
@@ -1616,16 +1662,13 @@ function _pagerer_itemize_js_element($element_type, $variables, $markers) {
   $variables['parameters'] = array_merge(pager_get_query_parameters(), $variables['parameters']);
 
   // Are we displaying pages or items; 'value' HTML attribute will bear
-  // the current $current value; $total is passed to the js widget to
-  // ensure input is not bigger.
+  // the current $current value.
   if ($variables['display'] == 'pages') {
     $current = $markers['pager_current'];
-    $total = $markers['pager_max'];
     $interval = 1;
   }
   else {
     $current = $markers['pager_current_first_item'];
-    $total = $markers['pager_item_max'];
     $interval = $pager_limits[$variables['element']];
   }
 
@@ -1634,19 +1677,34 @@ function _pagerer_itemize_js_element($element_type, $variables, $markers) {
 
   // Prepare js widget state.
   $state = array(
-    'path'     => $path,
-    'element'  => $variables['element'],
-    'quantity' => $variables['quantity'],
-    'total'    => $total,
-    'current'  => $current,
-    'interval' => $interval,
-    'display'  => $variables['display'],
+    'path'           => $path,
+    'element'        => $variables['element'],
+    'quantity'       => $variables['quantity'],
+    'total'          => $markers['pager_max'],
+    'totalItems'     => $markers['pager_item_max'],
+    'current'        => $markers['pager_current'] -1,
+    'interval'       => $interval,
+    'display'        => $variables['display'],
+    'rangeSeparator' => $variables['range_separator'],
   );
-  if ($element_type == 'slider') {
-    $state['action'] = $variables['slider_action'];
-    $state['timelapse'] = $variables['slider_action_timelapse'];
-    $state['icons'] = $variables['slider_navigation_icons'];
-    $state['tickmark_title'] = $variables['tags']['slider_tickmark_title'];
+  switch ($element_type) {
+    case 'widget':
+      $state['widgetResize'] = $variables['widget_resize'];
+      break;
+
+    case 'slider':
+      $state['action'] = $variables['slider_action'];
+      $state['timelapse'] = $variables['slider_action_timelapse'];
+      $state['icons'] = $variables['slider_navigation_icons'];
+      $state['tickmarkTitle'] = $variables['tags']['slider_tickmark_title'];
+      break;
+
+    case 'scrollpane':
+      $state['pageTitle'] = $variables['tags']['page_title'];
+      $state['firstTitle'] = $variables['tags']['first_title'];
+      $state['lastTitle'] = $variables['tags']['last_title'];
+      break;
+
   }
   $state_encoded = drupal_json_encode($state);
 
@@ -1662,6 +1720,21 @@ function _pagerer_itemize_js_element($element_type, $variables, $markers) {
         );
         break;
 
+      case 'scrollpane':
+        // Add ui.button library.
+        drupal_add_library('system', 'ui.button');
+        $variables['current_display'] = 'normal';
+        $variables['first_link'] = 'never';
+        $variables['previous_link'] = 'never';
+        $variables['next_link'] = 'never';
+        $variables['last_link'] = 'never';
+        $items[] = array(
+          'class' => array('pager-item', 'pagerer-scrollpane'),
+          'id' => $state_encoded,
+          'data' => theme('pagerer_standard', $variables),
+        );
+        break;
+
       case 'slider':
         // Add ui.slider library.
         drupal_add_library('system', 'ui.slider');
diff --git a/pagerer_example.module b/pagerer_example.module
index b60fb5a..14f033c 100644
--- a/pagerer_example.module
+++ b/pagerer_example.module
@@ -173,6 +173,13 @@ function pagerer_example_page() {
     '#theme' => 'pagerer_mini',
     '#element' => 0,
   );
+  $build['l_pagerer_scrollpane_0'] = array('#markup' => '<br/><b>' . t("'pagerer_scrollpane' pager theme:") . '</b>');
+  $build['pagerer_scrollpane_0'] = array(
+    '#theme' => 'pagerer_scrollpane',
+    '#element' => 0,
+    '#quantity' => 5,
+    '#display' => 'pages'
+  );
   $build['l_pagerer_slider_0'] = array('#markup' => '<br/><b>' . t("'pagerer_slider' pager theme:") . '</b>');
   $build['pagerer_slider_0'] = array(
     '#theme' => 'pagerer_slider',
