Cleanup match info data

Change-Id: I815cf976fbb78223968274fa4955a52f708a03dc
diff --git a/dev/demo/all.html b/dev/demo/all.html
index 6cbfa65..e19b474 100644
--- a/dev/demo/all.html
+++ b/dev/demo/all.html
@@ -203,8 +203,8 @@
 	        <div class="snippet startMore endMore"><span class="context-left">Der Fehler unterläuft häufig bei der direkten Übersetzung aus dem Englischen, wenn im originalen Ausdruck die beiden Wortteile verschiedene Wörter sind und sich das Adjektiv wahlweise auf das erste oder zweite Wort bezieht. Ein Beispiel ist multiples Testproblem für multiple </span><span class="match">test</span><span class="context-right"> problem.</span></div>
 	        <div class="tokenInfo"></div>
 	      </div>
-	      <p class="ref"><strong>Fehlbezogenes Adjektiv</strong> by Joni2,Peterlustig,BWBot; published on 2005-03-28 as FFF.01460 (WPD)</p>
       </div>
+	    <p class="ref"><strong>Fehlbezogenes Adjektiv</strong> by Joni2,Peterlustig,BWBot; published on 2005-03-28 as FFF.01460 (WPD)</p>
 	  </li>
 
 	  <li data-corpus-id="WPD"
diff --git a/dev/js/src/match.js b/dev/js/src/match.js
index 3827af1..e70d975 100644
--- a/dev/js/src/match.js
+++ b/dev/js/src/match.js
@@ -178,113 +178,79 @@
       close.classList.add('close');
       close.setAttribute('title', loc.CLOSE);
       
-      // Add info button
-      /*
-      var info = document.createElement('li');
-      info.appendChild(document.createElement('span'))
-        .appendChild(document.createTextNode(loc.SHOWINFO));
-      info.classList.add('info');
-      info.setAttribute('title', loc.SHOWINFO);
-      */
-
       var that = this;
 
       // Add meta button
       var refLine = element.querySelector("p.ref");
 
-      // There is a reference line
-      if (refLine) {
+      if (!refLine)
+        return;
+      
+      // TODO: Simplify
+      var ops = document.createElement('div');
+      ops.classList.add('action', 'bottom', 'button-group');
+      
+      var meta = document.createElement('span');
+      ops.appendChild(meta);
+      meta.appendChild(document.createTextNode('Meta'));
+      meta.setAttribute('title', loc.SHOW_META);
+      meta.classList.add('meta');
 
-        // Temporary
-        var ops = document.createElement('div');
-        ops.classList.add('action', 'bottom', 'button-group');
+      var info = document.createElement('span');
+      ops.appendChild(info);
+      info.appendChild(document.createTextNode('Anno'));
+      info.setAttribute('title', loc.SHOWINFO);
+      info.classList.add('info');
 
-        var meta = document.createElement('span');
-        ops.appendChild(meta);
-        meta.appendChild(document.createTextNode('+ Meta'));
-        meta.setAttribute('title', loc.SHOW_META);
-        meta.classList.add('meta');
+      var tree = document.createElement('span');
+      ops.appendChild(tree);
+      tree.appendChild(document.createTextNode('+ Tree'));
+      tree.setAttribute('title', loc.ADDTREE);
+      tree.classList.add('tree');
 
-        var info = document.createElement('span');
-        ops.appendChild(info);
-        info.appendChild(document.createTextNode('+ Anno'));
-        info.setAttribute('title', loc.SHOWINFO);
-        info.classList.add('info');
+      // Insert before reference line
+      refLine.insertBefore(
+        ops,
+        refLine.firstChild
+      );
 
-        var tree = document.createElement('span');
-        ops.appendChild(tree);
-        tree.appendChild(document.createTextNode('+ Tree'));
-        tree.setAttribute('title', loc.ADDTREE);
-        tree.classList.add('tree');
-        
-        refLine.insertBefore(
-          ops,
-          refLine.firstChild
-        );
+      // Click on meta - add meta (unless already there)
+      meta.addEventListener(
+        'click', function (e) {
+          e.halt();
+          that.info().showMeta();
+        }
+      );
 
-        /*
-        var meta = document.createElement('span');
-        meta.appendChild(
-          document.createElement('span')
-        ).appendChild(
-          document.createTextNode(loc.SHOW_META)
-        );
-        meta.setAttribute('title', loc.SHOW_META);
-        meta.classList.add('meta');
-        refLine.insertBefore(
-          meta,
-          refLine.firstChild
-        );
-        */
+      // Click on token annotations - add token annotations (unless already there)
+      info.addEventListener(
+        'click', function (e) {
+          e.halt();
+          that.info().showTable();
+        }
+      );
 
-        meta.addEventListener(
-          'click', function (e) {
-            e.halt();
-            that.info().addMeta();
-          }
-        );
+      // Click to show tree menu
+      tree.addEventListener(
+        'click', function (e) {
+          e.halt();
 
-        // Add information, unless it already exists
-        info.addEventListener(
-          'click', function (e) {
-            e.halt();
-            that.info().addTable();
-          }
-        );
+          if (KorAP.TreeMenu === undefined) {
+            KorAP.TreeMenu = matchTreeMenuClass.create([]);
+          };
 
-        tree.addEventListener(
-          'click', function (e) {
-            e.halt();
+          var tm = KorAP.TreeMenu;
 
-            if (KorAP.TreeMenu === undefined) {
-              KorAP.TreeMenu = matchTreeMenuClass.create([]);
-            };
+          // Reread list
+          tm.info(that.info());
+          tm.readItems(that.treeMenuList());
 
-            var tm = KorAP.TreeMenu;
-
-            // Reread list
-            tm.info(that.info());
-            tm.readItems(that.treeMenuList());
-            tm.attachTo(this);
-
-            // Not yet initialized
-            /*
-              if (that._treemenu === undefined) {
-              that._treemenu = that.initTreeMenu();
-
-              // TODO:
-              // Do not add the tree menu to the button!
-              // Only reposition a global treemenu element there,
-              // that is positioned below the annotation helper!
-              this.appendChild(that._treemenu.element());
-            };
-            var tm = that._treemenu;
-            */
-            tm.show();
-            tm.focus();
-          }
-        );
-      };
+          // Reposition and show menu
+          tm.attachTo(this);
+          tm.show();
+          tm.focus();
+        }
+      );
 
       // Close match
       close.addEventListener('click', function (e) {
@@ -292,16 +258,7 @@
         that.close()
       });
 
