Style query creator

Change-Id: I07a6b17927869c7e802e4a893807669bb328924a
diff --git a/dev/demo/query-creator.html b/dev/demo/query-creator.html
index c28c16c..b904441 100644
--- a/dev/demo/query-creator.html
+++ b/dev/demo/query-creator.html
@@ -3,55 +3,49 @@
   <head>
     <title>Query creator demo</title>
     <meta charset="utf-8" />
+    <script data-main="query-creator.js" src="../js/lib/require.js" async="async"></script>
+    <link type="text/css" rel="stylesheet" href="../css/kalamar.css" />
+
     <style type="text/css" rel="stylesheet">
-      * {
-      outline: none;
-      }
-      td, tbody th, thead th:not(:nth-child(1)):not(:nth-child(2)) {
-        cursor: pointer;
-      }
-      td.chosen, th.chosen {
-        background-color: red;
-      }
-      input {
-        display: block;
-        width: 80%;
+      body {
+        background-color: #f6a800;
       }
     </style>
   </head>
   <body>
     <div class="matchinfo">
-      <table>
-        <thead>
-          <tr>
-            <th>Foundry</th>
-            <th>Layer</th>
-            <th>Der</th>
-            <th>älteste</th>
-            <th>lebende</th>
-            <th>Baum</th>
-          </tr>
-        </thead>
-        <tbody>
-          <tr tabindex="0">
-            <th>corenlp</th>
-            <th>p</th>
-            <td>ART</td>
-            <td>ADJA</td>
-            <td>ADJA</td>
-            <td>NN</td>
-          </tr>
-          <tr tabindex="0">
-            <th>opennlp</th>
-            <th>p</th>
-            <td>ART</td>
-            <td>ADJA</td>
-            <td>ADJA</td>
-            <td>NN</td>
-          </tr>
-        </tbody>
-      </table>
+      <div class="matchtable">
+        <table>
+          <thead>
+            <tr>
+              <th>Foundry</th>
+              <th>Layer</th>
+              <th>Der</th>
+              <th>älteste</th>
+              <th>lebende</th>
+              <th>Baum</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr tabindex="0">
+              <th>corenlp</th>
+              <th>p</th>
+              <td>ART</td>
+              <td>ADJA</td>
+              <td>ADJA</td>
+              <td>NN</td>
+            </tr>
+            <tr tabindex="0">
+              <th>opennlp</th>
+              <th>p</th>
+              <td>ART</td>
+              <td>ADJA</td>
+              <td>ADJA</td>
+              <td>NN</td>
+            </tr>
+          </tbody>
+        </table>
+      </div>
     </div>
   </body>
-  <script src="query-creator.js"></script>
 </html>
diff --git a/dev/demo/query-creator.js b/dev/demo/query-creator.js
index ee178ce..244f719 100644
--- a/dev/demo/query-creator.js
+++ b/dev/demo/query-creator.js
@@ -1,187 +1,12 @@
-(function () {
-  "use strict";
+requirejs.config({
+  baseUrl: '../js/src',
+  paths : {
+    'lib': '../lib'
+  }
+});
 
-  var qc = {
-    create : function (matchInfo) {
-      return Object.create(this)._init(matchInfo);
-    },
-
-    // Initialize query creator
-    _init : function (matchInfo) {
-
-      // This may be probably a hint helper
-      this._query = []
-      this._matchInfo = matchInfo;
-
-      // Listen on the match table
-      this._matchInfo.addEventListener(
-        "click", this.clickOnAnno.bind(this), false
-      );
-      return this;
-    },
-
-    clickOnAnno : function (event) {
-
-      // Listen for clicks on table cells
-      if (event.target !== event.currentTarget) {
-
-        // Get target event
-        var target = event.target;
-
-        if (target.tagName == 'TD') {
-
-          // Check foundry and layer
-          var head    = target.parentNode.getElementsByTagName('th');
-          var foundry = head[0].innerText;
-          var layer   = head[1].innerText;
-
-          // Check index position:
-          var i = -2;
-          var sib = target;
-          while((sib = sib.previousSibling) != null) {
-            if (sib.nodeType === 1)
-              i++;
-          };
-
-          this.toggleInToken(target, i, foundry + '/' + layer + '=' + target.innerText);
-        }
-
-        // Get orth values
-        else if (target.tagName == 'TH') {
-
-          // The head is in the top row
-          if (target.parentNode.parentNode.tagName == 'THEAD') {
-
-            var i = -2;
-            var sib = target;
-            while ((sib = sib.previousSibling) != null) {
-              if (sib.nodeType === 1)
-                i++;
-            };
-
-            // Target is an orth
-            if (i >= 0) {
-              this.toggleInToken(target, i, 'orth=' + target.innerText);
-            }            
-          }
-
-          // The head refers to the complete row
-          else {
-
-            // Check foundry and layer
-            var head    = target.parentNode.getElementsByTagName('th');
-            var foundry = head[0].innerText;
-            var layer   = head[1].innerText;
-            var prefix = foundry + '/' + layer + '=';
-
-            // Iterate over all siblings
-            var i = 0;
-            var sib = target;
-            while ((sib = sib.nextSibling) != null) {
-              if (sib.nodeType !== 1 || sib.tagName === 'TH')
-                continue;
-              this.addToToken(i, prefix + sib.innerText);
-              sib.className = 'chosen';
-              i++;
-            };
-          };
-        };
-      };
-
-      event.stopPropagation();
-    },
-
-    // Add term to token
-    addToToken : function (index, term) {
-
-      var token = this._query[index];
-
-      // Initialize token
-      if (token === undefined) {
-        token = this._query[index] = [];
-      };
-
-      // Push to token array
-      token.push(term);
-
-      // Make terms unique
-      this._query[index] = token.filter(
-        function (e, i, arr) {
-          return arr.lastIndexOf(e) === i;
-        }
-      );
-
-      this.show();
-    },
-
-    // Remove term from token
-    removeFromToken : function (index, term) {
-      var token = this._query[index];
-
-      if (token === undefined)
-        return;
-
-      token.splice(token.indexOf(term), 1);
-
-      if (token.length > 0)
-        this._query[index] = token;
-      else
-        this._query[index] = undefined;
-
-      this.show();
-    },
-
-    // Get element representing annotation line
-    element : function () {
-      return this._element;
-    },
-
-    // Show annotation fragment
-    show : function () {
-      var str = '';
-      this._query.forEach(function (token, index) {
-        if (token !== undefined) {
-          str += _createToken(token);
-        };
-      });
-
-      // Element is not yet defined
-      if (this._element === undefined) {
-
-        // Better create a div
-        this._element = document.createElement('input');
-        this._element.setAttribute('type', 'text');
-        this._matchInfo.appendChild(this._element);
-      };
-
-      if (str === '') {
-        this._matchInfo.removeChild(this._element);
-        this._element = undefined;
-      }
-      else {
-        this._element.value = str;
-      };
-    },
-
-    // Add term to token if not yet chosen, otherwise remove
-    toggleInToken : function (node, index, term) {
-      if (node.className == 'chosen') {
-        this.removeFromToken(index, term);
-        node.className = '';
-      }
-      else {
-        this.addToToken(index, term);
-        node.className = 'chosen';
-      };
-    }
-  };
-
-  function _createToken (token) {
-    var str = '[';
-    str += token.sort().join(" & ");
-    return str + ']';
-  };
-
-  qc.create(document.getElementsByClassName('matchinfo')[0]);
-
-})();
+define(['match/querycreator', 'lib/domReady'], function (qc, domReady) {
+  domReady(function () {
+    qc.create(document.getElementsByClassName('matchtable')[0]);
+  });
+});
diff --git a/dev/js/src/loc/de.js b/dev/js/src/loc/de.js
index 0b57409..4f280ba 100644
--- a/dev/js/src/loc/de.js
+++ b/dev/js/src/loc/de.js
@@ -32,4 +32,6 @@
   loc.TOGGLE_ALIGN = 'tausche Textausrichtung';
   loc.SHOW_KQ      = 'zeige KoralQuery';
   loc.SHOW_META    = 'zeige Metadaten';
+
+  loc.NEW_QUERY = 'Neue Anfrage';
 });
