Modernize view scripts and improve specifications

Change-Id: Ie45465c8c29aef272c719942290f4ab0c9dc8550
diff --git a/dev/js/runner/all.html b/dev/js/runner/all.html
index 037d04e..912fabd 100644
--- a/dev/js/runner/all.html
+++ b/dev/js/runner/all.html
@@ -41,7 +41,7 @@
         'spec/menuSpec',
         'spec/selectMenuSpec',
         'spec/panelSpec',
-        'spec/kqViewSpec',
+        'spec/viewSpec',
         'spec/pluginSpec',
         'spec/queryCreatorSpec',
         'spec/corpusByMatchSpec',
diff --git a/dev/js/spec/kqViewSpec.js b/dev/js/spec/kqViewSpec.js
deleted file mode 100644
index 3870324..0000000
--- a/dev/js/spec/kqViewSpec.js
+++ /dev/null
@@ -1,37 +0,0 @@
-define(['view/result/koralquery','util'], function (kqClass) {
-  describe('KorAP.View.Result.KoralQuery', function () {
-
-    beforeEach(
-      function () {
-       KorAP.koralQuery = {} 
-      }
-    );
-
-    afterEach(
-      function () {
-        KorAP.koralQuery = {} 
-      }
-    );
-    
-    it('should be initializable', function () {
-      KorAP.koralQuery = {
-        "test" : "cool"
-      };
-      var kq = kqClass.create();
-      var content = kq.element().firstChild.textContent;
-      expect(content).toMatch(/test/);
-      expect(content).toMatch(/cool/);
-    });
-
-    it('should deal with XML fragments', function () {
-      KorAP.koralQuery = {
-        "test" : "Das ist <b>Super!</b>"
-      };
-      var kq = kqClass.create();
-      var content = kq.element().firstChild.textContent;
-      expect(content).toMatch(/test/);
-      expect(content).toMatch(/Das ist <b>Super!<\/b>/);
-    });
-
-  });
-});
diff --git a/dev/js/spec/panelSpec.js b/dev/js/spec/panelSpec.js
index fb2008f..a72223d 100644
--- a/dev/js/spec/panelSpec.js
+++ b/dev/js/spec/panelSpec.js
@@ -24,55 +24,6 @@
         return Object.create(viewClass)._init(['secview']).upgradeTo(this);
       },
   };
