Change buttonGroup API to accept various information in data parameter

Change-Id: I0c3eb998d9be04fd1e7955b6c412277ec44755aa
diff --git a/Changes b/Changes
index 09f4811..9d22d33 100755
--- a/Changes
+++ b/Changes
@@ -10,6 +10,8 @@
         - Exclude search results from robot indices.
         - Added responsive 'news' style.
         - Add support for icons in plugin definition (hebasta).
+        - Change buttonGroup API to accept class and
+          icon definitions.
 
         WARNING: If you relied on the former default API endpoint
           being http://localhost:9999/, this will break your
diff --git a/dev/demo/panel.html b/dev/demo/panel.html
index 5782365..ea8f57d 100644
--- a/dev/demo/panel.html
+++ b/dev/demo/panel.html
@@ -28,7 +28,7 @@
   let actions = panel.actions;
 
   // Add simple button
-  actions.add('Meta',['meta'], function () {
+  actions.add('Meta',{'cls':['meta']}, function () {
     console.log(this.button.classList.contains('meta'));
     view = kqClass.create();
     panel.add(view);
diff --git a/dev/js/spec/buttongroupSpec.js b/dev/js/spec/buttongroupSpec.js
index f51d90c..bf7eafb 100644
--- a/dev/js/spec/buttongroupSpec.js
+++ b/dev/js/spec/buttongroupSpec.js
@@ -26,7 +26,7 @@
       var group = buttonGroupClass.create();
       expect(group.element().classList.contains('button-group')).toBeTruthy();
 
-      group.add('Meta', ['meta', 'top'], function (e) {});
+      group.add('Meta', { 'cls':['meta', 'top']}, function (e) {});
 
       var btn = group.element().firstChild;
       expect(btn.tagName).toEqual('SPAN');
@@ -39,8 +39,8 @@
       var group = buttonGroupClass.create();
       expect(group.element().classList.contains('button-group')).toBeTruthy();
 
-      group.add('Meta', ['meta', 'top'], function (e) {});
-      group.add('Mate', ['mate'], function (e) {});
+      group.add('Meta', {'cls':['meta', 'top']}, function (e) {});
+      group.add('Mate', {'cls':['mate']}, function (e) {});
 
       var btn = group.element().children[0];
       expect(btn.tagName).toEqual('SPAN');
@@ -59,7 +59,7 @@
 
       expect(group.element().children.length).toEqual(0);
 
-      group.add('New', ['new'], function (e) {});
+      group.add('New', {'cls':['new']}, function (e) {});
 
       btn = group.element().children[0];
       expect(btn.tagName).toEqual('SPAN');
@@ -110,7 +110,7 @@
       var group = buttonGroupClass.create();
       expect(group.element().classList.contains('button-group')).toBeTruthy();
 
-      group.add('Meta', ['meta'], function (e) {}, 'metaicon');
+      group.add('Meta', {'cls':['meta'], 'icon': 'metaicon'}, function (e) {});
 
       var btn = group.element().firstChild;
       expect(btn.tagName).toEqual('SPAN');
@@ -124,7 +124,7 @@
       var group = buttonGroupClass.create();
       expect(group.element().classList.contains('button-group')).toBeTruthy();
 
-      var list = group.addList('More', ['more']);
+      var list = group.addList('More', {'cls':['more']});
 
       list.readItems([
         ['cool', 'cool', function () { }],
@@ -156,7 +156,7 @@
 
       expect(s.get()).toBeFalsy();
       
-      group.addToggle('example',["examplecls"],s);
+      group.addToggle('example',{'cls':["examplecls"]}, s);
 
       let e = group.element();
 
diff --git a/dev/js/spec/panelSpec.js b/dev/js/spec/panelSpec.js
index 9df1c22..d0a9349 100644
--- a/dev/js/spec/panelSpec.js
+++ b/dev/js/spec/panelSpec.js
@@ -90,7 +90,7 @@
       var panel = panelClass.create();
 
       controlStr = "";
-      panel.actions.add("New", ["new"], function () {
+      panel.actions.add("New", {'cls':["new"]}, function () {
         controlStr = 'New!!!';
       });
 
diff --git a/dev/js/src/buttongroup.js b/dev/js/src/buttongroup.js
index b4d7813..e71d082 100644
--- a/dev/js/src/buttongroup.js
+++ b/dev/js/src/buttongroup.js
@@ -49,16 +49,19 @@
      * 
      * Returns the button element
      */
-    // TODO: Accept an object instead of a list
-    add : function (title, classes, cb, icon) {
+    add : function (title, data, cb) {
+      
       var b = this._element.addE('span');
       b.setAttribute('title',title);
-      if (classes !== undefined) {
-        b.classList.add.apply(b.classList, classes);
-      };
+
+      if (data !== undefined) {
+        if (data['cls'] !== undefined) {
+          b.classList.add.apply(b.classList, data['cls']);
+        };
      
-      if (icon !== undefined){ 
-        b.setAttribute('data-icon', icon);
+        if (data['icon'] !== undefined){ 
+          b.setAttribute('data-icon', data['icon']);
+        };
       };
      
       b.addE('span').addT(title);
@@ -84,10 +87,9 @@
      * 
      * Returns the list object.
      */
-    // TODO: Support icons by switching to a data object (see add())
-    addList : function (title, classes, itemClass = defaultItemClass) {
+    addList : function (title, data, itemClass = defaultItemClass) {
       var list = treeMenuClass.create([], itemClass);
-      this.add(title, classes, function (e) {
+      this.add(title, data, function (e) {
         list.show();
         list.button(this.button);
         list.focus();
@@ -100,11 +102,14 @@
      * Add button that can toggle a state.
      * The state has to be a state object.
      */
-    addToggle : function (title, classes, state) {
+    addToggle : function (title, data, state) {
       let b = this._element.addE('span');
       b.setAttribute('title',title);
-      if (classes !== undefined) {
-        b.classList.add.apply(b.classList, classes);
+
+      if (data != undefined) {
+        if (data['cls'] !== undefined) {
+          b.classList.add.apply(b.classList, data['cls']);
+        };
       };
 
       // Set check marker
diff --git a/dev/js/src/match.js b/dev/js/src/match.js
index f38a68a..92062cc 100644
--- a/dev/js/src/match.js
+++ b/dev/js/src/match.js
@@ -200,7 +200,7 @@
       );
 
       var that = this;
-      btn.add(loc.MINIMIZE, ['button-icon','minimize'], function () {
+      btn.add(loc.MINIMIZE, {'cls':['button-icon','minimize']}, function () {
         that.minimize();
       });
       element.appendChild(btn.element());
diff --git a/dev/js/src/panel/match.js b/dev/js/src/panel/match.js
index 64dbf5d..c901cee 100644
--- a/dev/js/src/panel/match.js
+++ b/dev/js/src/panel/match.js
@@ -44,21 +44,21 @@
 
       // Add meta button
       a.add(
-        loc.SHOW_META, ['metatable'], function (e) {
+        loc.SHOW_META, {'cls':['metatable']}, function (e) {
           this.addMeta();
         }
       );
 
       // Add token annotation button
       a.add(
-        loc.SHOWANNO, ['info'], function (e) {
+        loc.SHOWANNO, {'cls':['info']}, function (e) {
           this.addTable();
         }
       );
 
       // Add relations button
       a.add(
-        loc.ADDTREE, ['tree'], function (e) {
+        loc.ADDTREE, {'cls':['tree']}, function (e) {
 
           // Get global tree menu
           if (KorAP.TreeMenu === undefined) {
diff --git a/dev/js/src/panel/result.js b/dev/js/src/panel/result.js
index 15eb479..d221081 100644
--- a/dev/js/src/panel/result.js
+++ b/dev/js/src/panel/result.js
@@ -49,7 +49,7 @@
     addKqAction : function () {
 
       // Open KoralQuery view
-      var kqButton = this.actions.add(loc.SHOW_KQ, ['show-kq','button-icon'], function () {
+      var kqButton = this.actions.add(loc.SHOW_KQ, {'cls':['show-kq','button-icon']}, function () {
 
         // Show only once - otherwise toggle
         if (this._kq && this._kq.shown()) {
@@ -80,7 +80,7 @@
       /**
        * Toggle the alignment (left <=> right)
        */
-      this.actions.add(loc.TOGGLE_ALIGN, ['align','right','button-icon'], function (e) {
+      this.actions.add(loc.TOGGLE_ALIGN, {'cls':['align','right','button-icon']}, function (e) {
         var olCl = d.querySelector('#search > ol').classList;
         if (olCl.contains('align-left')) {
           olCl.remove('align-left');
diff --git a/dev/js/src/panel/vc.js b/dev/js/src/panel/vc.js
index 39deef5..978c442 100644
--- a/dev/js/src/panel/vc.js
+++ b/dev/js/src/panel/vc.js
@@ -28,7 +28,7 @@
      this.vc = vc;
      var actions = this.actions;
      var that = this;
-     actions.add(loc.SHOW_STAT, [ 'statistic' ], function() {
+      actions.add(loc.SHOW_STAT, {'cls':['statistic']}, function() {
        that.addCorpStat();
       });
      
diff --git a/dev/js/src/plugin/server.js b/dev/js/src/plugin/server.js
index 90dcd7c..cb49364 100644
--- a/dev/js/src/plugin/server.js
+++ b/dev/js/src/plugin/server.js
@@ -160,17 +160,17 @@
 
           // Add to dynamic button list (e.g. for matches)
           if (buttons[panel]) {
-            buttons[panel].push([title, embed["classes"], cb, icon]);
+            buttons[panel].push([title, {'cls':embed["classes"], 'icon': icon }, cb]);
           }
 
           // Add to static button list (e.g. for query) already loaded
           else if (KorAP.Panel[panel]) {
-            KorAP.Panel[panel].actions.add(title, embed["classes"], cb, icon);
+            KorAP.Panel[panel].actions.add(title, {'cls':embed["classes"], 'icon':icon}, cb);
           }
 
           // Add to static button list (e.g. for query) not yet loaded
           else {
-            buttonsSingle[panel].push([title, embed["classes"], cb, icon]);
+            buttonsSingle[panel].push([title, {'cls':embed["classes"], 'icon':icon}, cb]);
           }
         }
         //TODO There is no possibility to add icons to an plugin toggle button right now. 
@@ -181,7 +181,7 @@
 
           // TODO:
           //   Lazy registration (see above!)
-          KorAP.Panel[panel].actions.addToggle(title, ["title"], state);
+          KorAP.Panel[panel].actions.addToggle(title, {'cls':["title"]}, state);
 
           // Get the URL of the service
 
diff --git a/dev/js/src/plugin/widget.js b/dev/js/src/plugin/widget.js
index 068ced4..707f5f0 100644
--- a/dev/js/src/plugin/widget.js
+++ b/dev/js/src/plugin/widget.js
@@ -43,7 +43,7 @@
       // is a nice idea as well.
       
       this.actions.add(
-        this.name, ['button-icon', 'plugin'], function (e) {
+        this.name, {'cls':['button-icon', 'plugin']}, function (e) {
 
           // Temporary
           window.alert("Basic information about this plugin");
diff --git a/dev/js/src/tutorial.js b/dev/js/src/tutorial.js
index fe224b5..2420707 100644
--- a/dev/js/src/tutorial.js
+++ b/dev/js/src/tutorial.js
@@ -139,7 +139,7 @@
         );
 
         var that = this;
-        btn.add(loc.CLOSE, ['button-icon','close'], function () {
+        btn.add(loc.CLOSE, {'cls':['button-icon','close']}, function () {
           element.style.display = 'none';
         });
         element.appendChild(btn.element());
diff --git a/dev/js/src/vc.js b/dev/js/src/vc.js
index b3a621a..6cd3c00 100644
--- a/dev/js/src/vc.js
+++ b/dev/js/src/vc.js
@@ -319,7 +319,7 @@
         ['action','button-view']
       );
       var that = this;
-      btn.add(loc.MINIMIZE, ['button-icon','minimize'], function () {
+      btn.add(loc.MINIMIZE, {'cls':['button-icon','minimize']}, function () {
         that.minimize();
       });
       this._element.appendChild(btn.element());
diff --git a/dev/js/src/vc/operators.js b/dev/js/src/vc/operators.js
index 50605a3..306c371 100644
--- a/dev/js/src/vc/operators.js
+++ b/dev/js/src/vc/operators.js
@@ -91,17 +91,17 @@
       this.clear();
 
       if (this._and === true) {
-        this.add(loc.AND, ['and'], KorAP._and);
+        this.add(loc.AND, {'cls':['and']}, KorAP._and);
       };
 
       // Add or button
       if (this._or === true) {
-        this.add(loc.OR, ['or'], KorAP._or);
+        this.add(loc.OR, {'cls':['or']}, KorAP._or);
       };
 
       // Add delete button
       if (this._del === true) {
-        this.add(loc.DEL, ['delete'], KorAP._delete);
+        this.add(loc.DEL, {'cls':['delete']}, KorAP._delete);
       };
 
       return this.element();
diff --git a/dev/js/src/view.js b/dev/js/src/view.js
index d0a517c..7243837 100644
--- a/dev/js/src/view.js
+++ b/dev/js/src/view.js
@@ -26,7 +26,7 @@
       
       this.actions = buttonGroupClass.create(c).bind(this);
 
-      this.actions.add(loc.CLOSE, ['button-icon','close'], function (e) {
+      this.actions.add(loc.CLOSE, {'cls':['button-icon','close']}, function (e) {
         this.close();
       });
 
diff --git a/dev/js/src/view/match/relations.js b/dev/js/src/view/match/relations.js
index fda2cde..c61a4ff 100644
--- a/dev/js/src/view/match/relations.js
+++ b/dev/js/src/view/match/relations.js
@@ -85,7 +85,7 @@
           if (type === "spans") {
 
             // Download link
-            that.actions.add(loc.DOWNLOAD, ['button-icon','download'], function (e) {
+            that.actions.add(loc.DOWNLOAD, {'cls':['button-icon','download']}, function (e) {
               var a = treeObj.downloadLink();
               d.body.appendChild(a);
               a.click();
diff --git a/dev/js/src/view/vc/corpstatv.js b/dev/js/src/view/vc/corpstatv.js
index 410ee42..316018f 100644
--- a/dev/js/src/view/vc/corpstatv.js
+++ b/dev/js/src/view/vc/corpstatv.js
@@ -140,16 +140,16 @@
     disableStat : function(){
       var statt = this._show;
   
-      if(statt.getElementsByClassName('reloadStatB').length == 0){
+      if (statt.getElementsByClassName('reloadStatB').length == 0) {
         let btg = buttonGroup.create(['reloadStatB', 'button-panel']);
         var that = this;
-        btg.add(loc.REFRESH, ['refresh', 'button-icon'], function (e) {
+        btg.add(loc.REFRESH, {'cls':['refresh', 'button-icon']}, function (e) {
           statt.classList.remove('stdisabled');
           that.panel.reloadCorpStat(); 
         });
         statt.appendChild(btg.element());
         statt.classList.add('stdisabled');
-        }
+      };
     },