diff --git a/dev/js/src/match/querycreator.js b/dev/js/src/match/querycreator.js
new file mode 100644
index 0000000..6786191
--- /dev/null
+++ b/dev/js/src/match/querycreator.js
@@ -0,0 +1,222 @@
+/**
+ * QueryCreator for Kalamar.
+ *
+ * @author Nils Diewald
+ */
+define(['util'], function () {
+  "use strict";
+
+  var loc = KorAP.Locale;
+  loc.NEW_QUERY = loc.NEW_QUERY || 'New Query';
+
+  return {
+    create : function (matchInfo) {
+      return Object.create(this)._init(matchInfo);
+    },
+
+    // Initialize query creator
+    _init : function (matchInfo) {
+
+      // This may be probably a hint helper
+      this._query = []
+      this._matchInfo = matchInfo;
+
+      // Listen on the match table
+      this._matchInfo.addEventListener(
+        "click", this.clickOnAnno.bind(this), false
+      );
+
+      // Initialize element
+      this._element = document.createElement('p');
+      this._element.className = 'queryfragment';
+
+      // Prepend info text
+      this._element.appendChild(document.createElement('span'))
+        .appendChild(document.createTextNode(loc.NEW_QUERY + ':'));
+
+      // Append query fragment part
+      this._queryFragment = this._element.appendChild(
+        document.createElement('span')
+      );
+
+      this._shown = false;
+      return this;
+    },
+
+    clickOnAnno : function (event) {
+
+      // Listen for clicks on table cells
+      if (event.target !== event.currentTarget) {
+
+        // Get target event
+        var target = event.target;
+
+        if (target.tagName == 'TD') {
+
+          // Check foundry and layer
+          var head    = target.parentNode.getElementsByTagName('th');
+          var foundry = head[0].innerText;
+          var layer   = head[1].innerText;
+
+          // Check index position:
+          var i = -2;
+          var sib = target;
+          while((sib = sib.previousSibling) != null) {
+            if (sib.nodeType === 1)
+              i++;
+          };
+
+          this.toggleInToken(target, i, foundry + '/' + layer + '=' + target.innerText);
+        }
+
+        // Get orth values
+        else if (target.tagName == 'TH') {
+
+          // The head is in the top row
+          if (target.parentNode.parentNode.tagName == 'THEAD') {
+
+            var i = -2;
+            var sib = target;
+            while ((sib = sib.previousSibling) != null) {
+              if (sib.nodeType === 1)
+                i++;
+            };
+
+            // Target is an orth
+            if (i >= 0) {
+              this.toggleInToken(target, i, 'orth=' + target.innerText);
+            }            
+          }
+
+          // The head refers to the complete row
+          else {
+
+            // Check foundry and layer
+            var head    = target.parentNode.getElementsByTagName('th');
+            var foundry = head[0].innerText;
+            var layer   = head[1].innerText;
+            var prefix = foundry + '/' + layer + '=';
+
+            // Iterate over all siblings
+            var i = 0;
+            var sib = target;
+            while ((sib = sib.nextSibling) != null) {
+              if (sib.nodeType !== 1 || sib.tagName === 'TH')
+                continue;
+              this.addToToken(i, prefix + sib.innerText);
+              sib.className = 'chosen';
+              i++;
+            };
+          };
+        };
+      };
+
+      event.stopPropagation();
+    },
+
+    // Add term to token
+    addToToken : function (index, term) {
+
+      var token = this._query[index];
+
+      // Initialize token
+      if (token === undefined) {
+        token = this._query[index] = [];
+      };
+
+      // Push to token array
+      token.push(term);
+
+      // Make terms unique
+      this._query[index] = token.filter(
+        function (e, i, arr) {
+          return arr.lastIndexOf(e) === i;
+        }
+      );
+
+      this.show();
+    },
+
+    // Remove term from token
+    removeFromToken : function (index, term) {
+      var token = this._query[index];
+
+      if (token === undefined)
+        return;
+
+      token.splice(token.indexOf(term), 1);
+
+      if (token.length > 0)
+        this._query[index] = token;
+      else
+        this._query[index] = undefined;
+
+      this.show();
+    },
+
+    // Get element representing annotation line
+    element : function () {
+      return this._element;
+    },
+
+    // Show annotation fragment
+    show : function () {
+
+      var str = this.toString();
+
+      // Fragment is empty
+      if (str === '') {
+
+        // Hide element
+        if (this._shown === true) {
+          this._matchInfo.removeChild(this._element);
+          this._shown = false;
+        }
+      }
+
+      // Fragment is defined
+      else {
+
+        if (this._shown === false) {
+          this._matchInfo.appendChild(this._element);
+          this._shown = true;
+        };
+
+        // set value
+        this._queryFragment.innerText = str;
+      };
+    },
+
+    // Add term to token if not yet chosen, otherwise remove
+    toggleInToken : function (node, index, term) {
+      if (node.className == 'chosen') {
+        this.removeFromToken(index, term);
+        node.className = '';
+      }
+      else {
+        this.addToToken(index, term);
+        node.className = 'chosen';
+      };
+    },
+
+
+    // Stringify annotation
+    toString : function () {
+      var str = '';
+      this._query.forEach(function (token) {
+        if (token !== undefined) {
+          str += '[' + token.sort().join(" & ") + ']';
+        };
+      });
+      return str;
+    },
+
+    toQueryBar : function () {
+      // 1. Activate Poliquarp-QL
+      // 2. Empty query helper
+      // 3. Reset annotation helper
+      // 4. Insert to query bar
+      // 5. scroll to top
+    }
+  };  
+});
diff --git a/dev/scss/main/matchinfo.scss b/dev/scss/main/matchinfo.scss
index f712ae0..ae73031 100644
--- a/dev/scss/main/matchinfo.scss
+++ b/dev/scss/main/matchinfo.scss
@@ -78,6 +78,40 @@
   overflow-y: visible;
   width: auto;
 
