Scroll menus with touch gestures on mobile devices

Change-Id: Ib9781b2ed678e546010aca195fc30cfbf504709d
diff --git a/dev/demo/menu.html b/dev/demo/menu.html
index e42f342..a0d2d5e 100644
--- a/dev/demo/menu.html
+++ b/dev/demo/menu.html
@@ -3,8 +3,15 @@
   <head>
     <title>Menu demo</title>
     <meta charset="utf-8" />
+
+    <!-- Load remote -->
+    <script data-main="/demo/menudemo.js" src="/js/lib/require.js" async="async"></script>
+    <link type="text/css" rel="stylesheet" href="/css/kalamar.css" />
+
+    <!-- Load local -->
     <script data-main="menudemo.js" src="../js/lib/require.js" async="async"></script>
     <link type="text/css" rel="stylesheet" href="../css/kalamar.css" />
+
     <style type="text/css" rel="stylesheet">
 .info {
   background-color: #ddd;
diff --git a/dev/demo/menudemo.js b/dev/demo/menudemo.js
index 1ca569a..d38c43f 100644
--- a/dev/demo/menudemo.js
+++ b/dev/demo/menudemo.js
@@ -2,7 +2,7 @@
   baseUrl: '../js/src'
 });
 
-require(['menu','menu/item', 'menu/prefix', 'menu/lengthField', 'selectMenu', 'hint/item', 'hint/lengthField', 'multimenu'], function (menuClass, itemClass, prefixClass, lengthFieldClass, selectMenuClass, hintItemClass, hintLengthField, multiMenuClass) {
+require(['menu','menu/item', 'menu/prefix', 'menu/lengthField', 'selectMenu', 'hint/item', 'hint/lengthField'], function (menuClass, itemClass, prefixClass, lengthFieldClass, selectMenuClass, hintItemClass, hintLengthField) {
 
   /**
    * Create own menu item class.
@@ -144,15 +144,16 @@
     ["XY", "XY ", "Non-Word"]
   ], { 'itemClass' : hintItemClass, 'lengthField' : hintLengthField });
 
-  var multiMenu = multiMenuClass.create([
+
+  /*var multiMenu = multiMenuClass.create([
     ["textSigle", "textSigle"],
     ["author", "author"]
   ]);
-
+  */
   
   document.getElementById('menu').appendChild(menu.element());
   document.getElementById('largemenu').appendChild(largeMenu.element());
-  document.getElementById('multimenu').appendChild(multiMenu.element());
+  // document.getElementById('multimenu').appendChild(multiMenu.element());
 
   menu.limit(3).show(3);
   menu.focus();
diff --git a/dev/demo/plugin-server.html b/dev/demo/plugin-server.html
index 5065d41..1c87fa2 100644
--- a/dev/demo/plugin-server.html
+++ b/dev/demo/plugin-server.html
@@ -7,7 +7,7 @@
         see https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
     <meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
 -->
-    <script data-main="/demo/plugin-serverdemo.js" src="/js/lib/require.js" async="async"></script>
+    <script data-main="/demo/menudemo.js" src="/js/lib/require.js" async="async"></script>
   </head>
   <body>
     <p>Start the demo server with <code>morbo -l 'http://*:3003' t/plugin-server.pl</code> and open <a href="http://localhost:3003/demo/plugin-server.html"><code>this website</code></a>.</p>
diff --git a/dev/js/src/menu.js b/dev/js/src/menu.js
index 439adbd..7155cdf 100644
--- a/dev/js/src/menu.js
+++ b/dev/js/src/menu.js
@@ -121,6 +121,25 @@
         this._mousewheel.bind(this),
         false
       );
+
+      // Touch
+      el.addEventListener(
+        'touchstart',
+        this._touch.bind(this),
+        false
+      );
+      el.addEventListener(
+        'touchend',
+        this._touch.bind(this),
+        false
+      );
+      el.addEventListener(
+        'touchmove',
+        this._touch.bind(this),
+        false
+      );
+
+      
       this._element = el;
 
       this._limit = menuLimit;
@@ -297,7 +316,6 @@
     // mouse wheel treatment
     _mousewheel : function (e) {
       var delta = 0;
-
       delta = e.deltaY / 120;
       if (delta > 0)
         this.next();
@@ -306,6 +324,34 @@
       e.halt();
     },
 
+    // touchmove treatment
+    _touch : function (e) {
+      var s = this.slider();
+      if (e.type === "touchstart") {
+        // s.active(true);
+        var t = e.touches[0];
+        this._lastTouch = t.clientY;
+      }
+      else if (e.type === "touchend") {
+        // s.active(false);
+        this._lastTouch = undefined;
+        // TODO:
+        // Release click event on touchend!
+      }
+      else if (e.type === "touchmove") {
+        var t = e.touches[0];
+        // s.movetoRel(t.clientY - this._initTouch);
+        if ((this._lastTouch + 26) < t.clientY) {
+          this.screen(this.offset - 1);
+          this._lastTouch = t.clientY;
+        }
+        else if ((this._lastTouch - 26) > t.clientY) {
+          this.screen(this.offset + 1);
+          this._lastTouch = t.clientY;
+        }
+        e.halt();
+      };
+    },
 
     // Arrow key and prefix treatment
     _keydown : function (e) {
diff --git a/dev/scss/header/menu.scss b/dev/scss/header/menu.scss
index 8841de5..7d76f4e 100644
--- a/dev/scss/header/menu.scss
+++ b/dev/scss/header/menu.scss
@@ -56,6 +56,7 @@
   @include choose-item;
 }
 
+ul.menu:active > div.ruler,
 ul.menu:hover > div.ruler,
 ul.menu > div.ruler.active {
   transition: opacity .1s ease;