Merge "Extended Guided Tour"
diff --git a/dev/js/spec/matchSpec.js b/dev/js/spec/matchSpec.js
index f71ba56..a51fd78 100644
--- a/dev/js/spec/matchSpec.js
+++ b/dev/js/spec/matchSpec.js
@@ -260,17 +260,18 @@
 
   var afterAllFunc = function () {
     KorAP.API.getMatchInfo = undefined;
-    // KorAP.annotationHelper = undefined;
+    KorAP.TreeMenu = undefined;
     var body = document.body;
-    for (var i in body.children) {
+    var i = body.children.length - 1;
+    while (i >= 0) {
       if (body.children[i].nodeType && body.children[i].nodeType === 1) {
         if (!body.children[i].classList.contains("jasmine_html-reporter")) {
           body.removeChild(body.children[i]);
         };
       };
+      i--;
     };
   };
-
   
   describe('KorAP.InfoLayer', function () {
     beforeAll(beforeAllFunc);
@@ -404,10 +405,10 @@
 
       expect(e.classList.contains('active')).toBe(false);
       expect(e["_match"]).not.toBe(undefined);
-
+      
       // Open the match
       m.open();
-
+      
       expect(e.classList.contains('active')).toBe(true);
       expect(e["_match"]).not.toBe(undefined);
 
@@ -430,21 +431,20 @@
       var relation = e.querySelector("p.ref > div.action.button-group > span:nth-of-type(3)");
       expect(relation.getAttribute("class")).toEqual("tree");
       expect(document.getElementsByClassName("button-group-list").length).toEqual(0);
-
       expect(document.activeElement.tagName).toEqual("BODY");
-
+ 
       // Show menu
       relation.click();
       expect(document.getElementsByClassName("button-group-list").length).toEqual(1);
-
       expect(document.activeElement.tagName).toEqual("UL");
-
+      
       // Choose first tree
       document.getElementsByClassName("button-group-list")[0].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");
+      
     });
 
   });
diff --git a/dev/js/spec/tourSpec.js b/dev/js/spec/tourSpec.js
index 4bb71ef..e495be4 100644
--- a/dev/js/spec/tourSpec.js
+++ b/dev/js/spec/tourSpec.js
@@ -1,13 +1,11 @@
 /**
- * Test suite for guided tour.
+ * Test suite for guided tour
  * 
  * @author Helge Stallkamp
  */
 
