Open hint and QL menu in the guided tour

Change-Id: I404b6c798fc403b9fd9e8bddaaf485c67a8d85e3
diff --git a/dev/js/spec/tourSpec.js b/dev/js/spec/tourSpec.js
index e495be4..5dac709 100644
--- a/dev/js/spec/tourSpec.js
+++ b/dev/js/spec/tourSpec.js
@@ -4,8 +4,9 @@
  * @author Helge Stallkamp
  */
 
-define(['tour/tours', 'vc', 'session', 'match'], function(tourClass, vcClass, sessionClass, matchClass){
+define(['tour/tours', 'vc', 'session', 'match', 'hint',  'hint/foundries/cnx', 'selectMenu'], function(tourClass, vcClass, sessionClass, matchClass, hintClass, hintArray, selectMenuClass){
   const loc   = KorAP.Locale;
+  
   var introKorAP =
   	"<form autocomplete='off' action='/' id='searchform'>" + 
     "<div id='searchbar' class=''>" +
@@ -399,7 +400,7 @@
   });
   
   KorAP.vc = vc;
-
+  
   describe('KorAP.GuidedTour', function(){
 
     afterAll(function () {
@@ -415,7 +416,9 @@
         i--;
       };
     })
-        
+    
+    KorAP.Hint = hintClass.create({inputField: intrkorap.getElementById("q-field")});
+    
     it('IDs and classes, that are needed for the guided tour should be in existence', function(){
       //gTstartSearch
       expect(intrkorap.querySelector('#searchbar')).not.toBeNull();
@@ -447,6 +450,7 @@
     });
       
    it('Guided Tour should be started and display steps and labels in the right order', function(){
+
      let vcpanel = intrkorap.getElementById("vc-view");
      vcpanel.appendChild(vc.element());
      let searchTour = tourClass.gTstartSearch(intrkorap);
@@ -461,17 +465,31 @@
      for(let i = 2; i <= totalSteps; i++){
        searchTour.goToStepNumber(i);
        expect(document.querySelector(".introjs-tooltiptext").textContent).toEqual(searchTour.testIntros[i-1]);
+
+       switch(i){
+       case 4:
+       expect(intrkorap.querySelector('#hint')).not.toBeNull(); 
+       expect(KorAP.Hint).not.toBeNull();
+       expect(KorAP.Hint.active().dontHide).toBe(true); 
+       expect(KorAP.Hint._active).not.toBeNull();
+       break;
        
-       if(i == totalSteps){
-         expect(document.querySelector(".introjs-donebutton").textContent).toEqual(loc.TOUR_seargo);
-         expect(document.querySelector(".introjs-prevbutton").textContent).toEqual(loc.TOUR_lprev);
-         expect(document.querySelector(".introjs-nextbutton").classList.contains("introjs-disabled")).toBe(true);
-       } 
+       case 5:
+       expect(KorAP.Hint._active).toBeNull();
+       break;
+                     
+       case totalSteps:
+       expect(document.querySelector(".introjs-donebutton").textContent).toEqual(loc.TOUR_seargo);
+       expect(document.querySelector(".introjs-prevbutton").textContent).toEqual(loc.TOUR_lprev);
+       expect(document.querySelector(".introjs-nextbutton").classList.contains("introjs-disabled")).toBe(true);
+       break;
+       }
        searchTour.exit();
      } 
      
      let resultTour = tourClass.gTshowResults(resultkor);
      KorAP.session = sessionClass.create('KalamarJSDem'); 
+     
      resultTour.start(resultkor);
      let totalStepsR = resultTour.stepCount;
      expect(document.querySelector(".introjs-tooltiptext").textContent).toEqual(loc.TOUR_kwic);
@@ -479,8 +497,7 @@
      expect(document.querySelector(".introjs-prevbutton").textContent).toEqual(loc.TOUR_lprev);
      expect(document.querySelector(".introjs-nextbutton").textContent).toEqual(loc.TOUR_lnext);
      resultTour.exit();
-     
-    for(let i = 2; i <= totalStepsR; i++){
+     for(let i = 2; i <= totalStepsR; i++){
        resultTour.goToStepNumber(i);
        expect(document.querySelector(".introjs-tooltiptext").textContent).toEqual(resultTour.testIntros[i-1]);
        if(i == totalStepsR){
@@ -489,5 +506,18 @@
        resultTour.exit();
      } 
    });
+   
+   it('Guided Tour should hide Hint and QL Menu if aborted',  function(){
+     let tourAbort = tourClass.gTstartSearch(intrkorap);
+     tourAbort.start(); 
+     expect(KorAP.Hint._active).toBeNull();
+     expect(document.querySelector(".introjs-skipbutton")).not.toBeNull();
+     tourAbort.goToStepNumber(4);
+     expect(KorAP.Hint._active).not.toBeNull()
+     expect(KorAP.Hint.active().dontHide).toBe(true);
+     tourAbort.exit();
+     expect(KorAP.Hint._active).toBeNull();
+   });
+   
   });
 });
diff --git a/dev/js/src/loc/de.js b/dev/js/src/loc/de.js
index 2358306..1f0c821 100644
--- a/dev/js/src/loc/de.js
+++ b/dev/js/src/loc/de.js
@@ -52,7 +52,7 @@
   loc.TOUR_vccho2 = "Eigene Definition von Subkorpora durch Verknüpfung beliebiger Metadatenfelder.";
   loc.TOUR_vcStat1 = "Es besteht die Möglichkeit, die Korpusstatistik anzuzeigen.";
   loc.TOUR_vcStat2 = "Korpusstatistik";
-  loc.TOUR_qlfield = "Auswahl der Suchanfragesprache";
+  loc.TOUR_qlfield = "Auswahl der Suchanfragesprache: In KorAP können mehrere Suchanfragesprachen verwendet werden.";
   loc.TOUR_glimpse = "Beim Wählen dieser Option wird festgelegt ob nur die ersten Treffer in zufälliger Reihenfolge ausgewählt werden.";
   loc.TOUR_help = "Hilfe zu KorAP";
   loc.TOUR_seargo = "Suchanfrage starten";
diff --git a/dev/js/src/menu.js b/dev/js/src/menu.js
index 1fb1ffd..3c2fff8 100644
--- a/dev/js/src/menu.js
+++ b/dev/js/src/menu.js
@@ -150,6 +150,8 @@
       // Make this separate from _init
       this.readItems(list);
 
+      this.dontHide = false;
+        
       return this;
     },
 