+  p.queryfragment {
+    position:relative;
+    @include choose-item;
+    border : {
+      width: $border-size;
+      style: solid;
+      radius: $standard-border-radius;
+    }
+    padding: 2pt 4pt !important;
+    &:hover {
+      cursor:pointer;
+      @include choose-hover;
+    }
+
+    // This is the description
+    > span:first-of-type {
+      font-weight: bold;
+      padding-right: 4pt;
+    }
+
+    // Query fragment
+    > span:nth-of-type(2) {
+      padding-right: 1.2em;
+    }
+
+    &::after {
+	    font-family: 'FontAwesome';
+	    content: $fa-to-query;
+      position: absolute;
+      right: 4pt;
+      top: 4pt;
+    }
+  }
+
   table {
     display: table;
     border-collapse: separate;
@@ -86,16 +120,34 @@
   th {
     color: $nearly-white;
   }
+
+  // Use matchinfo cells for query creation
+  td,
+  tbody th,
+  thead th:not(:nth-child(1)):not(:nth-child(2)) {
+    cursor: pointer;
+  }
+  tr {
+    outline: none;
+    > td.chosen,
+    > th.chosen {
+      background-color: $light-green !important;
+      color: $nearly-white;
+      // transition: color 0.1s, background-color 0.15s ease-out;
+    }
+  }
+
   thead {
     tr th {
       background-color: $darker-orange;
       border-top-width: 0px !important;
       text-align: center;
       &:nth-of-type(1), &:nth-of-type(2) {
-	text-align: left;
+	                        text-align: left;
       }
     }
   }
+  
   tbody {
     > tr:nth-of-type(1) > th {
       border-top-color: transparent;
@@ -103,13 +155,14 @@
     /**
      * Click on a row and it's highlighted.
      */
-    > tr:focus {
-      outline: none;
-      /*
+          /*
 	outline:  (2 * $border-size) solid $light-green;
 	-moz-outline-radius: $border-size;
 	outline-radius: $border-size;
 	*/
+    /*
+    > tr:focus {
+      outline: none;
       background-color: $light-green;
       border-color: $light-green;
       td {
@@ -118,6 +171,7 @@
         border-color: $light-green;
       }
     }
+   */
   }
   tr {
     /**
diff --git a/dev/scss/util.scss b/dev/scss/util.scss
index a60a37a..4050ed5 100644
--- a/dev/scss/util.scss
+++ b/dev/scss/util.scss
@@ -245,4 +245,5 @@
 $fa-check:       "\f096";
 $fa-code:        "\f121";
 $fa-marked:      "\f005";
-$fa-metadata:    "\f067";
\ No newline at end of file
+$fa-metadata:    "\f067";
+$fa-to-query:    "\f102";