Implements 'scrollable' widget.
authorSalvatore Iovene <salvatore.iovene@intel.com>
Wed, 12 Dec 2012 11:56:25 +0000 (13:56 +0200)
committerSalvatore Iovene <salvatore.iovene@intel.com>
Wed, 12 Dec 2012 11:56:25 +0000 (13:56 +0200)
LICENSES [new file with mode: 0644]
docs/templates/pages/javascript.mustache
grunt.js
lib/jquery.mCustomScrollbar.css [new file with mode: 0644]
lib/jquery.mCustomScrollbar.js [new file with mode: 0644]
lib/jquery.mousewheel.js [new file with mode: 0644]
src/javascripts/cowhide-ng-scrollable.js [new file with mode: 0644]
src/javascripts/cowhide-scrollable.js [new file with mode: 0644]

diff --git a/LICENSES b/LICENSES
new file mode 100644 (file)
index 0000000..61968a9
--- /dev/null
+++ b/LICENSES
@@ -0,0 +1,7 @@
+jquery.mCustomScrollbar
+================================================================================
+This work is licensed under the Creative Commons Attribution 3.1 Unported
+License. To view a copy of this license, visit
+http://creativecommons.org/licenses/by/3.0/ or send a letter to Creative
+Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA.
+
index 8be6fbc..492e42e 100644 (file)
@@ -31,6 +31,7 @@
           <li><a href="#affix"><i class="icon-chevron-right"></i> {{_i}}Affix{{/i}}</a></li>
           <li><a href="#slider"><i class="icon-chevron-right"></i> {{_i}}Slider{{/i}}</a></li>
           <li><a href="#header"><i class="icon-chevron-right"></i> {{_i}}Header{{/i}}</a></li>
+          <li><a href="#scrollable"><i class="icon-chevron-right"></i> {{_i}}Scrollable{{/i}}</a></li>
         </ul>
       </div>
       <div class="span9">
