Merge "Improve windows-abandoning in makefile"
diff --git a/dev/demo/hintdemo.js b/dev/demo/hintdemo.js
index 7882787..e33faab 100644
--- a/dev/demo/hintdemo.js
+++ b/dev/demo/hintdemo.js
@@ -7,7 +7,7 @@
 
 var hint = undefined;
 
-require(['hint','hint/array','lib/domReady'], function (hintClass, hintArray, domReady) {
+require(['hint','hint/foundries/cnx','lib/domReady'], function (hintClass, hintArray, domReady) {
   KorAP.hintArray = hintArray;
   KorAP.Hint = null;
   domReady(function() {
diff --git a/dev/js/spec/matchSpec.js b/dev/js/spec/matchSpec.js
index 716022e..5a4111b 100644
--- a/dev/js/spec/matchSpec.js
+++ b/dev/js/spec/matchSpec.js
@@ -350,14 +350,42 @@
       expect(e.classList.contains('active')).toBe(true);
       expect(e["_match"]).not.toBe(undefined);
 
+      actions = e.querySelector("p.ref > div.action.bottom").getElementsByTagName("span");
+      expect(actions[0].getAttribute("class")).toEqual("meta");
+      expect(actions[1].getAttribute("class")).toEqual("info");
+      expect(actions[2].getAttribute("class")).toEqual("tree");
+      
       // Close the match
       m.close();
       expect(e.classList.contains('active')).toBe(false);
       expect(e["_match"]).not.toBe(undefined);
-
     });
-  });
 
+    it('should open tree menu', function () {
+      var e = matchElementFactory();
+      var m = matchClass.create(e);
+      m.open();
+      var relation = e.querySelector("p.ref > div.action.bottom > span:nth-of-type(3)");
+      expect(relation.getAttribute("class")).toEqual("tree");
+      expect(document.getElementById("treeMenu")).toBeNull();
+
+      expect(document.activeElement.tagName).toEqual("BODY");
+
+      // Show menu
+      relation.click();
+      expect(document.getElementById("treeMenu")).toBeTruthy();
+
+      expect(document.activeElement.tagName).toEqual("UL");
+
+      // Choose first tree
+      document.getElementById("treeMenu").getElementsByTagName("li")[1].click();
+      expect(e.querySelector("div.matchinfo div.matchtree h6 span").innerText).toEqual("corenlp");
+
+      // This should blur the focus
+      expect(document.activeElement.tagName).toEqual("BODY");
+    });
+
+  });
 
   describe('KorAP.MatchInfo', function () {
 
diff --git a/dev/js/spec/queryCreatorSpec.js b/dev/js/spec/queryCreatorSpec.js
index 8b79fbe..dffd3d3 100644
--- a/dev/js/spec/queryCreatorSpec.js
+++ b/dev/js/spec/queryCreatorSpec.js
@@ -1,5 +1,11 @@
 function matchTableFactory () {
   var table = document.createElement('div');
+
+  Element.prototype.innerString = function () {
+    return this.innerText.split("\n").join("");
+  };
+
+  
   table.className = 'matchtable';
   table.innerHTML = 
     "    <table>" +
@@ -124,7 +130,7 @@
 
       // Click on cell 0:0 "Foundry"
       var cell = matchTable.querySelector("thead > tr > th:first-child");
-      expect(cell.innerText).toEqual("Foundry");
+      expect(cell.innerString()).toEqual("Foundry");
       cell.click();
       expect(cell.classList.contains("chosen")).toBe(false);
       expect(qc.toString()).toEqual("");
@@ -132,7 +138,7 @@
 
       // Click on cell 0:2 "Der"
       cell = matchTable.querySelector("thead > tr > th:nth-child(3)")
-      expect(cell.innerText).toEqual("Der");
+      expect(cell.innerString()).toEqual("Der");
       cell.click();
       expect(cell.classList.contains("chosen")).toBeTruthy();
       expect(qc.toString()).toEqual("[orth=Der]");
@@ -140,7 +146,7 @@
 
       // Click on cell 0:2 "Der" again - to hide
       cell = matchTable.querySelector("thead > tr > th:nth-child(3)")
-      expect(cell.innerText).toEqual("Der");
+      expect(cell.innerString()).toEqual("Der");
       cell.click();
       expect(cell.classList.contains("chosen")).toBe(false);
       expect(qc.toString()).toEqual("");
@@ -152,17 +158,17 @@
       var qc = qcClass.create(matchTable);
 
       var cell = matchTable.querySelector("tbody > tr:nth-child(2) > td:nth-child(4)");
-      expect(cell.innerText).toEqual("ADJA");
+      expect(cell.innerString()).toEqual("ADJA");
       cell.click();
       expect(qc.toString()).toEqual("[opennlp/p=ADJA]");
 
       cell = matchTable.querySelector("thead > tr > th:nth-child(4)");
-      expect(cell.innerText).toEqual("älteste");
+      expect(cell.innerString()).toEqual("älteste");
       cell.click();
       expect(qc.toString()).toEqual("[opennlp/p=ADJA & orth=älteste]");
 
       cell = matchTable.querySelector("tbody > tr > td:nth-child(4)");
-      expect(cell.innerText).toEqual("ADJA");
+      expect(cell.innerString()).toEqual("ADJA");
       cell.click();
       expect(qc.toString()).toEqual("[corenlp/p=ADJA & opennlp/p=ADJA & orth=älteste]");
     });
@@ -172,17 +178,17 @@
       var qc = qcClass.create(matchTable);
 
       var cell = matchTable.querySelector("thead > tr > th:nth-child(5)");
-      expect(cell.innerText).toEqual("lebende");
+      expect(cell.innerString()).toEqual("lebende");
       cell.click();
       expect(qc.toString()).toEqual("[orth=lebende]");
 
       cell = matchTable.querySelector("tbody > tr:nth-child(2) > td:nth-child(3)");
-      expect(cell.innerText).toEqual("ART");
+      expect(cell.innerString()).toEqual("ART");
       cell.click();
       expect(qc.toString()).toEqual("[opennlp/p=ART][][orth=lebende]");
 
       cell = matchTable.querySelector("tbody > tr > td:nth-child(4)");
-      expect(cell.innerText).toEqual("ADJA");
+      expect(cell.innerString()).toEqual("ADJA");
       cell.click();
       expect(qc.toString()).toEqual("[opennlp/p=ART][corenlp/p=ADJA][orth=lebende]");
     });
