Added hint and vc to collected kalamar assets
diff --git a/public/Gruntfile.js b/public/Gruntfile.js
index 4183d33..059bb37 100644
--- a/public/Gruntfile.js
+++ b/public/Gruntfile.js
@@ -84,7 +84,7 @@
},
*/
css: {
- files: ['scss/{util,fonts,base,header,searchbar,matchinfo,resultinfo,kwic,menu,pagination,logos,alertify,kalamar}.scss'],
+ files: ['scss/{util,fonts,base,header,searchbar,matchinfo,resultinfo,kwic,menu,hint,pagination,logos,alertify,vc,kalamar}.scss'],
tasks: ['sass'],
options: {
spawn: false
diff --git a/public/js/demo/all.html b/public/js/demo/all.html
index aba76c4..26337fa 100644
--- a/public/js/demo/all.html
+++ b/public/js/demo/all.html
@@ -1,16 +1,15 @@
-<!DOCTYPE html>
+ <!DOCTYPE html>
<html>
<head>
<title>CSS demo</title>
<meta charset="utf-8" />
<script src="../lib/dagre/dagre.min.js"></script>
<script src="../src/util.js"></script>
+ <script src="../src/hint.js"></script>
<script src="../src/match.js"></script>
<script src="../src/menu.js"></script>
- <script src="../src/matchInfo.js"></script>
-
+ <script src="../src/vc.js"></script>
<script src="./all.js"></script>
-
<link type="text/css" rel="stylesheet" href="../../css/build/kalamar.css" />
</head>
<body>
@@ -29,6 +28,8 @@
<i class="fa fa-arrow-circle-down show-hint" onclick="hint.popUp()"></i>
-->
</div>
+ <div id="vc"></div>
+ in Wikipedia
with <span class="select">
<!-- Change this to js-menu -->
<select name="ql" id="ql-field">
diff --git a/public/js/demo/all.js b/public/js/demo/all.js
index b0871be..dc1e051 100644
--- a/public/js/demo/all.js
+++ b/public/js/demo/all.js
@@ -95,33 +95,6 @@
"</span>" +
"<span class=\"context-right\"></span>";
-/*
-var available =[
- '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'
-];
-*/
-/*
-var match = {
- 'corpusID' : 'WPD',
- 'docID' : 'UUU',
- 'textID' : '01912',
- 'matchID' : 'p121-122'
-};
-*/
-
var menuContent = [
['cnx/c', 'cnx', 'c'],
['mate/c', 'mate', 'c'],
@@ -130,6 +103,280 @@
['tt/c', 'tt', 'c']
];
+var namedEntities = [
+ ["I-LOC", "I-LOC ", "Location"],
+ ["I-MISC", "I-MISC ", "Miscellaneous"],
+ ["I-ORG", "I-ORG ", "Organization"],
+ ["I-PER", "I-PER ", "Person"]
+];
+
+// http://www.ids-mannheim.de/cosmas2/projekt/referenz/stts/morph.html
+// http://nachhalt.sfb632.uni-potsdam.de/owl-docu/stts.html
+var sttsArray = [
+ // "$.", "$(", "$,"
+ ["ADJA","ADJA ", "Attributive Adjective"],
+ ["ADJD","ADJD ", "Predicative Adjective"],
+ ["ADV","ADV ", "Adverb"],
+ ["APPO","APPO ", "Postposition"],
+ ["APPR","APPR ", "Preposition"],
+ ["APPRART","APPRART ", "Preposition with Determiner"],
+ ["APZR","APZR ","Right Circumposition"],
+ ["ART","ART ", "Determiner"],
+ ["CARD","CARD ", "Cardinal Number"],
+ ["FM","FM ", "Foreign Material"],
+ ["ITJ","ITJ ", "Interjection"],
+ ["KOKOM","KOKOM ", "Comparison Particle"],
+ ["KON","KON ", "Coordinating Conjuncion"],
+ ["KOUI","KOUI ", "Subordinating Conjunction with 'zu'"],
+ ["KOUS","KOUS ", "Subordinating Conjunction with Sentence"],
+ ["NE","NE ", "Named Entity"],
+ ["NN","NN ", "Normal Nomina"],
+ ["PAV", "PAV ", "Pronominal Adverb"],
+ ["PDAT","PDAT ","Attributive Demonstrative Pronoun"],
+ ["PDS","PDS ", "Substitutive Demonstrative Pronoun"],
+ ["PIAT","PIAT ", "Attributive Indefinite Pronoun without Determiner"],
+ ["PIDAT","PIDAT ", "Attributive Indefinite Pronoun with Determiner"],
+ ["PIS","PIS ", "Substitutive Indefinite Pronoun"],
+ ["PPER","PPER ", "Personal Pronoun"],
+ ["PPOSAT","PPOSAT ", "Attributive Possessive Pronoun"],
+ ["PPOSS","PPOSS ", "Substitutive Possessive Pronoun"],
+ ["PRELAT","PRELAT ", "Attributive Relative Pronoun"],
+ ["PRELS","PRELS ", "Substitutive Relative Pronoun"],
+ ["PRF","PRF ", "Reflexive Pronoun"],
+ ["PROAV","PROAV ", "Pronominal Adverb"],
+ ["PTKA","PTKA ","Particle with Adjective"],
+ ["PTKANT","PTKANT ", "Answering Particle"],
+ ["PTKNEG","PTKNEG ", "Negation Particle"],
+ ["PTKVZ","PTKVZ ", "Separated Verbal Particle"],
+ ["PTKZU","PTKZU ", "'zu' Particle"],
+ ["PWAT","PWAT ", "Attributive Interrogative Pronoun"],
+ ["PWAV","PWAV ", "Adverbial Interrogative Pronoun"],
+ ["PWS","PWS ", "Substitutive Interrogative Pronoun"],
+ ["TRUNC","TRUNC ","Truncated"],
+ ["VAFIN","VAFIN ", "Auxiliary Finite Verb"],
+ ["VAINF","VAINF ", "Auxiliary Infinite Verb"],
+ ["VAIMP","VAIMP ", "Auxiliary Finite Imperative Verb"],
+ ["VAPP","VAPP ", "Auxiliary Perfect Participle"],
+ ["VMFIN","VMFIN ", "Modal Finite Verb"],
+ ["VMINF","VMINF ", "Modal Infinite Verb"],
+ ["VMPP","VMPP ", "Modal Perfect Participle"],
+ ["VVFIN","VVFIN ","Finite Verb"],
+ ["VVIMP","VVIMP ", "Finite Imperative Verb"],
+ ["VVINF","VVINF ", "Infinite Verb"],
+ ["VVIZU","VVIZU ", "Infinite Verb with 'zu'"],
+ ["VVPP","VVPP ", "Perfect Participle"],
+ ["XY", "XY ", "Non-Word"]
+];
+
+var mateSttsArray = sttsArray.slice(0);
+mateSttsArray.push(
+ ["<root-POS>","<root-POS>","Root Part of Speech"]
+);
+
+
+var vcExample = {
+ "@type":"koral:docGroup",
+ "operation":"operation:or",
+ "operands":[
+ {
+ "@type":"koral:docGroup",
+ "operation":"operation:and",
+ "operands":[
+ {
+ "@type":"koral:doc",
+ "key":"Titel",
+ "value":"Der Birnbaum",
+ "match":"match:eq"
+ },
+ {
+ "@type":"koral:doc",
+ "key":"Veröffentlichungsort",
+ "value":"Mannheim",
+ "match":"match:eq"
+ },
+ {
+ "@type":"koral:docGroup",
+ "operation":"operation:or",
+ "operands":[
+ {
+ "@type":"koral:doc",
+ "key":"Untertitel",
+ "value":"Aufzucht und Pflege",
+ "match":"match:eq"
+ },
+ {
+ "@type":"koral:doc",
+ "key":"Untertitel",
+ "value":"Gedichte",
+ "match":"match:eq",
+ "rewrites" : [
+ {
+ "@type": "koral:rewrite",
+ "src" : "policy",
+ "operation" : "operation:injection",
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "@type":"koral:doc",
+ "key":"Veröffentlichungsdatum",
+ "type":"type:date",
+ "value":"2015-03-05",
+ "match":"match:geq"
+ }
+ ]
+};
+
+
+KorAP.hintArray = {
+ "-" : [
+ ["Connexor", "cnx/", "Constituency, Lemma, Morphology, Part-of-Speech, Syntax"],
+ ["CoreNLP", "corenlp/", "Named Entities"],
+ ["Mate", "mate/", "Lemma, Morphology, Part-of-Speech"],
+ ["OpenNLP", "opennlp/", "Part-of-Speech"],
+ ["TreeTagger", "tt/", "Lemma, Part-of-Speech"],
+ ["Xerox Parser", "xip/", "Constituency, Lemma, Part-of-Speech"]
+ ],
+ "corenlp/" : [
+ ["Named Entity", "ne=" , "Combined"],
+ ["Named Entity", "ne_dewac_175m_600=" , "ne_dewac_175m_600"],
+ ["Named Entity", "ne_hgc_175m_600=", "ne_hgc_175m_600"]
+ ],
+ "corenlp/ne=" : namedEntities,
+ "corenlp/ne_dewac_175m_600=" : namedEntities,
+ "corenlp/ne_hgc_175m_600=" : namedEntities,
+ "cnx/" : [
+ ["Constituency", "c="],
+ ["Lemma", "l="],
+ ["Morphology", "m="],
+ ["Part-of-Speech", "p="],
+ ["Syntax", "syn="]
+ ],
+ "cnx/c=" : [
+ ["np", "np ", "Nominal Phrase"]
+ ],
+ // http://www.ids-mannheim.de/cosmas2/projekt/referenz/connexor/morph.html
+ "cnx/m=" : [
+ ["Abbr","Abbr ", "Nouns: Abbreviation"],
+ ["CMP","CMP ", "Adjective: Comparative"],
+ ["IMP", "IMP ", "Mood: Imperative"],
+ ["IND", "IND ", "Mood: Indicative"],
+ ["INF", "INF ", "Infinitive"],
+ ["ORD","ORD ", "Numeral: Ordinal"],
+ ["PAST", "PAST ", "Tense: past"],
+ ["PCP", "PCP ", "Participle"],
+ ["PERF", "PERF ", "Perfective Participle"],
+ ["PL","PL ", "Nouns: Plural"],
+ ["PRES", "PRES ", "Tense: present"],
+ ["PROG", "PROG ", "Progressive Participle"],
+ ["Prop","Prop ", "Nouns: Proper Noun"],
+ ["SUB", "SUB ", "Mood: Subjunctive"],
+ ["SUP","SUP ", "Adjective: Superlative"]
+ ],
+ // http://www.ids-mannheim.de/cosmas2/projekt/referenz/connexor/morph.html
+ "cnx/p=" : [
+ ["A", "A ", "Adjective"],
+ ["ADV", "ADV ", "Adverb"],
+ ["CC", "CC ", "Coordination Marker"],
+ ["CS", "CS ", "Clause Marker"],
+ ["DET", "DET ", "Determiner"],
+ ["INTERJ", "INTERJ ", "Interjection"],
+ ["N", "N ", "Noun"],
+ ["NUM", "NUM ", "Numeral"],
+ ["PREP", "PREP ", "Preposition"],
+ ["PRON", "PRON ", "Pro-Nominal"],
+ ["V", "V ", "Verb"]
+ ],
+ // http://www.ids-mannheim.de/cosmas2/projekt/referenz/connexor/syntax.html
+ "cnx/syn=" : [
+ ["@ADVL", "@ADVL ", "Adverbial Head"],
+ ["@AUX", "@AUX ", "Auxiliary Verb"],
+ ["@CC", "@CC ", "Coordination"]
+ ["@MAIN", "@MAIN ", "Main Verb"],
+ ["@NH", "@NH ", "Nominal Head"],
+ ["@POSTMOD", "@POSTMOD ", "Postmodifier"],
+ ["@PREMARK", "@PREMARK ", "Preposed Marker"],
+ ["@PREMOD", "@POSTMOD ", "Premodifier"]
+ ],
+ "opennlp/" : [
+ ["Part-of-Speech", "p="]
+ ],
+ "opennlp/p=" : sttsArray,
+ "xip/" : [
+ ["Constituency", "c="],
+ // Inactive: ["Dependency", "d="],
+ ["Lemma", "l="],
+ ["Part-of-Speech", "p="],
+ ],
+ // "xip/c=" : [],
+ // Inactive: "xip/d=" : [],
+ // "xip/p=" : [],
+ "tt/" : [
+ ["Lemma", "l="],
+ ["Part-of-Speech", "p="]
+ ],
+ "tt/p=" : sttsArray,
+ "mate/" : [
+ // Inactive: "d" : ["d=", "Dependency"],
+ ["Lemma", "l="],
+ ["Morphology", "m="],
+ ["Part-of-Speech", "p="]
+ ],
+ // Inactive: mate/d=
+ "mate/p=" : mateSttsArray,
+ "mate/m=" : [
+ ["Case", "case:"],
+ ["Degree", "degree:"],
+ ["Gender", "gender:"],
+ ["Mood", "mood:"],
+ ["Number", "number:"],
+ ["Person", "person:"],
+ ["Tense","tense:"],
+ ["No type", "<no-type> "]
+ ],
+ "mate/m=case:" : [
+ ["acc", "acc ", "Accusative"],
+ ["dat","dat ", "Dative"],
+ ["gen", "gen ","Genitive"],
+ ["nom","nom ", "Nominative"],
+ ["*","* ", "Undefined"]
+ ],
+ "mate/m=degree:" : [
+ ["comp","comp ", "Comparative"],
+ ["pos","pos ", "Positive"],
+ ["sup","sup ", "Superative"]
+ ],
+ "mate/m=gender:" : [
+ ["fem", "fem ", "Feminium"],
+ ["masc", "masc ", "Masculinum"],
+ ["neut","neut ", "Neuter"],
+ ["*","* ","Undefined"]
+ ],
+ "mate/m=mood:" : [
+ ["imp","imp ", "Imperative"],
+ ["ind","ind ", "Indicative"],
+ ["subj","subj ", "Subjunctive"]
+ ],
+ "mate/m=number:" : [
+ ["pl","pl ","Plural"],
+ ["sg","sg ","Singular"],
+ ["*","* ","Undefined"]
+ ],
+ "mate/m=person:" : [
+ ["1","1 ", "First Person"],
+ ["2","2 ", "Second Person"],
+ ["3","3 ", "Third Person"]
+ ],
+ "mate/m=tense:" : [
+ ["past","past ", "Past"],
+ ["pres","pres ", "Present"]
+ ]
+};
+
// Parse and show the table
// Override getMatchInfo API call
KorAP.API.getMatchInfo = function(match, callObj) {
@@ -141,6 +388,7 @@
}
};
+
/**
* Do some things at the beginning.
*/
@@ -154,15 +402,14 @@
menuContent
);
+ var vc = KorAP.VirtualCollection.render(vcExample);
+ document.getElementById('vc').appendChild(vc.element());
+
+
// Don't hide!!!
menu.hide = function () {};
document.getElementById('menu').appendChild(menu.element());
menu.limit(3);
menu.show();
menu.focus();
- /*
- var e = KorAP.MatchInfo.create(match, available);
- document.getElementById('WPD-WWW.03313-p102-103').children[0].appendChild(e.element());
- e.addTree('cnx', 'c');
- */
};
diff --git a/public/js/demo/hint.html b/public/js/demo/hint.html
new file mode 100644
index 0000000..154bcaf
--- /dev/null
+++ b/public/js/demo/hint.html
@@ -0,0 +1,248 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Hint demo</title>
+ <meta charset="utf-8" />
+ <script src="../src/menu.js"></script>
+ <script src="../src/hint.js"></script>
+ <link type="text/css" rel="stylesheet" href="../../css/build/kalamar.css" />
+ <script>
+// http://www.nlpado.de/~sebastian/software/ner_german.shtml
+// http://www.cnts.ua.ac.be/conll2003/ner/
+var namedEntities = [
+ ["I-LOC", "I-LOC ", "Location"],
+ ["I-MISC", "I-MISC ", "Miscellaneous"],
+ ["I-ORG", "I-ORG ", "Organization"],
+ ["I-PER", "I-PER ", "Person"]
+];
+
+// http://www.ids-mannheim.de/cosmas2/projekt/referenz/stts/morph.html
+// http://nachhalt.sfb632.uni-potsdam.de/owl-docu/stts.html
+var sttsArray = [
+ // "$.", "$(", "$,"
+ ["ADJA","ADJA ", "Attributive Adjective"],
+ ["ADJD","ADJD ", "Predicative Adjective"],
+ ["ADV","ADV ", "Adverb"],
+ ["APPO","APPO ", "Postposition"],
+ ["APPR","APPR ", "Preposition"],
+ ["APPRART","APPRART ", "Preposition with Determiner"],
+ ["APZR","APZR ","Right Circumposition"],
+ ["ART","ART ", "Determiner"],
+ ["CARD","CARD ", "Cardinal Number"],
+ ["FM","FM ", "Foreign Material"],
+ ["ITJ","ITJ ", "Interjection"],
+ ["KOKOM","KOKOM ", "Comparison Particle"],
+ ["KON","KON ", "Coordinating Conjuncion"],
+ ["KOUI","KOUI ", "Subordinating Conjunction with 'zu'"],
+ ["KOUS","KOUS ", "Subordinating Conjunction with Sentence"],
+ ["NE","NE ", "Named Entity"],
+ ["NN","NN ", "Normal Nomina"],
+ ["PAV", "PAV ", "Pronominal Adverb"],
+ ["PDAT","PDAT ","Attributive Demonstrative Pronoun"],
+ ["PDS","PDS ", "Substitutive Demonstrative Pronoun"],
+ ["PIAT","PIAT ", "Attributive Indefinite Pronoun without Determiner"],
+ ["PIDAT","PIDAT ", "Attributive Indefinite Pronoun with Determiner"],
+ ["PIS","PIS ", "Substitutive Indefinite Pronoun"],
+ ["PPER","PPER ", "Personal Pronoun"],
+ ["PPOSAT","PPOSAT ", "Attributive Possessive Pronoun"],
+ ["PPOSS","PPOSS ", "Substitutive Possessive Pronoun"],
+ ["PRELAT","PRELAT ", "Attributive Relative Pronoun"],
+ ["PRELS","PRELS ", "Substitutive Relative Pronoun"],
+ ["PRF","PRF ", "Reflexive Pronoun"],
+ ["PROAV","PROAV ", "Pronominal Adverb"],
+ ["PTKA","PTKA ","Particle with Adjective"],
+ ["PTKANT","PTKANT ", "Answering Particle"],
+ ["PTKNEG","PTKNEG ", "Negation Particle"],
+ ["PTKVZ","PTKVZ ", "Separated Verbal Particle"],
+ ["PTKZU","PTKZU ", "'zu' Particle"],
+ ["PWAT","PWAT ", "Attributive Interrogative Pronoun"],
+ ["PWAV","PWAV ", "Adverbial Interrogative Pronoun"],
+ ["PWS","PWS ", "Substitutive Interrogative Pronoun"],
+ ["TRUNC","TRUNC ","Truncated"],
+ ["VAFIN","VAFIN ", "Auxiliary Finite Verb"],
+ ["VAINF","VAINF ", "Auxiliary Infinite Verb"],
+ ["VAIMP","VAIMP ", "Auxiliary Finite Imperative Verb"],
+ ["VAPP","VAPP ", "Auxiliary Perfect Participle"],
+ ["VMFIN","VMFIN ", "Modal Finite Verb"],
+ ["VMINF","VMINF ", "Modal Infinite Verb"],
+ ["VMPP","VMPP ", "Modal Perfect Participle"],
+ ["VVFIN","VVFIN ","Finite Verb"],
+ ["VVIMP","VVIMP ", "Finite Imperative Verb"],
+ ["VVINF","VVINF ", "Infinite Verb"],
+ ["VVIZU","VVIZU ", "Infinite Verb with 'zu'"],
+ ["VVPP","VVPP ", "Perfect Participle"],
+ ["XY", "XY ", "Non-Word"]
+];
+
+var mateSttsArray = sttsArray.slice(0);
+mateSttsArray.push(
+ ["<root-POS>","<root-POS>","Root Part of Speech"]
+);
+
+
+var hintArray = {
+ "-" : [
+ ["Connexor", "cnx/", "Constituency, Lemma, Morphology, Part-of-Speech, Syntax"],
+ ["CoreNLP", "corenlp/", "Named Entities"],
+ ["Mate", "mate/", "Lemma, Morphology, Part-of-Speech"],
+ ["OpenNLP", "opennlp/", "Part-of-Speech"],
+ ["TreeTagger", "tt/", "Lemma, Part-of-Speech"],
+ ["Xerox Parser", "xip/", "Constituency, Lemma, Part-of-Speech"]
+ ],
+ "corenlp/" : [
+ ["Named Entity", "ne=" , "Combined"],
+ ["Named Entity", "ne_dewac_175m_600=" , "ne_dewac_175m_600"],
+ ["Named Entity", "ne_hgc_175m_600=", "ne_hgc_175m_600"]
+ ],
+ "corenlp/ne=" : namedEntities,
+ "corenlp/ne_dewac_175m_600=" : namedEntities,
+ "corenlp/ne_hgc_175m_600=" : namedEntities,
+ "cnx/" : [
+ ["Constituency", "c="],
+ ["Lemma", "l="],
+ ["Morphology", "m="],
+ ["Part-of-Speech", "p="],
+ ["Syntax", "syn="]
+ ],
+ "cnx/c=" : [
+ ["np", "np ", "Nominal Phrase"]
+ ],
+ // http://www.ids-mannheim.de/cosmas2/projekt/referenz/connexor/morph.html
+ "cnx/m=" : [
+ ["Abbr","Abbr ", "Nouns: Abbreviation"],
+ ["CMP","CMP ", "Adjective: Comparative"],
+ ["IMP", "IMP ", "Mood: Imperative"],
+ ["IND", "IND ", "Mood: Indicative"],
+ ["INF", "INF ", "Infinitive"],
+ ["ORD","ORD ", "Numeral: Ordinal"],
+ ["PAST", "PAST ", "Tense: past"],
+ ["PCP", "PCP ", "Participle"],
+ ["PERF", "PERF ", "Perfective Participle"],
+ ["PL","PL ", "Nouns: Plural"],
+ ["PRES", "PRES ", "Tense: present"],
+ ["PROG", "PROG ", "Progressive Participle"],
+ ["Prop","Prop ", "Nouns: Proper Noun"],
+ ["SUB", "SUB ", "Mood: Subjunctive"],
+ ["SUP","SUP ", "Adjective: Superlative"]
+ ],
+ // http://www.ids-mannheim.de/cosmas2/projekt/referenz/connexor/morph.html
+ "cnx/p=" : [
+ ["A", "A ", "Adjective"],
+ ["ADV", "ADV ", "Adverb"],
+ ["CC", "CC ", "Coordination Marker"],
+ ["CS", "CS ", "Clause Marker"],
+ ["DET", "DET ", "Determiner"],
+ ["INTERJ", "INTERJ ", "Interjection"],
+ ["N", "N ", "Noun"],
+ ["NUM", "NUM ", "Numeral"],
+ ["PREP", "PREP ", "Preposition"],
+ ["PRON", "PRON ", "Pro-Nominal"],
+ ["V", "V ", "Verb"]
+ ],
+ // http://www.ids-mannheim.de/cosmas2/projekt/referenz/connexor/syntax.html
+ "cnx/syn=" : [
+ ["@ADVL", "@ADVL ", "Adverbial Head"],
+ ["@AUX", "@AUX ", "Auxiliary Verb"],
+ ["@CC", "@CC ", "Coordination"]
+ ["@MAIN", "@MAIN ", "Main Verb"],
+ ["@NH", "@NH ", "Nominal Head"],
+ ["@POSTMOD", "@POSTMOD ", "Postmodifier"],
+ ["@PREMARK", "@PREMARK ", "Preposed Marker"],
+ ["@PREMOD", "@POSTMOD ", "Premodifier"]
+ ],
+ "opennlp/" : [
+ ["Part-of-Speech", "p="]
+ ],
+ "opennlp/p=" : sttsArray,
+ "xip/" : [
+ ["Constituency", "c="],
+ // Inactive: ["Dependency", "d="],
+ ["Lemma", "l="],
+ ["Part-of-Speech", "p="],
+ ],
+ // "xip/c=" : [],
+ // Inactive: "xip/d=" : [],
+ // "xip/p=" : [],
+ "tt/" : [
+ ["Lemma", "l="],
+ ["Part-of-Speech", "p="]
+ ],
+ "tt/p=" : sttsArray,
+ "mate/" : [
+ // Inactive: "d" : ["d=", "Dependency"],
+ ["Lemma", "l="],
+ ["Morphology", "m="],
+ ["Part-of-Speech", "p="]
+ ],
+ // Inactive: mate/d=
+ "mate/p=" : mateSttsArray,
+ "mate/m=" : [
+ ["Case", "case:"],
+ ["Degree", "degree:"],
+ ["Gender", "gender:"],
+ ["Mood", "mood:"],
+ ["Number", "number:"],
+ ["Person", "person:"],
+ ["Tense","tense:"],
+ ["No type", "<no-type> "]
+ ],
+ "mate/m=case:" : [
+ ["acc", "acc ", "Accusative"],
+ ["dat","dat ", "Dative"],
+ ["gen", "gen ","Genitive"],
+ ["nom","nom ", "Nominative"],
+ ["*","* ", "Undefined"]
+ ],
+ "mate/m=degree:" : [
+ ["comp","comp ", "Comparative"],
+ ["pos","pos ", "Positive"],
+ ["sup","sup ", "Superative"]
+ ],
+ "mate/m=gender:" : [
+ ["fem", "fem ", "Feminium"],
+ ["masc", "masc ", "Masculinum"],
+ ["neut","neut ", "Neuter"],
+ ["*","* ","Undefined"]
+ ],
+ "mate/m=mood:" : [
+ ["imp","imp ", "Imperative"],
+ ["ind","ind ", "Indicative"],
+ ["subj","subj ", "Subjunctive"]
+ ],
+ "mate/m=number:" : [
+ ["pl","pl ","Plural"],
+ ["sg","sg ","Singular"],
+ ["*","* ","Undefined"]
+ ],
+ "mate/m=person:" : [
+ ["1","1 ", "First Person"],
+ ["2","2 ", "Second Person"],
+ ["3","3 ", "Third Person"]
+ ],
+ "mate/m=tense:" : [
+ ["past","past ", "Past"],
+ ["pres","pres ", "Present"]
+ ]
+};
+
+ </script>
+ </head>
+ <body>
+ <header>
+ <form autocomplete="off" action="/kalamar">
+ <div id="searchbar">
+ <input type="search"
+ placeholder="Find ..."
+ name="q"
+ id="q-field"
+ autofocus="autofocus" />
+ <button type="submit"><span>Go</span></button>
+ </div>
+ </form>
+ </header>
+ <script>
+KorAP.hintArray = hintArray;
+var input = KorAP.Hint.create();
+ </script>
+ </body>
+</html>
diff --git a/public/js/demo/match.html b/public/js/demo/match.html
index 373b0ee..7b51996 100644
--- a/public/js/demo/match.html
+++ b/public/js/demo/match.html
@@ -4,6 +4,7 @@
<title>Match demo</title>
<meta charset="utf-8" />
<script src="../lib/dagre/dagre.min.js"></script>
+ <script src="../src/util.js"></script>
<script src="../src/menu.js"></script>
<script src="../src/match.js"></script>
<link type="text/css"
@@ -31,6 +32,21 @@
</style>
</head>
<body>
+ <div id="search">
+ <ol class="align-left">
+ <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"
+ id="WPD-WWW.03313-p102-103">
+ <div>
+ <div class="snippet startMore endMore"><span class="context-left">In diesem Beispiel ist zu sehen, dass die beiden Variablen a und b lediglich ihre Werte an die Funktion </span><span class="match">test</span><span class="context-right"> übergeben, aber im Gegensatz zu einem Referenzparamter dabei unverändert bleiben.</span></div>
+ </div>
+ <p class="ref"><strong>Wertparameter</strong> by Hubi,Zwobot,4; published on 2005-03-28 as WWW.03313 (WPD)</p>
+ </li>
+ </ol>
+ </div>
<script>
var snippet = "<span title=\"cnx/l:meist\">" +
@@ -130,31 +146,6 @@
"</span>" +
"<span class=\"context-right\"></span>";
-var available =[
- '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'
-];
-
-var match = {
- 'corpusID' : 'WPD',
- 'docID' : 'UUU',
- 'textID' : '01912',
- 'pos' : 'p121-122',
- 'available' : available
-};
-
// Parse and show the table
// Override getMatchInfo API call
KorAP.API.getMatchInfo = function(match, callObj) {
@@ -166,31 +157,7 @@
}
};
-var e = KorAP.Match.create(match).open();
-
-document.getElementsByTagName('body')[0].appendChild(e.element());
-
-e.addTree('cnx', 'c');
-
-
-
-/*
-var t = KorAP.MatchInfo.create(match, available).getTable();
-document.getElementsByClassName('matchtable')[0]
-.appendChild(t.element());
-
-// parse and show the tree
-KorAP.API.getMatchInfo = function() {
- return { "snippet": treeSnippet };
-};
-
-var tree = KorAP.MatchInfo.create(match, available).getTree();
-document.getElementsByClassName('matchtree')[0]
-.getElementsByTagName('div')[0]
-.appendChild(tree.element());
-
-tree.center();
-*/
+KorAP.init();
</script>
<!--
diff --git a/public/js/demo/vc.html b/public/js/demo/vc.html
index 0a7efa9..ae6aef1 100644
--- a/public/js/demo/vc.html
+++ b/public/js/demo/vc.html
@@ -5,9 +5,17 @@
<meta charset="utf-8" />
<script src="../src/menu.js"></script>
<script src="../src/vc.js"></script>
- <link href="../../css/vc.css" rel="stylesheet" type="text/css"></link>
- <link href="../../css/menu.css" rel="stylesheet" type="text/css"></link>
+ <link href="../../css/build/kalamar.css" rel="stylesheet" type="text/css"></link>
<style type="text/css" rel="stylesheet">
+
+body {
+ background-color: #7ba400;
+ color: white;
+ font-family: tahoma, verdana, arial;
+ font-size: 10pt;
+ margin: 20px;
+}
+
.info {
background-color:white;
color: black;
diff --git a/public/js/runner/hint.html b/public/js/runner/hint.html
index 36538fd..81f0422 100644
--- a/public/js/runner/hint.html
+++ b/public/js/runner/hint.html
@@ -8,6 +8,7 @@
<script src="../lib/jasmine-2.1.1/jasmine.js"></script>
<script src="../lib/jasmine-2.1.1/jasmine-html.js"></script>
<script src="../lib/jasmine-2.1.1/boot.js"></script>
+ <script src="../src/menu.js"></script>
<script src="../src/hint.js"></script>
<script src="../spec/hintSpec.js"></script>
</head>
diff --git a/public/js/spec/hintSpec.js b/public/js/spec/hintSpec.js
index a7232d4..66c831f 100644
--- a/public/js/spec/hintSpec.js
+++ b/public/js/spec/hintSpec.js
@@ -24,7 +24,146 @@
};
-describe('KorAP.MenuItem', function () {
+describe('KorAP.InputField', function () {
+ var input;
+
+ beforeEach(function () {
+ input = document.createElement("input");
+ input.setAttribute("type", "text");
+ input.setAttribute("value", "abcdefghijklmno");
+ input.style.position = 'absolute';
+ input.style.top = "20px";
+ input.style.left = "30px";
+ input.focus();
+ input.selectionStart = 5;
+ });
+
+ afterAll(function () {
+ try {
+ // document.getElementsByTagName("body")[0].removeChild(input);
+ document.getElementsByTagName("body")[0].removeChild(
+ document.getElementById("searchMirror")
+ );
+ }
+ catch (e) {};
+ });
+
+ it('should be initializable', function () {
+ // Supports: context, searchField
+ var inputField = KorAP.InputField.create(input);
+ expect(inputField._element).not.toBe(undefined);
+ });
+
+ it('should have text', function () {
+ expect(input.value).toEqual('abcdefghijklmno');
+ var inputField = KorAP.InputField.create(input);
+
+ expect(inputField.value()).toEqual("abcdefghijklmno");
+
+ expect(inputField.element().selectionStart).toEqual(5);
+ expect(inputField.split()[0]).toEqual("abcde");
+ expect(inputField.split()[1]).toEqual("fghijklmno");
+
+ inputField.insert("xyz");
+ expect(inputField.value()).toEqual('abcdexyzfghijklmno');
+ expect(inputField.split()[0]).toEqual("abcdexyz");
+ expect(inputField.split()[1]).toEqual("fghijklmno");
+ });
+
+ it('should be correctly positioned', function () {
+ expect(input.value).toEqual('abcdefghijklmno');
+ var inputField = KorAP.InputField.create(input);
+ document.getElementsByTagName("body")[0].appendChild(input);
+ inputField.reposition();
+ expect(inputField.mirror().style.left).toEqual("30px");
+ expect(inputField.mirror().style.top.match(/^(\d+)px$/)[1]).toBeGreaterThan(20);
+ });
+
+ it('should have a correct context', function () {
+ expect(input.value).toEqual('abcdefghijklmno');
+ var inputField = KorAP.InputField.create(input);
+
+ expect(inputField.value()).toEqual("abcdefghijklmno");
+
+ expect(inputField.element().selectionStart).toEqual(5);
+ expect(inputField.split()[0]).toEqual("abcde");
+ expect(inputField.context()).toEqual("abcde");
+ });
+
+/*
+ it('should be correctly triggerable', function () {
+ // https://developer.mozilla.org/samples/domref/dispatchEvent.html
+ var hint = KorAP.Hint.create({ "inputField" : input });
+ emitKeyboardEvent(hint.inputField.element, "keypress", 20);
+ });
+*/
+});
+
+
+describe('KorAP.ContextAnalyzer', function () {
+ it('should be initializable', function () {
+ var analyzer = KorAP.ContextAnalyzer.create(")");
+ expect(analyzer).toBe(undefined);
+
+ analyzer = KorAP.ContextAnalyzer.create(".+?");
+ expect(analyzer).not.toBe(undefined);
+
+ });
+
+ it('should check correctly', function () {
+ analyzer = KorAP.ContextAnalyzer.create(KorAP.context);
+ expect(analyzer.test("cnx/]cnx/c=")).toEqual("cnx/c=");
+ expect(analyzer.test("cnx/c=")).toEqual("cnx/c=");
+ expect(analyzer.test("cnx/c=np mate/m=mood:")).toEqual("mate/m=mood:");
+ expect(analyzer.test("impcnx/")).toEqual("impcnx/");
+ expect(analyzer.test("cnx/c=npcnx/")).toEqual("npcnx/");
+ expect(analyzer.test("mate/m=degree:pos corenlp/ne_dewac_175m_600="))
+ .toEqual("corenlp/ne_dewac_175m_600=");
+ });
+});
+
+
+describe('KorAP.Hint', function () {
+ KorAP.hintArray = {
+ "corenlp/" : [
+ ["Named Entity", "ne=" , "Combined"],
+ ["Named Entity", "ne_dewac_175m_600=" , "ne_dewac_175m_600"],
+ ["Named Entity", "ne_hgc_175m_600=", "ne_hgc_175m_600"]
+ ]
+ };
+
+ beforeEach(function () {
+ input = document.createElement("input");
+ input.setAttribute("type", "text");
+ input.setAttribute("value", "abcdefghijklmno");
+ input.style.position = 'absolute';
+ input.style.top = "20px";
+ input.style.left = "30px";
+ input.focus();
+ input.selectionStart = 5;
+ });
+
+ it('should be initializable', function () {
+ // Supports: context, searchField
+ var hint = KorAP.Hint.create({
+ inputField : input
+ });
+
+ expect(hint).toBeTruthy();
+ });
+});
+
+
+
+
+
+
+
+
+
+
+
+xdescribe('KorAP.MenuItem', function () {
it('should be initializable', function () {
expect(
@@ -237,7 +376,7 @@
});
-describe('KorAP.Menu', function () {
+describe('KorAP.HintMenu', function () {
var list = [
["Constituency", "c=", "Example 1"],
@@ -250,12 +389,12 @@
it('should be initializable', function () {
- var menu = KorAP.Menu.create("cnx/", list);
- expect(menu.context).toEqual('cnx/');
- expect(menu.element.nodeName).toEqual('UL');
- expect(menu.element.style.opacity).toEqual("0");
+ var menu = KorAP.HintMenu.create("cnx/", list);
+ expect(menu.context()).toEqual('cnx/');
+ expect(menu.element().nodeName).toEqual('UL');
+ expect(menu.element().style.opacity).toEqual("0");
- KorAP.limit = 8;
+ menu.limit(8);
// view
menu.show();
@@ -269,517 +408,7 @@
expect(menu.item(2).noMore()).toBe(false);
// Last element in list
- expect(menu.item(menu.length - 1).active()).toBe(false);
- expect(menu.item(menu.length - 1).noMore()).toBe(true);
- });
-
- it('should be visible', function () {
- var menu = KorAP.Menu.create("cnx/", list);
- expect(menu.delete()).toBe(undefined);
-
- KorAP.limit = 3;
-
- expect(menu.show()).toBe(undefined);
- expect(menu.element.firstChild.innerHTML).toEqual("<strong>Constituency</strong><span>Example 1</span>");
- expect(menu.element.childNodes[1].innerHTML).toEqual("<strong>Lemma</strong>");
- expect(menu.element.childNodes[1].getAttribute("data-action")).toEqual("l=");
- expect(menu.element.childNodes[2].innerHTML).toEqual("<strong>Morphology</strong><span>Example 2</span>");
- expect(menu.element.childNodes[3]).toBe(undefined);
-
- // Check boundaries
- expect(menu.element.childNodes[0].classList.contains("no-more")).toBe(true);
- expect(menu.element.childNodes[1].classList.contains("no-more")).toBe(false);
- expect(menu.element.childNodes[2].classList.contains("no-more")).toBe(false);
- });
-
-
- it('should be filterable', function () {
- var menu = KorAP.Menu.create("cnx/", list);
-
- KorAP.limit = 3;
-
- expect(menu.show("o")).toBe(undefined);
- expect(menu.element.childNodes[0].innerHTML).toEqual("<strong>C<em>o</em>nstituency</strong><span>Example 1</span>");
- expect(menu.element.childNodes[1].innerHTML).toEqual("<strong>M<em>o</em>rphology</strong><span>Example 2</span>");
- expect(menu.element.childNodes[2].innerHTML).toEqual("<strong>Part-<em>o</em>f-Speech</strong>");
- expect(menu.element.childNodes[3]).toBe(undefined);
-
- // Check boundaries
- expect(menu.element.childNodes[0].classList.contains("no-more")).toBe(true);
- expect(menu.element.childNodes[1].classList.contains("no-more")).toBe(false);
- expect(menu.element.childNodes[2].classList.contains("no-more")).toBe(true);
-
-
- KorAP.limit = 2;
-
- expect(menu.show("o")).toBe(undefined);
- expect(menu.element.childNodes[0].innerHTML).toEqual("<strong>C<em>o</em>nstituency</strong><span>Example 1</span>");
- expect(menu.element.childNodes[1].innerHTML).toEqual("<strong>M<em>o</em>rphology</strong><span>Example 2</span>");
- expect(menu.element.childNodes[2]).toBe(undefined);
-
- // Check boundaries
- expect(menu.element.childNodes[0].classList.contains("no-more")).toBe(true);
- expect(menu.element.childNodes[1].classList.contains("no-more")).toBe(false);
- expect(menu.element.childNodes[2]).toBe(undefined);
- });
-
- it('should be nextable', function () {
- var menu = KorAP.Menu.create("cnx/", list);
-
- KorAP.limit = 3;
- expect(menu.show()).toBe(undefined);
-
- expect(menu.element.childNodes[0].innerHTML).toEqual("<strong>Constituency</strong><span>Example 1</span>");
- expect(menu.shownItem(0).active()).toBe(true);
- expect(menu.element.childNodes[1].innerHTML).toEqual("<strong>Lemma</strong>");
- expect(menu.shownItem(1).active()).toBe(false);
- expect(menu.element.childNodes[2].innerHTML).toEqual("<strong>Morphology</strong><span>Example 2</span>");
- expect(menu.shownItem(2).active()).toBe(false);
- expect(menu.element.childNodes[3]).toBe(undefined);
-
- // Activate next (1)
- menu.next();
- expect(menu.element.childNodes[0].innerHTML).toEqual("<strong>Constituency</strong><span>Example 1</span>");
- expect(menu.shownItem(0).active()).toBe(false);
- expect(menu.element.childNodes[1].innerHTML).toEqual("<strong>Lemma</strong>");
- expect(menu.shownItem(1).active()).toBe(true);
- expect(menu.element.childNodes[2].innerHTML).toEqual("<strong>Morphology</strong><span>Example 2</span>");
- expect(menu.shownItem(2).active()).toBe(false);
- expect(menu.element.childNodes[3]).toBe(undefined);
-
- // Activate next (2)
- menu.next();
- expect(menu.element.childNodes[0].innerHTML).toEqual("<strong>Constituency</strong><span>Example 1</span>");
- expect(menu.shownItem(0).active()).toBe(false);
- expect(menu.element.childNodes[1].innerHTML).toEqual("<strong>Lemma</strong>");
- expect(menu.shownItem(1).active()).toBe(false);
- expect(menu.element.childNodes[2].innerHTML).toEqual("<strong>Morphology</strong><span>Example 2</span>");
- expect(menu.shownItem(2).active()).toBe(true);
- expect(menu.element.childNodes[3]).toBe(undefined);
-
- // Activate next (3)
- menu.next();
- expect(menu.element.childNodes[0].innerHTML).toEqual("<strong>Lemma</strong>");
- expect(menu.shownItem(0).active()).toBe(false);
- expect(menu.element.childNodes[1].innerHTML).toEqual("<strong>Morphology</strong><span>Example 2</span>");
- expect(menu.shownItem(1).active()).toBe(false);
- expect(menu.element.childNodes[2].innerHTML).toEqual("<strong>Part-of-Speech</strong>");
- expect(menu.shownItem(2).active()).toBe(true);
- expect(menu.element.childNodes[3]).toBe(undefined);
-
- // Activate next (4)
- menu.next();
- expect(menu.element.childNodes[0].innerHTML).toEqual("<strong>Morphology</strong><span>Example 2</span>");
- expect(menu.shownItem(0).active()).toBe(false);
- expect(menu.element.childNodes[1].innerHTML).toEqual("<strong>Part-of-Speech</strong>");
- expect(menu.shownItem(1).active()).toBe(false);
- expect(menu.element.childNodes[2].innerHTML).toEqual("<strong>Syntax</strong>");
- expect(menu.shownItem(2).active()).toBe(true);
- expect(menu.element.childNodes[3]).toBe(undefined);
-
- // Activate next (5) - ROLL
- menu.next();
- expect(menu.element.childNodes[0].innerHTML).toEqual("<strong>Constituency</strong><span>Example 1</span>");
- expect(menu.shownItem(0).active()).toBe(true);
- expect(menu.element.childNodes[1].innerHTML).toEqual("<strong>Lemma</strong>");
- expect(menu.shownItem(1).active()).toBe(false);
- expect(menu.element.childNodes[2].innerHTML).toEqual("<strong>Morphology</strong><span>Example 2</span>");
- expect(menu.shownItem(2).active()).toBe(false);
- expect(menu.element.childNodes[3]).toBe(undefined);
-
- // Active next (6)
- menu.next();
- expect(menu.element.childNodes[0].innerHTML).toEqual("<strong>Constituency</strong><span>Example 1</span>");
- expect(menu.shownItem(0).active()).toBe(false);
- expect(menu.element.childNodes[1].innerHTML).toEqual("<strong>Lemma</strong>");
- expect(menu.shownItem(1).active()).toBe(true);
- expect(menu.element.childNodes[2].innerHTML).toEqual("<strong>Morphology</strong><span>Example 2</span>");
- expect(menu.shownItem(2).active()).toBe(false);
- expect(menu.element.childNodes[3]).toBe(undefined);
-
- });
-
-
- it('should be prevable', function () {
- var menu = KorAP.Menu.create("cnx/", list);
-
- KorAP.limit = 3;
- expect(menu.show()).toBe(undefined);
-
- expect(menu.element.childNodes[0].innerHTML).toEqual("<strong>Constituency</strong><span>Example 1</span>");
- expect(menu.shownItem(0).active()).toBe(true);
- expect(menu.element.childNodes[1].innerHTML).toEqual("<strong>Lemma</strong>");
- expect(menu.shownItem(1).active()).toBe(false);
- expect(menu.element.childNodes[2].innerHTML).toEqual("<strong>Morphology</strong><span>Example 2</span>");
- expect(menu.shownItem(2).active()).toBe(false);
- expect(menu.element.childNodes[3]).toBe(undefined);
-
- // Activate prev (1) - roll to bottom
- menu.prev();
- expect(menu.element.childNodes[0].innerHTML).toEqual("<strong>Morphology</strong><span>Example 2</span>");
- expect(menu.shownItem(0).active()).toBe(false);
- expect(menu.element.childNodes[1].innerHTML).toEqual("<strong>Part-of-Speech</strong>");
- expect(menu.shownItem(1).active()).toBe(false);
- expect(menu.element.childNodes[2].innerHTML).toEqual("<strong>Syntax</strong>");
- expect(menu.shownItem(2).active()).toBe(true);
- expect(menu.element.childNodes[3]).toBe(undefined);
-
- // Activate prev (2)
- menu.prev();
- expect(menu.element.childNodes[0].innerHTML).toEqual("<strong>Morphology</strong><span>Example 2</span>");
- expect(menu.shownItem(0).active()).toBe(false);
- expect(menu.element.childNodes[1].innerHTML).toEqual("<strong>Part-of-Speech</strong>");
- expect(menu.shownItem(1).active()).toBe(true);
- expect(menu.element.childNodes[2].innerHTML).toEqual("<strong>Syntax</strong>");
- expect(menu.shownItem(2).active()).toBe(false);
- expect(menu.element.childNodes[3]).toBe(undefined);
-
- // Activate prev (3)
- menu.prev();
- expect(menu.shownItem(0).name).toEqual("Morphology");
- expect(menu.shownItem(0).active()).toBe(true);
- expect(menu.shownItem(1).name).toEqual("Part-of-Speech");
- expect(menu.shownItem(1).active()).toBe(false);
- expect(menu.shownItem(2).name).toEqual("Syntax");
- expect(menu.shownItem(2).active()).toBe(false);
- expect(menu.element.childNodes[3]).toBe(undefined);
-
- // Activate prev (4)
- menu.prev();
- expect(menu.shownItem(0).name).toEqual("Lemma");
- expect(menu.shownItem(0).active()).toBe(true);
- expect(menu.shownItem(1).name).toEqual("Morphology");
- expect(menu.shownItem(1).active()).toBe(false);
- expect(menu.shownItem(2).name).toEqual("Part-of-Speech");
- expect(menu.shownItem(2).active()).toBe(false);
- expect(menu.element.childNodes[3]).toBe(undefined);
-
- // Activate prev (5)
- menu.prev();
- expect(menu.shownItem(0).name).toEqual("Constituency");
- expect(menu.shownItem(0).active()).toBe(true);
- expect(menu.shownItem(1).name).toEqual("Lemma");
- expect(menu.shownItem(1).active()).toBe(false);
- expect(menu.shownItem(2).name).toEqual("Morphology");
- expect(menu.shownItem(2).active()).toBe(false);
- expect(menu.element.childNodes[3]).toBe(undefined);
-
- // Activate next (1)
- menu.next();
- expect(menu.shownItem(0).name).toEqual("Constituency");
- expect(menu.shownItem(0).active()).toBe(false);
- expect(menu.shownItem(1).name).toEqual("Lemma");
- expect(menu.shownItem(1).active()).toBe(true);
- expect(menu.shownItem(2).name).toEqual("Morphology");
- expect(menu.shownItem(2).active()).toBe(false);
- expect(menu.element.childNodes[3]).toBe(undefined);
-
- // Activate prev (6)
- menu.prev();
-
- // Activate prev (7)
- menu.prev();
- expect(menu.shownItem(0).name).toEqual("Morphology");
- expect(menu.shownItem(0).active()).toBe(false);
- expect(menu.shownItem(1).name).toEqual("Part-of-Speech");
- expect(menu.shownItem(1).active()).toBe(false);
- expect(menu.shownItem(2).name).toEqual("Syntax");
- expect(menu.shownItem(2).active()).toBe(true);
- expect(menu.element.childNodes[3]).toBe(undefined);
- });
-
- it('should be navigatable and filterable (prefix = "o")', function () {
- var menu = KorAP.Menu.create("cnx/", list);
-
- KorAP.limit = 2;
-
- expect(menu.show("o")).toBe(undefined);
-
- expect(menu.shownItem(0).name).toEqual("Constituency");
- expect(menu.element.childNodes[0].innerHTML).toEqual("<strong>C<em>o</em>nstituency</strong><span>Example 1</span>");
- expect(menu.shownItem(0).active()).toBe(true);
- expect(menu.shownItem(1).name).toEqual("Morphology");
- expect(menu.element.childNodes[1].innerHTML).toEqual("<strong>M<em>o</em>rphology</strong><span>Example 2</span>");
- expect(menu.shownItem(1).active()).toBe(false);
- expect(menu.shownItem(2)).toBe(undefined);
-
- // Next (1)
- menu.next();
- expect(menu.shownItem(0).name).toEqual("Constituency");
- expect(menu.element.childNodes[0].innerHTML).toEqual("<strong>C<em>o</em>nstituency</strong><span>Example 1</span>");
- expect(menu.shownItem(0).active()).toBe(false);
- expect(menu.shownItem(1).name).toEqual("Morphology");
- expect(menu.element.childNodes[1].innerHTML).toEqual("<strong>M<em>o</em>rphology</strong><span>Example 2</span>");
- expect(menu.shownItem(1).active()).toBe(true);
- expect(menu.shownItem(2)).toBe(undefined);
-
-
- // Next (2)
- menu.next();
- expect(menu.shownItem(0).name).toEqual("Morphology");
- expect(menu.element.childNodes[0].innerHTML).toEqual("<strong>M<em>o</em>rphology</strong><span>Example 2</span>");
- expect(menu.shownItem(0).active()).toBe(false);
- expect(menu.shownItem(1).name).toEqual("Part-of-Speech");
- expect(menu.element.childNodes[1].innerHTML).toEqual("<strong>Part-<em>o</em>f-Speech</strong>");
- expect(menu.shownItem(1).active()).toBe(true);
- expect(menu.shownItem(2)).toBe(undefined);
-
- // Next (3)
- menu.next();
- expect(menu.shownItem(0).name).toEqual("Constituency");
- expect(menu.element.childNodes[0].innerHTML).toEqual("<strong>C<em>o</em>nstituency</strong><span>Example 1</span>");
- expect(menu.shownItem(0).active()).toBe(true);
- expect(menu.shownItem(1).name).toEqual("Morphology");
- expect(menu.element.childNodes[1].innerHTML).toEqual("<strong>M<em>o</em>rphology</strong><span>Example 2</span>");
- expect(menu.shownItem(1).active()).toBe(false);
- expect(menu.shownItem(2)).toBe(undefined);
- });
-
- it('should be navigatable and filterable (prefix = "ex", "e")', function () {
- var menu = KorAP.Menu.create("cnx/", list);
-
- KorAP.limit = 2;
-
- expect(menu.show("ex")).toBe(undefined);
-
- expect(menu.shownItem(0).name).toEqual("Constituency");
- expect(menu.element.childNodes[0].innerHTML).toEqual("<strong>Constituency</strong><span><em>Ex</em>ample 1</span>");
- expect(menu.shownItem(0).active()).toBe(true);
- expect(menu.shownItem(1).name).toEqual("Morphology");
- expect(menu.element.childNodes[1].innerHTML).toEqual("<strong>Morphology</strong><span><em>Ex</em>ample 2</span>");
- expect(menu.shownItem(1).active()).toBe(false);
- expect(menu.shownItem(2)).toBe(undefined);
-
- // Next (1)
- menu.next();
- expect(menu.shownItem(0).name).toEqual("Constituency");
- expect(menu.element.childNodes[0].innerHTML).toEqual("<strong>Constituency</strong><span><em>Ex</em>ample 1</span>");
- expect(menu.shownItem(0).active()).toBe(false);
- expect(menu.shownItem(1).name).toEqual("Morphology");
- expect(menu.element.childNodes[1].innerHTML).toEqual("<strong>Morphology</strong><span><em>Ex</em>ample 2</span>");
- expect(menu.shownItem(1).active()).toBe(true);
- expect(menu.shownItem(2)).toBe(undefined);
-
- // Next (2)
- menu.next();
- expect(menu.shownItem(0).name).toEqual("Constituency");
- expect(menu.element.childNodes[0].innerHTML).toEqual("<strong>Constituency</strong><span><em>Ex</em>ample 1</span>");
- expect(menu.shownItem(0).active()).toBe(true);
- expect(menu.shownItem(1).name).toEqual("Morphology");
- expect(menu.element.childNodes[1].innerHTML).toEqual("<strong>Morphology</strong><span><em>Ex</em>ample 2</span>");
- expect(menu.shownItem(1).active()).toBe(false);
- expect(menu.shownItem(2)).toBe(undefined);
-
- // Reset limit
- KorAP.limit = 5;
-
- // Change show
- expect(menu.show("e")).toBe(undefined);
-
- expect(menu.shownItem(0).name).toEqual("Constituency");
- expect(menu.element.childNodes[0].innerHTML).toEqual("<strong>Constitu<em>e</em>ncy</strong><span><em>E</em>xample 1</span>");
- expect(menu.shownItem(0).active()).toBe(true);
- expect(menu.shownItem(1).name).toEqual("Morphology");
- expect(menu.element.childNodes[1].innerHTML).toEqual("<strong>Morphology</strong><span><em>E</em>xample 2</span>");
- expect(menu.shownItem(1).active()).toBe(false);
- expect(menu.shownItem(2)).toBe(undefined);
-
- // Next (1)
- menu.next();
- expect(menu.shownItem(0).name).toEqual("Constituency");
- expect(menu.element.childNodes[0].innerHTML).toEqual("<strong>Constitu<em>e</em>ncy</strong><span><em>E</em>xample 1</span>");
- expect(menu.shownItem(0).active()).toBe(false);
- expect(menu.shownItem(1).name).toEqual("Morphology");
- expect(menu.element.childNodes[1].innerHTML).toEqual("<strong>Morphology</strong><span><em>E</em>xample 2</span>");
- expect(menu.shownItem(1).active()).toBe(true);
- expect(menu.shownItem(2)).toBe(undefined);
-
- // Next (2)
- menu.next();
- expect(menu.shownItem(0).name).toEqual("Constituency");
- expect(menu.element.childNodes[0].innerHTML).toEqual("<strong>Constitu<em>e</em>ncy</strong><span><em>E</em>xample 1</span>");
- expect(menu.shownItem(0).active()).toBe(true);
- expect(menu.shownItem(1).name).toEqual("Morphology");
- expect(menu.element.childNodes[1].innerHTML).toEqual("<strong>Morphology</strong><span><em>E</em>xample 2</span>");
- expect(menu.shownItem(1).active()).toBe(false);
- expect(menu.shownItem(2)).toBe(undefined);
+ expect(menu.item(menu.length() - 1).active()).toBe(false);
+ expect(menu.item(menu.length() - 1).noMore()).toBe(true);
});
});
-
-describe('KorAP.ContextAnalyzer', function () {
-
- it('should be initializable', function () {
- var analyzer = KorAP.ContextAnalyzer.create(")");
- expect(analyzer).toBe(undefined);
-
- analyzer = KorAP.ContextAnalyzer.create(".+?");
- expect(analyzer).not.toBe(undefined);
-
- });
-
- it('should check correctly', function () {
- analyzer = KorAP.ContextAnalyzer.create(KorAP.context);
- expect(analyzer.test("cnx/]cnx/c=")).toEqual("cnx/c=");
- expect(analyzer.test("cnx/c=")).toEqual("cnx/c=");
- expect(analyzer.test("cnx/c=np mate/m=mood:")).toEqual("mate/m=mood:");
- expect(analyzer.test("impcnx/")).toEqual("impcnx/");
- expect(analyzer.test("cnx/c=npcnx/")).toEqual("npcnx/");
- expect(analyzer.test("mate/m=degree:pos corenlp/ne_dewac_175m_600="))
- .toEqual("corenlp/ne_dewac_175m_600=");
- });
-});
-
-describe('KorAP.InputField', function () {
- var input;
-
- beforeAll(function () {
- input = document.createElement("input");
- input.setAttribute("type", "text");
- input.setAttribute("value", "abcdefghijklmno");
- input.style.position = 'absolute';
- input.style.top = "20px";
- input.style.left = "30px";
- input.focus();
- input.selectionStart = 5;
- });
-
- afterAll(function () {
- document.getElementsByTagName("body")[0].removeChild(input);
- document.getElementsByTagName("body")[0].removeChild(
- document.getElementById("searchMirror")
- );
- });
-
- it('should be initializable', function () {
- // Supports: context, searchField
- var inputField = KorAP.InputField.create(input);
- expect(inputField._element).not.toBe(undefined);
- });
-
- it('should have text', function () {
- var inputField = KorAP.InputField.create(input);
-
- expect(inputField.value).toEqual("abcdefghijklmno");
- expect(inputField.element.selectionStart).toEqual(5);
- expect(inputField.split()[0]).toEqual("abcde");
- expect(inputField.split()[1]).toEqual("fghijklmno");
-
- inputField.insert("xyz");
- expect(inputField.split()[0]).toEqual("abcdexyz");
- expect(inputField.split()[1]).toEqual("fghijklmno");
-
- });
-
- it('should be correctly positioned', function () {
- var inputField = KorAP.InputField.create(input);
- document.getElementsByTagName("body")[0].appendChild(input);
- inputField.reposition();
- expect(inputField.mirror.style.left).toEqual("30px");
- expect(inputField.mirror.style.top.match(/^(\d+)px$/)[1]).toBeGreaterThan(20);
- });
-
-/*
- it('should be correctly triggerable', function () {
- // https://developer.mozilla.org/samples/domref/dispatchEvent.html
- var hint = KorAP.Hint.create({ "inputField" : input });
- emitKeyboardEvent(hint.inputField.element, "keypress", 20);
- });
-*/
-
-});
-
-
-
-/*
-describe('KorAP.Hint', function () {
- KorAP.hintArray = {
- "corenlp/" : [
- ["Named Entity", "ne=" , "Combined"],
- ["Named Entity", "ne_dewac_175m_600=" , "ne_dewac_175m_600"],
- ["Named Entity", "ne_hgc_175m_600=", "ne_hgc_175m_600"]
- ]
- };
-
- it('should be initializable', function () {
- // Supports: context, searchField
- var hint = KorAP.Hint.create();
- });
-});
-
-
-describe('KorAP.ContextAnalyzer', function () {
-
- it('should be initializable', function () {
- var analyzer = KorAP.ContextAnalyzer.create(")");
- expect(analyzer).toBe(undefined);
-
- analyzer = KorAP.ContextAnalyzer.create(".+?");
- expect(analyzer).not.toBe(undefined);
-
- });
-
- it('should check correctly', function () {
- analyzer = KorAP.ContextAnalyzer.create(KorAP.context);
- expect(analyzer.test("cnx/]cnx/c=")).toEqual("cnx/c=");
- expect(analyzer.test("cnx/c=")).toEqual("cnx/c=");
- expect(analyzer.test("cnx/c=np mate/m=mood:")).toEqual("mate/m=mood:");
- expect(analyzer.test("impcnx/")).toEqual("impcnx/");
- expect(analyzer.test("cnx/c=npcnx/")).toEqual("npcnx/");
- expect(analyzer.test("mate/m=degree:pos corenlp/ne_dewac_175m_600="))
- .toEqual("corenlp/ne_dewac_175m_600=");
- });
-});
-
-describe('KorAP.InputField', function () {
- var input;
-
- beforeAll(function () {
- input = document.createElement("input");
- input.setAttribute("type", "text");
- input.setAttribute("value", "abcdefghijklmno");
- input.style.position = 'absolute';
- input.style.top = "20px";
- input.style.left = "30px";
- input.focus();
- input.selectionStart = 5;
- });
-
- afterAll(function () {
- document.getElementsByTagName("body")[0].removeChild(input);
- document.getElementsByTagName("body")[0].removeChild(
- document.getElementById("searchMirror")
- );
- });
-
- it('should be initializable', function () {
- // Supports: context, searchField
- var inputField = KorAP.InputField.create(input);
- expect(inputField._element).not.toBe(undefined);
- });
-
- it('should have text', function () {
- var inputField = KorAP.InputField.create(input);
-
- expect(inputField.value).toEqual("abcdefghijklmno");
- expect(inputField.element.selectionStart).toEqual(5);
- expect(inputField.split()[0]).toEqual("abcde");
- expect(inputField.split()[1]).toEqual("fghijklmno");
-
- inputField.insert("xyz");
- expect(inputField.split()[0]).toEqual("abcdexyz");
- expect(inputField.split()[1]).toEqual("fghijklmno");
-
- });
-
- it('should be correctly positioned', function () {
- var inputField = KorAP.InputField.create(input);
- document.getElementsByTagName("body")[0].appendChild(input);
- inputField.reposition();
- expect(inputField.mirror.style.left).toEqual("30px");
- expect(inputField.mirror.style.top.match(/^(\d+)px$/)[1]).toBeGreaterThan(20);
- });
-});
-
-
-
-*/
diff --git a/public/js/spec/matchSpec.js b/public/js/spec/matchSpec.js
index dc54dc6..0e638c4 100644
--- a/public/js/spec/matchSpec.js
+++ b/public/js/spec/matchSpec.js
@@ -329,6 +329,7 @@
expect(matchElement.children[0].children[1]).toBe(undefined);
var info = KorAP.Match.create(matchElement).info();
+ info.toggle();
// Match
expect(matchElement.children[0].tagName).toEqual('DIV');
@@ -371,6 +372,7 @@
expect(matchElement.tagName).toEqual('LI');
var info = KorAP.Match.create(matchElement).info();
+ info.toggle();
// Match
expect(matchElement.children[0].tagName).toEqual('DIV');
diff --git a/public/js/src/hint.js b/public/js/src/hint.js
index b5c2043..8011bee 100644
--- a/public/js/src/hint.js
+++ b/public/js/src/hint.js
@@ -1,64 +1,21 @@
/**
- * Context aware drop down menu
- * for annotation related query hints.
+ * Hint menu for Kalamar.
*
* @author Nils Diewald
*/
-// - http://www.cryer.co.uk/resources/javascript/script20_respond_to_keypress.htm
-// - https://developers.google.com/closure/compiler/docs/js-for-compiler
-// TODO:
-// - Add help option that opens the tutorial, e.g. to the foundry
-// - http://en.wikipedia.org/wiki/JSDoc
+// requires menu.js
-// The last entry types (foundry, foundry/layer) is remembered and chosen by default
-
-// Show the context at the top as breadcrumbs
-// Highlight the context in the query (probably)
-// Support backspace for removing the last prefix
-
-/*
-Alternative: Use right arrow for temporary context switch and arrow back
-for temporary context removal
-*/
-
-/**
- * The KorAP namespace for project related scripts
- * @namespace
- */
var KorAP = KorAP || {};
-/*
- this._search.addEventListener(
- "keyup",
- function () {
- that.update();
- },
- false
- );
-*/
-
(function (KorAP) {
"use strict";
- // Don't let events bubble up
- if (Event.halt === undefined) {
- Event.prototype.halt = function () {
- this.stopPropagation();
- this.preventDefault();
- };
- };
-
// Default log message
KorAP.log = KorAP.log || function (type, msg) {
console.log(type + ": " + msg);
};
- /* TODO: Add event listener on windows resize to change that! */
-
- /** @define {number} Limited view of menu items */
- KorAP.limit = 8;
-
/**
* @define {regex} Regular expression for context
*/
@@ -74,14 +31,12 @@
// Initialize hint array
KorAP.hintArray = KorAP.hintArray || {};
-
- KorAP.updateKeyDown = function (event) {
- };
-
+ // Input field for queries
KorAP.InputField = {
create : function (element) {
return Object.create(KorAP.InputField)._init(element);
},
+
_init : function (element) {
this._element = element;
@@ -90,6 +45,7 @@
this._mirror = document.createElement("div");
this._mirror.setAttribute("id", "searchMirror");
this._mirror.appendChild(document.createElement("span"));
+ this._container = this._mirror.appendChild(document.createElement("div"));
this._mirror.style.height = "1px";
document.getElementsByTagName("body")[0].appendChild(this._mirror);
};
@@ -99,39 +55,47 @@
window.resize = function () {
that.reposition();
};
-/*
- // Add event listener for key down
- element.addEventListener(
- "keydown",
- function (e) {
-// KorAP.updateKeyDown(e).bind(that)
- },
- false
- );
-*/
+
+ that.reposition();
+
return this;
},
- get mirror () {
+
+ rightPos : function () {
+ var box = this._mirror.getBoundingClientRect();
+ return box.right - box.left;
+ },
+
+ mirror : function () {
return this._mirror;
},
- get element () {
+
+ container : function () {
+ return this._container;
+ },
+
+ element : function () {
return this._element;
},
- get value () {
+
+ value : function () {
return this._element.value;
},
+
update : function () {
this._mirror.firstChild.textContent = this.split()[0];
},
+
insert : function (text) {
var splittedText = this.split();
- var s = this.element;
+ var s = this._element;
s.value = splittedText[0] + text + splittedText[1];
s.selectionStart = (splittedText[0] + text).length;
s.selectionEnd = s.selectionStart;
this._mirror.firstChild.textContent = splittedText[0] + text;
},
- // Return two substrings, splitted at current position
+
+ // Return two substrings, splitted at current cursor position
split : function () {
var s = this._element;
var value = s.value;
@@ -141,13 +105,16 @@
value.substring(start, value.length)
);
},
+
// Position the input mirror directly below the input box
reposition : function () {
var inputClientRect = this._element.getBoundingClientRect();
var inputStyle = window.getComputedStyle(this._element, null);
+
+ // Reset position
var mirrorStyle = this._mirror.style;
mirrorStyle.left = inputClientRect.left + "px";
- mirrorStyle.top = inputClientRect.bottom + "px";
+ mirrorStyle.top = inputClientRect.bottom + "px";
// These may be relevant in case of media depending css
mirrorStyle.paddingLeft = inputStyle.getPropertyValue("padding-left");
@@ -157,182 +124,14 @@
mirrorStyle.fontSize = inputStyle.getPropertyValue("font-size");
mirrorStyle.fontFamily = inputStyle.getPropertyValue("font-family");
},
- get context () {
+ context : function () {
return this.split()[0];
}
};
- KorAP.Hint = {
- _firstTry : true,
- create : function (param) {
- return Object.create(KorAP.Hint)._init(param);
- },
- _init : function (param) {
- param = param || {};
- this._menu = {};
-
- // Get input field
- this._inputField = KorAP.InputField.create(
- param["inputField"] || document.getElementById("q-field")
- );
-
- var that = this;
- var inputFieldElement = this._inputField.element;
-
- // Add event listener for key pressed down
- inputFieldElement.addEventListener(
- "keypress", function (e) {that.updateKeyPress(e)}, false
- );
-
- // Set Analyzer for context
- this._analyzer = KorAP.ContextAnalyzer.create(
- param["context"]|| KorAP.context
- );
-
- return this;
- },
- _codeFromEvent : function (e) {
- if ((e.charCode) && (e.keyCode==0))
- return e.charCode
- return e.keyCode;
- },
- updateKeyPress : function (e) {
- if (!this._active)
- return;
-
- var character = String.fromCharCode(
- this._codeFromEvent(e)
- );
-
- e.halt(); // No event propagation
-
- console.log("TODO: filter view");
- },
- updateKeyDown : function (e) {
- var code = this._codeFromEvent(e)
-
- /*
- * keyCodes:
- * - Down = 40
- * - Esc = 27
- * - Up = 38
- * - Enter = 13
- * - shift = 16
- * for characters use e.key
- */
- switch (code) {
- case 27: // 'Esc'
- // TODO: menu.hide();
- break;
- case 40: // 'Down'
- e.halt(); // No event propagation
-
- // Menu is not active
- if (!this._active)
- this.popUp();
- // Menu is active
- else {
- // TODO: that.removePrefix();
- // TODO: menu.next();
- };
-
- break;
- case 38: // "Up"
- if (!this._active)
- break;
- e.halt(); // No event propagation
- // TODO: that.removePrefix();
- // TODO: menu.prev();
- break;
- case 13: // "Enter"
- if (!this._active)
- break;
- e.halt(); // No event propagation
- // TODO: that.insertText(menu.getActiveItem().getAction());
- // TODO: that.removePrefix();
-
- // Remove menu
- // TODO: menu.hide();
-
- // Fill this with the correct value
- // Todo: This is redundant with click function
- /*
- var show;
- if ((show = that.analyzeContext()) != "-") {
- menu.show(show);
- menu.update(
- e.target.getBoundingClientRect().right
- );
- };
- */
-
- break;
- default:
- if (!this._active)
- return;
-
- // Surpress propagation in firefox
- /*
- if (e.key !== undefined && e.key.length != 1) {
- menu.hide();
- };
- */
- };
- },
-
- getMenuByContext : function () {
- var context = this._inputField.context;
- if (context === undefined || context.length == 0)
- return this.menu("-");
-
- context = this._analyzer.analyze(context);
- if (context === undefined || context.length == 0)
- return this.menu("-");
-
- return this.menu(context);
- },
- // Return and probably init a menu based on an action
- menu : function (action) {
- if (this._menu[action] === undefined) {
- if (KorAP.hintArray[action] === undefined)
- return;
- this._menu[action] = KorAP.menu.create(action, KorAP.hintArray[action]);
- };
- return this._menu[action];
- },
- get inputField () {
- return this._inputField;
- },
- get active () {
- return this._active;
- },
- popUp : function () {
- if (this.active)
- return;
-
- if (this._firstTry) {
- this._inputField.reposition();
- this._firstTry = false;
- };
-
- // update
-
- var menu;
- if (menu = this.getMenuByContext()) {
- menu.show();
-// Update bounding box
- }
- else {
-// this.hide();
- };
-
- // Focus on input field
- this.inputField.element.focus();
- }
- };
/**
- Regex object for checking the context of the hint
+ * Regex object for checking the context of the hint
*/
KorAP.ContextAnalyzer = {
create : function (regex) {
@@ -357,498 +156,295 @@
/**
- * List of items for drop down menu (complete).
- * Only a sublist of the menu is filtered (live).
- * Only a sublist of the filtered menu is visible (shown).
+ * Hint menu item based on MenuItem
*/
- KorAP.Menu = {
- _position : 0, // position in the active list
- _active : -1, // active item in the item list
-
- /**
- * Create new Menu based on the action prefix
- * and a list of menu items.
- *
- * @this {Menu}
- * @constructor
- * @param {string} Context prefix
- * @param {Array.<Array.<string>>} List of menu items
- */
- create : function (context, items) {
- return Object.create(KorAP.Menu)._init(context, items);
+ KorAP.HintMenuItem = {
+ create : function (params) {
+ return Object.create(KorAP.MenuItem)
+ .upgradeTo(KorAP.HintMenuItem)
+ ._init(params);
},
-
- /*
- * Make the previous item in the menu active
- */
- prev : function () {
- if (this._position == -1)
- return;
-
- // Set new live item
- var oldItem = this.liveItem(this._position--);
- oldItem.active(false);
- var newItem = this.liveItem(this._position);
-
- // The previous element is undefined - roll to bottom
- if (newItem === undefined) {
- this._position = this.liveLength - 1;
- newItem = this.liveItem(this._position);
- this._offset = this.liveLength - this.limit;
- this._showItems(this._offset);
- }
-
- // The previous element is outside the view - roll up
- else if (this._position < this._offset) {
- this._removeLast();
- this._offset--;
- this._prepend(this._list[this._position]);
+ content : function (content) {
+ if (arguments.length === 1) {
+ this._content = content;
};
- newItem.active(true);
+ return this._content;
},
-
- /*
- * Make the next item in the menu active
- */
- next : function () {
- // No active element set
- if (this._position == -1)
- return;
-
- // Set new live item
- var oldItem = this.liveItem(this._position++);
- oldItem.active(false);
- var newItem = this.liveItem(this._position);
-
- // The next element is undefined - roll to top
- if (newItem === undefined) {
- this._offset = 0;
- this._position = 0;
- newItem = this.liveItem(0);
- this._showItems(0);
- }
-
- // The next element is outside the view - roll down
- else if (this._position >= (this.limit + this._offset)) {
- this._removeFirst();
- this._offset++;
- this._append(this._list[this._position]);
- };
- newItem.active(true);
- },
-
- /**
- * Delete all visible items from the menu element
- */
- delete : function () {
- var child;
- for (var i = 0; i <= this.limit; i++)
- if (child = this.shownItem(i))
- child.lowlight();
- while (child = this._element.firstChild)
- this._element.removeChild(child);
- },
-
- /**
- * Filter the list and make it visible
- *
- * @param {string} Prefix for filtering the list
- */
- show : function (prefix) {
- this._prefix = prefix;
-
- // Initialize the list
- if (!this._initList())
- return;
-
- // show based on offset
- this._showItems(0);
-
- // Set the first element to active
- this.liveItem(0).active(true);
- this._position = 0;
- this._active = this._list[0];
-
- // Add classes for rolling menus
- this._boundary(true);
- },
-
- /**
- * Get the prefix for filtering,
- * e.g. "ve"" for "verb"
- */
- get prefix () {
- return this._prefix || '';
- },
-
- /**
- * Get the numerical value for limit
- */
- get limit () {
- return KorAP.limit;
- },
-
- /**
- * Get the context of the menue,
- * e.g. "tt/" for the tree tagger menu
- */
- get context () {
- return this._context;
- },
-
- /**
- * Get a specific item from the complete list
- *
- * @param {number} index of the list item
- */
- item : function (index) {
- return this._items[index]
- },
-
- /**
- * Get a specific item from the filtered list
- *
- * @param {number} index of the list item
- */
- liveItem : function (index) {
- if (this._list === undefined)
- if (!this._initList())
- return;
-
- return this._items[this._list[index]];
- },
- /*
- * Get a specific item from the visible list
- *
- * @param {number} index of the list item
- */
- shownItem : function (index) {
- if (index >= this.limit)
- return;
- return this.liveItem(this._offset + index);
- },
- get element () {
- return this._element;
- },
- get length () {
- return this._items.length;
- },
- get liveLength () {
- if (this._list === undefined)
- this._initList();
- return this._list.length;
- },
- chooseHint : function (e) {
-/*
- var element = e.target;
- while (element.nodeName == "STRONG" || element.nodeName == "SPAN")
- element = element.parentNode;
-
- if (element === undefined || element.nodeName != "LI")
- return;
-
- var action = element.getAttribute('data-action');
- hint.insertText(action);
- var menu = hint.menu();
- menu.hide();
-
- // Fill this with the correct value
- var show;
- if ((show = hint.analyzeContext()) != "-") {
- menu.show(show);
- menu.update(
- hint._search.getBoundingClientRect().right
- );
+ _init : function (params) {
+ if (params[0] === undefined ||
+ params[1] === undefined)
+ throw new Error("Missing parameters");
+
+ this._name = params[0];
+ this._action = params[1];
+ this._lcField = ' ' + this._name.toLowerCase();
+
+ if (params.length > 2) {
+ this._desc = params[2];
+ this._lcField += " " + this._desc.toLowerCase();
};
- hint._search.focus();
-*/
- },
-
- _reset : function () {
- this._offset = 0;
- this._pos = 0;
- this._prefix = undefined;
- },
- _boundary : function (bool) {
- this.item(this._list[0]).noMore(bool);
- this.item(this._list[this._list.length - 1]).noMore(bool);
- },
- _initList : function () {
-
-console.log("..." + this._items.length);
-
- if (this._list === undefined)
- this._list = [];
- else if (this._list.length != 0) {
- this._boundary(false);
- this._list.length = 0;
- };
-
- this._offset = 0;
-
- if (this.prefix().length <= 0) {
- for (var i = 0; i < this._items.length; i++)
- this._list.push(i);
- return true;
- };
-
- var pos;
- var paddedPrefix = " " + this.prefix;
- for (pos = 0; pos < this._items.length; pos++) {
- if ((this.item(pos).lcfield.indexOf(paddedPrefix)) >= 0)
- this._list.push(pos);
- };
- if (this._list.length == 0) {
- for (pos = 0; pos < this._items.length; pos++) {
- if ((this.item(pos).lcfield.indexOf(this.prefix)) >= 0)
- this._list.push(pos);
- };
- };
-
- // Filter was successful
- return this._list.length > 0 ? true : false;
- },
-
- _removeFirst : function () {
- this.item(this._list[this._offset]).lowlight();
- this._element.removeChild(this._element.firstChild);
- },
-
- _removeLast : function () {
- this.item(this._list[this._offset + this.limit - 1]).lowlight();
- this._element.removeChild(this._element.lastChild);
- },
-
- // Append item to the shown list based on index
- _append : function (i) {
- var item = this.item(i);
-
- // Highlight based on prefix
- if (this.prefix.length > 0)
- item.highlight(this.prefix);
-
- // Append element
- this.element.appendChild(item.element);
- },
-
- // Prepend item to the shown list based on index
- _prepend : function (i) {
- var item = this.item(i);
-
- // Highlight based on prefix
- if (this.prefix.length > 0)
- item.highlight(this.prefix);
-
- // Append element
- this.element.insertBefore(
- item.element,
- this.element.firstChild
- );
- },
- _init : function (context, items) {
- this._context = context;
- this._element = document.createElement("ul");
- this._element.style.opacity = 0;
- this.active = false;
-/*
- Todo:
- this._element.addEventListener("click", chooseHint, false);
-*/
- this._items = new Array();
- var i;
- for (i in items)
- this._items.push(KorAP.MenuItem.create(items[i]));
-
- this._reset();
return this;
},
+ onclick : function () {
+ var m = this.menu();
+ var h = m.hint();
+ m.hide();
- _showItems : function (offset) {
- this.delete();
+ h.inputField().insert(this._action);
+ h.active = false;
- // Use list
- var shown = 0;
- var i;
- for (i in this._list) {
-
- // Don't show - it's before offset
- if (shown++ < offset)
- continue;
-
- this._append(this._list[i]);
-
- if (shown >= (this.limit + this._offset))
- break;
- };
- }
- };
-
-
- /**
- * Item in the Dropdown menu
- */
- KorAP.MenuItem = {
-
- /**
- * Create a new MenuItem object.
- *
- * @constructor
- * @this {MenuItem}
- * @param {Array.<string>} An array object of name, action and
- * optionally a description
- */
- create : function (params) {
- return Object.create(KorAP.MenuItem)._init(params);
+ h.show(true);
},
-
- /**
- * Get the name of the item
- */
- get name () {
+ name : function () {
return this._name;
},
-
- /**
- * Get the action string
- */
- get action () {
+ action : function () {
return this._action;
},
-
- /**
- * Get the description of the item
- */
- get desc () {
+ desc : function () {
return this._desc;
},
-
- /**
- * Get the lower case field
- */
- get lcfield () {
- return this._lcfield;
- },
-
- /**
- * Check or set if the item is active
- *
- * @param {boolean|null} State of activity
- */
- active : function (bool) {
- var cl = this.element.classList;
- if (bool === undefined)
- return cl.contains("active");
- else if (bool)
- cl.add("active");
- else
- cl.remove("active");
- },
-
- /**
- * Check or set if the item is
- * at the boundary of the menu
- * list
- *
- * @param {boolean|null} State of activity
- */
- noMore : function (bool) {
- var cl = this.element.classList;
- if (bool === undefined)
- return cl.contains("no-more");
- else if (bool)
- cl.add("no-more");
- else
- cl.remove("no-more");
- },
-
- /**
- * Get the document element of the menu item
- */
- get element () {
+ element : function () {
// already defined
if (this._element !== undefined)
return this._element;
// Create list item
var li = document.createElement("li");
- li.setAttribute("data-action", this._action);
+
+ if (this.onclick !== undefined) {
+ li["onclick"] = this.onclick.bind(this);
+ };
// Create title
- var name = document.createElement("strong");
+ var name = document.createElement("span");
name.appendChild(document.createTextNode(this._name));
-
+
li.appendChild(name);
// Create description
if (this._desc !== undefined) {
var desc = document.createElement("span");
+ desc.classList.add('desc');
desc.appendChild(document.createTextNode(this._desc));
li.appendChild(desc);
};
return this._element = li;
+ }
+ };
+
+ KorAP.HintMenuPrefix = {
+ create : function (params) {
+ return Object.create(KorAP.MenuPrefix).upgradeTo(KorAP.HintMenuPrefix)._init(params);
},
+ onclick : function () {
+ var m = this.menu();
+ var h = m.hint();
+ m.hide();
- /**
- * Highlight parts of the item
- *
- * @param {string} Prefix string for highlights
- */
- highlight : function (prefix) {
- var e = this.element;
- this._highlight(e.firstChild, prefix);
- if (this._desc !== undefined)
- this._highlight(e.lastChild, prefix);
- },
+ h.inputField().insert(this.value());
+ h.active = false;
+ }
+ };
- /**
- * Remove highlight of the menu item
- */
- lowlight : function () {
- var e = this.element;
- e.firstChild.innerHTML = this._name;
- if (this._desc !== undefined)
- e.lastChild.innerHTML = this._desc;
- },
+ KorAP.HintMenu = {
+ create : function (hint, context, params) {
+ var obj = Object.create(KorAP.Menu)
+ .upgradeTo(KorAP.HintMenu)
+ ._init(KorAP.HintMenuItem, KorAP.HintMenuPrefix, params);
+ obj._context = context;
+ obj._element.classList.add('hint');
+ obj._hint = hint;
- // Initialize menu item
- _init : function (params) {
- if (params[0] === undefined || params[1] === undefined)
- throw new Error("Missing parameters");
+ // This is only domspecific
+ obj.element().addEventListener('blur', function (e) {
+ this.menu.hide();
+ });
- this._name = params[0];
- this._action = params[1];
- this._lcfield = " " + this._name.toLowerCase();
-
- if (params.length > 2) {
- this._desc = params[2];
- this._lcfield += " " + this._desc.toLowerCase();
+ // Focus on input field on hide
+ obj.onHide = function () {
+ var input = this._hint.inputField();
+ input.element().focus();
};
+
+ return obj;
+ },
+ // Todo: Is this necessary?
+ context : function () {
+ return this._context;
+ },
+ hint : function () {
+ return this._hint;
+ }
+ };
+
+
+ /**
+ * KorAP.Hint.create({
+ * inputField : node,
+ * context : context regex
+ * });
+ */
+ KorAP.Hint = {
+
+ // Some variables
+ // _firstTry : true,
+ active : false,
+
+ create : function (param) {
+ return Object.create(KorAP.Hint)._init(param);
+ },
+
+ _init : function (param) {
+ param = param || {};
+
+ // Holds all menus per prefix context
+ this._menu = {};
+
+ // Get input field
+ this._inputField = KorAP.InputField.create(
+ param["inputField"] || document.getElementById("q-field")
+ );
+
+ var inputFieldElement = this._inputField.element();
+
+ var that = this;
+
+ // Add event listener for key pressed down
+ inputFieldElement.addEventListener(
+ "keypress", function (e) {
+ var code = _codeFromEvent(e);
+ if (code === 40) {
+ that.show(false);
+ e.halt();
+ };
+ }, false
+ );
+
+ // Move infobox
+ inputFieldElement.addEventListener(
+ "keyup", function (e) {
+ var input = that._inputField;
+ input.update();
+ input.container().style.left = input.rightPos() + 'px';
+ }
+ );
+
+ // Set Analyzer for context
+ this._analyzer = KorAP.ContextAnalyzer.create(
+ param["context"] || KorAP.context
+ );
return this;
},
- // Highlight a certain element of the menu item
- _highlight : function (elem, prefix) {
- var text = elem.firstChild.nodeValue;
- var textlc = text.toLowerCase();
- var pos = textlc.indexOf(prefix);
- if (pos >= 0) {
+ inputField : function () {
+ return this._inputField;
+ },
- // First element
- elem.firstChild.nodeValue = pos > 0 ? text.substr(0, pos) : "";
+ /**
+ * A new update by keypress
+ */
+ /*
+updateKeyPress : function (e) {
+ if (!this._active)
+ return;
- // Second element
- var hl = document.createElement("em");
- hl.appendChild(
- document.createTextNode(text.substr(pos, prefix.length))
+ var character = String.fromCharCode(_codeFromEvent(e));
+
+ e.halt(); // No event propagation
+
+ // Only relevant for key down
+ console.log("TODO: filter view");
+ },
+ */
+
+ // updateKeyDown : function (e) {},
+
+ /**
+ * Return hint menu and probably init based on an action
+ */
+ menu : function (action) {
+
+ if (this._menu[action] === undefined) {
+
+ // No matching hint menu
+ if (KorAP.hintArray[action] === undefined)
+ return;
+
+ // Create matching hint menu
+ this._menu[action] = KorAP.HintMenu.create(
+ this, action, KorAP.hintArray[action]
);
- elem.appendChild(hl);
- // Third element
- elem.appendChild(
- document.createTextNode(text.substr(pos + prefix.length))
- );
+ };
+
+ // Return matching hint menu
+ return this._menu[action];
+ },
+
+ /**
+ * Get the correct menu based on the context
+ */
+ contextMenu : function (ifContext) {
+ var context = this._inputField.context();
+ if (context === undefined || context.length == 0)
+ return ifContext ? undefined : this.menu("-");
+
+ context = this._analyzer.test(context);
+ if (context === undefined || context.length == 0)
+ return ifContext ? undefined : this.menu("-");
+
+ return this.menu(context);
+ },
+
+
+ /**
+ * Show the menu
+ */
+ show : function (ifContext) {
+
+ // Menu is already active
+ if (this.active)
+ return;
+
+ // Initialize the menus position
+ /*
+ if (this._firstTry) {
+ this._inputField.reposition();
+ this._firstTry = false;
+ };
+ */
+
+ // update
+
+ // Get the menu
+ var menu;
+ if (menu = this.contextMenu(ifContext)) {
+ this._inputField.container().appendChild(menu.element());
+ menu.show('');
+ menu.focus();
+// Update bounding box
+/*
+ }
+ else if (!ifContext) {
+ // this.hide();
+ };
+*/
+ // Focus on input field
+ // this.inputField.element.focus();
};
}
};
+
+
+ /**
+ * Return keycode based on event
+ */
+ function _codeFromEvent (e) {
+ if ((e.charCode) && (e.keyCode==0))
+ return e.charCode
+ return e.keyCode;
+ };
+
}(this.KorAP));
diff --git a/public/js/src/match.js b/public/js/src/match.js
index f8fdd91..b974031 100644
--- a/public/js/src/match.js
+++ b/public/js/src/match.js
@@ -195,7 +195,7 @@
// Add information, unless it already exists
info.addEventListener('click', function (e) {
e.halt();
- that.info();
+ that.info().toggle();
});
ul.appendChild(close);
@@ -204,7 +204,6 @@
return true;
},
-
/**
* Close info view
*/
@@ -219,7 +218,6 @@
},
-
/**
* Get and open associated match info.
*/
@@ -235,14 +233,9 @@
return this._info;
// Info is already activated
- if (this._info._elemet !== undefined)
+ if (this._info._element !== undefined)
return this._info;
- // Append element to match
- this._element.children[0].appendChild(
- this._info.element()
- );
-
return this._info;
},
@@ -276,10 +269,10 @@
*/
_init : function (match) {
this._match = match;
+ this.opened = false;
return this;
},
-
/**
* Get match object
*/
@@ -287,6 +280,24 @@
return this._match;
},
+ toggle : function () {
+ if (this.opened == true) {
+ this._match.element().children[0].removeChild(
+ this.element()
+ );
+ this.opened = false;
+ }
+ else {
+ // Append element to match
+ this._match.element().children[0].appendChild(
+ this.element()
+ );
+ this.opened = true;
+ };
+
+ return this.opened;
+ },
+
/**
* Retrieve and parse snippet for table representation
diff --git a/public/js/src/menu.js b/public/js/src/menu.js
index a7271c5..3267b69 100644
--- a/public/js/src/menu.js
+++ b/public/js/src/menu.js
@@ -52,7 +52,7 @@
for (var i = 0; i < this._items.length; i++) {
delete this._items[i]["_menu"];
};
-
+ delete this._prefix['_menu'];
},
focus : function () {
@@ -147,11 +147,13 @@
else
this._prefix = KorAP.MenuPrefix.create();
+ this._prefix._menu = this;
+
var e = document.createElement("ul");
e.style.opacity = 0;
e.style.outline = 0;
e.setAttribute('tabindex', 0);
- e.setAttribute('class', 'menu');
+ e.classList.add('menu');
e.appendChild(this._prefix.element());
// This has to be cleaned up later on
@@ -274,9 +276,13 @@
this.active = false;
this.delete();
this._element.style.opacity = 0;
+ this.onHide();
/* this._element.blur(); */
},
+ // To be override
+ onHide : function () {},
+
// Initialize the list
_initList : function () {
@@ -676,7 +682,6 @@
return this;
},
-
content : function (content) {
if (arguments.length === 1)
this._content = document.createTextNode(content);
@@ -737,8 +742,9 @@
var li = document.createElement("li");
// Connect action
- if (this.onclick !== undefined)
+ if (this["onclick"] !== undefined) {
li["onclick"] = this.onclick.bind(this);
+ };
// Append template
li.appendChild(this.content());
@@ -866,7 +872,8 @@
this._element = document.createElement('span');
this._element.classList.add('pref');
// Connect action
- if (this.onclick !== undefined)
+
+ if (this["onclick"] !== undefined)
this._element["onclick"] = this.onclick.bind(this);
return this;
@@ -898,13 +905,16 @@
else
cl.remove("active");
},
+
element : function () {
return this._element;
},
+
isSet : function () {
return this._string.length > 0 ?
true : false;
},
+
value : function (string) {
if (arguments.length === 1) {
this._string = string;
@@ -912,11 +922,14 @@
};
return this._string;
},
+
add : function (string) {
this._string += string;
this._update();
},
- onclick : function (e) {},
+
+ onclick : function () {},
+
backspace : function () {
if (this._string.length > 1) {
this._string = this._string.substring(
@@ -928,6 +941,13 @@
};
this._update();
+ },
+
+ /**
+ * Return menu list.
+ */
+ menu : function () {
+ return this._menu;
}
};
diff --git a/public/js/src/util.js b/public/js/src/util.js
index 0f0f114..3adf5a0 100644
--- a/public/js/src/util.js
+++ b/public/js/src/util.js
@@ -31,35 +31,36 @@
(function (KorAP) {
"use strict";
+
+ /**
+ * Initialize user interface elements
+ */
KorAP.init = function () {
/**
* Add actions to match entries
*/
- var inactiveLi = document.querySelectorAll('#search > ol > li:not(.active)');
+ var inactiveLi = document.querySelectorAll(
+ '#search > ol > li:not(.active)'
+ );
var i = 0;
for (i = 0; i < inactiveLi.length; i++) {
- inactiveLi[i].addEventListener('click', function () {
-
- if (this._match !== undefined) {
+ inactiveLi[i].addEventListener('click', function (e) {
+ if (this._match !== undefined)
this._match.open();
- console.log('already open');
- }
- else {
+ else
KorAP.Match.create(this).open();
- console.log('newly open');
- }
-
-
+ e.halt();
});
};
+
/**
* Toggle the alignment (left <=> right)
*/
if (i > 0) {
var br = document.getElementById('button-right');
- if (br !== undefined) {
+ if (br !== null) {
var toggle = document.createElement('a');
toggle.setAttribute('title', 'toggle Alignment');
// Todo: Reuse old alignment from cookie!
@@ -78,57 +79,11 @@
br.appendChild(toggle);
};
};
+
+ /**
+ * Init hint helper
+ */
+ KorAP.Hint.create();
};
- /*
- function _openMatch (e) {
- e.halt();
- this.classList.add("active");
- var matchElement = this;
-
- // Todo: Add object to element
- var ul = document.createElement('ul');
- ul.classList.add('action', 'right');
- matchElement.appendChild(ul);
-
- // Todo:: Localize!
- var close = document.createElement('li');
- close.appendChild(document.createElement('span'))
- .appendChild(document.createTextNode('Close'));
- close.classList.add('close');
- close.setAttribute('title', 'Close');
-
- close.addEventListener('click', function (ie) {
- ie.halt();
- var match = matchElement['_match'];
- match.destroy();
- matchElement.classList.remove('active');
- matchElement.removeChild(ul);
- });
-
- // Todo:: Localize!
- var info = document.createElement('li');
- info.appendChild(document.createElement('span'))
- .appendChild(document.createTextNode('Info'));
- info.classList.add('info');
- info.setAttribute('title', 'Information');
-
- // Add information, unless it already exists
- info.addEventListener('click', function (ie) {
- ie.halt();
- KorAP.Match.create(matchElement).addInfo();
- });
-
- ul.appendChild(close);
- ul.appendChild(info);
- };
-*/
-
- /**
- function _closeMatch (e) {
- e.halt();
- this.parentNode.parentNode.classList.remove("active");
- };
- */
-
}(this.KorAP));
diff --git a/public/scss/hint.scss b/public/scss/hint.scss
new file mode 100644
index 0000000..470cd17
--- /dev/null
+++ b/public/scss/hint.scss
@@ -0,0 +1,69 @@
+@charset "utf-8";
+@import "util";
+
+$border-size: 2px;
+
+ul.menu.hint {
+ text-align:left;
+// margin-left: -1 * $border-size;
+ max-width: 23em !important;
+ min-width: 7em;
+
+ > li:first-of-type {
+ border-top: {
+ width: 1px;
+ left-radius: 0;
+ right-radius: 0;
+ }
+ }
+ span.desc {
+ display: block;
+ font-size: 75%;
+ }
+}
+
+#searchMirror {
+ position: absolute;
+ left: 0;
+ top: 0;
+ white-space: pre-wrap;
+ overflow: show;
+ height: 0;
+ > span {
+ display: block;
+ opacity: 0;
+ white-space: pre-wrap;
+ overflow: hidden;
+ }
+ // Todo: Besser nur, wenn im Focus
+ > div {
+ cursor: pointer;
+ transition: left 0.3s ease 0s;
+ position: absolute;
+ top: 0;
+ left: 0;
+ text-align: center;
+ padding: 0;
+ border-top: 5px solid $dark-orange;
+
+ height: 10px;
+ width: 1.2em;
+
+ &:hover {
+/*
+ border: {
+ width: $border-size;
+ style: solid;
+ radius: $standard-border-radius;
+ top: {
+ left-radius: 0;
+ right-radius: 0;
+ width: 0px;
+ }
+ }
+ @include choose-hover;
+*/
+ border-top: 10px solid $dark-orange;
+ }
+ }
+}
\ No newline at end of file
diff --git a/public/scss/kalamar.scss b/public/scss/kalamar.scss
index be2cf6f..1ffb671 100644
--- a/public/scss/kalamar.scss
+++ b/public/scss/kalamar.scss
@@ -8,7 +8,9 @@
@import "header"; // Top
@import "searchbar"; // The search bar
@import "menu"; // Menu list
+@import "hint"; // Hint specific menu list
@import "pagination"; // Pagination
@import "resultinfo"; // Information on results
@import "matchinfo"; // Match table and tree
@import "kwic"; // Kwic view information
+@import "vc"; // Kwic view information
diff --git a/public/scss/kwic.scss b/public/scss/kwic.scss
index 88a7da3..e768e5a 100644
--- a/public/scss/kwic.scss
+++ b/public/scss/kwic.scss
@@ -40,13 +40,17 @@
&:nth-of-type(even) {
background-color: $kwic-line-even;
}
- }
- > div {
- > div.snippet {
+ .matchinfo {
+ display: none;
+ }
+ > div > div.snippet {
text-overflow: ellipsis;
text-indent: 0;
text-shadow: $light-shadow;
-
+ }
+ }
+ > div {
+ > div.snippet {
> span,
> mark {
white-space: no-wrap !important;
diff --git a/public/scss/searchbar.scss b/public/scss/searchbar.scss
index 5ac8c0c..2b54e01 100644
--- a/public/scss/searchbar.scss
+++ b/public/scss/searchbar.scss
@@ -4,6 +4,9 @@
$border-size: 2px;
$right-distance: 30px;
+/**
+ * Input field
+ */
#q-field {
@include box-sizing-box();
outline: none;
@@ -12,9 +15,14 @@
padding: 2px;
width: 100%;
margin: 0;
+ margin-bottom: 3px;
display: block;
}
+header > form {
+ min-height: 2.7em;
+}
+
#searchbar {
position: relative;
@include box-sizing-box();
diff --git a/public/scss/vc.scss b/public/scss/vc.scss
new file mode 100644
index 0000000..4d759ef
--- /dev/null
+++ b/public/scss/vc.scss
@@ -0,0 +1,253 @@
+@charset "utf-8";
+@import "util";
+
+$left-padding: 28pt; // 2.8em;
+$border-size: 4px;
+
+.vc {
+ background-color: $light-green;
+
+ .docGroup {
+ position: relative;
+ display: inline-block;
+ color: $nearly-white;
+
+ margin-left: $left-padding; // 2.8em
+
+ // .6em .5em
+ border-width: 0 $border-size;
+
+ padding: {
+ top: 10pt;
+ bottom: 2pt;
+ left: 0pt;
+ right: 6pt;
+ }
+/*
+
+ background-color: yellow;
+*/
+ border: {
+ radius: $standard-border-radius * 2;
+ style: solid;
+ }
+
+ .docGroup {
+ display: block;
+ }
+
+ > .operators {
+ position: absolute;
+ display: block;
+ top: 10px;
+ vertical-align: middle;
+ left: 3px;
+ border-width: 2px 2px 2px 0;
+ border-top-right-radius: 7px;
+ border-bottom-right-radius: 7px;
+ margin-left: 100%;
+ padding: 0;
+ }
+
+ &:hover {
+ background-color: rgba(255,255,255,.05);
+ }
+
+ &[data-operation=or] {
+ border-color: $dark-orange;
+ > .doc::before,
+ > .docGroup::before {
+ content: "oder";
+ }
+ > .operators {
+ border-color: $dark-orange;
+ background-color: $dark-orange;
+ color: $nearly-white;
+ }
+ }
+
+ &[data-operation=and] {
+ > .doc::before,
+ > .docGroup::before {
+ content: "und";
+ }
+ }
+
+ &[data-operation] {
+ > .doc:first-child::before,
+ > .docGroup:first-child::before {
+ content: '';
+ }
+ > .doc::before,
+ > .docGroup::before {
+ display: inline-block;
+ text-align: right;
+// width: 2.2em;
+ width: $left-padding;
+ color: $dark-green;
+ }
+ > .doc::before {
+ padding-right: 1.2em;
+ margin-right: .1em;
+ }
+ > .docGroup::before {
+ position: absolute;
+ }
+ }
+ }
+
+ .doc {
+ > span + span {
+ margin-left: 5pt;
+ }
+ > span.key,
+ > span.value {
+ font-weight: bold;
+ }
+ > .operators {
+ display: inline-block;
+ border-color: $dark-orange;
+ border-width: 2px 2px 2px 2px;
+ border-radius: 7px;
+
+ margin-left: 10px;
+ > span {
+ &.and {
+ border: {
+ radius: inherit;
+ top-right-radius: 0;
+ bottom-right-radius: 0;
+ }
+ &.delete {
+ border: {
+ top-left-radius: 0;
+ bottom-left-radius: 0;
+ }
+ }
+ }
+ }
+ }
+ > span.key {
+ position: relative;
+ > ul {
+ margin: 0;
+ margin-left: 3.3em;
+ }
+ }
+ }
+
+ .rewritten {
+ .rewrite {
+ margin-left: 4pt;
+ display: inline-block;
+ color: $dark-orange;
+ &::after {
+ font-family: FontAwesome;
+ font-style: normal;
+ font-weight: normal;
+ content: "\f040"; // "\f14b";
+ text-decoration: underline;
+ }
+ span {
+ display: none;
+ }
+ }
+ }
+
+ .operators {
+ opacity: 0;
+ white-space: nowrap;
+ padding: 0;
+ font-size: 0;
+ line-height: 0;
+ color: $light-green;
+ border-color: $nearly-white;
+ text-align: center;
+ font-weight: bold;
+ border-style: solid;
+
+ > span {
+ cursor: pointer;
+ font-size: 9pt;
+ line-height: 1.3em;
+ padding: 0 4px;
+ display: inline-block;
+ &.and {
+ background-color: $nearly-white;
+ color: $light-green;
+ }
+ &.or {
+ background-color: $dark-orange;
+ color: $nearly-white;
+ }
+ &.delete {
+ background-color: red;
+ border-radius: inherit;
+ color: $nearly-white;
+ }
+ }
+ }
+
+ > .docGroup {
+ margin-left: 0;
+ }
+
+
+ .docGroup > .docGroup::before {
+ background-color: red;
+ margin-left: -1 * $left-padding; // -3.4em;
+ }
+
+ .doc, .docGroup {
+ &:hover > .operators {
+ opacity: 1;
+ }
+ }
+
+}
+
+
+/*
+.vc .docGroup[data-operation=and]::before,
+.vc .docGroup[data-operation=and] .operators {
+ background-color: white;
+}
+*/
+
+$dg-index : 30;
+
+.docGroup {
+ > .operators {
+ z-index: $dg-index;
+ }
+ .docGroup {
+ > .operators {
+ z-index: $dg-index + 1;
+ }
+ .docGroup {
+ > .operators {
+ z-index: $dg-index + 2;
+ }
+ .docGroup {
+ > .operators {
+ z-index: $dg-index + 3;
+ }
+ .docGroup {
+ > .operators {
+ z-index: $dg-index + 4;
+ }
+ .docGroup {
+ > .operators {
+ z-index: $dg-index + 5;
+ }
+ .docGroup {
+ > .operators {
+ z-index: $dg-index + 6;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}