Use containerMenu as a base for HintMenu instead of regular menu

Change-Id: Ic1ed2e216a9c61aabf1f1cac41972b1a4e96a91a
diff --git a/dev/js/src/container/container.js b/dev/js/src/container/container.js
index 02d6fba..3f6a54d 100644
--- a/dev/js/src/container/container.js
+++ b/dev/js/src/container/container.js
@@ -7,7 +7,7 @@
 
 "use strict";
 define([
-  'container/containeritem'   //TODO why does this not work!!!
+  'container/containeritem'
 ], function (
   defaultContainerItemClass
 ) {
@@ -31,14 +31,10 @@
       } else {
         this._containerItemClass = defaultContainerItemClass;
       };
-      var el = document.createElement("ul");
-      el.style.outline = 0;
-      el.setAttribute('tabindex', 0);
-      el.classList.add('menu', 'container'); //container class allows for more stylesheet changes
-
-      this._el = el;
-      this._prefix = undefined; //required for re-setting the menus pointer correctly
-      // after having upgraded a new item scss style to the prefix object.
+      this._el = document.createElement("ul");
+      this._el.style.outline = 0;
+      this._el.setAttribute('tabindex', 0);
+      this._el.classList.add('menu', 'container'); //container class allows for more stylesheet changes
 
       this.items = new Array();
       //items are stored in the order they are added in. This includes the prefix.
@@ -54,24 +50,48 @@
       this._prefixPosition = undefined; //Required so that switching
       // to prefix by default is supported
 
+      this._menu = undefined // add later
+
 
       
       //t._el.classList.add('visible'); //Done by containermenu
+    },
 
-  },
-
+    /**
+     * Adds a static item to this container by creating a standard containerItem as specified when this container was created,
+     * then upgrading it to the item passed to this function, and calling element() and content(). For a full list of supported functions see
+     * containeritem.js .
+     * Example:
+     * 
+     * menu.container().addItem(
+     *  {defaultTextValue : "dynamic", onClick : function (e) { ... }
+     * )
+     * 
+     *  For a full demo see containermenudemo.js.
+     * 
+     * @param {Object} item An object with any number of functions like in containeritem.js or an attribute defaultTextValue,
+     * as well as any number of own properties.
+     * @returns the new use-ready containerItem
+     */
     addItem : function (item) {
+      //Call Order: First _containerItemClass is created and then upgraded To whatever object is passed to this function
+      //Then container calls first element() and then container()
       var cItem = this._containerItemClass.create().upgradeTo(item);
       cItem._menu = this._menu; //if not set then undefined, but thats OK
       this.items.push(cItem);
+      if (this._cItemPrefix !== undefined){ //this must be dynamic adding of CIs, move prefix to the back
+        this.items.splice(this.items.indexOf(this._cItemPrefix) , 1); //remove cItemPrefix
+        this.items.push(this._cItemPrefix); //and move it to the end;
+      };
       this._el.appendChild(cItem.element());
+      cItem.content(); // create its textNode
       return cItem;
     },
 
     addMenu : function (menu) {
       this._menu = menu;
-      if (this._prefix !== undefined) {
-        this._menu._prefix = this._prefix; // better than going via classList or something
+      if (this._cItemPrefix !== undefined) {
+        this._menu._prefix = this._cItemPrefix; // better than going via classList or something
       };
       for (let item of this.items) {
         item._menu=menu;
@@ -83,13 +103,16 @@
         return this.isSet(); //TODO check!
       }
       this._prefixPosition = this.items.length;
+      prefix.content = function () {}; //Does not need a textNode Child!
       var prefItem = this.addItem(prefix);
-      this._prefix = prefItem;
+      this._cItemPrefix = prefItem;
+      prefItem._el["onclick"] = prefItem.onclick.bind(prefItem);
       if (this._menu !== undefined){
         this._menu._prefix=prefItem;
       }
     },
     
+    //Taken from Branch 5133
     /**
     * Remove a containeritem from the container by identity. Should not be used with prefix.
     * If the active item is removed, this calls menu.next().
@@ -100,9 +123,10 @@
         KorAP.log(0,"Invalid item in containers removeItemByIndex: This containerItem is not contained", "container.js");
         return;
       };
-      if (item === this._prefix) {//CHANGE TO _cItemPrefix later!!!
-        KorAP.log(0,"Tried to remove the prefix item by calling removeItem. Please cut all connections from the menu to prefix and then\
- the connection container._prefix before calling this function if you really want to remove the prefix.","container.js");
+      if (item === this._cItemPrefix) {
+        KorAP.log(0,"Tried to remove the prefix item. Illegal.");
+        console.log("Tried to remove the prefix item by calling removeItem. Please cut all connections from the menu to prefix and then\
+ the connection container._cItemPrefix before calling this function if you really want to remove the prefix.","container.js");
         return;
       };
       if (item.active()) {
@@ -173,14 +197,14 @@
      * menus list empty while we had it selected.
      * This potentially requires adjusting this.position.
      */
-     makeActive : function () {
+    makeActive : function () {
       if (this.position === undefined) {
-        if (this._prefix.isSelectable()) {
+        if (this._cItemPrefix.isSelectable()) {
           this.position = this._prefixPosition; //make prefix active if it exists
           this.item().active(true);
         } else if (this.liveLength() > 0) {
           this.position = 0;
-          this._prefix.active(false); // usually the menu makes the prefix active anyway.
+          this._cItemPrefix.active(false); // usually the menu makes the prefix active anyway.
           this.item().active(true);
         }
       }
diff --git a/dev/js/src/container/containeritem.js b/dev/js/src/container/containeritem.js
index a9a209b..6d0ef59 100644
--- a/dev/js/src/container/containeritem.js
+++ b/dev/js/src/container/containeritem.js
@@ -31,9 +31,11 @@
 
   /**
    * Get/create the document element of the container item. Can be overwritten. Standard class: li
+   * If you wish to change the textNode please overwrite the content function instead.
    */
   element : function () {
-    // already defined
+    //Call Order: First this class is created and then upgraded To whatever object is passed to container
+    //Then container calls first element() and then container()
     if (this._el !== undefined) return this._el;
     
     // Create list item
@@ -47,7 +49,32 @@
   },
 
   /**
-   * Expected to be overwritten
+   * Get/create a TextNode with text "content". If content is left blank it gets set to this.defaultTextValue,
+   * or the empty string if it does not exists
+   * @param {String} content String to which to set the text
+   * @returns textNode with content or undefined
+   */
+  content : function (content) {
+    var newText; //set textNode to this
+    if (arguments.length === 1) { //new value!
+      newText = content;
+    } else { //use default
+      if (this.defaultTextValue === undefined) { //default default is ""
+        this.defaultTextValue = "";
+      }
+      newText = this.defaultTextValue;
+    };
+    if (this._content === undefined) { //no Element until now
+      this._content = document.createTextNode(newText); //create one
+      this.element().appendChild(this._content);
+    } else { //just change it
+      this._content.nodeValue = newText; // use nodeValue instead of _innerHTML
+    };
+    return this._content;
+  },
+
+  /**
+   * Expected to be overwritten. Default returns true always.
    * @returns whether the item is currently an option to be selected, or if it should just be skipped
    */
   isSelectable : function () {