-
-  
-  describe('KorAP.View', function () {
-    it('should be initializable', function () {
-      var view = viewClass.create();
-
-      expect(view.shown()).toBeFalsy();
-
-      var e = view.element();
-      expect(view.shown()).toBeTruthy();
-
-      expect(e.tagName).toEqual("DIV");
-      expect(e.classList.contains("view")).toBeTruthy();
-
-      var btn = e.firstChild;
-      expect(btn.tagName).toEqual("DIV");
-      expect(btn.classList.contains("button-view")).toBeTruthy();
-      expect(btn.classList.contains("button-group")).toBeTruthy();
-
-      expect(btn.firstChild.tagName).toEqual("SPAN");
-      expect(btn.firstChild.getAttribute("title")).toEqual("Close");
-      expect(btn.firstChild.classList.contains("button-icon")).toBeTruthy();
-      expect(btn.firstChild.classList.contains("close")).toBeTruthy();
-      expect(btn.firstChild.firstChild.tagName).toEqual("SPAN");
-      expect(btn.firstChild.firstChild.firstChild.data).toEqual("Close");
-    });
-
-    it('should be classable', function () {
-      var view = viewClass.create(['versuch']);
-      var e = view.element();
-      expect(e.tagName).toEqual("DIV");
-      expect(e.classList.contains("view")).toBeTruthy();
-      expect(e.classList.contains("versuch")).toBeTruthy();
-
-      var btn = e.firstChild;
-      expect(btn.tagName).toEqual("DIV");
-      expect(btn.classList.contains("button-view")).toBeTruthy();
-      expect(btn.classList.contains("button-group")).toBeTruthy();
-      expect(btn.classList.contains("versuch")).toBeTruthy();
-    });
-
-    it('should be minimizable', function () {
-      var view = viewClass.create(['versuch']);
-      var e = view.element();
-      expect(e.classList.contains('show')).toBeTruthy();
-      view.minimize();
-      expect(e.classList.contains('show')).toBeFalsy();
-    });
-  });
   
   describe('KorAP.Panel', function () {
 
diff --git a/dev/js/spec/viewSpec.js b/dev/js/spec/viewSpec.js
new file mode 100644
index 0000000..dc7053d
--- /dev/null
+++ b/dev/js/spec/viewSpec.js
@@ -0,0 +1,143 @@
+define([
+  'panel',
+  'view',
+  'view/match/meta',
+  'view/match/relations',
+  'view/match/tokentable',
+  'view/result/koralquery',
+  'util'], function (
+    panelClass,
+    viewClass,
+    metaViewClass,
+    relViewClass,
+    tokenViewClass,
+    kqViewClass) {
+
+  describe('KorAP.View', function () {
+    it('should be initializable', function () {
+      var view = viewClass.create();
+
+      expect(view.shown()).toBeFalsy();
+
+      var e = view.element();
+      expect(view.shown()).toBeTruthy();
+
+      expect(e.tagName).toEqual("DIV");
+      expect(e.classList.contains("view")).toBeTruthy();
+
+      var btn = e.firstChild;
+      expect(btn.tagName).toEqual("DIV");
+      expect(btn.classList.contains("button-view")).toBeTruthy();
+      expect(btn.classList.contains("button-group")).toBeTruthy();
+
+      expect(btn.firstChild.tagName).toEqual("SPAN");
+      expect(btn.firstChild.getAttribute("title")).toEqual("Close");
+      expect(btn.firstChild.classList.contains("button-icon")).toBeTruthy();
+      expect(btn.firstChild.classList.contains("close")).toBeTruthy();
+      expect(btn.firstChild.firstChild.tagName).toEqual("SPAN");
+      expect(btn.firstChild.firstChild.firstChild.data).toEqual("Close");
+    });
+
+    it('should be classable', function () {
+      var view = viewClass.create(['versuch']);
+      var e = view.element();
+      expect(e.tagName).toEqual("DIV");
+      expect(e.classList.contains("view")).toBeTruthy();
+      expect(e.classList.contains("versuch")).toBeTruthy();
+
+      var btn = e.firstChild;
+      expect(btn.tagName).toEqual("DIV");
+      expect(btn.classList.contains("button-view")).toBeTruthy();
+      expect(btn.classList.contains("button-group")).toBeTruthy();
+      expect(btn.classList.contains("versuch")).toBeTruthy();
+    });
+
+    it('should be minimizable', function () {
+      var view = viewClass.create(['versuch']);
+      var e = view.element();
+      expect(e.classList.contains('show')).toBeTruthy();
+      view.minimize();
+      expect(e.classList.contains('show')).toBeFalsy();
+    });
+  });
+
+  describe('KorAP.View.Match.Meta', function () {
+    it('should be initializable', function () {
+      let match = null;      
+      let view = metaViewClass.create(match);
+      expect(view).toBeTruthy();
+    })
+  });
+
+  describe('KorAP.View.Match.Relation', function () {
+    it('should be initializable', function () {
+      let match = null;
+      let view = relViewClass.create(match, "corenlp","l");
+      expect(view).toBeTruthy();
+    });
+
+    it('should be visible', function () {
+      let match = null;
+      let view = relViewClass.create(match, "corenlp","l","spans");
+      var el = view.show();
+      expect(el.tagName).toEqual('DIV');
+      expect(el.children[0].tagName).toEqual('H6');
+      expect(el.children[0].getElementsByTagName('span')[0].textContent).toEqual('corenlp');
+      expect(el.children[0].getElementsByTagName('span')[1].textContent).toEqual('l');
+      expect(el.children[1].tagName).toEqual('DIV');
+    })
+  });
+
+  describe('KorAP.View.Match.TokenTable', function () {
+    it('should be initializable', function () {
+      let match = null;      
+      let view = tokenViewClass.create(match);
+      expect(view).toBeTruthy();
+    })
+
+    it('should be visible', function () {
+      let match = null;      
+      let view = tokenViewClass.create(match);
+      expect(view).toBeTruthy();
+
+      let el = view.show();
+      expect(el.tagName).toEqual("DIV");
+      expect(el.classList.contains("loading")).toBeTruthy();
+    })
+  });
+
+  describe('KorAP.View.Result.KoralQuery', function () {
+
+    beforeEach(
+      function () {
+       KorAP.koralQuery = {} 
+      }
+    );
+
+    afterEach(
+      function () {
+        KorAP.koralQuery = {} 
+      }
+    );
+    
+    it('should be initializable', function () {
+      KorAP.koralQuery = {
+        "test" : "cool"
+      };
+      var kq = kqViewClass.create();
+      var content = kq.element().firstChild.textContent;
+      expect(content).toMatch(/test/);
+      expect(content).toMatch(/cool/);
+    });
+
+    it('should deal with XML fragments', function () {
+      KorAP.koralQuery = {
+        "test" : "Das ist <b>Super!</b>"
+      };
+      var kq = kqViewClass.create();
+      var content = kq.element().firstChild.textContent;
+      expect(content).toMatch(/test/);
+      expect(content).toMatch(/Das ist <b>Super!<\/b>/);
+    });
+  });
+});
diff --git a/dev/js/src/view.js b/dev/js/src/view.js
index 27d1ab2..77f8d60 100644
--- a/dev/js/src/view.js
+++ b/dev/js/src/view.js
@@ -3,6 +3,8 @@
  * like a tree view or the metadata view.
  */
 
+"use strict";
+
 define(['buttongroup', 'util'], function (buttonGroupClass) {
 
   const loc = KorAP.Locale;
@@ -20,7 +22,7 @@
       this._shown = false;
 
       // The buttonclass is bind to the view
-      var c = ['action', 'button-view'];
+      const c = ['action', 'button-view'];
       if (classes)
         c.push.apply(c,classes);
       
@@ -36,6 +38,7 @@
       return this;
     },
 
+
     /**
      * Element of the view
      */
@@ -46,30 +49,28 @@
       };
 
       // Create panel element
-      var e = document.createElement('div');
+      const e = document.createElement('div');
+      const cl = e.classList;
 
-      var cl = e.classList;
       cl.add('view', 'show');
       if (this._classes)
         cl.add.apply(cl, this._classes);
 
       // TODO: The show may need to be wrapped in another DIV!
       if (this.show !== undefined) {
-        let s = this.show();
+        const s = this.show();
         if (s) {
           e.appendChild(s);
         } else {
           return e
-        }
+        };
       }
 
       this._shown = true;
 
       e.appendChild(this.actions.element());
 
-      this._element = e;
-
-      return e;
+      return this._element = e;
     },
 
 