@@ -583,12 +585,13 @@
      * Hide the menu and call the onHide callback.
      */
     hide : function () {
-      this.removeItems();
-      this._prefix.clear();
-      this.onHide();
-      this._element.classList.remove('visible');
-
-      /* this._element.blur(); */
+      if(!this.dontHide){
+          this.removeItems();
+          this._prefix.clear();
+          this.onHide();
+          this._element.classList.remove('visible');
+      } 
+       /* this._element.blur(); */
     },
 
     /**
diff --git a/dev/js/src/tour/tours.js b/dev/js/src/tour/tours.js
index 69d7392..45992ce 100644
--- a/dev/js/src/tour/tours.js
+++ b/dev/js/src/tour/tours.js
@@ -19,13 +19,13 @@
   //localization guided tour gTstartSearch
   loc.TOUR_sear1 = loc.TOUR_sear1 || "Enter your search enquiry here.";
   loc.TOUR_sear2 = loc.TOUR_sear2 || "For example the search for '" +  loc.TOUR_Qexample + "'.";
-  loc.TOUR_searAnnot = loc.TOUR_searAnnot || "Annotation helper: By clicking, the annotations of the differents layers are displayed and can be selected.";
-  loc.TOUR_annotAss =  loc.TOUR_annotAss || "The annoation assistant helps to formulate queries with annotations";
+  loc.TOUR_searAnnot = loc.TOUR_searAnnot || "Annotation helper";
+  loc.TOUR_annotAss =  loc.TOUR_annotAss || "The assistant displays the annotations of the different layers and helps to formulate queries.";
   loc.TOUR_vccho1 = loc.TOUR_vccho1 || "Choose corpus";  
   loc.TOUR_vccho2 = loc.TOUR_vccho2 || "Define your corpus here.";
   loc.TOUR_vcStat1 = loc.TOUR_vcStat1 || "Click here to display corpus statistic.";
   loc.TOUR_vcStat2 = loc.TOUR_vcStat2 || "Corpus statistic";
-  loc.TOUR_qlfield = loc.TOUR_qlfield|| "You can use KorAP with different query languages, select the query language here.";  
+  loc.TOUR_qlfield = loc.TOUR_qlfield|| "Selection of the query language: You can use KorAP with different languages.";  
   loc.TOUR_help = loc.TOUR_help || "Help and more information about KorAP.";
   loc.TOUR_glimpse = loc.TOUR_glimpse || "Select to show only the first hits in arbitrary order.";
   loc.TOUR_seargo = loc.TOUR_seargo || "Start the search.";
@@ -75,12 +75,12 @@
       //steps of the example tour
       let Steps =[
         {
-          element: '#searchbar',
+          element: '#q-field',
           intro: loc.TOUR_sear1,
           position: 'bottom'
         },
         {
-          element: '#searchbar',
+          element: '#q-field',
           intro: loc.TOUR_sear2,
           position: 'bottom'
         },
@@ -90,6 +90,11 @@
           position: 'bottom'
         },
         {
+          element: doe.querySelector("#hint > .menu.hint"),
+          intro: loc.TOUR_annotAss,
+          position: 'bottom',
+          }, 
+        {
           element:'#vc-choose',
           intro: loc.TOUR_vccho1,
           position: "bottom",
@@ -138,18 +143,16 @@
       //changes before executing the single steps
       intro.onbeforechange(function(targetedElement){
         switch(targetedElement.id){
-        case "searchbar": 
+        case "q-field": 
           /* 
            * TODO:
            * #268 is not merged at the time beeing: 
            * introJs.currentStep() merge requested https://github.com/usablica/intro.js/pull/268/files
            */
           if(this._currentStep == 1){ 
-            input = doe.querySelector('#q-field');
-            input.value= loc.TOUR_Qexample;
+            targetedElement.value = loc.TOUR_Qexample;
           }   
           break;