-define(['tour/tours', 'vc', 'session'], function(tourClass, vcClass, sessionClass){
+define(['tour/tours', 'vc', 'session', 'match'], function(tourClass, vcClass, sessionClass, matchClass){
   const loc   = KorAP.Locale;
- 
-  //TODO Read this file from the file system, see https://korap.ids-mannheim.de/gerrit/#/c/KorAP/Kalamar/+/2241/
   var introKorAP =
   	"<form autocomplete='off' action='/' id='searchform'>" + 
     "<div id='searchbar' class=''>" +
@@ -78,11 +76,320 @@
   }; 
   
 
+  var resultkorap =  
+    "<div id='search'>" +
+      "<ol class='align-left' tabindex='-8'>" +
+        "<li data-corpus-id='WPD' " +
+          "data-doc-id='WWW'" +
+          "data-text-id='03313'" +
+          "data-match-id='p102-103'" +
+          "data-available-info='base/s=spans corenlp/c=spans corenlp/ne=tokens corenlp/p=tokens corenlp/s=spans glemm/l=tokens mate/l=tokens mate/m=tokens mate/p=tokens opennlp/p=tokens opennlp/s=spans tt/l=tokens tt/p=tokens tt/s=spans xip/c=spans malt/d=rels'"+
+          "id='WPD-WWW.03313-p102-103'" +
+          "tabindex='6'>" +
+          "<div class='meta'>WPD/WWW/03313</div>" +
+          "<div class='match-main'>" +
+            "<div class='match-wrap'>" +
+              "<div class='snippet startMore endMore'>" +
+                "<div class='flag'></div>" +
+                "<span class='context-left'>In diesem Beispiel ist zu sehen, dass die beiden Variablen a und b lediglich ihre Werte an" +
+                " die Funktion </span><mark><mark class='class-2 level-1'>Dies </mark><mark class='class-1 level-0'><mark class='class-2 level-1'><mark class='class-3 level-2'>ist</mark>" +
+                " ein</mark> Test</mark></mark><span class='context-right'> übergeben, aber im Gegensatz zu einem Referenzparamter dabei unverändert bleiben.</span></div>" + 
+              "</div>"+
+              "<!-- only inject via javascript! -->" +
+             "</div>" + 
+             "<p class='ref'><strong>Wertparameter</strong> by Hubi,Zwobot,4; published on 2005-03-28 as WWW.03313 (WPD)</p>" +
+             "<!-- only inject via javascript! -->" +
+           "</li>" + 
+      "</div>"; 
+
+
+
+  var snippet = "<span title=\"cnx/l:meist\">" +
+      "  <span title=\"cnx/p:ADV\">" +
+      "    <span title=\"cnx/syn:@PREMOD\">" +
+      "      <span title=\"mate/l:meist\">" +
+      "        <span title=\"mate/l:meist\">" +
+      "          <span title=\"mate/p:ADV\">" +
+      "            <span title=\"opennlp/p:ADV\">meist</span>" +
+      "          </span>" +
+      "        </span>" +
+      "      </span>" +
+      "    </span>" +
+      "  </span>" +
+      "</span>" +
+      "<mark>" + 
+      "<span title=\"cnx/l:deutlich\">" +
+      "  <span title=\"cnx/p:A\">" +
+      "    <span title=\"cnx/syn:@PREMOD\">" +
+      "      <span title=\"mate/l:deutlich\">" +
+      "        <span title=\"mate/m:degree:pos\">" +
+      "          <span title=\"mate/p:ADJD\">" +
+      "            <span title=\"opennlp/p:ADJD\">deutlich</span>" +
+      "          </span>" +
+      "        </span>" +
+      "      </span>" +
+      "    </span>" +
+      "  </span>" +
+      "</span>" +
+      "</mark>" +
+      "<span title=\"cnx/l:fähig\">" +
+      "  <span title=\"cnx/l:leistung\">" +
+      "    <span title=\"cnx/p:A\">" +
+      "      <span title=\"cnx/p:ADJA\">" +
+      "        <span title=\"cnx/syn:@NH\">" +
+      "          <span title=\"mate/l:leistungsfähig\">" +
+      "            <span title=\"mate/m:degree:comp\">" +
+      "              <span title=\"mate/p:ADJD\">" +
+      "                <span title=\"opennlp/p:ADJD\">leistungsfähiger</span>" +
+      "              </span>" +
+      "            </span>" +
+      "          </span>" +
+      "        </span>" +
+      "      </span>" +
+      "    </span>" +
+      "  </span>" +
+      "</span>";
+
+  var treeSnippet =
+      "<span class=\"context-left\"></span>" +
+      "<span class=\"match\">" +
+      "  <span title=\"xip/c:MC\">" +
+      "    <span title=\"xip/c:TOP\">" +
+      "      <span title=\"xip/c:PP\">" +
+      "        <span title=\"xip/c:PREP\">Mit</span>" +
+      "        <span title=\"xip/c:NP\">" +
+      "          <span title=\"xip/c:DET\">dieser</span>" +
+      "          <span title=\"xip/c:NPA\">" +
+      "            <span title=\"xip/c:NOUN\">Methode</span>" +
+      "          </span>" +
+      "        </span>" +
+      "      </span>" +
+      "      <span title=\"xip/c:VERB\">ist</span>" +
+      "      <mark>" +
+      "        <span title=\"xip/c:NP\">" +
+      "          <span title=\"xip/c:PRON\">es</span>" +
+      "        </span>" +  
+      "        <span title=\"xip/c:AP\">" +
+      "          <span title=\"xip/c:ADV\">nun</span>" +
+      "          <span title=\"xip/c:ADJ\">möglich</span>" +
+      "        </span>" +
+      "      </mark>" +
+      "      <span title=\"xip/c:ADV\">z. B.</span>" +
+      "      <span title=\"xip/c:NPA\">" +
+      "        <span title=\"xip/c:NP\">" +
+      "          <span title=\"xip/c:NOUN\">Voice</span>" +
+      "        </span>" +
+      "      </span>" + "(" +
+      "      <span title=\"xip/c:INS\">" +
+      "        <span title=\"xip/c:NPA\">" +
+      "          <span title=\"xip/c:NP\">" +
+      "            <span title=\"xip/c:NOUN\">Sprache</span>" +
+      "          </span>" +
+      "        </span>" +
+      "      </span>" + ")" +
+      "      <span title=\"xip/c:VERB\">bevorzugt</span>" +
+      "      <span title=\"xip/c:PP\">" +
+      "        <span title=\"xip/c:PREP\">in</span>" +
+      "        <span title=\"xip/c:NP\">" +
+      "          <span title=\"xip/c:PRON\">der</span>" +
+      "        </span>" +
+      "        <span title=\"xip/c:NPA\">" +
+      "          <span title=\"xip/c:NP\">" +
+      "            <span title=\"xip/c:NOUN\">Bridge</span>" +
+      "          </span>" +
+      "        </span>" +
+      "      </span>" +
+      "      <span title=\"xip/c:INFC\">" +
+      "        <span title=\"xip/c:INS\">" +
+      "          <span title=\"xip/c:VERB\">weiterzugeben</span>" +
+      "        </span>" +
+      "      </span>" +
+      "    </span>" +
+      "  </span>" +
+      "</span>" +
+      "<span class=\"context-right\"></span>";
+  
+  KorAP.API.getTextInfo = function (doc, param, cb) {
+    cb(textInfo);
+  };
+
+    // Override getMatchInfo API call
+    KorAP.API.getMatchInfo = function (x, param, cb) {
+      if (param['spans'] === undefined || param['spans'] === false)
+        cb({ "snippet": snippet });
+      else
+        cb({ "snippet": treeSnippet });
+    };
+
+    var textInfo = {
+        "@context":"http:\/\/korap.ids-mannheim.de\/ns\/KoralQuery\/v0.3\/context.jsonld",
+        "document":{
+          "@type":"koral:document",
+          "fields":[
+            {
+              "@type":"koral:field",
+              "key":"editor",
+              "type":"type:store",
+              "value":"wikipedia.org"
+            },
+            {
+              "@type":"koral:field",
+              "key":"textSigle",
+              "type":"type:string",
+              "value":"WPD15\/264\/58336"
+            },
+            {
+              "@type":"koral:field",
+              "key":"author",
+              "type":"type:text",
+              "value":"Sprachpfleger, u.a."
+            },
+            {
+              "@type":"koral:field",
+              "key":"docSigle",
+              "type":"type:string",
+              "value":"WPD15\/264"
+            },
+            {
+              "@type":"koral:field",
+              "key":"textTypeArt",
+              "type":"type:string",
+              "value":"Enzyklopädie-Artikel"
+            },
+            {
+              "@type":"koral:field",
+              "key":"language",
+              "type":"type:string",
+              "value":"de"
+            },
+            {
+              "@type":"koral:field",
+              "key":"docTitle",
+              "type":"type:text",
+              "value":"Wikipedia, Artikel mit Anfangszahl 2, Teil 64"
+            },
+            {
+              "@type":"koral:field",
+              "key":"textType",
+              "type":"type:string",
+              "value":"Enzyklopädie"
+            },
+            {
+              "@type":"koral:field",
+              "key":"availability",
+              "type":"type:string",
+              "value":"CC-BY-SA"
+            },
+            {
+              "@type":"koral:field",
+              "key":"foundries",
+              "type":"type:keywords",
+              "value":[
+                "corenlp",
+                "corenlp\/constituency",
+                "corenlp\/morpho",
+                "corenlp\/sentences",
+                "dereko",
+                "dereko\/structure",
+                "dereko\/structure\/base-sentences-paragraphs-pagebreaks",
+                "opennlp",
+                "opennlp\/morpho",
+                "opennlp\/sentences"
+              ]
+            },
+            {
+              "@type":"koral:field",
+              "key":"creationDate",
+              "type":"type:date",
+              "value":"2015-04-17"
+            },
+            {
+              "@type":"koral:field",
+              "key":"title",
+              "type":"type:text",
+              "value":"22:43 – Das Schicksal hat einen Plan"
+            },
+            {
+              "@type":"koral:field",
+              "key":"pubDate",
+              "type":"type:date",
+              "value":"2015-05-01"
+            },
+            {
+              "@type":"koral:field",
+              "key":"reference",
+              "type":"type:store",
+              "value":"22:43 – Das Schicksal hat einen Plan, In: Wikipedia - URL:http:\/\/de.wikipedia.org\/wiki\/22:43_–_Das_Schicksal_hat_einen_Plan: Wikipedia, 2015"
+            },
+            {
+              "@type":"koral:field",
+              "key":"textClass",
+              "type":"type:keywords",
+              "value":["kultur","film"]
+            },
+            {
+              "@type":"koral:field",
+              "key":"tokenSource",
+              "type":"type:store",
+              "value":"base#tokens"
+            },
+            {
+              "@type":"koral:field",
+              "key":"publisher",
+              "type":"type:store",
+              "value":"Wikipedia"
+            },
+            {
+              "@type":"koral:field",
+              "key":"layerInfos",
+              "type":"type:store",
+              "value":"corenlp\/c=spans corenlp\/p=tokens corenlp\/s=spans dereko\/s=spans opennlp\/p=tokens opennlp\/s=spans"
+            },
+            {
+              "@type":"koral:field",
+              "key":"pubPlace",
+              "type":"type:string",
+              "value":"URL:http:\/\/de.wikipedia.org"
+            },
+            {
+              "@type":"koral:field",
+              "key":"corpusTitle",
+              "type":"type:text",
+              "value":"Wikipedia"
+            },
+            {
+              "@type":"koral:field",
+              "key":"corpusEditor",
+              "type":"type:store",
+              "value":"wikipedia.org"
+            },
+            {
+              "@type":"koral:field",
+              "key":"corpusSigle",
+              "type":"type:string",
+              "value":"WPD15"
+            }
+          ]
+        }
+      };
   let template = document.createElement('template');
   let html = introKorAP.trim(); // Do not return a text node of whitespace as the result
   template.innerHTML = html;
   let intrkorap = template.content;
   
+  let resulttemplate = document.createElement('template');
+  let htmlZwei = resultkorap.trim(); 
+  resulttemplate.innerHTML = resultkorap;
+  var resultkor = resulttemplate.content;
+
+  resultkor.querySelector('#search > ol > li:not(.active)').addEventListener('click', function (e) {
+    if (this._match !== undefined)
+      this._match.open();
+    else {
+      matchClass.create(this).open();
+    }
+  });
+  
   let vc= vcClass.create().fromJson({
     '@type' : 'koral:doc',
     'key' : 'title', 
@@ -92,10 +399,25 @@
   });
   
   KorAP.vc = vc;
-  //TODO Add hint and vc-choose, they are not part of the generated file
-  
+
   describe('KorAP.GuidedTour', function(){
+
+    afterAll(function () {
+      KorAP.API.getMatchInfo = undefined;
+      var body = document.body;
+      var i = body.children.length - 1;
+      while (i >= 0) {
+        if (body.children[i].nodeType && body.children[i].nodeType === 1) {
+          if (!body.children[i].classList.contains("jasmine_html-reporter")) {
+            body.removeChild(body.children[i]);
+          };
+        };
+        i--;
+      };
+    })
+        
     it('IDs and classes, that are needed for the guided tour should be in existence', function(){
+      //gTstartSearch
       expect(intrkorap.querySelector('#searchbar')).not.toBeNull();
       expect(intrkorap.querySelector('#q-field')).not.toBeNull();
       expect(intrkorap.querySelector('#hint')).not.toBeNull();
@@ -111,12 +433,20 @@
       expect(statbut).not.toBeNull();
       statbut.click();
       expect(show.querySelector('.stattable')).not.toBeNull();
+      //IDs and classes, that are needed for the second guided tour(gTshowResults()) should be in existence, too
+      expect(resultkor.querySelector('#search')).not.toBeNull();
+      expect(resultkor.querySelector('#search > ol > li')).not.toBeNull();
+      resultkor.querySelector("#search > ol > li").click();      
+      expect(resultkor.querySelector('.action > .metatable')).not.toBeNull();
+      resultkor.querySelector(".metatable").click();
+      expect(resultkor.querySelector('.view.metatable')).not.toBeNull();
+      expect(resultkor.querySelector('.action > .info')).not.toBeNull();
+      resultkor.querySelector(".info").click();
+      expect(resultkor.querySelector('.view.tokentable')).not.toBeNull();
+      expect(resultkor.querySelector('.tree')).not.toBeNull(); 
     });
-    
-   
-  
+      
    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);
@@ -140,14 +470,24 @@
        searchTour.exit();
      } 
      
-     let resultTour = tourClass.gTshowResults(intrkorap);
+     let resultTour = tourClass.gTshowResults(resultkor);
      KorAP.session = sessionClass.create('KalamarJSDem'); 
-     resultTour.start();
-     expect(document.querySelector(".introjs-tooltiptext").textContent).toEqual(loc.TOUR_result);
-     expect(document.querySelector(".introjs-donebutton").textContent).toEqual(loc.TOUR_ldone);   
+     resultTour.start(resultkor);
+     let totalStepsR = resultTour.stepCount;
+     expect(document.querySelector(".introjs-tooltiptext").textContent).toEqual(loc.TOUR_kwic);
+     expect(document.querySelector(".introjs-skipbutton").textContent).toEqual(loc.TOUR_lskip);
+     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++){
+       resultTour.goToStepNumber(i);
+       expect(document.querySelector(".introjs-tooltiptext").textContent).toEqual(resultTour.testIntros[i-1]);
+       if(i == totalStepsR){
+         expect(document.querySelector(".introjs-donebutton").textContent).toEqual(loc.TOUR_ldone);  
+       }   
+       resultTour.exit();
+     } 
+   });
   });
