Cleanup and document menus
diff --git a/dev/js/spec/menuSpec.js b/dev/js/spec/menuSpec.js
index 55ee44b..f993d33 100644
--- a/dev/js/spec/menuSpec.js
+++ b/dev/js/spec/menuSpec.js
@@ -535,6 +535,15 @@
       expect(menu.element().childNodes[6]).toBe(undefined);
     });
 
+    it('should be nextable without active field', function () {
+      var menu = KorAP.HintMenu.create("cnx/", list);
+      menu.limit(3);
+      expect(menu.show()).toBe(true);
+      menu.next();
+      expect(menu.shownItem(0).active()).toEqual(true);
+    });
+
+
     it('should be prevable', function () {
       var menu = KorAP.HintMenu.create("cnx/", list);
       menu._firstActive = true;
@@ -623,6 +632,14 @@
       expect(menu.element().childNodes[6]).toBe(undefined);
     });
 
+    it('should be prevable without active field', function () {
+      var menu = KorAP.HintMenu.create("cnx/", list);
+      menu.limit(3);
+      expect(menu.show()).toBe(true);
+      menu.prev();
+      expect(menu.shownItem(2).active()).toEqual(true);
+      expect(menu.shownItem(2).lcField()).toEqual(' syntax');
+    });
 
     it('should be navigatable and filterable (prefix = "o")', function () {
       var menu = KorAP.HintMenu.create("cnx/", list);
diff --git a/dev/js/src/menu.js b/dev/js/src/menu.js
index b2c541e..2cd99d6 100644
--- a/dev/js/src/menu.js
+++ b/dev/js/src/menu.js
@@ -6,7 +6,7 @@
 /*
  * TODO: space is not a valid prefix!
  * TODO: Show the slider briefly on move (whenever screen is called).
- * TODO: Optimize scrolling to active item.
+ * TODO: Ignore alt+ and strg+ key strokes.
  */
 define([
   'menu/item',
@@ -75,46 +75,45 @@
       this._slider = sliderClass.create(this);
 
       // Create the element
-      var e = document.createElement("ul");
-      e.style.opacity = 0;
-      e.style.outline = 0;
-      e.setAttribute('tabindex', 0);
-      e.classList.add('menu');
-      e.classList.add('roll');
-      e.appendChild(this._prefix.element());
-      e.appendChild(this._lengthField.element());
-      e.appendChild(this._slider.element());
+      var el = document.createElement("ul");
+      with (el) {
+	style.opacity = 0;
+	style.outline = 0;
+	setAttribute('tabindex', 0);
+	classList.add('menu', 'roll');
+	appendChild(this._prefix.element());
+	appendChild(this._lengthField.element());
+	appendChild(this._slider.element());
+      };
 
       // This has to be cleaned up later on
-      e["menu"] = this;
+      el["menu"] = this;
 
       // Arrow keys
-      e.addEventListener(
+      el.addEventListener(
 	'keydown',
 	this._keydown.bind(this),
 	false
       );
 
       // Strings
-      e.addEventListener(
+      el.addEventListener(
 	'keypress',
 	this._keypress.bind(this),
 	false
       );
 
       // Mousewheel
-      e.addEventListener(
+      el.addEventListener(
 	'wheel',
 	this._mousewheel.bind(this),
 	false
       );
+      this._element = el;
 
-      this._element = e;
-      this.active = false;
-      // this.selected = undefined;
       this._items = new Array();
-      var i = 0;
 
+      var i = 0;
       // Initialize item list based on parameters
       for (i in params) {
 	var obj = this._itemClass.create(params[i]);
@@ -125,12 +124,14 @@
 	this._items.push(obj);
       };
 
-      this._limit    = menuLimit;
-      this._slider.length(this.liveLength());
-      this._slider.limit(this._limit);
+      this._limit = menuLimit;
+      this._slider.length(this.liveLength())
+	.limit(this._limit)
+	.reInit();
 
       this._firstActive = false; // Show the first item active always?
-      this._reset();
+      this.offset = 0;
+      this.position = 0;
       return this;
     },
 
@@ -147,7 +148,7 @@
       };
 
       // Offset is initially zero
-      this._offset = 0;
+      this.offset = 0;
 
       // There is no prefix set
       if (this.prefix().length <= 0) {
@@ -159,7 +160,7 @@
 	  this._items[i].lowlight();
 	};
 
-	this._slider.length(i);
+	this._slider.length(i).reInit();;
 
 	return true;
       };
@@ -188,7 +189,7 @@
 	};
       };
 
-      this._slider.length(this._list.length);
+      this._slider.length(this._list.length).reInit();
 
       // Filter was successful - yeah!
       return this._list.length > 0 ? true : false;
@@ -320,7 +321,7 @@
 	nr = (this.liveLength() - this.limit());
       };
 
-      if (this._offset === nr)
+      if (this.offset === nr)
 	return;
 
       this._showItems(nr);
@@ -348,7 +349,7 @@
       if (arguments.length === 1) {
 	if (this._limit !== limit) {
 	  this._limit = limit;
-	  this._slider.limit(limit);
+	  this._slider.limit(limit).reInit();
 	};
 	return this;
       };
@@ -428,7 +429,7 @@
 	this.position = -1;
       };
 