@@ -90,8 +91,10 @@
       }
     },
 
+
     // onClose : function () {},
 
+    
     /**
      * Close the view.
      */
@@ -101,7 +104,7 @@
       if (this.onClose)
         this.onClose();
 
-      var e = this.element();
+      const e = this.element();
       if (e.parentNode) {
         e.parentNode.removeChild(e);
       };
@@ -109,6 +112,7 @@
       this._shown = false;
     },
 
+
     /**
      * Upgrade this object to another object,
      * while private data stays intact.
@@ -116,7 +120,7 @@
      * @param {Object] An object with properties.
      */
     upgradeTo : function (props) {
-      for (var prop in props) {
+      for (let prop in props) {
         this[prop] = props[prop];
       };
       return this;
diff --git a/dev/js/src/view/match/meta.js b/dev/js/src/view/match/meta.js
index f54c7fb..406c10a 100644
--- a/dev/js/src/view/match/meta.js
+++ b/dev/js/src/view/match/meta.js
@@ -1,3 +1,5 @@
+"use strict";
+
 define([
   'view',
   'match/meta'
@@ -7,7 +9,10 @@
   
   return {
     create : function (match) {
-      return Object.create(viewClass)._init(['metatable']).upgradeTo(this)._init(match);
+      return Object.create(viewClass)
+        ._init(['metatable'])
+        .upgradeTo(this)
+        ._init(match);
     },
 
 
@@ -24,26 +29,24 @@
       if (this._show)
         return this._show;
 
-      var metaTable = document.createElement('div');
+      const metaTable = document.createElement('div');
       metaTable.classList.add('metatable', 'loading');
 
       this.getData(function (meta) {
-
         if (meta === null)
           return;
 
         // Load data
         metaTable.classList.remove('loading');
-
         metaTable.appendChild(meta.element());
       });
 
+
       // TODO:
       //   Loading should have a timeout on view-level
       //   matchtable.classList.remove('loading');
 
-      this._show = metaTable;
-      return metaTable;
+      return this._show = metaTable;
     },
 
 
@@ -61,7 +64,7 @@
      */
     getData : function (cb) {
 
-      var match = this._match;
+      const match = this._match;
       try {
         KorAP.API.getTextInfo(
           match, {}, function (textResponse) {
@@ -71,14 +74,13 @@
               return;
             };
 
-            var doc = textResponse["document"];
-       
+            const doc = textResponse["document"];
             if (doc === undefined) {
               cb(null);
               return;
             };
 
-            var fields = doc["fields"];
+            const fields = doc["fields"];
             if (fields === undefined) {
               cb(null);
               return;
@@ -97,6 +99,7 @@
       };
     },
 
+
     // Delete circular references
     onClose : function () {
       this._match = undefined;
diff --git a/dev/js/src/view/match/relations.js b/dev/js/src/view/match/relations.js
index c61a4ff..1c9bdad 100644
--- a/dev/js/src/view/match/relations.js
+++ b/dev/js/src/view/match/relations.js
@@ -11,7 +11,10 @@
   
   return {
     create : function (match,foundry,layer,type) {
-      return Object.create(viewClass)._init(['relations']).upgradeTo(this)._init(match, foundry, layer, type);
+      return Object.create(viewClass)
+        ._init(['relations'])
+        .upgradeTo(this)
+        ._init(match, foundry, layer, type);
     },
 
 
@@ -33,20 +36,17 @@
       if (this._show)
         return this._show;
 
-      var matchtree = d.createElement('div');
+      const matchtree = d.createElement('div');
       matchtree.classList.add('matchtree', 'loading');
 
-      // this.element().appendChild(matchtree);
-
       // Add title line
-      var h6 = matchtree.addE('h6');
+      const h6 = matchtree.addE('h6');
       h6.addE('span').addT(this._foundry);
       h6.addE('span').addT(this._layer);      
 
       this._tree = matchtree.addE('div');
 
-      this._show = matchtree;
-      return matchtree;
+      return this._show = matchtree;
     },
 
 
@@ -55,13 +55,13 @@
      */
     afterEmbed : function () {
 
-      var foundry = this._foundry,
-          layer = this._layer,
-          type = this._type;
+      const foundry = this._foundry,
+            layer = this._layer,
+            type = this._type;
 
-      var that = this;
-      var tree = this._tree;
-      var matchtree = this._show;
+      const that = this,
+            tree = this._tree,
+            matchtree = this._show;
 
       // Get tree data async
       this.getData(foundry, layer, type, function (treeObj) {
@@ -85,21 +85,20 @@
           if (type === "spans") {
 
             // Download link
-            that.actions.add(loc.DOWNLOAD, {'cls':['button-icon','download']}, function (e) {
-              var a = treeObj.downloadLink();
-              d.body.appendChild(a);
-              a.click();
-              d.body.removeChild(a)
-            });
+            that.actions.add(
+              loc.DOWNLOAD,
+              {'cls':['button-icon','download']},
+              function (e) {
+                const a = treeObj.downloadLink();
+                d.body.appendChild(a);
+                a.click();
+                d.body.removeChild(a)
+              }
+            );
           };
           
           treeObj.center();
         };
-  
-        /*
-          if (cb)
-          cb(treeObj);
-          */
       });
 
       matchtree.classList.remove('loading');
@@ -163,6 +162,7 @@
       };
     },
   
+
     // Delete circular references
     onClose : function () {
       this._match = undefined;
diff --git a/dev/js/src/view/match/tokentable.js b/dev/js/src/view/match/tokentable.js
index e954068..e06ec52 100644
--- a/dev/js/src/view/match/tokentable.js
+++ b/dev/js/src/view/match/tokentable.js
@@ -1,3 +1,5 @@
+"use strict";
+
 define([
   'view',
   'match/table',
@@ -8,7 +10,10 @@
   
   return {
     create : function (match) {
-      return Object.create(viewClass)._init(['tokentable']).upgradeTo(this)._init(match);
+      return Object.create(viewClass)
+        ._init(['tokentable'])
+        .upgradeTo(this)
+        ._init(match);
     },
 
 
@@ -17,6 +22,7 @@
       return this;
     },
     
+
     /**
      * TokenTable view element
      */
@@ -25,12 +31,13 @@
         return this._show;
 
       // Append default table
-      var matchtable = d.createElement('div');
+      const matchtable = d.createElement('div');
       matchtable.classList.add('matchtable', 'loading');
       this._show = matchtable;
       return matchtable;
     },
 
+
     /**
      * Do after embedding
      */
@@ -43,7 +50,7 @@
       //   matchtable.classList.remove('loading');
 
       // var that = this;
-      var matchtable = this._show;
+      const matchtable = this._show;
 
       // Create the table asynchronous
       this.getData(undefined, function (table) {
@@ -52,7 +59,6 @@
           matchtable.appendChild(table.element());
           table.toMark();
 	      };
-
       });
 
       // Load data
@@ -73,12 +79,12 @@
      * representation
      */
     getData : function (tokens, cb) {
-      var focus = [];
+      let focus = [];
 
       // Get all tokens
       if (tokens === undefined) {
         focus = this._match.getTokens();
-      } 
+      }
 
       // Get only some tokens
       else {
@@ -87,7 +93,7 @@
         tokens.forEach(function(term) {
           try {
             // Create info layer objects
-            var layer = infoLayerClass.create(term);
+            const layer = infoLayerClass.create(term);
             layer.type = "tokens";
             focus.push(layer);
           }
@@ -115,8 +121,9 @@
 
             // Get snippet from match info
             if (matchResponse["snippet"] !== undefined) {
-              this._table = matchTableClass.create(matchResponse["snippet"]);
-              cb(this._table);
+              cb(
+                this._table = matchTableClass.create(matchResponse["snippet"])
+              );
             };
           }.bind(this)
         );
@@ -132,6 +139,7 @@
       */
     },
 
+
     // Delete circular references
     onClose : function () {
       this._match = undefined;
diff --git a/dev/js/src/view/result/koralquery.js b/dev/js/src/view/result/koralquery.js
index c456eee..74aec5a 100644
--- a/dev/js/src/view/result/koralquery.js
+++ b/dev/js/src/view/result/koralquery.js
@@ -1,10 +1,14 @@
+"use strict";
+
 define([
   'view',
   'lib/highlight/highlight.pack',
 ], function (viewClass) {
   return {
     create : function (classes) {
-      return Object.create(viewClass)._init(classes).upgradeTo(this);
+      return Object.create(viewClass)
+        ._init(classes)
+        .upgradeTo(this);
     },
 
     /**
@@ -14,10 +18,10 @@
       if (this._show)
         return this._show;
 
-      var kq = document.createElement('div');
+      const kq = document.createElement('div');
       kq.setAttribute('id', 'koralquery');
 
-      var kqInner = kq.addE('div');
+      const kqInner = kq.addE('div');
 
       kqInner.addT(
         JSON.stringify(KorAP.koralQuery || {}, null, '  ')
diff --git a/dev/js/src/view/vc/corpstatv.js b/dev/js/src/view/vc/corpstatv.js
index 316018f..e4aacb0 100644
--- a/dev/js/src/view/vc/corpstatv.js
+++ b/dev/js/src/view/vc/corpstatv.js
@@ -4,7 +4,7 @@
  * @author Helge Stallkamp
  */
 
-define([ 'view', 'vc/statistic', 'buttongroup' ], function(viewClass, statClass, buttonGroup) {
+define([ 'view', 'vc/statistic', 'buttongroup' ], function (viewClass, statClass, buttonGroup) {
 
   // Localization values
   const loc   = KorAP.Locale;
@@ -38,7 +38,7 @@
      */
     getStatistic : function(cb) {
       // cq = corpusQuery
-      var vc = this.vc;
+      const vc = this.vc;
 
       try {
         KorAP.API.getCorpStat(vc.toQuery(), function(statResponse) {
@@ -79,15 +79,13 @@
       if (this._show)
         return this._show; 
       
-      var statTable = document.createElement('div');
+      const statTable = document.createElement('div');
       statTable.classList.add('stattable', 'loading');
   
-      var that = this;
-     
       /*
-      * Get corpus statistic, remove "loading"-image and
-      * append result to statTable
-      */
+       * Get corpus statistic, remove "loading"-image and
+       * append result to statTable
+       */
       this.getStatistic(function(statistic) {
         statTable.classList.remove('loading');
 
@@ -96,57 +94,53 @@
 
         statisticobj = statClass.create(statistic);
         statTable.appendChild(statisticobj.element());
-    
       });
 
-      this._show = statTable;
-      return statTable;
-
+      return this._show = statTable;
     },
-    
 
     
     /**
      * Checks if statistic has to be disabled
      */
-    checkStatActive : function (){
-     var newString = KorAP.vc.toQuery();
-     var oldString = this.vc.oldvcQuery;
-     /*
-      * Do ignore surrounding round brackets
-      * Definining an incomplete docGroup in the vc builder: 
-      * (foo = bar and author = Goethe) and ... 
-      * leads to 
-      * vc.toQuery() -> (foo = bar and author=Goethe)
-      */
+    checkStatActive : function () {
+      let newString = KorAP.vc.toQuery();
+      const oldString = this.vc.oldvcQuery;
+      /*
+       * Do ignore surrounding round brackets
+       * Definining an incomplete docGroup in the vc builder: 
+       * (foo = bar and author = Goethe) and ... 
+       * leads to 
+       * vc.toQuery() -> (foo = bar and author=Goethe)
+       */
   
-     if(newString || newString === ''){
-       if(newString.startsWith('(')){
-         newString = newString.slice(1, newString.length-1);
-       }
+      if (newString || newString === '') {
+        if (newString.startsWith('(')) {
+          newString = newString.slice(1, newString.length-1);
+        };
        
-       if(newString != oldString) {
-        this.disableStat();
-      }  
-     }
-     
-   },
+        if (newString != oldString) {
+          this.disableStat();
+        }
+      }
+    },
    
+
     /**
      * Disabling corpus statistic if in vc builder a different vc is choosen.
      * After clicking at the reload-button the up-to-date corpus statistic is displayed.
      */   
-
     disableStat : function(){
-      var statt = this._show;
+      const statt = this._show;
   
       if (statt.getElementsByClassName('reloadStatB').length == 0) {
-        let btg = buttonGroup.create(['reloadStatB', 'button-panel']);
-        var that = this;
+        const btg = buttonGroup.create(['reloadStatB', 'button-panel']);
+
         btg.add(loc.REFRESH, {'cls':['refresh', 'button-icon']}, function (e) {
           statt.classList.remove('stdisabled');
-          that.panel.reloadCorpStat(); 
-        });
+          this.panel.reloadCorpStat(); 
+        }.bind(this));
+
         statt.appendChild(btg.element());
         statt.classList.add('stdisabled');
       };