Use requirejs for clientside scripting
diff --git a/dev/js/src/menu.js b/dev/js/src/menu.js
index 78f9ea7..0d5e6ac 100644
--- a/dev/js/src/menu.js
+++ b/dev/js/src/menu.js
@@ -1,35 +1,35 @@
-var KorAP = KorAP || {};
-
 /**
  * Create scrollable drop-down menus.
  *
  * @author Nils Diewald
  */
-
 /*
-  * TODO: space is not a valid prefix!
+ * TODO: space is not a valid prefix!
  */
-(function (KorAP) {
-  "use strict";
+define([
+  'menu/item',
+  'menu/prefix',
+  'util'
+], function (defaultItemClass,
+	     defaultPrefixClass) {
 
-  // Don't let events bubble up
-  if (Event.halt === undefined) {
-    // Don't let events bubble up
-    Event.prototype.halt = function () {
-      this.stopPropagation();
-      this.preventDefault();
-    };
+  // Todo: This may not be necessary
+  // Default maximum number of menu items
+  var menuLimit = 8;
+
+  function _codeFromEvent (e) {
+    if (e.charCode && (e.keyCode == 0))
+      return e.charCode
+    return e.keyCode;
   };
 
-  // Default maximum number of menu items
-  KorAP.menuLimit = 8;
 
   /**
    * List of items for drop down menu (complete).
    * Only a sublist of the menu is filtered (live).
    * Only a sublist of the filtered menu is visible (shown).
    */
-  KorAP.Menu = {
+  return {
     /**
      * Create new Menu based on the action prefix
      * and a list of menu items.
@@ -40,7 +40,7 @@
      * @param {Array.<Array.<string>>} List of menu items
      */
     create : function (params) {
-      return Object.create(KorAP.Menu)._init(params);
+      return Object.create(this)._init(params);
     },
 
     /**
@@ -143,12 +143,12 @@
     // Initialize list
     _init : function (itemClass, prefixClass, params) {
       var that = this;
-      this._itemClass = itemClass;
+      this._itemClass = itemClass || defaultItemClass;
 
       if (prefixClass !== undefined)
 	this._prefix = prefixClass.create();
       else
-	this._prefix = KorAP.MenuPrefix.create();
+	this._prefix = defaultPrefixClass.create();
 
       this._prefix._menu = this;
 
@@ -188,14 +188,14 @@
 
       // Initialize item list based on parameters
       for (i in params) {
-	var obj = itemClass.create(params[i]);
+	var obj = this._itemClass.create(params[i]);
 
 	// This may become circular
 	obj["_menu"] = this;
 
 	this._items.push(obj);
       };
-      this._limit    = KorAP.menuLimit;
+      this._limit    = menuLimit;
       this._position = 0;  // position in the active list
       this._active   = -1; // active item in the item list
       this._reset();
@@ -654,318 +654,4 @@
       this._element.removeChild(this._element.lastChild);
     }
   };
-
-
-  /**
-   * Item in the Dropdown menu
-   */
-  KorAP.MenuItem = {
-
-    /**
-     * Create a new MenuItem object.
-     *
-     * @constructor
-     * @this {MenuItem}
-     * @param {Array.<string>} An array object of name, action and
-     *   optionally a description
-     */
-    create : function (params) {
-      return Object.create(KorAP.MenuItem)._init(params);
-    },
-
-    /**
-     * Upgrade this object to another object,
-     * while private data stays intact.
-     *
-     * @param {Object] An object with properties.
-     */
-    upgradeTo : function (props) {
-      for (var prop in props) {
-	this[prop] = props[prop];
-      };
-      return this;
-    },
-
-    content : function (content) {
-      if (arguments.length === 1)
-	this._content = document.createTextNode(content);
-      return this._content;
-    },
-
-    lcField : function () {
-      return this._lcField;
-    },
-
-    action : function (action) {
-      if (arguments.length === 1)
-	this._action = action;
-      return this._action;
-    },
-
-    /**
-     * Check or set if the item is active
-     *
-     * @param {boolean|null} State of activity
-     */
-    active : function (bool) {
-      var cl = this.element().classList;
-      if (bool === undefined)
-	return cl.contains("active");
-      else if (bool)
-	cl.add("active");
-      else
-	cl.remove("active");
-    },
-
-    /**
-     * Check or set if the item is
-     * at the boundary of the menu
-     * list
-     *
-     * @param {boolean|null} State of activity
-     */
-    noMore : function (bool) {
-      var cl = this.element().classList;
-      if (bool === undefined)
-	return cl.contains("no-more");
-      else if (bool)
-	cl.add("no-more");
-      else
-	cl.remove("no-more");
-    },
-
-    /**
-     * Get the document element of the menu item
-     */
-    element : function () {
-      // already defined
-      if (this._element !== undefined)
-	return this._element;
-
-      // Create list item
-      var li = document.createElement("li");
-
-      // Connect action
-      if (this["onclick"] !== undefined) {
-	li["onclick"] = this.onclick.bind(this);
-      };
-
-      // Append template
-      li.appendChild(this.content());
-
-      return this._element = li;
-    },
-
-    /**
-     * Highlight parts of the item
-     *
-     * @param {string} Prefix string for highlights
-     */
-    highlight : function (prefix) {
-      var children = this.element().childNodes;
-      for (var i = children.length -1; i >= 0; i--) {
-	this._highlight(children[i], prefix);
-      };
-    },
-
-    // Highlight a certain substring of the menu item
-    _highlight : function (elem, prefix) {
-
-      if (elem.nodeType === 3) {
-
-	var text   = elem.nodeValue;
-	var textlc = text.toLowerCase();
-	var pos    = textlc.indexOf(prefix);
-	if (pos >= 0) {
-
-	  // First element
-	  if (pos > 0) {
-	    elem.parentNode.insertBefore(
-	      document.createTextNode(text.substr(0, pos)),
-	      elem
-	    );
-	  };
-
-	  // Second element
-	  var hl = document.createElement("mark");
-	  hl.appendChild(
-	    document.createTextNode(text.substr(pos, prefix.length))
-	  );
-	  elem.parentNode.insertBefore(hl, elem);
-
-	  // Third element
-	  var third = text.substr(pos + prefix.length);
-	  if (third.length > 0) {
-	    var thirdE = document.createTextNode(third);
-	    elem.parentNode.insertBefore(
-	      thirdE,
-	      elem
-	    );
-	    this._highlight(thirdE, prefix);
-	  };
-
-	  var p = elem.parentNode;
-	  p.removeChild(elem);
-	};
-      }
-      else {
-	var children = elem.childNodes;
-	for (var i = children.length -1; i >= 0; i--) {
-	  this._highlight(children[i], prefix);
-	};
-      };
-    },
-
-
-    /**
-     * Remove highlight of the menu item
-     */
-    lowlight : function () {
-      var e = this.element();
-
-      var marks = e.getElementsByTagName("mark");
-      for (var i = marks.length - 1; i >= 0; i--) {
-	// Create text node clone
-	var x = document.createTextNode(
-	  marks[i].firstChild.nodeValue
-	);
-
-	// Replace with content
-	marks[i].parentNode.replaceChild(
-	  x,
-	  marks[i]
-	);
-      };
-
-      // Remove consecutive textnodes
-      e.normalize();
-    },
-
-    // Initialize menu item
-    _init : function (params) {
-
-      if (params[0] === undefined)
-	throw new Error("Missing parameters");
-
-      this.content(params[0]);
-
-      if (params.length === 2)
-	this._action = params[1];
-
-      this._lcField = ' ' + this.content().textContent.toLowerCase();
-
-      return this;
-    },
-
-    /**
-     * Return menu list.
-     */
-    menu : function () {
-      return this._menu;
-    }
-  };
-
-  KorAP.MenuPrefix = {
-    create : function (params) {
-      return Object.create(KorAP.MenuPrefix)._init();
-    },
-    _init : function () {
-      this._string = '';
-
-      // Add prefix span
-      this._element = document.createElement('span');
-      this._element.classList.add('pref');
-      // Connect action
-
-      if (this["onclick"] !== undefined)
-	this._element["onclick"] = this.onclick.bind(this);
-
-      return this;
-    },
-    _update : function () {
-      this._element.innerHTML
-      = this._string;
-    },
-
-    /**
-     * Upgrade this object to another object,
-     * while private data stays intact.
-     *
-     * @param {Object} An object with properties.
-     */
-    upgradeTo : function (props) {
-      for (var prop in props) {
-	this[prop] = props[prop];
-      };
-      return this;
-    },
-
-    active : function (bool) {
-      var cl = this.element().classList;
-      if (bool === undefined)
-	return cl.contains("active");
-      else if (bool)
-	cl.add("active");
-      else
-	cl.remove("active");
-    },
-
-    element : function () {
-      return this._element;
-    },
-
-    isSet : function () {
-      return this._string.length > 0 ?
-	true : false;
-    },
-
-    value : function (string) {
-      if (arguments.length === 1) {
-	this._string = string;
-	this._update();
-      };
-      return this._string;
-    },
-
-    add : function (string) {
-      this._string += string;
-      this._update();
-    },
-
-    onclick : function () {},
-
-    backspace : function () {
-      if (this._string.length > 1) {
-	this._string = this._string.substring(
-	  0, this._string.length - 1
-	);
-      }
-      else {
-	this._string = '';
-      };
-
-      this._update();
-    },
-
-    /**
-     * Return menu list.
-     */
-    menu : function () {
-      return this._menu;
-    }
-  };
-
-  function _codeFromEvent (e) {
-    if (e.charCode && (e.keyCode == 0))
-      return e.charCode
-    return e.keyCode;
-  };
-
-}(this.KorAP));
-
-/**
- * MenuItems may define:
- *
- * onclick: action happen on click and enter.
- * further: action happen on right arrow
- */
+});