-      this._offset = offset;
+      this.offset = offset;
       this._showItems(offset); // Show new item list
 
       // Make chosen value active
@@ -452,8 +453,6 @@
      * Hide the menu and call the onHide callback.
      */
     hide : function () {
-      this.active = false;
-      this._unmark();
       this.removeItems();
       this._element.style.opacity = 0;
       this._prefix.clear();
@@ -545,12 +544,12 @@
     shownItem : function (index) {
       if (index >= this.limit())
 	return;
-      return this.liveItem(this._offset + index);
+      return this.liveItem(this.offset + index);
     },
 
 
     /**
-     * Get the length of the full list
+     * Get the length of the full item list
      */
     length : function () {
       return this._items.length;
@@ -572,24 +571,18 @@
      */
     next : function () {
 
-      // No active element set
-      var newItem;
-
-      if (this.position !== -1) {
-	// Set new live item
-	if (!this._prefix.active()) {
-	  var oldItem = this.liveItem(this.position);
-	  oldItem.active(false);
-	};
-      };
-
       // No list
       if (this.liveLength() === 0)
 	return;
 
-      this.position++;
+      // Deactivate old item
+      if (this.position !== -1 && !this._prefix.active()) {
+	this.liveItem(this.position).active(false);
+      };
 
-      newItem = this.liveItem(this.position);
+      // Get new active item
+      this.position++;
+      var newItem = this.liveItem(this.position);
 
       // The next element is undefined - roll to top or to prefix
       if (newItem === undefined) {
@@ -597,26 +590,29 @@
 	// Activate prefix
 	var prefix = this._prefix;
 
-	// Mark prefix
+	// Prefix is set and not active - choose!
 	if (prefix.isSet() && !prefix.active()) {
 	  this.position--;
 	  prefix.active(true);
 	  return;
 	}
+
+	// Choose first item
 	else {
-	  this.position = 0;
 	  newItem = this.liveItem(0);
+	  // choose first item
+	  this.position = 0;
 	  this._showItems(0);
 	};
       }
 
       // The next element is after the viewport - roll down
-      else if (this.position >= (this.limit() + this._offset)) {
+      else if (this.position >= (this.limit() + this.offset)) {
 	this.screen(this.position - this.limit() + 1);
       }
 
       // The next element is before the viewport - roll up
-      else if (this.position <= this._offset) {
+      else if (this.position <= this.offset) {
 	this.screen(this.position);
       };
 
@@ -629,25 +625,26 @@
      */
     prev : function () {
 
-      // No active element set
-      if (this.position === -1) {
-	// TODO: Choose last item
-	return;
-      };
-
       // No list
       if (this.liveLength() === 0)
 	return;
 
-      var newItem;
-
-      // Set new live item
+      // Deactivate old item
       if (!this._prefix.active()) {
-	var oldItem = this.liveItem(this.position--);
-	oldItem.active(false);
+
+	// No active element set
+	if (this.position === -1) {
+	  this.position = this.liveLength();
+	}
+
+	// No active element set
+	else {
+	  this.liveItem(this.position--).active(false);
+	};
       };
 
-      newItem = this.liveItem(this.position);
+      // Get new active item
+      var newItem = this.liveItem(this.position);
 
       // The previous element is undefined - roll to bottom
       if (newItem === undefined) {
@@ -655,34 +652,35 @@
 	// Activate prefix
 	var prefix = this._prefix;
 	var offset =  this.liveLength() - this.limit();
-	// this._offset = this.liveLength() - this.limit();
 
 	// Normalize offset
-	// this._offset = this._offset < 0 ? 0 : this._offset;
 	offset = offset < 0 ? 0 : offset;
 
+	// Choose the last item
 	this.position = this.liveLength() - 1;
 
+	// Prefix is set and not active - choose!
 	if (prefix.isSet() && !prefix.active()) {
 	  this.position++;
 	  prefix.active(true);
-	  this._offset = offset;
+	  this.offset = offset;
 	  return;
 	}
+
+	// Choose last item
 	else {
 	  newItem = this.liveItem(this.position);
-	  this._unmark();
 	  this._showItems(offset);
 	};
       }
 
       // The previous element is before the view - roll up
-      else if (this.position < this._offset) {
+      else if (this.position < this.offset) {
 	this.screen(this.position);
       }
 
       // The previous element is after the view - roll down
-      else if (this.position >= (this.limit() + this._offset)) {
+      else if (this.position >= (this.limit() + this.offset)) {
 	this.screen(this.position - this.limit() + 2);
       };
 
@@ -694,7 +692,7 @@
      * Move the page up by limit!
      */
     pageUp : function () {
-      this.screen(this._offset - this.limit());
+      this.screen(this.offset - this.limit());
     },
 
 
@@ -702,7 +700,7 @@
      * Move the page down by limit!
      */
     pageDown : function () {
-      this.screen(this._offset + this.limit());
+      this.screen(this.offset + this.limit());
     },
 
 
@@ -715,15 +713,6 @@
       };
     },
 
-
-    // Reset chosen item and prefix
-    _reset : function () {
-      this._offset = 0;
-      this.position = 0;
-      this._prefix.clear();
-    },
-
-
     // Set boundary for viewport
     _boundary : function (bool) {
       this.item(this._list[0]).noMore(bool);
@@ -735,21 +724,27 @@
     _showItems : function (off) {
 
       // optimization: scroll down one step
-      if (this._offset === (off - 1)) {
-	this._offset = off;
-	this._removeFirst();
-	var pos = this._offset + this.limit() - 1;
+      if (this.offset === (off - 1)) {
+	this.offset = off;
+
+	// Remove the HTML node from the first item
+	// leave lengthField/prefix/slider
+	this._element.removeChild(this._element.children[3]);
+	var pos = this.offset + this.limit() - 1;
 	this._append(this._list[pos]);
       }
 
       // optimization: scroll up one step
-      else if (this._offset === (off + 1)) {
-	this._offset = off;
-	this._removeLast();
-	this._prepend(this._list[this._offset]);
+      else if (this.offset === (off + 1)) {
+	this.offset = off;
+
+	// Remove the HTML node from the last item
+	this._element.removeChild(this._element.lastChild);
+
+	this._prepend(this._list[this.offset]);
       }
       else {
-	this._offset = off;
+	this.offset = off;
 
 	// Remove all items
 	this.removeItems();
@@ -775,7 +770,7 @@
       };
 
       // set the slider to the new offset
-      this._slider.offset(this._offset);
+      this._slider.offset(this.offset);
     },
 
 
@@ -804,26 +799,12 @@
       };
 
       var e = this.element();
+
       // Append element after lengthField/prefix/slider
       e.insertBefore(
 	item.element(),
 	e.children[3]
       );
-    },
-
-
-    // Remove the HTML node from the first item
-    _removeFirst : function () {
-      // this.item(this._list[this._offset]).lowlight();
-      // leave lengthField/prefix/slider
-      this._element.removeChild(this._element.children[3]);
-    },
-
-
-    // Remove the HTML node from the last item
-    _removeLast : function () {
-      // this.item(this._list[this._offset + this.limit() - 1]).lowlight();
-      this._element.removeChild(this._element.lastChild);
     }
   };
 });
diff --git a/dev/js/src/menu/slider.js b/dev/js/src/menu/slider.js
index 0b0aed0..baef16a 100644
--- a/dev/js/src/menu/slider.js
+++ b/dev/js/src/menu/slider.js
@@ -1,32 +1,56 @@
+/**
+ * Create slider for menus.
+ * The slider will only be used by mouse - touch support
+ * shouldn't be necessary, as the menu can be scrolled using touch.
+ *
+ * @author Nils Diewald
+ */
 define({
 
   /**
-   * Create new slider object.
-   * The slider will only be used by mouse - touch support
-   * shouldn't be necessary.
+   * Create new slider for Menu.
+   * @this {Slider}
+   * @constructor
+   * @param {Menu} menu object
    */
   create : function (menu) {
     return Object.create(this)._init(menu);
   },
 
+  /**
+   * Length attribute of the slider
+   * (as number of items).
+   *
+   * @param {number} Number of items (optional)
+   */
   length : function (i) {
     if (arguments.length === 0)
       return this._length;
     if (i == this._length)
-      return;
+      return this;
     this._length = i;
-    this._initSize();
+    return this;
   },
 
+  /**
+   * Limit of items per screen.
+   *
+   * @param {number} Number of items per screen (optional)
+   */
   limit : function (i) {
     if (arguments.length === 0)
       return this._limit;
     if (i == this._limit)
-      return;
+      return this;
     this._limit = i;
-    this._initSize();
+    return this;
   },
 
+  /**
+   * Is the slider active or not.
+   *
+   * @param {bool} true or false (optional)
+   */
   active : function (bool) {
     if (arguments.length === 1) {
       if (bool) {
@@ -43,6 +67,11 @@
     return this._active;
   },
 
+  /**
+   * Move the slider to a relative position
+   *
+   * @param {number} relative position
+   */
   movetoRel : function (relativePos) {
     var diffHeight = (this._rulerHeight - this._sliderHeight);
     var relativeOffset = (relativePos / diffHeight);
@@ -53,6 +82,11 @@
     };
   },
 
+  /**
+   * Move the slider to an absolute position
+   *
+   * @param {number} absolute position
+   */
   movetoAbs : function (absPos) {
     var absOffset = (absPos / this._rulerHeight);
 
@@ -62,30 +96,61 @@
     };
   },
 
+  /**
+   * Screen offset of the slider
+   *
+   * @param {number} Offset position of the slider (optional)
+   */
   offset : function (off) {
     if (arguments.length === 0)
       return this._offset;
 
-    if (off > this._screens) {
+    // Normalize offset
+    if (off > this._screens)
       off = this._screens;
-    }
-    else if (off < 0) {
+    else if (off < 0)
       off = 0;
-    };
 
+    // Identical with old value
     if (off === this._offset)
       return undefined;
 
+    // Set offset and move
     this._offset = off;
     this._slider.style.top = (this._step * off) + '%';
-
     return off;
   },
 
+  /**
+   * Get the associated dom element.
+   */
   element : function () {
     return this._element;
   },
 
+  /**
+   * Reinitialize the size of the slider.
+   * Necessary to call after each adjustment of the list.
+   */
+  reInit : function () {
+
+    var s = this._element.style;
+
+    // Do not show the slider, in case there is nothing to scroll
+    if (this._length <= this._limit) {
+      s.display = 'none';
+      return;
+    }
+    else {
+      s.display = 'block';
+    };
+
+    this._height  = ((this._limit / this._length) * 100);
+    this._screens = this._length - this._limit;
+    this._step    = (100 - this._height) / this._screens;
+    this._slider.style.height = this._height + '%';
+  },
+
   // Initialize prefix object
   _init : function (menu) {
 
@@ -95,14 +160,14 @@
     this._event = {};
     this._active = false;
 
-    this._element = document.createElement('div');
-    this._element.setAttribute('class', 'ruler');
+    var el = this._element = document.createElement('div');
+    el.setAttribute('class', 'ruler');
 
-    this._slider = this._element.appendChild(
+    this._slider = el.appendChild(
       document.createElement('span')
     );
 
-    this._ruler = this._element.appendChild(document.createElement('div'));
+    this._ruler = el.appendChild(document.createElement('div'));
 
     // Do not mark the menu on mousedown
     this._ruler.addEventListener('mousedown', function (e) {
@@ -117,32 +182,19 @@
     return this;
   },
 
-  _initSize : function () {
-    if (this._length <= this._limit) {
-      this._element.style.display = 'none';
-      return;
-    }
-    else {
-      this._element.style.display = 'block';
-    };
-
-    this._height = ((this._limit / this._length) * 100);
-    this._screens = this._length - this._limit;
-    this._step = (100 - this._height) / this._screens;
-    this._slider.style.height = this._height + '%';
-  },
-
+  // Reinit height based on dom position
   _initClientHeight : function () {
-    this._rulerHeight  = this._element.clientHeight; // offsetHeight?
-    this._sliderHeight = this._slider.clientHeight;  // offsetHeight?
+    this._rulerHeight  = this._element.clientHeight;
+    this._sliderHeight = this._slider.clientHeight;
   },
 
+  // Release mousemove event
   _mousemove : function (e) {
     this.movetoRel(e.clientY - this._event.init);
     e.halt();
-    // Support touch!
   },
 
+  // Release mouseup event
   _mouseup : function (e) {
     this.active(false);
     window.removeEventListener('mousemove', this._event.mov);
@@ -150,12 +202,13 @@
     this._menu.focus();
   },
 
+  // Release mousedown event
   _mousedown : function (e) {
     // Bind drag handler
     var ev = this._event;
     ev.init = e.clientY - (this._step * this._offset);
-    ev.mov = this._mousemove.bind(this);
-    ev.up = this._mouseup.bind(this);
+    ev.mov  = this._mousemove.bind(this);
+    ev.up   = this._mouseup.bind(this);
 
     // TODO: This may not be necessary all the time
     this._initClientHeight();
@@ -168,6 +221,7 @@
     e.halt();
   },
 
+  // Release event to reposition slider on ruler
   _mouseclick : function (e) {
     this._initClientHeight();