@@ -192,31 +198,31 @@
       var qc = qcClass.create(matchTable);
 
       var cell = matchTable.querySelector("tbody > tr:nth-child(2) > td:nth-child(4)");
-      expect(cell.innerText).toEqual("ADJA");
+      expect(cell.innerString()).toEqual("ADJA");
       cell.click();
       expect(qc.toString()).toEqual("[opennlp/p=ADJA]");
       var cell1 = cell;
 
       cell = matchTable.querySelector("thead > tr > th:nth-child(4)");
-      expect(cell.innerText).toEqual("älteste");
+      expect(cell.innerString()).toEqual("älteste");
       cell.click();
       expect(qc.toString()).toEqual("[opennlp/p=ADJA & orth=älteste]");
       var cell2 = cell;
 
       cell = matchTable.querySelector("tbody > tr > td:nth-child(3)");
-      expect(cell.innerText).toEqual("ART");
+      expect(cell.innerString()).toEqual("ART");
       cell.click();
       expect(qc.toString()).toEqual("[corenlp/p=ART][opennlp/p=ADJA & orth=älteste]");
       var cell3 = cell;
 
       cell = matchTable.querySelector("thead > tr > th:nth-child(6)");
-      expect(cell.innerText).toEqual("Baum");
+      expect(cell.innerString()).toEqual("Baum");
       cell.click();
       expect(qc.toString()).toEqual("[corenlp/p=ART][opennlp/p=ADJA & orth=älteste][][orth=Baum]");
       var cell4 = cell;
 
       cell = matchTable.querySelector("thead > tr > th:nth-child(5)");
-      expect(cell.innerText).toEqual("lebende");
+      expect(cell.innerString()).toEqual("lebende");
       cell.click();
       expect(qc.toString()).toEqual("[corenlp/p=ART][opennlp/p=ADJA & orth=älteste][orth=lebende][orth=Baum]");
       var cell5 = cell;
@@ -284,14 +290,14 @@
       expect(qc.element().className).toEqual("queryfragment");
 
       var cell = matchTable.querySelector("tbody > tr:nth-child(2) > td:nth-child(4)");
-      expect(cell.innerText).toEqual("ADJA");
+      expect(cell.innerString()).toEqual("ADJA");
       expect(cell.classList.contains("chosen")).toBe(false);
       cell.click();
       expect(cell.classList.contains("chosen")).toBeTruthy();
       expect(qc.toString()).toEqual("[opennlp/p=ADJA]");
 
       cell = matchTable.querySelector("tbody > tr:nth-child(2) > td:nth-child(5)");
-      expect(cell.innerText).toEqual("");
+      expect(cell.innerString()).toEqual("");
       expect(cell.classList.contains("chosen")).toBe(false);
       cell.click();
       expect(cell.classList.contains("chosen")).toBe(false);
@@ -311,14 +317,14 @@
       expect(qc.element().className).toEqual("queryfragment");
 
       var cell = matchTable.querySelector("thead > tr > th:nth-child(5)");
