Make actions private in panels and views

Change-Id: I3f2c68c6e51525bbba96c24c4fddf9f9498333b1
diff --git a/dev/js/spec/panelSpec.js b/dev/js/spec/panelSpec.js
index a72223d..8618369 100644
--- a/dev/js/spec/panelSpec.js
+++ b/dev/js/spec/panelSpec.js
@@ -41,7 +41,7 @@
       expect(e.lastChild.classList.contains("button-group")).toBeTruthy();
       expect(e.lastChild.firstChild).toBeFalsy();
 
-      expect(panel.actions).toBeTruthy();
+      expect(panel.actions()).toBeTruthy();
     });
 
     
@@ -49,7 +49,7 @@
       var panel = panelClass.create();
 
       controlStr = "";
-      panel.actions.add("New", {'cls':["new"]}, function () {
+      panel.actions().add("New", {'cls':["new"]}, function () {
         controlStr = 'New!!!';
       });
 
diff --git a/dev/js/spec/pluginSpec.js b/dev/js/spec/pluginSpec.js
index 43fd303..966d123 100644
--- a/dev/js/spec/pluginSpec.js
+++ b/dev/js/spec/pluginSpec.js
@@ -168,7 +168,7 @@
         }]
       });
 
-      let b = p.actions.element().firstChild;
+      let b = p.actions().element().firstChild;
       expect(b.hasAttribute("data-icon")).toBeFalsy();
       expect(b.hasAttribute("cls")).toBeFalsy();
       expect(b.getAttribute("title")).toEqual("Add");
@@ -209,7 +209,7 @@
         }]
       });
 
-      let b = p.actions.element().firstChild;
+      let b = p.actions().element().firstChild;
       expect(b.hasAttribute("data-icon")).toBeFalsy();
       expect(b.hasAttribute("cls")).toBeFalsy();
       expect(b.getAttribute("title")).toEqual("Add");
@@ -268,7 +268,7 @@
 
       expect(alertMsg).toBeUndefined();
 
-      let b = p.actions.element().firstChild;
+      let b = p.actions().element().firstChild;
       b.click();
 
       // This may only be temporary and should open the plugin window instead
@@ -307,7 +307,7 @@
 
       expect(alertMsg).toBeUndefined();
 
-      let b = p.actions.element().firstChild;
+      let b = p.actions().element().firstChild;
       b.click();
 
       // This may only be temporary and should open the plugin window instead
@@ -338,7 +338,7 @@
         }]
       });
 
-      let b = p.actions.element().firstChild;
+      let b = p.actions().element().firstChild;
       b.click();
       expect(p.element().querySelectorAll("iframe").length).toEqual(1);
       expect(p.element().querySelector("iframe").getAttribute('sandbox')).toEqual('allow-forms allow-scripts');
@@ -522,7 +522,7 @@
       });
 
       expect(manager.buttonGroup('result').length).toEqual(0);
-      expect(KorAP.Panel['result'].actions.element().innerHTML).toContain('Dosomething');
+      expect(KorAP.Panel['result'].actions().element().innerHTML).toContain('Dosomething');
 
       // Clean up
       KorAP.Panel['result'] = undefined;
@@ -553,7 +553,7 @@
       KorAP.Panel = KorAP.Panel || {};
       KorAP.Panel['result'] = resultPanel;
       expect(KorAP.Plugin.buttonGroup('result').length).toEqual(0);
-      expect(KorAP.Panel['result'].actions.element().innerHTML).toContain('Dosomething');
+      expect(KorAP.Panel['result'].actions().element().innerHTML).toContain('Dosomething');
      
       // Clean up
       KorAP.Panel['result'] = undefined;
diff --git a/dev/js/src/buttongroup.js b/dev/js/src/buttongroup.js
index 85543e4..755ad7f 100644
--- a/dev/js/src/buttongroup.js
+++ b/dev/js/src/buttongroup.js
@@ -106,6 +106,11 @@
      * Add button that can toggle a state.
      * The state has to be a state object.
      */