-
         case "vc-view":  
           vchoo = doe.querySelector("#vc-choose");
           vcv = doe.querySelector("#vc-view");  
@@ -161,8 +164,8 @@
             /*
              * Intro.js caches elements at the beginning, so element and position has to be set again.
              */
-            intro._introItems[5].element = doe.querySelector('.statistic');
-            intro._introItems[5].position = "left";
+            intro._introItems[6].element = doe.querySelector('.statistic');
+            intro._introItems[6].position = "left";
           }   
           break;   
           
@@ -177,15 +180,41 @@
           break;
         } 
         
-        if(this._currentStep == 6){
+        if(this._currentStep == 7){
           let statbut = doe.querySelector('.statistic');
           statbut.click();
-          intro._introItems[6].element = doe.querySelector(".stattable");
-          intro._introItems[6].position = "bottom";
+          intro._introItems[7].element = doe.querySelector(".stattable");
+          intro._introItems[7].position = "bottom";
         }
       });
 
-
+      intro.onbeforeexit(function(){
+          if(KorAP.Hint.active() && KorAP.Hint.active().dontHide){
+            KorAP.Hint.unshow();
+          }
+        });
+      
+      intro.onchange(function(targetElement) {
+        var that = this; 
+        switch(this._currentStep){
+        //hides Hint if back button is pressed 
+        case 2:   
+          if(KorAP.Hint.active()){
+          KorAP.Hint.unshow(); 
+          }
+          break;
+        case 3:
+          KorAP.Hint.show(false);
+          KorAP.Hint.active().dontHide = true;
+          intro._introItems[3].element = doe.querySelector(".menu.roll.hint");
+          intro._introItems[3].position = doe.querySelector("bottom");
+          break;
+        case 4: 
+          KorAP.Hint.unshow();      
+          break;
+        }
+        });  
+      
       // Execute at the end of the tour (By clicking at the done-Button)
       intro.oncomplete(function(){
         KorAP.session.set("tour", true);
@@ -254,9 +283,9 @@
         }, 
         //Step 9, intro_item 8
         {     
-          element: doe.querySelector("view.relations"),
+          element: doe.querySelector(".view.relations"),
           intro: loc.TOUR_tree,
-          position: "auto",
+          position: "bottom",
         }, 
         //Step 10, intro_item 9
         {     
@@ -266,11 +295,10 @@
       
         tourR.setOptions({steps:StepsSR});
         tourR.setOptions(labelOptions);
-      
-        tourR.onbeforechange(function (){ 
-        KorAP.session.set("tour", false);
+     
+        tourR.onbeforeexit(function(){
+          KorAP.session.set("tour", false);
         });
-      
         //See also: https://introjs.com/docs/intro/options/
         tourR.setOption('scrollToElement', true);
         tourR.setOption('scrollTo','tooltip');
@@ -306,9 +334,10 @@
         if(this._currentStep == 8){
           doe.querySelector(".tree").click();
           document.querySelectorAll(".button-group-list")[0].querySelectorAll('li')[1].click();
+          tourR._introItems[8].element = doe.querySelector(".view.relations");
         }
       });       
-
+  
       return tourR;
     },  
     /*