-      expect(cell.innerText).toEqual("lebende");
+      expect(cell.innerString()).toEqual("lebende");
       expect(cell.classList.contains("chosen")).toBe(false);
       cell.click();
       expect(cell.classList.contains("chosen")).toBeTruthy();
       expect(qc.toString()).toEqual("[orth=lebende]");
 
       cell = matchTable.querySelector("tbody > tr:nth-child(1) > td:nth-child(5)");
-      expect(cell.innerText).toEqual("ADJAADJD");
+      expect(cell.innerString()).toEqual("ADJAADJD");
       expect(cell.classList.contains("chosen")).toBe(false);
       cell.click();
       expect(cell.classList.contains("chosen")).toBeTruthy();
@@ -346,14 +352,14 @@
       var corenlpRow = matchTable.querySelector("tbody > tr:nth-child(1)");
 
       var cell = corenlpRow.querySelector("td:nth-child(4)");
-      expect(cell.innerText).toEqual("ADJA");
+      expect(cell.innerString()).toEqual("ADJA");
       expect(cell.classList.contains("chosen")).toBe(false);
       cell.click();
       expect(cell.classList.contains("chosen")).toBeTruthy();
 
       // Activate another cell in another row
       cell = matchTable.querySelector("tbody > tr:nth-child(2) td:nth-child(3)");
-      expect(cell.innerText).toEqual("ART");
+      expect(cell.innerString()).toEqual("ART");
       expect(cell.classList.contains("chosen")).toBe(false);
       cell.click();
       expect(cell.classList.contains("chosen")).toBeTruthy();
@@ -367,7 +373,7 @@
 
       // Mark all corenlp lists
       cell = corenlpRow.querySelector("th:nth-child(1)");
-      expect(cell.innerText).toEqual("corenlp");
+      expect(cell.innerString()).toEqual("corenlp");
       expect(cell.classList.contains("chosen")).toBe(false);
       cell.click();
       expect(cell.classList.contains("chosen")).toBe(false);
@@ -379,7 +385,7 @@
 
       // Replay the choice without any effect
       cell = corenlpRow.querySelector("th:nth-child(1)");
-      expect(cell.innerText).toEqual("corenlp");
+      expect(cell.innerString()).toEqual("corenlp");
       expect(cell.classList.contains("chosen")).toBe(false);
       cell.click();
       expect(cell.classList.contains("chosen")).toBe(false);
@@ -394,7 +400,7 @@
 
       // Remove one of the cells again
       cell = corenlpRow.querySelector("td:nth-child(5).chosen");
-      expect(cell.innerText).toEqual("ADJAADJD");
+      expect(cell.innerString()).toEqual("ADJAADJD");
       expect(cell.classList.contains("chosen")).toBeTruthy();
       cell.click();
       expect(cell.classList.contains("chosen")).toBe(false);
@@ -418,7 +424,7 @@
 
       // Mark all opennlp lists
       cell = opennlpRow.querySelector("th:nth-child(1)");
-      expect(cell.innerText).toEqual("opennlp");
+      expect(cell.innerString()).toEqual("opennlp");
       expect(cell.classList.contains("chosen")).toBe(false);
       cell.click();
       expect(cell.classList.contains("chosen")).toBe(false);
@@ -436,17 +442,17 @@
       var qc = qcClass.create(matchTable);
 
       var cell = matchTable.querySelector("thead > tr > th:nth-child(3)");
-      expect(cell.innerText).toEqual("Der");
+      expect(cell.innerString()).toEqual("Der");
       cell.click();
       expect(qc.toString()).toEqual("[orth=Der]");
 
       cell = matchTable.querySelector("thead > tr > th:nth-child(7)");
-      expect(cell.innerText).toEqual("hier");
+      expect(cell.innerString()).toEqual("hier");
       cell.click();
       expect(qc.toString()).toEqual("[orth=Der][]{3}[orth=hier]");
 
       cell = matchTable.querySelector("thead > tr > th:nth-child(5)");
-      expect(cell.innerText).toEqual("lebende");
+      expect(cell.innerString()).toEqual("lebende");
       cell.click();
       expect(qc.toString()).toEqual("[orth=Der][][orth=lebende][][orth=hier]");
     });
@@ -463,7 +469,7 @@
       expect(qc.element().className).toEqual("queryfragment");
 
       var cell = matchTable.querySelector("thead > tr > th:nth-child(5)");
-      expect(cell.innerText).toEqual("lebende");
+      expect(cell.innerString()).toEqual("lebende");
       expect(cell.classList.contains("chosen")).toBe(false);
       cell.click();
       expect(cell.classList.contains("chosen")).toBeTruthy();
@@ -471,7 +477,7 @@
 
       // Check complex cell
       cell = matchTable.querySelector("tbody > tr:nth-child(1) > td:nth-child(6)");