+    /*
+     * addToggle() should be removed in favor of add(toggleObj)
+     * or similar, so the API of buttongroups and lists is similar
+     * for use as action plugins.
+     */
     addToggle : function (title, data, state) {
       const b = this._el.addE('span');
       b.setAttribute('title',title);
diff --git a/dev/js/src/buttongroup/menu.js b/dev/js/src/buttongroup/menu.js
index 32ba0eb..4a4abfc 100644
--- a/dev/js/src/buttongroup/menu.js
+++ b/dev/js/src/buttongroup/menu.js
@@ -3,6 +3,9 @@
  */
 "use strict";
 
+// TODO:
+//   Add addToggle() method
+
 define(['menu'], function (menuClass) {
 
   return {
diff --git a/dev/js/src/init.js b/dev/js/src/init.js
index d246a8c..cc8abea 100644
--- a/dev/js/src/init.js
+++ b/dev/js/src/init.js
@@ -259,7 +259,7 @@
     if (resultInfo != null) {
 
       // Move buttons to resultinfo
-      resultInfo.appendChild(resultPanel.actions.element());
+      resultInfo.appendChild(resultPanel.actions().element());
 
       // The views are at the top of the search results
       var sb = d.getElementById('search');
diff --git a/dev/js/src/match.js b/dev/js/src/match.js
index df7db03..6c9fe6e 100644
--- a/dev/js/src/match.js
+++ b/dev/js/src/match.js
@@ -166,7 +166,7 @@
 
       // Insert before reference line
       refLine.insertBefore(
-        t.panel.actions.element(),
+        t.panel.actions().element(),
         refLine.firstChild
       );
 
diff --git a/dev/js/src/panel.js b/dev/js/src/panel.js
index bfc95c5..53ea757 100644
--- a/dev/js/src/panel.js
+++ b/dev/js/src/panel.js
@@ -32,17 +32,27 @@
       if (classes)
         c.push.apply(c,classes);
 
-      t.actions = buttonGroupClass.create(c).bind(this);
+      t._actions = buttonGroupClass.create(c).bind(this);
 
       //prepend or append views of the panel
       t.prepend = false;
       
       // Warning: This is circular
-      t.actions.panel = t;
+      t._actions.panel = t;
       return t;
     },
 
+
+    /**
+     * The actions of the panel.
+     * Can be represented as a buttongroup,
+     * a list, ..., requires an "add()" minimum at least.
+     */
+    actions : function () {
+      return this._actions;
+    },
     
+
     /**
      * The element of the panel
      */
@@ -62,7 +72,7 @@
 
       // Per default the action buttons are below the view
       // and integrated
-      const aElem = this.actions.element();
+      const aElem = this.actions().element();
       if (!aElem.parentNode)
         e.appendChild(aElem);
 
diff --git a/dev/js/src/panel/match.js b/dev/js/src/panel/match.js
index 603a230..6a3fe57 100644
--- a/dev/js/src/panel/match.js
+++ b/dev/js/src/panel/match.js
@@ -36,7 +36,7 @@
 
       this._match = match;
 
-      const a = this.actions;
+      const a = this.actions();
 
       // TODO:
       //   Ugly hack!
diff --git a/dev/js/src/panel/query.js b/dev/js/src/panel/query.js
index d2bf80f..a4658b0 100644
--- a/dev/js/src/panel/query.js
+++ b/dev/js/src/panel/query.js
@@ -22,7 +22,7 @@
     // Initialize panel
     _init : function (opened) {
       this._opened = opened;
-      const a = this.actions;
+      const a = this.actions();
       
       // If plugins are enabled, add all buttons for the query panel
       if (KorAP.Plugin) {
diff --git a/dev/js/src/panel/result.js b/dev/js/src/panel/result.js
index 1626a95..94ab856 100644
--- a/dev/js/src/panel/result.js
+++ b/dev/js/src/panel/result.js
@@ -34,7 +34,7 @@
         // Add all result buttons in order
         KorAP.Plugin
           .buttonGroup("result")
-          .forEach(i => this.actions.add.apply(this.actions, i));
+          .forEach(i => this.actions().add.apply(this.actions(), i));
 
         KorAP.Plugin.clearButtonGroup("result");
       };
@@ -51,7 +51,7 @@
     addKqAction : function () {
 
       // Open KoralQuery view
-      const kqButton = this.actions.add(
+      const kqButton = this.actions().add(
         loc.SHOW_KQ,
         {'cls':['show-kq','button-icon']},
         function () {
@@ -89,7 +89,7 @@
       /**
        * Toggle the alignment (left <=> right)
        */
-      this.actions.add(loc.TOGGLE_ALIGN, {'cls':['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;
 
         aRoll.find(function(align, i) {
diff --git a/dev/js/src/panel/vc.js b/dev/js/src/panel/vc.js
index 6259d48..b9dc7a2 100644
--- a/dev/js/src/panel/vc.js
+++ b/dev/js/src/panel/vc.js
@@ -28,7 +28,7 @@
     
     _init : function(vc){
      this.vc = vc;
-     const actions = this.actions;
+      const actions = this.actions();
       actions.add(loc.SHOW_STAT, {'cls':['statistic']}, function() {
         this.addCorpStat();
       }.bind(this));
diff --git a/dev/js/src/plugin/server.js b/dev/js/src/plugin/server.js
index daea33c..d86eebc 100644
--- a/dev/js/src/plugin/server.js
+++ b/dev/js/src/plugin/server.js
@@ -214,7 +214,7 @@
 
           // Add to static button list (e.g. for query) already loaded
           else if (KorAP.Panel[panel]) {
-            KorAP.Panel[panel].actions.add(title, obj, cb);
+            KorAP.Panel[panel].actions().add(title, obj, cb);
           }
 
           // Add to static button list (e.g. for query) not yet loaded
@@ -235,7 +235,7 @@
 
           // TODO:
           //   Lazy registration (see above!)
-          KorAP.Panel[panel].actions.addToggle(title, {'cls':["title"]}, state);
+          KorAP.Panel[panel].actions().addToggle(title, {'cls':["title"]}, state);
 
           // Add the service
           let id = this.addService({
diff --git a/dev/js/src/plugin/widget.js b/dev/js/src/plugin/widget.js
index 48cc393..07b1af6 100644
--- a/dev/js/src/plugin/widget.js
+++ b/dev/js/src/plugin/widget.js
@@ -46,7 +46,7 @@
       // Otherwise a button indicating this is a plugin
       // is a nice idea as well.
       
-      this.actions.add(
+      this.actions().add(
         this.name, {'cls':['button-icon', 'plugin']}, function (e) {
 
           // Temporary
diff --git a/dev/js/src/view.js b/dev/js/src/view.js
index a8a79cb..b45c485 100644
--- a/dev/js/src/view.js
+++ b/dev/js/src/view.js
@@ -26,14 +26,14 @@
       if (classes)
         c.push.apply(c,classes);
       
-      this.actions = buttonGroupClass.create(c).bind(this);
+      this._actions = buttonGroupClass.create(c).bind(this);
 
-      this.actions.add(loc.CLOSE, {'cls':['button-icon','close']}, function (e) {
+      this._actions.add(loc.CLOSE, {'cls':['button-icon','close']}, function (e) {
         this.close();
       });
 
       // Warning: This is circular
-      this.actions.view = this;
+      this._actions.view = this;
 
       return this;
     },
@@ -68,13 +68,22 @@
 
       this._shown = true;
 
-      e.appendChild(this.actions.element());
+      e.appendChild(this.actions().element());
 
       return this._el = e;
     },
 
 
     /**
+     * The actions of the view.
+     * Can be represented as a buttongroup,
+     * a list, ..., requires an "add()" minimum at least.
+     */
+    actions : function () {
+      return this._actions;
+    },
+
+    /**
      * Is the object shown?
      */
     shown : function () {
diff --git a/dev/js/src/view/match/relations.js b/dev/js/src/view/match/relations.js
index 7e874fc..452841c 100644
--- a/dev/js/src/view/match/relations.js
+++ b/dev/js/src/view/match/relations.js
@@ -87,7 +87,7 @@
           if (type === "spans") {
 
             // Download link
-            that.actions.add(
+            that.actions().add(
               loc.DOWNLOAD,
               {'cls':['button-icon','download']},
               function (e) {