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";