-      expect(cell.innerText).toMatch(/case:nom/);
+      expect(cell.innerString()).toMatch(/case:nom/);
       expect(cell.classList.contains("chosen")).toBe(false);
       cell.click();
       expect(cell.classList.contains("chosen")).toBe(false);
@@ -479,7 +485,7 @@
 
       // Check complex cell div
       cell = matchTable.querySelector("tbody > tr:nth-child(1) > td:nth-child(6) > div:nth-child(1)");
-      expect(cell.innerText).toEqual('case:nom');
+      expect(cell.innerString()).toEqual('case:nom');
       expect(cell.classList.contains("chosen")).toBe(false);
       cell.click();
       expect(cell.classList.contains("chosen")).toBe(true);
@@ -487,7 +493,7 @@
       var cell = cell;
 
       cell = matchTable.querySelector("tbody > tr:nth-child(1) > td:nth-child(6) > div:nth-child(3)");
-      expect(cell.innerText).toEqual('number:sg');
+      expect(cell.innerString()).toEqual('number:sg');
       expect(cell.classList.contains("chosen")).toBe(false);
       cell.click();
       expect(cell.classList.contains("chosen")).toBe(true);
@@ -495,7 +501,7 @@
       var cell2 = cell;
 
       cell = matchTable.querySelector("tbody > tr:nth-child(1) > td:nth-child(6) > div:nth-child(2)");
-      expect(cell.innerText).toEqual('gender:mascgender:fem');
+      expect(cell.innerString()).toEqual('gender:mascgender:fem');
       expect(cell.classList.contains("chosen")).toBe(false);
       cell.click();
       expect(cell.classList.contains("chosen")).toBe(true);
@@ -504,7 +510,7 @@
 
       // Remove cell again
       cell = cell2;
-      expect(cell.innerText).toEqual('number:sg');
+      expect(cell.innerString()).toEqual('number:sg');
       expect(cell.classList.contains("chosen")).toBe(true);
       cell.click();
       expect(cell.classList.contains("chosen")).toBe(false);
@@ -512,7 +518,7 @@
 
       // Remove cell again
       cell = cell3;
-      expect(cell.innerText).toEqual('gender:mascgender:fem');
+      expect(cell.innerString()).toEqual('gender:mascgender:fem');
       expect(cell.classList.contains("chosen")).toBe(true);
       cell.click();
       expect(cell.classList.contains("chosen")).toBe(false);
@@ -536,7 +542,7 @@
 
       // Mark all opennlp lists
       cell = corenlpRow.querySelector("th:nth-child(1)");
-      expect(cell.innerText).toEqual("corenlp");
+      expect(cell.innerString()).toEqual("corenlp");
       expect(cell.classList.contains("chosen")).toBe(false);
       cell.click();
       expect(cell.classList.contains("chosen")).toBe(false);
diff --git a/dev/js/src/hint.js b/dev/js/src/hint.js
index 19c360f..e1b0796 100644
--- a/dev/js/src/hint.js
+++ b/dev/js/src/hint.js
@@ -259,7 +259,7 @@
 
       // Remove the active object
       this._unshow();
-      
+     
       // Get the menu
       var menu;
       if (menu = this.contextMenu(ifContext)) {
@@ -300,12 +300,12 @@
     _unshow : function () {
       if (this.active() !== null) {
         // var act = this.active();
-        
+
         // This does not work for alert currently!
 	      //if (act._type !== 'alert') {
         if (!this._alert.active) {
           var c = this._inputField.container();
-	        c.removeChild(this._active.element());
+          c.removeChild(this._active.element());
 	      }
         else {
           this._unshowAlert();
diff --git a/dev/js/src/hint/menu.js b/dev/js/src/hint/menu.js
index fcf3fc6..dd99d1f 100644
--- a/dev/js/src/hint/menu.js
+++ b/dev/js/src/hint/menu.js
@@ -27,7 +27,7 @@
 
       // This is only domspecific
       obj.element().addEventListener('blur', function (e) {
-	      this.menu.hide();
+        this.menu.hideWithoutDestruction();
       });
 
       // Focus on input field on hide
@@ -44,6 +44,16 @@
      */ 
     hint : function () {
       return this._hint;
+    },
+
+    /**
+     * Hide the menu just for the moment,
+     * without cleaning up anything.
+     */
+    hideWithoutDestruction : function () {
+      this.element().classList.remove("visible");
+      if (this._hint)
+        this._hint.inputField().element().focus();
     }
   };
 });
diff --git a/dev/js/src/match/treemenu.js b/dev/js/src/match/treemenu.js
index 1a12774..6b8a76a 100644
--- a/dev/js/src/match/treemenu.js
+++ b/dev/js/src/match/treemenu.js
@@ -76,6 +76,7 @@
       if (this._onscroll !== undefined) {
         window.removeEventListener('scroll', this._onscroll);
       };
+      this.element().blur();
     },
 
     _repos : function (e) {