-      // Add information, unless it already exists
-      /*
-      info.addEventListener('click', function (e) {
-        e.halt();
-        that.info().addTable();
-      });
-      */
-
       ul.appendChild(close);
-      // ul.appendChild(info);
 
       return true;
     },
@@ -321,15 +278,16 @@
      */
     close : function () {
       this._element.classList.remove('active');
-      /* if (this._info !== undefined) {
-       *   this._info.destroy();
-       * };
-       */
+      /*
+      if (this._info !== undefined) {
+        this._info.destroy();
+      };
+      */
     },
 
 
     /**
-     * Get and open associated match info.
+     * Get and open associated match infos.
      */
     info : function () {
 
@@ -346,11 +304,6 @@
       if (this._info._element !== undefined)
         return this._info;
 
-      /*
-        this.element().appendChild(
-        this._info.element()
-      );
-      */
       var refLine = this._element.querySelector("p.ref");
       this._element.insertBefore(
         this._info.element(),
@@ -361,6 +314,7 @@
     },
 
 
+    // Return tree menu list
     treeMenuList : function () {
 
       if (this._menuList)
@@ -414,34 +368,8 @@
       // Create tree menu
       this._menuList = menuList;
       return menuList;
-      /*
-      var span = document.createElement('p');
-      span.classList.add('addtree');
-      span.appendChild(document.createTextNode(loc.ADDTREE));
-      var treeElement = treemenu.element();
-      span.appendChild(treeElement);
-
-      span.addEventListener('click', function (e) {
-        treemenu.show();
-        treemenu.focus();
-      });
-      */
     },
 
-        
-    /**
-     * Get tree menu.
-     * There is only one menu rendered
-     * - no matter how many trees exist
-     */
-    /*
-    treeMenu : function (list) {
-      if (this._treeMenu !== undefined)
-        return this._treeMenu;
-      
-      return this._treeMenu = matchTreeMenuClass.create(this, list);
-    },
-    */
     
     /**
      * Get match element.
diff --git a/dev/js/src/match/info.js b/dev/js/src/match/info.js
index a0b7424..07d4550 100644
--- a/dev/js/src/match/info.js
+++ b/dev/js/src/match/info.js
@@ -5,14 +5,14 @@
   'match/infolayer',
   'match/table',
   'match/tree',
-  'match/reference', // rename to meta
+  'match/meta',
   'match/relations',
   'match/querycreator',
   'util'
 ], function (infoLayerClass,
 	           matchTableClass,
 	           matchTreeClass,
-	           matchRefClass,
+	           matchMetaClass,
              matchRelClass,
              matchQueryCreator) {
   
@@ -33,6 +33,7 @@
       return Object.create(this)._init(match);
     },
 
+
     /**
      * Initialize object
      */
@@ -42,6 +43,7 @@
       return this;
     },
 