-}    
-);
+});
diff --git a/dev/js/src/loc/de.js b/dev/js/src/loc/de.js
index 467adc4..2358306 100644
--- a/dev/js/src/loc/de.js
+++ b/dev/js/src/loc/de.js
@@ -58,6 +58,16 @@
   loc.TOUR_seargo = "Suchanfrage starten";
   
   //Guided Tour: explain the result
-  loc.TOUR_result = "Viel Spaß mit KorAP!";
+  loc.TOUR_kwic = "Anzeige des Ergebnisses als KWIC (keyword in context).";
+  loc.TOUR_snippet = "Durch Klicken auf das KWIC kann ein größerer Kontext angezeigt werden.";  
+  loc.TOUR_snippetb = "Anzeige des Snippets";
+  loc.TOUR_metadatab = "Durch die Auswahl des Buttons werden die Metadaten angezeigt.";
+  loc.TOUR_metadata = "Anzeige der Metadaten";
+  loc.TOUR_tokenb = loc.TOUR_tokenb || "Anzeige der Token-Annotationen";
+  loc.TOUR_token = loc.TOUR_token || "KorAP unterstützt multiple Annotationen.";
+  loc.TOUR_treeb = loc.TOUR_tree || "Anzeige weiterer Ansichten"
+  loc.TOUR_tree = loc.TOUR_tree || "Weitere Ansichten können als Baum- oder Bogenansichten angezeigt werden.";
+  loc.TOUR_tourdone = "Viel Spaß mit KorAP!";
+  
   
 });