@@ -1724,6 +1725,45 @@ $('#myHeader').on('back', function () {
 
         </section>
 
+
+        <!-- Scrollable
+          ================================================== -->
+          <section id="scrollable">
+            <div class="page-header">
+              <h1>{{_i}}Scrollable{{/i}}</h1>
+            </div>
+
+            <h2>{{_i}}Example{{/i}}</h2>
+            <div class="ch-scrollable" style="width: 435px; height: 250px;">
+              <h2>{{_i}}This box is a CowHide scrollable.{{/i}}</h2>
+              <p>
+                Lorem ipsum dolor sit amet, class libero aliquam non, wisi viverra. Dictum sed lobortis laoreet blandit eros, nascetur vulputate, ac amet a vivamus sed wisi dui, ad magna ipsum ut sed. Mauris wisi dapibus, vitae rutrum nulla, wisi massa lobortis in non, erat vel sapien ornare pretium nunc faucibus. Gravida ducimus tenetur praesent donec rutrum at, eleifend pede pede magnis, iaculis et. Vestibulum natoque leo enim ut sapien, a auctor quis consectetuer nunc sit lorem, ipsum quidem vehicula in dapibus. Vitae sapien amet a sed. Sapien amet. Vel aenean et blandit, leo sed sed nisl, vel est nec eget suspendisse diam, qui a nunc feugiat massa ipsum rutrum, nam libero augue vivamus. Sit egestas pharetra orci neque ut, tincidunt mollis mauris et interdum amet habitasse, mauris amet erat quis, massa quis. Augue vel, rutrum etiam diam possimus egestas nam duis, morbi mattis mollis hac et vivamus, massa vehicula nunc wisi semper tortor vestibulum, tortor eget quam.
+              </p>
+
+              <p>
+                Nec arcu, nulla fermentum maecenas eget, sapien neque vestibulum wisi quis imperdiet. Urna ultricies ornare ut viverra, nisl dictumst interdum sed dolor ut lorem. Suscipit nulla iaculis vivamus, porttitor est sit aenean maecenas quam vero, semper consequat vestibulum dui pulvinar sed suspendisse. Pellentesque quam, porttitor imperdiet nec orci, porta egestas elementum at odio mi nibh. Ac quis, aenean id viverra bibendum, nunc in lacinia mi velit enim lectus, sapien lorem nibh. Laoreet faucibus tortor vel eveniet nisl donec. Incididunt phasellus ac quam vitae lorem dui, sagittis iaculis est. Vel blandit. Sit vivamus adipiscing minima commodo parturient a, pede elit curabitur vestibulum ut quam, mauris aliquam dictum condimentum magna arcu. Nisl nam litora turpis integer, libero nec hendrerit vestibulum, laoreet ipsum erat justo, phasellus augue suspendisse ut. Ac lacus fringilla vehicula nunc tempus malesuada. Non vehicula, sodales est arcu ut leo risus laboris, sem euismod nulla.
+              </p>
+
+              <p>
+                Etiam in etiam sagittis morbi, id ut eget volutpat augue eget eu, nec lectus. Quis nulla conubia placerat aliquam commodo nullam, ante in sit ac quam, odio nunc quis. Eu leo aenean lorem, suspendisse morbi, ut egestas pede ultrices tellus. Magnis vestibulum pellentesque vestibulum lacinia commodo. Donec at dignissim, dolor aliquam cum vel nostra morbi, accumsan et id. Phasellus ut maecenas arcu amet massa, dolor vestibulum pellentesque est platea risus feugiat, nam neque lectus sed, nulla erat a ac tortor aliquam vitae, et dui urna diam et. Non sed facilisis mauris sapien sit id, libero aenean eros aliquam natoque vitae, magna scelerisque sollicitudin sed pellentesque enim aliquam, dictum tempor.
+              </p>
+
+              <p>
+                Pellentesque at orci scelerisque unde nulla libero, lacus quam luctus eros enim quis, magna venenatis nulla. Urna adipiscing, quis molestie leo proin, nulla cursus amet velit tortor iaculis nullam. Et natus malesuada semper nonummy fusce, ipsum in in mauris egestas cras eget, lobortis volutpat libero. A eu. Tempor pellentesque, ornare mattis nunc platea. Assumenda ut amet quis, eu pretium hac et, a turpis mauris ut odio quo mi, sodales cum lectus taciti donec at velit, non eros mattis lectus. Quaerat in aliquam mattis vestibulum wisi, minim porta nibh nam volutpat est, metus dapibus aliquam nibh sed suspendisse. Bibendum tincidunt libero sed quibusdam, parturient wisi justo, mauris pulvinar quis lectus in sem sodales.
+              </p>
+            </div>
+
+            <h2>{{_i}}Usage{{/i}}</h2>
+
+            <h3>{{_i}}Via CSS class{{/i}}</h3>
+            <p>{{_i}}Activate a scrollable without any JavaScript code. Set <code>class="ch-scrollable"</code> on a container element, like a <code>div</code>.{{/i}}</p>
+            <pre class="prettyprint linenums">&lt;div class="ch-scollable"&gt;Your content here...&lt;/div&gt;</pre>
+
+            <h3>{{_i}}Via JavaScript{{/i}}</h3>
+            <p>{{_i}}Make a scrollable out of any container element with a single line of JavaScript:{{/i}}</p>
+            <pre class="prettyprint linenums">$('#myContainer').ch_scrollable('enable')</pre>
+        </section>
+
       </div>{{! /span9 }}
     </div>{{! row}}
 
index f8eed81..3ed3ce6 100644 (file)
--- a/grunt.js
+++ b/grunt.js
@@ -94,6 +94,7 @@ module.exports = function(grunt) {
           'lib/jquery-1.8.3.js',
           'lib/jquery-ui-1.9.2.custom.js',
           'lib/jquery.ui.slider.js',
+          'lib/jquery.mCustomScrollbar.js',
           'lib/underscore-min.js',
 
           // Bootstrap files must preserve order.
@@ -123,7 +124,8 @@ module.exports = function(grunt) {
           'src/javascripts/cowhide-checkbox-input.js',
           'src/javascripts/cowhide-select.js',
           'src/javascripts/cowhide-page.js',
-          'src/javascripts/cowhide-header.js'
+          'src/javascripts/cowhide-header.js',
+          'src/javascripts/cowhide-scrollable.js'
         ], dest: 'dist/cowhide.js'
       },
       cowhide_ng_js: {
@@ -134,43 +136,50 @@ module.exports = function(grunt) {
           'src/javascripts/cowhide-ng-page.js',
           'src/javascripts/cowhide-ng-header.js',
           'src/javascripts/cowhide-ng-button.js',
-          'src/javascripts/cowhide-ng-slider.js'
+          'src/javascripts/cowhide-ng-slider.js',
+          'src/javascripts/cowhide-ng-scrollable.js'
         ], dest: 'dist/cowhide-ng.js'
       },
       css_default: {
         src: [
           'dist/cowhide-default.css',
-          'lib/jquery.ui.slider.css'
+          'lib/jquery.ui.slider.css',
+          'lib/jquery.mCustomScrollbar.css'
         ], dest: 'dist/cowhide-default.css'
       },
       css_default_night: {
         src: [
           'dist/cowhide-default-night.css',
-          'lib/jquery.ui.slider.css'
+          'lib/jquery.ui.slider.css',
+          'lib/jquery.mCustomScrollbar.css'
         ], dest: 'dist/cowhide-default-night.css'
       },
       css_amelia: {
         src: [
           'dist/cowhide-amelia.css',
-          'lib/jquery.ui.slider.css'
+          'lib/jquery.ui.slider.css',
+          'lib/jquery.mCustomScrollbar.css'
         ], dest: 'dist/cowhide-amelia.css'
       },
       css_amelia_night: {
         src: [
           'dist/cowhide-amelia-night.css',
-          'lib/jquery.ui.slider.css'
+          'lib/jquery.ui.slider.css',
+          'lib/jquery.mCustomScrollbar.css'
         ], dest: 'dist/cowhide-amelia-night.css'
       },
       css_spruce: {
         src: [
           'dist/cowhide-spruce.css',
-          'lib/jquery.ui.slider.css'
+          'lib/jquery.ui.slider.css',
+          'lib/jquery.mCustomScrollbar.css'
         ], dest: 'dist/cowhide-spruce.css'
       },
       css_spruce_night: {
         src: [
           'dist/cowhide-spruce-night.css',
-          'lib/jquery.ui.slider.css'
+          'lib/jquery.ui.slider.css',
+          'lib/jquery.mCustomScrollbar.css'
         ], dest: 'dist/cowhide-spruce-night.css'
       }
     },
diff --git a/lib/jquery.mCustomScrollbar.css b/lib/jquery.mCustomScrollbar.css
new file mode 100644 (file)
index 0000000..1416410
--- /dev/null
@@ -0,0 +1,208 @@
+/* basic scrollbar styling */
+/* vertical scrollbar */
+.mCSB_container{
+       width:auto;
+       margin-right:30px;
+       overflow:hidden;
+}
+.mCSB_container.mCS_no_scrollbar{
+       margin-right:0;
+}
+.mCS_disabled .mCSB_container.mCS_no_scrollbar,
+.mCS_destroyed .mCSB_container.mCS_no_scrollbar{
+       margin-right:30px;
+}
+.mCustomScrollBox .mCSB_scrollTools{
+       width:16px;
+       height:100%;
+       top:0;
+       right:0;
+}
+.mCSB_scrollTools .mCSB_draggerContainer{
+       height:100%;
+       -webkit-box-sizing:border-box;
+       -moz-box-sizing:border-box;
+       box-sizing:border-box;
+}
+.mCSB_scrollTools .mCSB_buttonUp+.mCSB_draggerContainer{
+       padding-bottom:40px;
+}
+.mCSB_scrollTools .mCSB_draggerRail{
+       width:2px;
+       height:100%;
+       margin:0 auto;
+       -webkit-border-radius:10px;
+       -moz-border-radius:10px;
+       border-radius:10px;
+}
+.mCSB_scrollTools .mCSB_dragger{
+       cursor:pointer;
+       width:100%;
+       height:30px;
+}
+.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{
+       width:4px;
+       height:100%;
+       margin:0 auto;
+       -webkit-border-radius:10px;
+       -moz-border-radius:10px;
+       border-radius:10px;
+       text-align:center;
+}
+.mCSB_scrollTools .mCSB_buttonUp,
+.mCSB_scrollTools .mCSB_buttonDown{
+       height:20px;
+       overflow:hidden;
+       margin:0 auto;
+       cursor:pointer;
+}
+.mCSB_scrollTools .mCSB_buttonDown{
+       bottom:0;
+       margin-top:-40px;
+}
+/* horizontal scrollbar */
+.mCSB_horizontal .mCSB_container{
+       height:auto;
+       margin-right:0;
+       margin-bottom:30px;
+       overflow:hidden;
+}
+.mCSB_horizontal .mCSB_container.mCS_no_scrollbar{
+       margin-bottom:0;
+}
+.mCS_disabled .mCSB_horizontal .mCSB_container.mCS_no_scrollbar,
+.mCS_destroyed .mCSB_horizontal .mCSB_container.mCS_no_scrollbar{
+       margin-right:0;
+       margin-bottom:30px;
+}
+.mCSB_horizontal.mCustomScrollBox .mCSB_scrollTools{
+       width:100%;
+       height:16px;
+       top:auto;
+       right:auto;
+       bottom:0;
+       left:0;
+       overflow:hidden;
+}
+.mCSB_horizontal .mCSB_scrollTools .mCSB_draggerContainer{
+       height:100%;
+       width:auto;
+       -webkit-box-sizing:border-box;
+       -moz-box-sizing:border-box;
+       box-sizing:border-box;
+       overflow:hidden;
+}
+.mCSB_horizontal .mCSB_scrollTools .mCSB_buttonLeft+.mCSB_draggerContainer{
+       padding-bottom:0;
+       padding-right:20px;
+}
+.mCSB_horizontal .mCSB_scrollTools .mCSB_draggerRail{
+       width:100%;
+       height:2px;
+       margin:7px 0;
+       -webkit-border-radius:10px;
+       -moz-border-radius:10px;
+       border-radius:10px;
+}
+.mCSB_horizontal .mCSB_scrollTools .mCSB_dragger{
+       width:30px;
+       height:100%;
+}
+.mCSB_horizontal .mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{
+       width:100%;
+       height:4px;
+       margin:6px auto;
+       -webkit-border-radius:10px;
+       -moz-border-radius:10px;
+       border-radius:10px;
+}
+.mCSB_horizontal .mCSB_scrollTools .mCSB_buttonLeft,
+.mCSB_horizontal .mCSB_scrollTools .mCSB_buttonRight{
+       width:20px;
+       height:100%;
+       overflow:hidden;
+       margin:0 auto;
+       cursor:pointer;
+       float:left;
+}
+.mCSB_horizontal .mCSB_scrollTools .mCSB_buttonRight{
+       right:0;
+       bottom:auto;
+       margin-left:-40px;
+       margin-top:-16px;
+       float:right;
+}
+
+/* default scrollbar colors and backgrounds */
+.mCustomScrollBox .mCSB_scrollTools{
+       opacity:0.75;
+}
+.mCustomScrollBox:hover .mCSB_scrollTools{
+       opacity:1;
+}
+.mCSB_scrollTools .mCSB_draggerRail{
+       background:#000; /* rgba fallback */
+       background:rgba(0,0,0,0.4);
+       filter:"alpha(opacity=40)"; -ms-filter:"alpha(opacity=40)"; /* old ie */
+}
+.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{
+       background:#fff; /* rgba fallback */
+       background:rgba(255,255,255,0.75);
+       filter:"alpha(opacity=75)"; -ms-filter:"alpha(opacity=75)"; /* old ie */
+}
+.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar{
+       background:rgba(255,255,255,0.85);
+       filter:"alpha(opacity=85)"; -ms-filter:"alpha(opacity=85)"; /* old ie */
+}
+.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar,
+.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{
+       background:rgba(255,255,255,0.9);
+       filter:"alpha(opacity=90)"; -ms-filter:"alpha(opacity=90)"; /* old ie */
+}
+.mCSB_scrollTools .mCSB_buttonUp,
+.mCSB_scrollTools .mCSB_buttonDown,
+.mCSB_scrollTools .mCSB_buttonLeft,
+.mCSB_scrollTools .mCSB_buttonRight{
+       background-image:url(mCSB_buttons.png);
+       background-repeat:no-repeat;
+       opacity:0.4;
+       filter:"alpha(opacity=40)"; -ms-filter:"alpha(opacity=40)"; /* old ie */
+}
+.mCSB_scrollTools .mCSB_buttonUp{
+       background-position:0 0;
+       /* 
+       sprites locations are 0 0/-16px 0/-32px 0/-48px 0 (light) and -80px 0/-96px 0/-112px 0/-128px 0 (dark) 
+       */
+}
+.mCSB_scrollTools .mCSB_buttonDown{
+       background-position:0 -20px;
+       /* 
+       sprites locations are 0 -20px/-16px -20px/-32px -20px/-48px -20px (light) and -80px -20px/-96px -20px/-112px -20px/-128px -20px (dark) 
+       */
+}
+.mCSB_scrollTools .mCSB_buttonLeft{
+       background-position:0 -40px;
+       /* 
+       sprites locations are 0 -40px/-20px -40px/-40px -40px/-60px -40px (light) and -80px -40px/-100px -40px/-120px -40px/-140px -40px (dark) 
+       */
+}
+.mCSB_scrollTools .mCSB_buttonRight{
+       background-position:0 -56px;
+       /* 
+       sprites locations are 0 -56px/-20px -56px/-40px -56px/-60px -56px (light) and -80px -56px/-100px -56px/-120px -56px/-140px -56px (dark) 
+       */
+}
+.mCSB_scrollTools .mCSB_buttonUp:hover,
+.mCSB_scrollTools .mCSB_buttonDown:hover,
+.mCSB_scrollTools .mCSB_buttonLeft:hover,
+.mCSB_scrollTools .mCSB_buttonRight:hover{
+       opacity:0.75;
+       filter:"alpha(opacity=75)"; -ms-filter:"alpha(opacity=75)"; /* old ie */
+}
+.mCSB_scrollTools .mCSB_buttonUp:active,
+.mCSB_scrollTools .mCSB_buttonDown:active,
+.mCSB_scrollTools .mCSB_buttonLeft:active,
+.mCSB_scrollTools .mCSB_buttonRight:active{
+       opacity:0.9;
+       filter:"alpha(opacity=90)"; -ms-filter:"alpha(opacity=90)"; /* old ie */
+}
\ No newline at end of file
diff --git a/lib/jquery.mCustomScrollbar.js b/lib/jquery.mCustomScrollbar.js
new file mode 100644 (file)
index 0000000..0b7a7f0
--- /dev/null
@@ -0,0 +1,874 @@
+/* 
+== malihu jquery custom scrollbars plugin == 
+version: 2.3.1 
+author: malihu (http://manos.malihu.gr) 
+plugin home: http://manos.malihu.gr/jquery-custom-content-scroller 
+*/
+(function($){
+       var methods={
+               init:function(options){
+                       var defaults={ 
+                               set_width:false, /*optional element width: boolean, pixels, percentage*/
+                               set_height:false, /*optional element height: boolean, pixels, percentage*/
+                               horizontalScroll:false, /*scroll horizontally: boolean*/
+                               scrollInertia:550, /*scrolling inertia: integer (milliseconds)*/
+                               scrollEasing:"easeOutCirc", /*scrolling easing: string*/
+                               mouseWheel:"pixels", /*mousewheel support and velocity: boolean, "auto", integer, "pixels"*/
+                               mouseWheelPixels:60, /*mousewheel pixels amount: integer*/
+                               autoDraggerLength:true, /*auto-adjust scrollbar dragger length: boolean*/
+                               scrollButtons:{ /*scroll buttons*/
+                                       enable:false, /*scroll buttons support: boolean*/
+                                       scrollType:"continuous", /*scroll buttons scrolling type: "continuous", "pixels"*/
+                                       scrollSpeed:20, /*scroll buttons continuous scrolling speed: integer*/
+                                       scrollAmount:40 /*scroll buttons pixels scroll amount: integer (pixels)*/
+                               },
+                               advanced:{
+                                       updateOnBrowserResize:true, /*update scrollbars on browser resize (for layouts based on percentages): boolean*/
+                                       updateOnContentResize:false, /*auto-update scrollbars on content resize (for dynamic content): boolean*/
+                                       autoExpandHorizontalScroll:false, /*auto-expand width for horizontal scrolling: boolean*/
+                                       autoScrollOnFocus:true /*auto-scroll on focused elements: boolean*/
+                               },
+                               callbacks:{
+                                       onScrollStart:function(){}, /*user custom callback function on scroll start event*/
+                                       onScroll:function(){}, /*user custom callback function on scroll event*/
+                                       onTotalScroll:function(){}, /*user custom callback function on scroll end reached event*/
+                                       onTotalScrollBack:function(){}, /*user custom callback function on scroll begin reached event*/
+                                       onTotalScrollOffset:0, /*scroll end reached offset: integer (pixels)*/
+                                       whileScrolling:false, /*user custom callback function on scrolling event*/
+                                       whileScrollingInterval:30 /*interval for calling whileScrolling callback: integer (milliseconds)*/
+                               }
+                       },
+                       options=$.extend(true,defaults,options);
+                       /*check for touch device*/
+                       $(document).data("mCS-is-touch-device",false);
+                       if(is_touch_device()){
+                               $(document).data("mCS-is-touch-device",true); 
+                       }
+                       function is_touch_device(){
+                               return !!("ontouchstart" in window) ? 1 : 0;
+                       }
+                       return this.each(function(){
+                               var $this=$(this);
+                               /*set element width/height, create markup for custom scrollbars, add classes*/
+                               if(options.set_width){
+                                       $this.css("width",options.set_width);
+                               }
+                               if(options.set_height){
+                                       $this.css("height",options.set_height);
+                               }
+                               if(!$(document).data("mCustomScrollbar-index")){
+                                       $(document).data("mCustomScrollbar-index","1");
+                               }else{
+                                       var mCustomScrollbarIndex=parseInt($(document).data("mCustomScrollbar-index"));
+                                       $(document).data("mCustomScrollbar-index",mCustomScrollbarIndex+1);
+                               }
+                               $this.wrapInner("<div class='mCustomScrollBox' id='mCSB_"+$(document).data("mCustomScrollbar-index")+"' style='position:relative; height:100%; overflow:hidden; max-width:100%;' />").addClass("mCustomScrollbar _mCS_"+$(document).data("mCustomScrollbar-index"));
+                               var mCustomScrollBox=$this.children(".mCustomScrollBox");
+                               if(options.horizontalScroll){
+                                       mCustomScrollBox.addClass("mCSB_horizontal").wrapInner("<div class='mCSB_h_wrapper' style='position:relative; left:0; width:999999px;' />");
+                                       var mCSB_h_wrapper=mCustomScrollBox.children(".mCSB_h_wrapper");
+                                       mCSB_h_wrapper.wrapInner("<div class='mCSB_container' style='position:absolute; left:0;' />").children(".mCSB_container").css({"width":mCSB_h_wrapper.children().outerWidth(),"position":"relative"}).unwrap();
+                               }else{
+                                       mCustomScrollBox.wrapInner("<div class='mCSB_container' style='position:relative; top:0;' />");
+                               }
+                               var mCSB_container=mCustomScrollBox.children(".mCSB_container");
+                               if($(document).data("mCS-is-touch-device")){
+                                       mCSB_container.addClass("mCS_touch");
+                               }
+                               mCSB_container.after("<div class='mCSB_scrollTools' style='position:absolute;'><div class='mCSB_draggerContainer' style='position:relative;'><div class='mCSB_dragger' style='position:absolute;'><div class='mCSB_dragger_bar' style='position:relative;'></div></div><div class='mCSB_draggerRail'></div></div></div>");
+                               var mCSB_scrollTools=mCustomScrollBox.children(".mCSB_scrollTools"),
+                                       mCSB_draggerContainer=mCSB_scrollTools.children(".mCSB_draggerContainer"),
+                                       mCSB_dragger=mCSB_draggerContainer.children(".mCSB_dragger");
+                               if(options.horizontalScroll){
+                                       mCSB_dragger.data("minDraggerWidth",mCSB_dragger.width());
+                               }else{
+                                       mCSB_dragger.data("minDraggerHeight",mCSB_dragger.height());
+                               }
+                               if(options.scrollButtons.enable){
+                                       if(options.horizontalScroll){
+                                               mCSB_scrollTools.prepend("<a class='mCSB_buttonLeft' style='display:block; position:relative;'></a>").append("<a class='mCSB_buttonRight' style='display:block; position:relative;'></a>");
+                                       }else{
+                                               mCSB_scrollTools.prepend("<a class='mCSB_buttonUp' style='display:block; position:relative;'></a>").append("<a class='mCSB_buttonDown' style='display:block; position:relative;'></a>");
+                                       }
+                               }
+                               /*mCustomScrollBox scrollTop and scrollLeft is always 0 to prevent browser focus scrolling*/
+                               mCustomScrollBox.bind("scroll",function(){
+                                       if(!$this.is(".mCS_disabled")){ /*native focus scrolling for disabled scrollbars*/
+                                               mCustomScrollBox.scrollTop(0).scrollLeft(0);
+                                       }
+                               });
+                               /*store options, global vars/states, intervals and update element*/
+                               $this.data({
+                                       /*init state*/
+                                       "mCS_Init":true,
+                                       /*option parameters*/
+                                       "horizontalScroll":options.horizontalScroll,
+                                       "scrollInertia":options.scrollInertia,
+                                       "scrollEasing":options.scrollEasing,
+                                       "mouseWheel":options.mouseWheel,
+                                       "mouseWheelPixels":options.mouseWheelPixels,
+                                       "autoDraggerLength":options.autoDraggerLength,
+                                       "scrollButtons_enable":options.scrollButtons.enable,
+                                       "scrollButtons_scrollType":options.scrollButtons.scrollType,
+                                       "scrollButtons_scrollSpeed":options.scrollButtons.scrollSpeed,
+                                       "scrollButtons_scrollAmount":options.scrollButtons.scrollAmount,
+                                       "autoExpandHorizontalScroll":options.advanced.autoExpandHorizontalScroll,
+                                       "autoScrollOnFocus":options.advanced.autoScrollOnFocus,
+                                       "onScrollStart_Callback":options.callbacks.onScrollStart,
+                                       "onScroll_Callback":options.callbacks.onScroll,
+                                       "onTotalScroll_Callback":options.callbacks.onTotalScroll,
+                                       "onTotalScrollBack_Callback":options.callbacks.onTotalScrollBack,
+                                       "onTotalScroll_Offset":options.callbacks.onTotalScrollOffset,
+                                       "whileScrolling_Callback":options.callbacks.whileScrolling,
+                                       "whileScrolling_Interval":options.callbacks.whileScrollingInterval,
+                                       /*events binding state*/
+                                       "bindEvent_scrollbar_click":false,
+                                       "bindEvent_mousewheel":false,
+                                       "bindEvent_focusin":false,
+                                       "bindEvent_buttonsContinuous_y":false,
+                                       "bindEvent_buttonsContinuous_x":false,
+                                       "bindEvent_buttonsPixels_y":false,
+                                       "bindEvent_buttonsPixels_x":false,
+                                       "bindEvent_scrollbar_touch":false,
+                                       "bindEvent_content_touch":false,
+                                       /*buttons intervals*/
+                                       "mCSB_buttonScrollRight":false,
+                                       "mCSB_buttonScrollLeft":false,
+                                       "mCSB_buttonScrollDown":false,
+                                       "mCSB_buttonScrollUp":false,
+                                       /*callback intervals*/
+                                       "whileScrolling":false
+                               }).mCustomScrollbar("update");
+                               /*detect max-width*/
+                               if(options.horizontalScroll){
+                                       if($this.css("max-width")!=="none"){
+                                               if(!options.advanced.updateOnContentResize){ /*needs updateOnContentResize*/
+                                                       options.advanced.updateOnContentResize=true;
+                                               }
+                                               $this.data({"mCS_maxWidth":parseInt($this.css("max-width")),"mCS_maxWidth_Interval":setInterval(function(){
+                                                       if(parseInt($this.css("width"))>$this.data("mCS_maxWidth")){
+                                                               clearInterval($this.data("mCS_maxWidth_Interval"));
+                                                               $this.mCustomScrollbar("update");
+                                                       }
+                                               },150)});
+                                       }
+                               }else{
+                                       /*detect max-height*/
+                                       if($this.css("max-height")!=="none"){
+                                               $this.data({"mCS_maxHeight":parseInt($this.css("max-height")),"mCS_maxHeight_Interval":setInterval(function(){
+                                                       mCustomScrollBox.css("max-height",$this.data("mCS_maxHeight"));
+                                                       if(parseInt($this.css("height"))>$this.data("mCS_maxHeight")){
+                                                               clearInterval($this.data("mCS_maxHeight_Interval"));
+                                                               $this.mCustomScrollbar("update");
+                                                       }
+                                               },150)});
+                                       }
+                               }
+                               /*window resize fn (for layouts based on percentages)*/
+                               if(options.advanced.updateOnBrowserResize){
+                                       var mCSB_resizeTimeout;
+                                       $(window).resize(function(){
+                                               if(mCSB_resizeTimeout){
+                                                       clearTimeout(mCSB_resizeTimeout);
+                                               }
+                                               mCSB_resizeTimeout=setTimeout(function(){
+                                                       if(!$this.is(".mCS_disabled") && !$this.is(".mCS_destroyed")){
+                                                               $this.mCustomScrollbar("update");
+                                                       }
+                                               },150);
+                                       });
+                               }
+                               /*content resize fn (for dynamically generated content)*/
+                               if(options.advanced.updateOnContentResize){
+                                       var mCSB_onContentResize;
+                                       if(options.horizontalScroll){
+                                               var mCSB_containerOldSize=mCSB_container.outerWidth();
+                                       }else{
+                                               var mCSB_containerOldSize=mCSB_container.outerHeight();
+                                       }
+                                       mCSB_onContentResize=setInterval(function(){
+                                               if(options.horizontalScroll){
+                                                       if(options.advanced.autoExpandHorizontalScroll){
+                                                               mCSB_container.css({"position":"absolute","width":"auto"}).wrap("<div class='mCSB_h_wrapper' style='position:relative; left:0; width:999999px;' />").css({"width":mCSB_container.outerWidth(),"position":"relative"}).unwrap();
+                                                       }
+                                                       var mCSB_containerNewSize=mCSB_container.outerWidth();
+                                               }else{
+                                                       var mCSB_containerNewSize=mCSB_container.outerHeight();
+                                               }
+                                               if(mCSB_containerNewSize!=mCSB_containerOldSize){
+                                                       $this.mCustomScrollbar("update");
+                                                       mCSB_containerOldSize=mCSB_containerNewSize;
+                                               }
+                                       },300);
+                               }
+                       });
+               },
+               update:function(){
+                       var $this=$(this),
+                               mCustomScrollBox=$this.children(".mCustomScrollBox"),
+                               mCSB_container=mCustomScrollBox.children(".mCSB_container");
+                       mCSB_container.removeClass("mCS_no_scrollbar");
+                       $this.removeClass("mCS_disabled mCS_destroyed");
+                       mCustomScrollBox.scrollTop(0).scrollLeft(0); /*reset scrollTop/scrollLeft to prevent browser focus scrolling*/
+                       var mCSB_scrollTools=mCustomScrollBox.children(".mCSB_scrollTools"),
+                               mCSB_draggerContainer=mCSB_scrollTools.children(".mCSB_draggerContainer"),
+                               mCSB_dragger=mCSB_draggerContainer.children(".mCSB_dragger");
+                       if($this.data("horizontalScroll")){
+                               var mCSB_buttonLeft=mCSB_scrollTools.children(".mCSB_buttonLeft"),
+                                       mCSB_buttonRight=mCSB_scrollTools.children(".mCSB_buttonRight"),
+                                       mCustomScrollBoxW=mCustomScrollBox.width();
+                               if($this.data("autoExpandHorizontalScroll")){
+                                       mCSB_container.css({"position":"absolute","width":"auto"}).wrap("<div class='mCSB_h_wrapper' style='position:relative; left:0; width:999999px;' />").css({"width":mCSB_container.outerWidth(),"position":"relative"}).unwrap();
+                               }
+                               var mCSB_containerW=mCSB_container.outerWidth();
+                       }else{
+                               var mCSB_buttonUp=mCSB_scrollTools.children(".mCSB_buttonUp"),
+                                       mCSB_buttonDown=mCSB_scrollTools.children(".mCSB_buttonDown"),
+                                       mCustomScrollBoxH=mCustomScrollBox.height(),
+                                       mCSB_containerH=mCSB_container.outerHeight();
+                       }
+                       if(mCSB_containerH>mCustomScrollBoxH && !$this.data("horizontalScroll")){ /*content needs vertical scrolling*/
+                               mCSB_scrollTools.css("display","block");
+                               var mCSB_draggerContainerH=mCSB_draggerContainer.height();
+                               /*auto adjust scrollbar dragger length analogous to content*/
+                               if($this.data("autoDraggerLength")){
+                                       var draggerH=Math.round(mCustomScrollBoxH/mCSB_containerH*mCSB_draggerContainerH),
+                                               minDraggerH=mCSB_dragger.data("minDraggerHeight");
+                                       if(draggerH<=minDraggerH){ /*min dragger height*/
+                                               mCSB_dragger.css({"height":minDraggerH});
+                                       }else if(draggerH>=mCSB_draggerContainerH-10){ /*max dragger height*/
+                                               var mCSB_draggerContainerMaxH=mCSB_draggerContainerH-10;
+                                               mCSB_dragger.css({"height":mCSB_draggerContainerMaxH});
+                                       }else{
+                                               mCSB_dragger.css({"height":draggerH});
+                                       }
+                                       mCSB_dragger.children(".mCSB_dragger_bar").css({"line-height":mCSB_dragger.height()+"px"});
+                               }
+                               var mCSB_draggerH=mCSB_dragger.height(),
+                               /*calculate and store scroll amount, add scrolling*/
+                                       scrollAmount=(mCSB_containerH-mCustomScrollBoxH)/(mCSB_draggerContainerH-mCSB_draggerH);
+                               $this.data("scrollAmount",scrollAmount).mCustomScrollbar("scrolling",mCustomScrollBox,mCSB_container,mCSB_draggerContainer,mCSB_dragger,mCSB_buttonUp,mCSB_buttonDown,mCSB_buttonLeft,mCSB_buttonRight);
+                               /*scroll*/
+                               var mCSB_containerP=Math.abs(Math.round(mCSB_container.position().top));
+                               $this.mCustomScrollbar("scrollTo",mCSB_containerP,{callback:false});
+                       }else if(mCSB_containerW>mCustomScrollBoxW && $this.data("horizontalScroll")){ /*content needs horizontal scrolling*/
+                               mCSB_scrollTools.css("display","block");
+                               var mCSB_draggerContainerW=mCSB_draggerContainer.width();
+                               /*auto adjust scrollbar dragger length analogous to content*/
+                               if($this.data("autoDraggerLength")){
+                                       var draggerW=Math.round(mCustomScrollBoxW/mCSB_containerW*mCSB_draggerContainerW),
+                                               minDraggerW=mCSB_dragger.data("minDraggerWidth");
+                                       if(draggerW<=minDraggerW){ /*min dragger height*/
+                                               mCSB_dragger.css({"width":minDraggerW});
+                                       }else if(draggerW>=mCSB_draggerContainerW-10){ /*max dragger height*/
+                                               var mCSB_draggerContainerMaxW=mCSB_draggerContainerW-10;
+                                               mCSB_dragger.css({"width":mCSB_draggerContainerMaxW});
+                                       }else{
+                                               mCSB_dragger.css({"width":draggerW});
+                                       }
+                               }
+                               var mCSB_draggerW=mCSB_dragger.width(),
+                               /*calculate and store scroll amount, add scrolling*/
+                                       scrollAmount=(mCSB_containerW-mCustomScrollBoxW)/(mCSB_draggerContainerW-mCSB_draggerW);
+                               $this.data("scrollAmount",scrollAmount).mCustomScrollbar("scrolling",mCustomScrollBox,mCSB_container,mCSB_draggerContainer,mCSB_dragger,mCSB_buttonUp,mCSB_buttonDown,mCSB_buttonLeft,mCSB_buttonRight);
+                               /*scroll*/
+                               var mCSB_containerP=Math.abs(Math.round(mCSB_container.position().left));
+                               $this.mCustomScrollbar("scrollTo",mCSB_containerP,{callback:false});
+                       }else{ /*content does not need scrolling*/
+                               /*unbind events, reset content position, hide scrollbars, remove classes*/
+                               mCustomScrollBox.unbind("mousewheel focusin");
+                               if($this.data("horizontalScroll")){
+                                       mCSB_dragger.add(mCSB_container).css("left",0);
+                               }else{
+                                       mCSB_dragger.add(mCSB_container).css("top",0);
+                               }
+                               mCSB_scrollTools.css("display","none");
+                               mCSB_container.addClass("mCS_no_scrollbar");
+                               $this.data({"bindEvent_mousewheel":false,"bindEvent_focusin":false});
+                       }
+               },
+               scrolling:function(mCustomScrollBox,mCSB_container,mCSB_draggerContainer,mCSB_dragger,mCSB_buttonUp,mCSB_buttonDown,mCSB_buttonLeft,mCSB_buttonRight){
+                       var $this=$(this);
+                       /*while scrolling callback*/
+                       $this.mCustomScrollbar("callbacks","whileScrolling"); 
+                       /*drag scrolling*/
+                       if(!mCSB_dragger.hasClass("ui-draggable")){ /*apply drag function once*/
+                               if($this.data("horizontalScroll")){
+                                       var draggableAxis="x";
+                               }else{
+                                       var draggableAxis="y";
+                               }
+                               mCSB_dragger.draggable({ 
+                                       axis:draggableAxis,
+                                       containment:"parent",
+                                       drag:function(event,ui){
+                                               $this.mCustomScrollbar("scroll");
+                                               mCSB_dragger.addClass("mCSB_dragger_onDrag");
+                                       },
+                                       stop:function(event,ui){
+                                               mCSB_dragger.removeClass("mCSB_dragger_onDrag");        
+                                       }
+                               });
+                       }
+                       if(!$this.data("bindEvent_scrollbar_click")){ /*bind once*/
+                               mCSB_draggerContainer.bind("click",function(e){
+                                       if($this.data("horizontalScroll")){
+                                               var mouseCoord=(e.pageX-mCSB_draggerContainer.offset().left);
+                                               if(mouseCoord<mCSB_dragger.position().left || mouseCoord>(mCSB_dragger.position().left+mCSB_dragger.width())){
+                                                       var scrollToPos=mouseCoord;
+                                                       if(scrollToPos>=mCSB_draggerContainer.width()-mCSB_dragger.width()){ /*max dragger position is bottom*/
+                                                               scrollToPos=mCSB_draggerContainer.width()-mCSB_dragger.width();
+                                                       }
+                                                       mCSB_dragger.css("left",scrollToPos);
+                                                       $this.mCustomScrollbar("scroll");
+                                               }
+                                       }else{
+                                               var mouseCoord=(e.pageY-mCSB_draggerContainer.offset().top);
+                                               if(mouseCoord<mCSB_dragger.position().top || mouseCoord>(mCSB_dragger.position().top+mCSB_dragger.height())){
+                                                       var scrollToPos=mouseCoord;
+                                                       if(scrollToPos>=mCSB_draggerContainer.height()-mCSB_dragger.height()){ /*max dragger position is bottom*/
+                                                               scrollToPos=mCSB_draggerContainer.height()-mCSB_dragger.height();
+                                                       }
+                                                       mCSB_dragger.css("top",scrollToPos);
+                                                       $this.mCustomScrollbar("scroll");
+                                               }
+                                       }
+                               });
+                               $this.data({"bindEvent_scrollbar_click":true});
+                       }
+                       /*mousewheel scrolling*/
+                       if($this.data("mouseWheel")){
+                               var mousewheelVel=$this.data("mouseWheel");
+                               if($this.data("mouseWheel")==="auto"){
+                                       mousewheelVel=8; /*default mousewheel velocity*/
+                                       /*check for safari browser on mac osx to lower mousewheel velocity*/
+                                       var os=navigator.userAgent;
+                                       if(os.indexOf("Mac")!=-1 && os.indexOf("Safari")!=-1 && os.indexOf("AppleWebKit")!=-1 && os.indexOf("Chrome")==-1){ 
+                                               mousewheelVel=1;
+                                       }
+                               }
+                               if(!$this.data("bindEvent_mousewheel")){ /*bind once*/
+                                       mCustomScrollBox.bind("mousewheel",function(event,delta){
+                                               event.preventDefault();
+                                               var vel=Math.abs(delta*mousewheelVel);
+                                               if($this.data("horizontalScroll")){
+                                                       if($this.data("mouseWheel")==="pixels"){
+                                                               if(delta<0){
+                                                                       delta=-1;
+                                                               }else{
+                                                                       delta=1;
+                                                               }
+                                                               var scrollTo=Math.abs(Math.round(mCSB_container.position().left))-(delta*$this.data("mouseWheelPixels"));
+                                                               $this.mCustomScrollbar("scrollTo",scrollTo);
+                                                       }else{
+                                                               var posX=mCSB_dragger.position().left-(delta*vel);
+                                                               mCSB_dragger.css("left",posX);
+                                                               if(mCSB_dragger.position().left<0){
+                                                                       mCSB_dragger.css("left",0);
+                                                               }
+                                                               var mCSB_draggerContainerW=mCSB_draggerContainer.width(),
+                                                                       mCSB_draggerW=mCSB_dragger.width();
+                                                               if(mCSB_dragger.position().left>mCSB_draggerContainerW-mCSB_draggerW){
+                                                                       mCSB_dragger.css("left",mCSB_draggerContainerW-mCSB_draggerW);
+                                                               }
+                                                               $this.mCustomScrollbar("scroll");
+                                                       }
+                                               }else{
+                                                       if($this.data("mouseWheel")==="pixels"){
+                                                               if(delta<0){
+                                                                       delta=-1;
+                                                               }else{
+                                                                       delta=1;
+                                                               }
+                                                               var scrollTo=Math.abs(Math.round(mCSB_container.position().top))-(delta*$this.data("mouseWheelPixels"));
+                                                               $this.mCustomScrollbar("scrollTo",scrollTo);
+                                                       }else{
+                                                               var posY=mCSB_dragger.position().top-(delta*vel);
+                                                               mCSB_dragger.css("top",posY);
+                                                               if(mCSB_dragger.position().top<0){
+                                                                       mCSB_dragger.css("top",0);
+                                                               }
+                                                               var mCSB_draggerContainerH=mCSB_draggerContainer.height(),
+                                                                       mCSB_draggerH=mCSB_dragger.height();
+                                                               if(mCSB_dragger.position().top>mCSB_draggerContainerH-mCSB_draggerH){
+                                                                       mCSB_dragger.css("top",mCSB_draggerContainerH-mCSB_draggerH);
+                                                               }
+                                                               $this.mCustomScrollbar("scroll");
+                                                       }
+                                               }
+                                       });
+                                       $this.data({"bindEvent_mousewheel":true});
+                               }
+                       }
+                       /*buttons scrolling*/
+                       if($this.data("scrollButtons_enable")){
+                               if($this.data("scrollButtons_scrollType")==="pixels"){ /*scroll by pixels*/
+                                       var pixelsScrollTo;
+                                       if($.browser.msie && parseInt($.browser.version)<9){ /*stupid ie8*/
+                                               $this.data("scrollInertia",0);
+                                       }
+                                       if($this.data("horizontalScroll")){
+                                               mCSB_buttonRight.add(mCSB_buttonLeft).unbind("mousedown touchstart onmsgesturestart mouseup mouseout touchend onmsgestureend",mCSB_buttonRight_stop,mCSB_buttonLeft_stop);
+                                               $this.data({"bindEvent_buttonsContinuous_x":false});
+                                               if(!$this.data("bindEvent_buttonsPixels_x")){ /*bind once*/
+                                                       /*scroll right*/
+                                                       mCSB_buttonRight.bind("click",function(e){
+                                                               e.preventDefault();
+                                                               if(!mCSB_container.is(":animated")){
+                                                                       pixelsScrollTo=Math.abs(mCSB_container.position().left)+$this.data("scrollButtons_scrollAmount");
+                                                                       $this.mCustomScrollbar("scrollTo",pixelsScrollTo);
+                                                               }
+                                                       });
+                                                       /*scroll left*/
+                                                       mCSB_buttonLeft.bind("click",function(e){
+                                                               e.preventDefault();
+                                                               if(!mCSB_container.is(":animated")){
+                                                                       pixelsScrollTo=Math.abs(mCSB_container.position().left)-$this.data("scrollButtons_scrollAmount");
+                                                                       if(mCSB_container.position().left>=-$this.data("scrollButtons_scrollAmount")){
+                                                                               pixelsScrollTo="left";
+                                                                       }
+                                                                       $this.mCustomScrollbar("scrollTo",pixelsScrollTo);
+                                                               }
+                                                       });
+                                                       $this.data({"bindEvent_buttonsPixels_x":true});
+                                               }
+                                       }else{
+                                               mCSB_buttonDown.add(mCSB_buttonUp).unbind("mousedown touchstart onmsgesturestart mouseup mouseout touchend onmsgestureend",mCSB_buttonRight_stop,mCSB_buttonLeft_stop);
+                                               $this.data({"bindEvent_buttonsContinuous_y":false});
+                                               if(!$this.data("bindEvent_buttonsPixels_y")){ /*bind once*/
+                                                       /*scroll down*/
+                                                       mCSB_buttonDown.bind("click",function(e){
+                                                               e.preventDefault();
+                                                               if(!mCSB_container.is(":animated")){
+                                                                       pixelsScrollTo=Math.abs(mCSB_container.position().top)+$this.data("scrollButtons_scrollAmount");
+                                                                       $this.mCustomScrollbar("scrollTo",pixelsScrollTo);
+                                                               }
+                                                       });
+                                                       /*scroll up*/
+                                                       mCSB_buttonUp.bind("click",function(e){
+                                                               e.preventDefault();
+                                                               if(!mCSB_container.is(":animated")){
+                                                                       pixelsScrollTo=Math.abs(mCSB_container.position().top)-$this.data("scrollButtons_scrollAmount");
+                                                                       if(mCSB_container.position().top>=-$this.data("scrollButtons_scrollAmount")){
+                                                                               pixelsScrollTo="top";
+                                                                       }
+                                                                       $this.mCustomScrollbar("scrollTo",pixelsScrollTo);
+                                                               }
+                                                       });
+                                                       $this.data({"bindEvent_buttonsPixels_y":true});
+                                               }
+                                       }
+                               }else{ /*continuous scrolling*/
+                                       if($this.data("horizontalScroll")){
+                                               mCSB_buttonRight.add(mCSB_buttonLeft).unbind("click");
+                                               $this.data({"bindEvent_buttonsPixels_x":false});
+                                               if(!$this.data("bindEvent_buttonsContinuous_x")){ /*bind once*/
+                                                       /*scroll right*/
+                                                       mCSB_buttonRight.bind("mousedown touchstart onmsgesturestart",function(e){
+                                                               e.preventDefault();
+                                                               e.stopPropagation();
+                                                               $this.data({"mCSB_buttonScrollRight":setInterval(function(){
+                                                                       var scrollTo=Math.round((Math.abs(Math.round(mCSB_container.position().left))+$this.data("scrollButtons_scrollSpeed"))/$this.data("scrollAmount"));
+                                                                       $this.mCustomScrollbar("scrollTo",scrollTo,{moveDragger:true});
+                                                               },30)});
+                                                       });
+                                                       var mCSB_buttonRight_stop=function(e){
+                                                               e.preventDefault();
+                                                               e.stopPropagation();
+                                                               clearInterval($this.data("mCSB_buttonScrollRight"));
+                                                       }
+                                                       mCSB_buttonRight.bind("mouseup touchend onmsgestureend mouseout",mCSB_buttonRight_stop);
+                                                       /*scroll left*/
+                                                       mCSB_buttonLeft.bind("mousedown touchstart onmsgesturestart",function(e){
+                                                               e.preventDefault();
+                                                               e.stopPropagation();
+                                                               $this.data({"mCSB_buttonScrollLeft":setInterval(function(){
+                                                                       var scrollTo=Math.round((Math.abs(Math.round(mCSB_container.position().left))-$this.data("scrollButtons_scrollSpeed"))/$this.data("scrollAmount"));
+                                                                       $this.mCustomScrollbar("scrollTo",scrollTo,{moveDragger:true});
+                                                               },30)});
+                                                       });     
+                                                       var mCSB_buttonLeft_stop=function(e){
+                                                               e.preventDefault();
+                                                               e.stopPropagation();
+                                                               clearInterval($this.data("mCSB_buttonScrollLeft"));
+                                                       }
+                                                       mCSB_buttonLeft.bind("mouseup touchend onmsgestureend mouseout",mCSB_buttonLeft_stop);
+                                                       $this.data({"bindEvent_buttonsContinuous_x":true});
+                                               }
+                                       }else{
+                                               mCSB_buttonDown.add(mCSB_buttonUp).unbind("click");
+                                               $this.data({"bindEvent_buttonsPixels_y":false});
+                                               if(!$this.data("bindEvent_buttonsContinuous_y")){ /*bind once*/
+                                                       /*scroll down*/
+                                                       mCSB_buttonDown.bind("mousedown touchstart onmsgesturestart",function(e){
+                                                               e.preventDefault();
+                                                               e.stopPropagation();
+                                                               $this.data({"mCSB_buttonScrollDown":setInterval(function(){
+                                                                       var scrollTo=Math.round((Math.abs(Math.round(mCSB_container.position().top))+$this.data("scrollButtons_scrollSpeed"))/$this.data("scrollAmount"));
+                                                                       $this.mCustomScrollbar("scrollTo",scrollTo,{moveDragger:true});
+                                                               },30)});
+                                                       });
+                                                       var mCSB_buttonDown_stop=function(e){
+                                                               e.preventDefault();
+                                                               e.stopPropagation();
+                                                               clearInterval($this.data("mCSB_buttonScrollDown"));
+                                                       }
+                                                       mCSB_buttonDown.bind("mouseup touchend onmsgestureend mouseout",mCSB_buttonDown_stop);
+                                                       /*scroll up*/
+                                                       mCSB_buttonUp.bind("mousedown touchstart onmsgesturestart",function(e){
+                                                               e.preventDefault();
+                                                               e.stopPropagation();
+                                                               $this.data({"mCSB_buttonScrollUp":setInterval(function(){
+                                                                       var scrollTo=Math.round((Math.abs(Math.round(mCSB_container.position().top))-$this.data("scrollButtons_scrollSpeed"))/$this.data("scrollAmount"));
+                                                                       $this.mCustomScrollbar("scrollTo",scrollTo,{moveDragger:true});
+                                                               },30)});
+                                                       });     
+                                                       var mCSB_buttonUp_stop=function(e){
+                                                               e.preventDefault();
+                                                               e.stopPropagation();
+                                                               clearInterval($this.data("mCSB_buttonScrollUp"));
+                                                       }
+                                                       mCSB_buttonUp.bind("mouseup touchend onmsgestureend mouseout",mCSB_buttonUp_stop);
+                                                       $this.data({"bindEvent_buttonsContinuous_y":true});
+                                               }
+                                       }
+                               }
+                       }
+                       /*scrolling on element focus (e.g. via TAB key)*/
+                       if($this.data("autoScrollOnFocus")){
+                               if(!$this.data("bindEvent_focusin")){ /*bind once*/
+                                       mCustomScrollBox.bind("focusin",function(){
+                                               mCustomScrollBox.scrollTop(0).scrollLeft(0);
+                                               var focusedElem=$(document.activeElement);
+                                               if(focusedElem.is("input,textarea,select,button,a[tabindex],area,object")){
+                                                       if($this.data("horizontalScroll")){
+                                                               var mCSB_containerX=mCSB_container.position().left,
+                                                                       focusedElemX=focusedElem.position().left,
+                                                                       mCustomScrollBoxW=mCustomScrollBox.width(),
+                                                                       focusedElemW=focusedElem.outerWidth();
+                                                               if(mCSB_containerX+focusedElemX>=0 && mCSB_containerX+focusedElemX<=mCustomScrollBoxW-focusedElemW){
+                                                                       /*just focus...*/
+                                                               }else{ /*scroll, then focus*/
+                                                                       var moveDragger=focusedElemX/$this.data("scrollAmount");
+                                                                       if(moveDragger>=mCSB_draggerContainer.width()-mCSB_dragger.width()){ /*max dragger position is bottom*/
+                                                                               moveDragger=mCSB_draggerContainer.width()-mCSB_dragger.width();
+                                                                       }
+                                                                       mCSB_dragger.css("left",moveDragger);
+                                                                       $this.mCustomScrollbar("scroll");
+                                                               }
+                                                       }else{
+                                                               var mCSB_containerY=mCSB_container.position().top,
+                                                                       focusedElemY=focusedElem.position().top,
+                                                                       mCustomScrollBoxH=mCustomScrollBox.height(),
+                                                                       focusedElemH=focusedElem.outerHeight();
+                                                               if(mCSB_containerY+focusedElemY>=0 && mCSB_containerY+focusedElemY<=mCustomScrollBoxH-focusedElemH){
+                                                                       /*just focus...*/
+                                                               }else{ /*scroll, then focus*/
+                                                                       var moveDragger=focusedElemY/$this.data("scrollAmount");
+                                                                       if(moveDragger>=mCSB_draggerContainer.height()-mCSB_dragger.height()){ /*max dragger position is bottom*/
+                                                                               moveDragger=mCSB_draggerContainer.height()-mCSB_dragger.height();
+                                                                       }
+                                                                       mCSB_dragger.css("top",moveDragger);
+                                                                       $this.mCustomScrollbar("scroll");
+                                                               }
+                                                       }
+                                               }
+                                       });
+                                       $this.data({"bindEvent_focusin":true});
+                               }
+                       }
+                       /*touch events*/
+                       if($(document).data("mCS-is-touch-device")){
+                               /*scrollbar touch-drag*/
+                               if(!$this.data("bindEvent_scrollbar_touch")){ /*bind once*/
+                                       var mCSB_draggerTouchY,
+                                               mCSB_draggerTouchX;
+                                       mCSB_dragger.bind("touchstart onmsgesturestart",function(e){
+                                               e.preventDefault();
+                                               e.stopPropagation();
+                                               var touch=e.originalEvent.touches[0] || e.originalEvent.changedTouches[0],
+                                                       elem=$(this),
+                                                       elemOffset=elem.offset(),
+                                                       x=touch.pageX-elemOffset.left,
+                                                       y=touch.pageY-elemOffset.top;
+                                               if(x<elem.width() && x>0 && y<elem.height() && y>0){
+                                                       mCSB_draggerTouchY=y;
+                                                       mCSB_draggerTouchX=x;
+                                               }
+                                       });
+                                       mCSB_dragger.bind("touchmove onmsgesturechange",function(e){
+                                               e.preventDefault();
+                                               e.stopPropagation();
+                                               var touch=e.originalEvent.touches[0] || e.originalEvent.changedTouches[0],
+                                                       elem=$(this),
+                                                       elemOffset=elem.offset(),
+                                                       x=touch.pageX-elemOffset.left,
+                                                       y=touch.pageY-elemOffset.top;
+                                               if($this.data("horizontalScroll")){
+                                                       $this.mCustomScrollbar("scrollTo",(mCSB_dragger.position().left-(mCSB_draggerTouchX))+x,{moveDragger:true});
+                                               }else{
+                                                       $this.mCustomScrollbar("scrollTo",(mCSB_dragger.position().top-(mCSB_draggerTouchY))+y,{moveDragger:true});
+                                               }
+                                       });
+                                       $this.data({"bindEvent_scrollbar_touch":true});
+                               }
+                               /*content touch-drag*/
+                               if(!$this.data("bindEvent_content_touch")){ /*bind once*/
+                                       var touch,
+                                               elem,
+                                               elemOffset,
+                                               x,
+                                               y,
+                                               mCSB_containerTouchY,
+                                               mCSB_containerTouchX;
+                                       mCSB_container.bind("touchstart onmsgesturestart",function(e){
+                                               touch=e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
+                                               elem=$(this);
+                                               elemOffset=elem.offset();
+                                               x=touch.pageX-elemOffset.left;
+                                               y=touch.pageY-elemOffset.top;
+                                               mCSB_containerTouchY=y;
+                                               mCSB_containerTouchX=x;
+                                       });
+                                       mCSB_container.bind("touchmove onmsgesturechange",function(e){
+                                               e.preventDefault();
+                                               e.stopPropagation();
+                                               touch=e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
+                                               elem=$(this).parent();
+                                               elemOffset=elem.offset();
+                                               x=touch.pageX-elemOffset.left;
+                                               y=touch.pageY-elemOffset.top;
+                                               if($this.data("horizontalScroll")){
+                                                       $this.mCustomScrollbar("scrollTo",mCSB_containerTouchX-x);
+                                               }else{
+                                                       $this.mCustomScrollbar("scrollTo",mCSB_containerTouchY-y);
+                                               }
+                                       });
+                                       $this.data({"bindEvent_content_touch":true});
+                               }
+                       }
+               },
+               scroll:function(bypassCallbacks){
+                       var $this=$(this),
+                               mCSB_dragger=$this.find(".mCSB_dragger"),
+                               mCSB_container=$this.find(".mCSB_container"),
+                               mCustomScrollBox=$this.find(".mCustomScrollBox");
+                       if($this.data("horizontalScroll")){
+                               var draggerX=mCSB_dragger.position().left,
+                                       targX=-draggerX*$this.data("scrollAmount"),
+                                       thisX=mCSB_container.position().left,
+                                       posX=Math.round(thisX-targX);
+                       }else{
+                               var draggerY=mCSB_dragger.position().top,
+                                       targY=-draggerY*$this.data("scrollAmount"),
+                                       thisY=mCSB_container.position().top,
+                                       posY=Math.round(thisY-targY);
+                       }
+                       if($.browser.webkit){ /*fix webkit zoom and jquery animate*/
+                               var screenCssPixelRatio=(window.outerWidth-8)/window.innerWidth,
+                                       isZoomed=(screenCssPixelRatio<.98 || screenCssPixelRatio>1.02);
+                       }
+                       if($this.data("scrollInertia")===0 || isZoomed){
+                               if(!bypassCallbacks){
+                                       $this.mCustomScrollbar("callbacks","onScrollStart"); /*user custom callback functions*/
+                               }
+                               if($this.data("horizontalScroll")){
+                                       mCSB_container.css("left",targX);
+                               }else{
+                                       mCSB_container.css("top",targY);
+                               }
+                               if(!bypassCallbacks){
+                                       /*user custom callback functions*/
+                                       if($this.data("whileScrolling")){
+                                               $this.data("whileScrolling_Callback").call();
+                                       }
+                                       $this.mCustomScrollbar("callbacks","onScroll");  
+                               }
+                               $this.data({"mCS_Init":false});
+                       }else{
+                               if(!bypassCallbacks){
+                                       $this.mCustomScrollbar("callbacks","onScrollStart"); /*user custom callback functions*/
+                               }
+                               if($this.data("horizontalScroll")){
+                                       mCSB_container.stop().animate({left:"-="+posX},$this.data("scrollInertia"),$this.data("scrollEasing"),function(){
+                                               if(!bypassCallbacks){
+                                                       $this.mCustomScrollbar("callbacks","onScroll"); /*user custom callback functions*/
+                                               }
+                                               $this.data({"mCS_Init":false});
+                                       });
+                               }else{
+                                       mCSB_container.stop().animate({top:"-="+posY},$this.data("scrollInertia"),$this.data("scrollEasing"),function(){
+                                               if(!bypassCallbacks){
+                                                       $this.mCustomScrollbar("callbacks","onScroll"); /*user custom callback functions*/
+                                               }
+                                               $this.data({"mCS_Init":false});
+                                       });
+                               }
+                       }
+               },
+               scrollTo:function(scrollTo,options){
+                       var defaults={
+                               moveDragger:false,
+                               callback:true
+                       },
+                               options=$.extend(defaults,options),
+                               $this=$(this),
+                               scrollToPos,
+                               mCustomScrollBox=$this.find(".mCustomScrollBox"),
+                               mCSB_container=mCustomScrollBox.children(".mCSB_container"),
+                               mCSB_draggerContainer=$this.find(".mCSB_draggerContainer"),
+                               mCSB_dragger=mCSB_draggerContainer.children(".mCSB_dragger"),
+                               targetPos;
+                       if(scrollTo || scrollTo===0){
+                               if(typeof(scrollTo)==="number"){ /*if integer, scroll by number of pixels*/
+                                       if(options.moveDragger){ /*scroll dragger*/
+                                               scrollToPos=scrollTo;
+                                       }else{ /*scroll content by default*/
+                                               targetPos=scrollTo;
+                                               scrollToPos=Math.round(targetPos/$this.data("scrollAmount"));
+                                       }
+                               }else if(typeof(scrollTo)==="string"){ /*if string, scroll by element position*/
+                                       var target;
+                                       if(scrollTo==="top"){ /*scroll to top*/
+                                               target=0;
+                                       }else if(scrollTo==="bottom" && !$this.data("horizontalScroll")){ /*scroll to bottom*/
+                                               target=mCSB_container.outerHeight()-mCustomScrollBox.height();
+                                       }else if(scrollTo==="left"){ /*scroll to left*/
+                                               target=0;
+                                       }else if(scrollTo==="right" && $this.data("horizontalScroll")){ /*scroll to right*/
+                                               target=mCSB_container.outerWidth()-mCustomScrollBox.width();
+                                       }else if(scrollTo==="first"){ /*scroll to first element position*/
+                                               target=$this.find(".mCSB_container").find(":first");
+                                       }else if(scrollTo==="last"){ /*scroll to last element position*/
+                                               target=$this.find(".mCSB_container").find(":last");
+                                       }else{ /*scroll to element position*/
+                                               target=$this.find(scrollTo);
+                                       }
+                                       if(target.length===1){ /*if such unique element exists, scroll to it*/
+                                               if($this.data("horizontalScroll")){
+                                                       targetPos=target.position().left;
+                                               }else{
+                                                       targetPos=target.position().top;
+                                               }
+                                               scrollToPos=Math.ceil(targetPos/$this.data("scrollAmount"));
+                                       }else{
+                                               scrollToPos=target;
+                                       }
+                               }
+                               /*scroll to*/
+                               if(scrollToPos<0){
+                                       scrollToPos=0;
+                               }
+                               if($this.data("horizontalScroll")){
+                                       if(scrollToPos>=mCSB_draggerContainer.width()-mCSB_dragger.width()){ /*max dragger position is bottom*/
+                                               scrollToPos=mCSB_draggerContainer.width()-mCSB_dragger.width();
+                                       }
+                                       mCSB_dragger.css("left",scrollToPos);
+                               }else{
+                                       if(scrollToPos>=mCSB_draggerContainer.height()-mCSB_dragger.height()){ /*max dragger position is bottom*/
+                                               scrollToPos=mCSB_draggerContainer.height()-mCSB_dragger.height();
+                                       }
+                                       mCSB_dragger.css("top",scrollToPos);
+                               }
+                               if(options.callback){
+                                       $this.mCustomScrollbar("scroll",false);
+                               }else{
+                                       $this.mCustomScrollbar("scroll",true);
+                               }
+                       }
+               },
+               callbacks:function(callback){
+                       var $this=$(this),
+                               mCustomScrollBox=$this.find(".mCustomScrollBox"),
+                               mCSB_container=$this.find(".mCSB_container");
+                       switch(callback){
+                               /*start scrolling callback*/
+                               case "onScrollStart":
+                                       if(!mCSB_container.is(":animated")){
+                                               $this.data("onScrollStart_Callback").call();
+                                       }
+                                       break;
+                               /*end scrolling callback*/
+                               case "onScroll":
+                                       if($this.data("horizontalScroll")){
+                                               var mCSB_containerX=Math.round(mCSB_container.position().left);
+                                               if(mCSB_containerX<0 && mCSB_containerX<=mCustomScrollBox.width()-mCSB_container.outerWidth()+$this.data("onTotalScroll_Offset")){
+                                                       $this.data("onTotalScroll_Callback").call();
+                                               }else if(mCSB_containerX>=-$this.data("onTotalScroll_Offset")){
+                                                       $this.data("onTotalScrollBack_Callback").call();
+                                               }else{
+                                                       $this.data("onScroll_Callback").call();
+                                               }
+                                       }else{
+                                               var mCSB_containerY=Math.round(mCSB_container.position().top);
+                                               if(mCSB_containerY<0 && mCSB_containerY<=mCustomScrollBox.height()-mCSB_container.outerHeight()+$this.data("onTotalScroll_Offset")){
+                                                       $this.data("onTotalScroll_Callback").call();
+                                               }else if(mCSB_containerY>=-$this.data("onTotalScroll_Offset")){
+                                                       $this.data("onTotalScrollBack_Callback").call();
+                                               }else{
+                                                       $this.data("onScroll_Callback").call();
+                                               }
+                                       }
+                                       break;
+                               /*while scrolling callback*/
+                               case "whileScrolling":
+                                       if($this.data("whileScrolling_Callback") && !$this.data("whileScrolling")){
+                                               $this.data({"whileScrolling":setInterval(function(){
+                                                       if(mCSB_container.is(":animated") && !$this.data("mCS_Init")){
+                                                               $this.data("whileScrolling_Callback").call();
+                                                       }
+                                               },$this.data("whileScrolling_Interval"))});
+                                       }
+                                       break;
+                       }
+               },
+               disable:function(resetScroll){
+                       var $this=$(this),
+                               mCustomScrollBox=$this.children(".mCustomScrollBox"),
+                               mCSB_container=mCustomScrollBox.children(".mCSB_container"),
+                               mCSB_scrollTools=mCustomScrollBox.children(".mCSB_scrollTools"),
+                               mCSB_dragger=mCSB_scrollTools.find(".mCSB_dragger");
+                       mCustomScrollBox.unbind("mousewheel focusin");
+                       if(resetScroll){
+                               if($this.data("horizontalScroll")){
+                                       mCSB_dragger.add(mCSB_container).css("left",0);
+                               }else{
+                                       mCSB_dragger.add(mCSB_container).css("top",0);
+                               }
+                       }
+                       mCSB_scrollTools.css("display","none");
+                       mCSB_container.addClass("mCS_no_scrollbar");
+                       $this.data({"bindEvent_mousewheel":false,"bindEvent_focusin":false}).addClass("mCS_disabled");
+               },
+               destroy:function(){
+                       var $this=$(this),
+                               content=$this.find(".mCSB_container").html();
+                       $this.find(".mCustomScrollBox").remove();
+                       $this.html(content).removeClass("mCustomScrollbar _mCS_"+$(document).data("mCustomScrollbar-index")).addClass("mCS_destroyed");
+               }
+       }
+       $.fn.mCustomScrollbar=function(method){
+               if(methods[method]){
+                       return methods[method].apply(this,Array.prototype.slice.call(arguments,1));
+               }else if(typeof method==="object" || !method){
+                       return methods.init.apply(this,arguments);
+               }else{
+                       $.error("Method "+method+" does not exist");
+               }
+       };
+})(jQuery); 
+/*iOS 6 bug fix 
+  iOS 6 suffers from a bug that kills timers that are created while a page is scrolling. 
+  The following fixes that problem by recreating timers after scrolling finishes (with interval correction).*/
+var iOSVersion=iOSVersion();
+if(iOSVersion>=6){
+       (function(h){var a={};var d={};var e=h.setTimeout;var f=h.setInterval;var i=h.clearTimeout;var c=h.clearInterval;if(!h.addEventListener){return false}function j(q,n,l){var p,k=l[0],m=(q===f);function o(){if(k){k.apply(h,arguments);if(!m){delete n[p];k=null}}}l[0]=o;p=q.apply(h,l);n[p]={args:l,created:Date.now(),cb:k,id:p};return p}function b(q,o,k,r,t){var l=k[r];if(!l){return}var m=(q===f);o(l.id);if(!m){var n=l.args[1];var p=Date.now()-l.created;if(p<0){p=0}n-=p;if(n<0){n=0}l.args[1]=n}function s(){if(l.cb){l.cb.apply(h,arguments);if(!m){delete k[r];l.cb=null}}}l.args[0]=s;l.created=Date.now();l.id=q.apply(h,l.args)}h.setTimeout=function(){return j(e,a,arguments)};h.setInterval=function(){return j(f,d,arguments)};h.clearTimeout=function(l){var k=a[l];if(k){delete a[l];i(k.id)}};h.clearInterval=function(l){var k=d[l];if(k){delete d[l];c(k.id)}};var g=h;while(g.location!=g.parent.location){g=g.parent}g.addEventListener("scroll",function(){var k;for(k in a){b(e,i,a,k)}for(k in d){b(f,c,d,k)}})}(window));
+}
+function iOSVersion(){
+       var agent=window.navigator.userAgent,
+               start=agent.indexOf('OS ');
+       if((agent.indexOf('iPhone')>-1 || agent.indexOf('iPad')>-1) && start>-1){
+               return window.Number(agent.substr(start+3,3).replace('_','.'));
+       }
+       return 0;
+}
\ No newline at end of file
diff --git a/lib/jquery.mousewheel.js b/lib/jquery.mousewheel.js
new file mode 100644 (file)
index 0000000..38b6095
--- /dev/null
@@ -0,0 +1,84 @@
+/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
+ * Licensed under the MIT License (LICENSE.txt).
+ *
+ * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
+ * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
+ * Thanks to: Seamus Leahy for adding deltaX and deltaY
+ *
+ * Version: 3.0.6
+ * 
+ * Requires: 1.2.2+
+ */
+
+(function($) {
+
+var types = ['DOMMouseScroll', 'mousewheel'];
+
+if ($.event.fixHooks) {
+    for ( var i=types.length; i; ) {
+        $.event.fixHooks[ types[--i] ] = $.event.mouseHooks;
+    }
+}
+
+$.event.special.mousewheel = {
+    setup: function() {
+        if ( this.addEventListener ) {
+            for ( var i=types.length; i; ) {
+                this.addEventListener( types[--i], handler, false );
+            }
+        } else {
+            this.onmousewheel = handler;
+        }
+    },
+    
+    teardown: function() {
+        if ( this.removeEventListener ) {
+            for ( var i=types.length; i; ) {
+                this.removeEventListener( types[--i], handler, false );
+            }
+        } else {
+            this.onmousewheel = null;
+        }
+    }
+};
+
+$.fn.extend({
+    mousewheel: function(fn) {
+        return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
+    },
+    
+    unmousewheel: function(fn) {
+        return this.unbind("mousewheel", fn);
+    }
+});
+
+
+function handler(event) {
+    var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0;
+    event = $.event.fix(orgEvent);
+    event.type = "mousewheel";
+    
+    // Old school scrollwheel delta
+    if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta/120; }
+    if ( orgEvent.detail     ) { delta = -orgEvent.detail/3; }
+    
+    // New school multidimensional scroll (touchpads) deltas
+    deltaY = delta;
+    
+    // Gecko
+    if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
+        deltaY = 0;
+        deltaX = -1*delta;
+    }
+    
+    // Webkit
+    if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; }
+    if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; }
+    
+    // Add event and delta to the front of the arguments
+    args.unshift(event, delta, deltaX, deltaY);
+    
+    return ($.event.dispatch || $.event.handle).apply(this, args);
+}
+
+})(jQuery);
diff --git a/src/javascripts/cowhide-ng-scrollable.js b/src/javascripts/cowhide-ng-scrollable.js
new file mode 100644 (file)
index 0000000..3e47169
--- /dev/null
@@ -0,0 +1,16 @@
+(function(ng, module) {
+  'use strict';
+
+  module.directive('chScrollable', function() {
+    return {
+      restrict: 'E',
+      template: '<div class="ch-scrollable" ng-transclude></div>',
+      replace: true,
+      transclude: true,
+
+      link: function postLink(scope, iElement, iAttrs) {
+        iElement.ch_scrollable('enable');
+      }
+    };
+  });
+})(window.angular, window.cowhide_ng_module);
diff --git a/src/javascripts/cowhide-scrollable.js b/src/javascripts/cowhide-scrollable.js
new file mode 100644 (file)
index 0000000..3d3e6f7
--- /dev/null
@@ -0,0 +1,49 @@
+(function($, undefined) {
+    'use strict';
+
+    var ChScrollable = function(element, options) {
+        $.fn.ch_widget.Constructor(element, options);
+        this.$element = $(element);
+        this.options = $.extend(
+            options,
+            $.fn.ch_widget.defaults,
+            {
+            });
+    };
+
+    ChScrollable.prototype = $.extend(
+        {},
+        $.fn.ch_widget.Constructor.prototype,
+        {
+            constructor: ChScrollable,
+
+            enable: function() {
+              this.$element.mCustomScrollbar();
+            }
+        }
+    );
+
+    $.fn.ch_scrollable = function(option) {
+        return this.each(function() {
+            var $this = $(this),
+                data = $this.data('ch_scrollable'),
+                options = typeof option == 'object' && option;
+
+            if (!data) {
+                $this.data('ch_scrollable', (data = new ChScrollable(this, options)));
+                data.register();
+            }
+
+            if(typeof option == 'string')
+                data[option]();
+        });
+    };
+
+    $.fn.ch_page.Constructor = ChScrollable;
+
+    /* CHSCROLLABLE DATA-API
+     * ================= */
+    $(function() {
+        $('div.ch-scrollable').ch_scrollable('enable');
+    })
+})(window.jQuery);