+
     /**
      * Get match object
      */
@@ -82,7 +84,7 @@
      * Retrieve and parse snippet for table
      * representation
      */
-    getTable : function (tokens, cb) {
+    getTableData : function (tokens, cb) {
       var focus = [];
 
       // Get all tokens
@@ -138,15 +140,15 @@
     },
 
 
-    getMeta : function (metaInfo, cb) {
-      
+    getMetaData : function (metaInfo, cb) {
+      // ...
     },
     
 
     /**
      * Retrieve and parse snippet for tree representation
      */
-    getTree : function (foundry, layer, type, cb) {
+    getTreeData : function (foundry, layer, type, cb) {
       var focus = [];
       
       // TODO: Support and cache multiple trees
@@ -180,6 +182,7 @@
       );
     },
 
+
     /**
      * Destroy this match information view.
      */
@@ -198,30 +201,29 @@
       // Element destroy
     },
 
+
     /**
      * Add a new tree view to the list
      */
-    addTree : function (foundry, layer, type, cb) {
+    showTree : function (foundry, layer, type, cb) {
       var matchtree = document.createElement('div');
       matchtree.classList.add('matchtree');
-      
-      var h6 = matchtree.appendChild(document.createElement('h6'));
-      h6.appendChild(document.createElement('span'))
-	      .appendChild(document.createTextNode(foundry));
-      h6.appendChild(document.createElement('span'))
-	      .appendChild(document.createTextNode(layer));      
 
-      var tree = matchtree.appendChild(
-        document.createElement('div')
-      );
+      // Add title line
+      var h6 = matchtree.addE('h6');
+      h6.addE('span').addT(foundry);
+      h6.addE('span').addT(layer);      
+
+      var tree = matchtree.addE('div');
       
       this._element.insertBefore(matchtree, this._element.lastChild);
 
-      var actions = tree.appendChild(document.createElement('ul'));
+      // Add close action button
+      var actions = tree.addE('ul');
       actions.classList.add('action', 'image');
-      var close = actions.appendChild(document.createElement('li'));
+      var close = actions.addE('li');
       close.className = 'close';
-      close.appendChild(document.createElement('span'));
+      close.addE('span');
       close.addEventListener(
         'click', function (e) {
           matchtree.parentNode.removeChild(matchtree);
@@ -232,22 +234,22 @@
       tree.classList.add('loading');
 
       // Get tree data async
-      this.getTree(foundry, layer, type, function (treeObj) {
+      this.getTreeData(foundry, layer, type, function (treeObj) {
 
         tree.classList.remove('loading');
 
         // Something went wrong - probably log!!!
 
         if (treeObj === null) {
-          tree.appendChild(document.createTextNode('No data available.'));
+          tree.addT('No data available.');
         }
         else {
           tree.appendChild(treeObj.element());
           treeObj.show();
+
           // Reposition the view to the center
           // (This may in a future release be a reposition
-          // to move the root into the center or the actual
-          // match)
+          // to move the root to the actual match)
 
           // This is currently not supported by relations
           if (type === "spans") {
@@ -255,14 +257,7 @@
             dl.className = 'download';
             dl.addEventListener(
               'click', function (e) {
-
-                var a = document.createElement('a');
-                a.setAttribute('href-lang', 'image/svg+xml');
-                a.setAttribute('href', 'data:image/svg+xml;base64,'+treeObj.toBase64());
-                a.setAttribute('download', 'tree.svg');
-                a.target = '_blank';
-                a.setAttribute('rel', 'noopener noreferrer');
-                
+                var a = treeObj.downloadLink();
                 document.body.appendChild(a);
                 a.click();
                 document.body.removeChild(a)
@@ -283,9 +278,8 @@
 
 
     // Add meta information to match
-    addMeta : function () {
+    showMeta : function () {
       var matchmeta = document.createElement('div');
-      // matchRefClass.create();
 
       // TODO: This is part of the getMeta!
       var metaInfo = this._match.element().getAttribute('data-info');
@@ -297,7 +291,7 @@
       if (metaInfo) {
 
         // Add metainfo to matchview
-        var metaElem = matchRefClass.create(this._match).element(metaInfo);
+        var metaElem = matchMetaClass.create(this._match).element(metaInfo);
         var elem = this.element();
 
         elem.insertBefore(
@@ -307,8 +301,9 @@
       };
     },
 
+
     // Add table
-    addTable : function () {
+    showTable : function () {
 
       var info = this.element();
 
@@ -318,20 +313,21 @@
       info.appendChild(matchtable);
 
       // Create the table asynchronous
-      this.getTable(undefined, function (table) {
+      this.getTableData(undefined, function (table) {
 
         if (table !== null) {
           matchtable.appendChild(table.element());
 	      };
-	      matchtable.classList.remove('loading');
+
+        // Load data
+        matchtable.classList.remove('loading');
 
         // Add query creator
         this._matchCreator = matchQueryCreator.create(info);
       });
-
-      // info.appendChild(this.addTreeMenu());
     },
 
+
     /**
      * Create match information view.
      */
diff --git a/dev/js/src/match/reference.js b/dev/js/src/match/meta.js
similarity index 100%
rename from dev/js/src/match/reference.js
rename to dev/js/src/match/meta.js
diff --git a/dev/js/src/match/tree.js b/dev/js/src/match/tree.js
index 88f0542..c17fe20 100644
--- a/dev/js/src/match/tree.js
+++ b/dev/js/src/match/tree.js
@@ -188,6 +188,9 @@
     },
 
 
+    /**
+     * Create svg and serialize as base64
+     */
     toBase64 : function () {
 
       // First clone element
@@ -310,6 +313,16 @@
       canvas.setAttribute('width', g.graph().width);
       canvas.setAttribute('height', height);
       return this._element;
+    },
+
+    downloadLink : function () {
+      var a = document.createElement('a');
+      a.setAttribute('href-lang', 'image/svg+xml');
+      a.setAttribute('href', 'data:image/svg+xml;base64,' + this.toBase64());
+      a.setAttribute('download', 'tree.svg');
+      a.target = '_blank';
+      a.setAttribute('rel', 'noopener noreferrer');
+      return a;
     }
   };
 });
diff --git a/dev/js/src/match/treeitem.js b/dev/js/src/match/treeitem.js
index ad457b1..68ffe8c 100644
--- a/dev/js/src/match/treeitem.js
+++ b/dev/js/src/match/treeitem.js
@@ -57,7 +57,7 @@
       menu.hide();
       e.halt();
       if (menu.info() !== undefined) {
-	      menu.info().addTree(this._foundry, this._layer, this._type);
+	      menu.info().showTree(this._foundry, this._layer, this._type);
       };
     },
 
diff --git a/dev/js/src/util.js b/dev/js/src/util.js
index d803a9d..719c889 100644
--- a/dev/js/src/util.js
+++ b/dev/js/src/util.js
@@ -33,6 +33,15 @@
 };
 
 
+HTMLElement.prototype.addE = function (tag) {
+  return this.appendChild(document.createElement(tag));
+};
+
+HTMLElement.prototype.addT = function (text) {
+  return this.appendChild(document.createTextNode(text));
+};
+
+
 // Utility for removing all children of a node
 function _removeChildren (node) {
   // Remove everything underneath
@@ -40,6 +49,7 @@
     node.removeChild(node.firstChild);
 };
 
+
 // Utility to get either the charCode
 // or the keyCode of an event
 function _codeFromEvent (e) {
diff --git a/dev/scss/main/matchinfo.scss b/dev/scss/main/matchinfo.scss
index ad25a63..c4acbd4 100644
--- a/dev/scss/main/matchinfo.scss
+++ b/dev/scss/main/matchinfo.scss
@@ -374,7 +374,7 @@
   display: flex;
   flex-direction: row;
   flex-wrap: wrap;
-  justify-content: flex-start;
+  justify-content: space-between;
   align-items: stretch;
   width: auto;
   padding-bottom: 0;