diff --git a/dev/js/src/tour/tours.js b/dev/js/src/tour/tours.js
index 6ae961c..69d7392 100644
--- a/dev/js/src/tour/tours.js
+++ b/dev/js/src/tour/tours.js
@@ -4,7 +4,8 @@
  * @author Helge Stallkamp
  */
 
-define(['lib/intro', 'vc', 'vc/doc', 'vc/docgroup'], function(introClass, vcClass, docClass, docGroup) {
+
+define(['lib/intro', 'vc', 'hint', 'menu', 'vc/doc', 'vc/docgroup'], function(introClass, vcClass, hintClass, menuClass, docClass, docGroup) {
 
   //needed for localization of labels and contents of the tour
   const loc   = KorAP.Locale;
@@ -28,8 +29,18 @@
   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.";
+
   //localization guided Tour gTshowResults
-  loc.TOUR_result = loc.TOUR_result || "Have fun with KorAP!";
+  loc.TOUR_kwic = loc.TOUR_kwic || "KWIC result (keyword in context)";
+  loc.TOUR_snippet = loc.TOUR_snippet ||  "Click on a match to show a larger snippet.";
+  loc.TOUR_snippetb = loc.TOUR_snippetb || "Display of larger snippet";
+  loc.TOUR_metadatab =  loc.TOUR_metadatab || "Click here to display the metadata.";
+  loc.TOUR_metadata = loc.TOUR_metadata || "Metadata";
+  loc.TOUR_tokenb = loc.TOUR_tokenb || "Click here to display the token annotations.";
+  loc.TOUR_token = loc.TOUR_token || "KorAP supports multiple annotations.";
+  loc.TOUR_treeb = loc.TOUR_treeb || "Display further annotations."
+  loc.TOUR_tree = loc.TOUR_tree || "Further annotations can be displayed as tree and arch views."
+  loc.TOUR_tourdone = loc.TOUR_tourdone || "Have fun with KorAP!";
   
   //localization of button labels
   let labelOptions = {
@@ -39,6 +50,8 @@
       'doneLabel': loc.TOUR_ldone,
       'showStepNumbers': false,
   };
+  
+  var doe = document;
 
   return{
 
@@ -51,7 +64,6 @@
       intro.setOption('doneLabel', loc.TOUR_seargo);
      
       //for testing purposes
-      var doe = document;
       if(elparam){
         doe = elparam;
       }
@@ -120,19 +132,9 @@
         ];
 
       //pass in the Steps array created earlier
-      intro.setOptions({steps: Steps});
-
-      //total number of steps, needed for jasmine tests
-      //TODO see also: introJS.totalSteps() merge requested: //github.com/usablica/intro.js/pull/268/files
-      intro.stepCount = Steps.length;
-
-      //array of intro content needed for efficient testing
-      intro.testIntros = [];
-
-      for(let i = 0; i< Steps.length; i++){
-        intro.testIntros.push(Steps[i].intro);
-      }
-
+      intro.setOptions({steps: Steps});      
+      this.testPrerequ(Steps, intro);
+      
       //changes before executing the single steps
       intro.onbeforechange(function(targetedElement){
         switch(targetedElement.id){
@@ -170,7 +172,6 @@
         * completion the gTshowResults Tour. Therefore, the skip-button is removed
         * and the label of the done button changed.
          */
-         
         case "qsubmit":
             intro.setOption('hideNext', true);
           break;
@@ -189,8 +190,6 @@
       intro.oncomplete(function(){
         KorAP.session.set("tour", true);
         doe.getElementById("qsubmit").click();
-        //input.value="";
-        //KorAP._delete.apply(KorAP.vc.root()); 
       });
 
       return intro;
@@ -198,25 +197,136 @@
 
 
     /* Guided Tour to explain the different views of the results */     
-    gTshowResults: function(elparam){  
+    gTshowResults: function(elparam){ 
+      //for testing purposes
       if(elparam){
         doe = elparam;
       }
       let tourR = introClass();
       let StepsSR = [
+        //Step 1, intro_item 0
+        {
+          element: '#search',
+          intro: loc.TOUR_kwic ,
+          position: "auto",
+        },
+        //Step 2, intro_item 1 
+        {
+          element: doe.querySelector("#search > ol > li"),
+          intro: loc.TOUR_snippet,
+          position: "bottom",
+        },
+        //Step 3, intro_item 2 
+        {
+          element: doe.querySelector("#search > ol > li"),
+          intro: loc.TOUR_snippetb,
+          position: "bottom",
+        },
+        //Step 4, intro_item 3
+        {
+          element: doe.querySelector(".action > .metatable"),
+          intro: loc.TOUR_metadatab,
+          position: "bottom",
+        },
+        //Step 5, intro_item 4
+        {
+          element: doe.querySelector(".view.metatable"),
+          intro: loc.TOUR_metadata,
+          position: "auto",
+        },
+        //Step 6, intro_item 5
+        {   
+          element: doe.querySelector(".action > .info"),
+          intro: loc.TOUR_tokenb,
+          position: "bottom",
+        },
+        //Step 7, intro_item 6
+        {   
+          element: doe.querySelector(".view.tokentable"),
+          intro: loc.TOUR_token,
+          position: "auto",
+        },
+        //Step 8, intro_item 7
         {     
-          intro: loc.TOUR_result,
-        }
+          element: doe.querySelector(".tree"),
+          intro: loc.TOUR_treeb,
+          position: "bottom",
+        }, 
+        //Step 9, intro_item 8
+        {     
+          element: doe.querySelector("view.relations"),
+          intro: loc.TOUR_tree,
+          position: "auto",
+        }, 
+        //Step 10, intro_item 9
+        {     
+          intro: loc.TOUR_tourdone, 
+        }    
         ]
-      tourR.setOptions({steps:StepsSR});
-      tourR.setOptions(labelOptions);
       
-      tourR.onbeforechange(function (){ 
+        tourR.setOptions({steps:StepsSR});
+        tourR.setOptions(labelOptions);
+      
+        tourR.onbeforechange(function (){ 
         KorAP.session.set("tour", false);
-      });
+        });
       
+        //See also: https://introjs.com/docs/intro/options/
+        tourR.setOption('scrollToElement', true);
+        tourR.setOption('scrollTo','tooltip');
+        this.testPrerequ(StepsSR, tourR);
+      
+        //TODO see also: introJS.totalSteps() merge requested: //github.com/usablica/intro.js/pull/268/files
+        tourR.onbeforechange(function(targetedElement){
+          
+        if(this._currentStep == 1){
+          KorAP.session.set("tour", false);
+        }
+        
+        if(this._currentStep == 2){
+          doe.querySelector("#search > ol > li").click();
+          tourR._introItems[3].element = doe.querySelector('.action > .metatable');
+          tourR._introItems[3].position = "bottom";
+        }
+  
+        if(this._currentStep == 4){
+          doe.querySelector(".metatable").click();
+          tourR._introItems[4].element = doe.querySelector('.view.metatable');
+          tourR._introItems[5].element = doe.querySelector('.action > .info');
+          tourR._introItems[5].position = "bottom";          
+        }   
+     
+        if(this._currentStep == 6){
+            doe.querySelector(".info").click();
+            tourR._introItems[6].element = doe.querySelector('.view.tokentable');
+            tourR._introItems[7].element = doe.querySelector('.tree');
+            tourR._introItems[7].position = "bottom";
+          }
+      
+        if(this._currentStep == 8){
+          doe.querySelector(".tree").click();
+          document.querySelectorAll(".button-group-list")[0].querySelectorAll('li')[1].click();
+        }
+      });       
+
       return tourR;
     },  
+    /* 
+     * The total number of steps and the text of the tooltips are needed for jasmine testing.
+     */
+    testPrerequ: function(steps, tour){
+      //TODO see also: introJS.totalSteps() merge requested: //github.com/usablica/intro.js/pull/268/files
+      let StepsT = steps;
+      let gtour = tour;      
+      gtour.stepCount = StepsT.length;
+
+      //Array of intro content needed for efficient testing
+      gtour.testIntros = [];
+
+      for(let i = 0; i< StepsT.length; i++){
+      gtour.testIntros.push(StepsT[i].intro);
+      }
+    },
 
   }
 });