blob: f9eaa1374a8c8000c9d93cf4bc656302cd35a9d4 [file] [log] [blame]
Akron7524be12016-06-01 17:31:33 +02001/*
Akron5cb9b2b2018-07-24 17:01:09 +02002 * Initialize The JS frontend part and decorate
3 * the static HTML data.
4 *
5 * @author Nils Diewald
6 *
Akron7524be12016-06-01 17:31:33 +02007 * TODO: Create lazy loading of objects including
8 * - obj.hint()
9 * - obj.alertify()
10 * - obj.session()
11 * - obj.tutorial()
12 * - obj.vc() // toggle
13 * - obj.matchCreate() (using webpack)
14 * - obj.koral() (show result, parse for errors ...)
15 * - obj.alignment() // toggle
16 */
17
Nils Diewald0e6992a2015-04-14 20:13:52 +000018define([
19 'match',
20 'hint',
21 'vc',
22 'tutorial',
23 'lib/domReady',
Akron27ae9ec2015-06-23 00:43:21 +020024 'vc/array',
Nils Diewald7148c6f2015-05-04 15:07:53 +000025 'lib/alertify',
Akron7716f012015-07-01 20:38:32 +020026 'session',
Akron6bb71582016-06-10 20:41:08 +020027 'selectMenu',
Akron5cb9b2b2018-07-24 17:01:09 +020028 'panel/result',
Akron2d0d96d2019-11-18 19:49:50 +010029 'panel/query',
hebasta75cfca52019-02-19 13:15:27 +010030 'tour/tours',
Akron24f48ea2020-07-01 09:37:19 +020031 'plugin/server',
32 'pipe',
Nils Diewald7148c6f2015-05-04 15:07:53 +000033 'api',
Nils Diewaldc46003b2015-05-07 15:55:35 +000034 'mailToChiffre',
Akron858cbc82019-12-05 16:53:13 +010035 'util',
36 'state'
Nils Diewald0e6992a2015-04-14 20:13:52 +000037], function (matchClass,
Akron19d97fe2016-09-06 20:47:05 +020038 hintClass,
39 vcClass,
40 tutClass,
41 domReady,
Akron19d97fe2016-09-06 20:47:05 +020042 vcArray,
43 alertifyClass,
44 sessionClass,
Akron4d926f12018-07-16 15:30:25 +020045 selectMenuClass,
hebasta75cfca52019-02-19 13:15:27 +010046 resultPanelClass,
Akron2d0d96d2019-11-18 19:49:50 +010047 queryPanelClass,
Akron24f48ea2020-07-01 09:37:19 +020048 tourClass,
49 pluginClass,
50 pipeClass) {
Nils Diewalda0defc42015-05-07 23:54:17 +000051
Akron0b489ad2018-02-02 16:49:32 +010052 const d = document;
Akron9cc3eaf2015-06-10 22:15:52 +020053
Akron0c4cd222019-07-19 16:33:34 +020054 // Create suffix if KorAP is run in a subfolder
55 KorAP.session = sessionClass.create(
56 KorAP.URL.length > 0 ? 'kalamarJS-' + KorAP.URL.slugify() : 'kalamarJS'
57 );
Akronf8035592018-05-24 20:40:51 +020058
Nils Diewalda0defc42015-05-07 23:54:17 +000059 // Override KorAP.log
60 window.alertify = alertifyClass;
Akronc0a2da82018-07-04 15:27:37 +020061 KorAP.log = function (code, msg, src) {
62
63 if (src) {
64 msg += '<code class="src">'+src+'</code>';
65 };
Nils Diewalda0defc42015-05-07 23:54:17 +000066
67 // Use alertify to log errors
68 alertifyClass.log(
Akronf55504a2015-06-18 16:42:55 +020069 (code === 0 ? '' : code + ': ') +
Akron19d97fe2016-09-06 20:47:05 +020070 msg,
Nils Diewalda0defc42015-05-07 23:54:17 +000071 'error',
Akronf55504a2015-06-18 16:42:55 +020072 10000
Nils Diewalda0defc42015-05-07 23:54:17 +000073 );
74 };
75
hebasta2758b582018-11-19 15:59:42 +010076 KorAP.vc = vcClass.create(vcArray);
77
hebasta5df796f2019-05-21 15:27:12 +020078 KorAP.tourshow = function(){
79 tourClass.gTstartSearch().start();
80 };
81
82 KorAP.tourshowR = function(){
83 tourClass.gTshowResults().start();
84 };
85
Nils Diewald0e6992a2015-04-14 20:13:52 +000086 domReady(function (event) {
hebasta5df796f2019-05-21 15:27:12 +020087
Nils Diewald0e6992a2015-04-14 20:13:52 +000088 var obj = {};
Akron71b91e42016-06-01 22:12:43 +020089
Akron4d926f12018-07-16 15:30:25 +020090 // What should be visible in the beginning?
Akronf8035592018-05-24 20:40:51 +020091 var show = KorAP.session.get('show') || {};
hebasta043e96f2019-11-28 12:33:00 +010092
93 KorAP.Panel = KorAP.Panel || {}
Nils Diewalda297f062015-04-02 00:23:46 +000094
95 /**
Akronf55504a2015-06-18 16:42:55 +020096 * Release notifications
97 */
98 if (KorAP.Notifications !== undefined) {
99 var n = KorAP.Notifications;
100 for (var i = 0; i < n.length; i++) {
Akron8ea84292018-10-24 13:41:52 +0200101 var msg = n[i][1];
102 if (n[i][2]) {
103 msg += '<code class="src">'+n[i][2]+'</code>';
104 };
105 alertifyClass.log(msg, n[i][0], 10000);
Akronf55504a2015-06-18 16:42:55 +0200106 };
107 };
108
109 /**
Akroncd42a142019-07-12 18:55:37 +0200110 * Replace Virtual Corpus field
Nils Diewald7148c6f2015-05-04 15:07:53 +0000111 */
Akron5c829e92017-05-12 18:10:00 +0200112 var vcname, vcchoose;
Akroncd42a142019-07-12 18:55:37 +0200113 var input = d.getElementById('cq');
Akron1f0521b2018-08-28 13:01:24 +0200114
hebasta2758b582018-11-19 15:59:42 +0100115 var vc = KorAP.vc;
hebasta48842cf2018-12-11 12:57:38 +0100116
Akron1f0521b2018-08-28 13:01:24 +0200117 // Add vc name object
Nils Diewald7148c6f2015-05-04 15:07:53 +0000118 if (input) {
119 input.style.display = 'none';
Akron0b489ad2018-02-02 16:49:32 +0100120 vcname = d.createElement('span');
Nils Diewald7148c6f2015-05-04 15:07:53 +0000121 vcname.setAttribute('id', 'vc-choose');
Akron6bb71582016-06-10 20:41:08 +0200122 vcname.classList.add('select');
Akron941551e2015-06-11 16:06:22 +0200123
Akron1f0521b2018-08-28 13:01:24 +0200124 // Load virtual corpus object
Akroncd42a142019-07-12 18:55:37 +0200125 // Supports "collection" for legacy reasons
126 if (KorAP.koralQuery !== undefined && (KorAP.koralQuery["collection"] || KorAP.koralQuery["corpus"])) {
Akron1f0521b2018-08-28 13:01:24 +0200127 try {
Akroncd42a142019-07-12 18:55:37 +0200128 vc.fromJson(KorAP.koralQuery["collection"] || KorAP.koralQuery["corpus"]);
Akron1f0521b2018-08-28 13:01:24 +0200129 }
130 catch (e) {
131 KorAP.log(0,e);
132 }
Akron27ae9ec2015-06-23 00:43:21 +0200133 };
134
Akron0b489ad2018-02-02 16:49:32 +0100135 vcchoose = vcname.addE('span');
Akronec6bb8e2018-08-29 13:07:56 +0200136 vcchoose.addT(vc.getName());
Akron27ae9ec2015-06-23 00:43:21 +0200137
Akron1f0521b2018-08-28 13:01:24 +0200138 if (vc.wasRewritten()) {
139 vcchoose.classList.add('rewritten');
140 };
141
Nils Diewald7148c6f2015-05-04 15:07:53 +0000142 input.parentNode.insertBefore(vcname, input);
143 };
144
Nils Diewald7148c6f2015-05-04 15:07:53 +0000145 /**
Nils Diewalda297f062015-04-02 00:23:46 +0000146 * Add actions to match entries
147 */
Akron3c390c42020-03-30 09:06:21 +0200148 var li = d.querySelectorAll(
149 '#search > ol > li'
Nils Diewald5c5a7472015-04-02 22:13:38 +0000150 );
Akron5cb9b2b2018-07-24 17:01:09 +0200151 var matchCount = 0;
Akron6a535d42015-08-26 20:16:58 +0200152
Akron3c390c42020-03-30 09:06:21 +0200153 for (matchCount = 0; matchCount < li.length; matchCount++) {
154
155 let e = li[matchCount];
156
157 // Define class for active elements
158 if (e.classList.contains('active')) {
159 if (this._match === undefined) {
Akron19d97fe2016-09-06 20:47:05 +0200160 // lazyLoad
Akron3c390c42020-03-30 09:06:21 +0200161 matchClass.create(e).init();
Akron19d97fe2016-09-06 20:47:05 +0200162 };
Akron3c390c42020-03-30 09:06:21 +0200163 }
164
165 // Define class for inactive elements
166 else {
167 e.addEventListener('click', function (e) {
Akron19d97fe2016-09-06 20:47:05 +0200168 if (this._match !== undefined)
Akron3c390c42020-03-30 09:06:21 +0200169 this._match.open();
Akron19d97fe2016-09-06 20:47:05 +0200170 else {
171 // lazyLoad
172 matchClass.create(this).open();
173 };
Akron3c390c42020-03-30 09:06:21 +0200174 // This would prevent the sidebar to go back
175 // e.halt();
176 });
177 e.addEventListener('keydown', function (e) {
178 var code = _codeFromEvent(e);
179
180 switch (code) {
181 case 32:
182 if (this._match !== undefined)
183 this._match.toggle();
184 else {
185 // lazyLoad
186 matchClass.create(this).open();
187 };
188 e.halt();
189 break;
190 };
191 });
192 };
Nils Diewalda297f062015-04-02 00:23:46 +0000193 };
Akron3c390c42020-03-30 09:06:21 +0200194
Akrone0c32c72017-04-25 22:38:23 +0200195 // Add focus listener to aside
Akron0b489ad2018-02-02 16:49:32 +0100196 var aside = d.getElementsByTagName('aside')[0];
Akrone0c32c72017-04-25 22:38:23 +0200197
198 if (aside && aside.classList.contains('active') == false) {
Akron1885ce92017-04-26 23:10:01 +0200199
Akron5258d462017-04-26 23:32:57 +0200200 // Horrible lock to deal with sidebar clicks
201 var asideClicked = false;
202
Akron1885ce92017-04-26 23:10:01 +0200203 // Make aside active on focus
204 aside.addEventListener('focus', function(e) {
Akrone0c32c72017-04-25 22:38:23 +0200205 this.classList.add('active');
206 });
207
Akron1885ce92017-04-26 23:10:01 +0200208 // Deactivate focus when clicking anywhere else
Akron0b489ad2018-02-02 16:49:32 +0100209 var body = d.getElementsByTagName('body')[0];
Akron1885ce92017-04-26 23:10:01 +0200210 if (body !== null) {
211 body.addEventListener('click', function() {
Akron5258d462017-04-26 23:32:57 +0200212 if (!asideClicked) {
213 aside.classList.remove('active');
214 }
215 else {
216 asideClicked = false;
217 };
Akron1885ce92017-04-26 23:10:01 +0200218 });
219 };
220
221 /* Stop click event on aside
222 * (to not trickle down to body)
223 */
224 aside.addEventListener('click', function(e) {
Akron5258d462017-04-26 23:32:57 +0200225 asideClicked = true;
Akrone0c32c72017-04-25 22:38:23 +0200226 });
227 };
Akronb9cdb102017-04-25 00:52:31 +0200228
229
Akron6bb71582016-06-10 20:41:08 +0200230 // Replace QL select menus with KorAP menus
Akron0b489ad2018-02-02 16:49:32 +0100231 var qlField = d.getElementById('ql-field');
Akronaba7a5a2016-08-15 21:58:33 +0200232 if (qlField !== null) {
Akron086fe5d2017-11-13 14:01:45 +0100233 KorAP.QLmenu = selectMenuClass.create(
Akron0b489ad2018-02-02 16:49:32 +0100234 d.getElementById('ql-field').parentNode
Akronaba7a5a2016-08-15 21:58:33 +0200235 ).limit(5);
236 };
Akron6bb71582016-06-10 20:41:08 +0200237
Akron4d926f12018-07-16 15:30:25 +0200238 var resultInfo = d.getElementById('resultinfo');
239
Akron4d926f12018-07-16 15:30:25 +0200240 /**
241 * Add result panel
242 */
Akron5cb9b2b2018-07-24 17:01:09 +0200243 var resultPanel = resultPanelClass.create(show);
244
Akron4d926f12018-07-16 15:30:25 +0200245 if (resultInfo != null) {
Akron4d926f12018-07-16 15:30:25 +0200246
247 // Move buttons to resultinfo
248 resultInfo.appendChild(resultPanel.actions.element());
249
Akrone6538cd2018-07-16 17:52:33 +0200250 // The views are at the top of the search results
Akron4d926f12018-07-16 15:30:25 +0200251 var sb = d.getElementById('search');
252 sb.insertBefore(resultPanel.element(), sb.firstChild);
Akron4d926f12018-07-16 15:30:25 +0200253 };
254
255
Akron179c8ac2015-06-30 19:30:50 +0200256 // There is a koralQuery
Akron4d926f12018-07-16 15:30:25 +0200257 if (KorAP.koralQuery !== undefined) {
Akron5cb9b2b2018-07-24 17:01:09 +0200258
259 // Add KoralQuery view to result panel
Akron4d926f12018-07-16 15:30:25 +0200260 if (resultInfo !== null) {
Akron5cb9b2b2018-07-24 17:01:09 +0200261 resultPanel.addKqAction()
Akron179c8ac2015-06-30 19:30:50 +0200262 };
Akron7716f012015-07-01 20:38:32 +0200263
Akron00cd4d12016-05-31 21:01:11 +0200264 if (KorAP.koralQuery["errors"]) {
Akron19d97fe2016-09-06 20:47:05 +0200265 var errors = KorAP.koralQuery["errors"];
266 for (var i in errors) {
Akronf0c31ed2016-06-11 11:27:01 +0200267
Akron19d97fe2016-09-06 20:47:05 +0200268 // Malformed query
269 if (errors[i][0] === 302 && errors[i][2]) {
270 obj.hint = hintClass.create();
271 obj.hint.alert(errors[i][2], errors[i][1]);
272 break;
273 }
Akronf0c31ed2016-06-11 11:27:01 +0200274
Akron19d97fe2016-09-06 20:47:05 +0200275 // no query
276 else if (errors[i][0] === 301) {
277 obj.hint = hintClass.create();
278 obj.hint.alert(0, errors[i][1]);
279 }
280 }
Akron00cd4d12016-05-31 21:01:11 +0200281 };
Akron179c8ac2015-06-30 19:30:50 +0200282 };
283
Akron5cb9b2b2018-07-24 17:01:09 +0200284
285 /*
286 * There is more than 0 matches, so allow for
287 * alignment toggling (left <=> right)
288 */
289 if (matchCount > 0)
290 resultPanel.addAlignAction();
Nils Diewald7148c6f2015-05-04 15:07:53 +0000291
hebasta043e96f2019-11-28 12:33:00 +0100292 KorAP.Panel['result'] = resultPanel;
Akron5cb9b2b2018-07-24 17:01:09 +0200293 /*
Akroncd42a142019-07-12 18:55:37 +0200294 * Toggle the Virtual Corpus builder
Nils Diewald7148c6f2015-05-04 15:07:53 +0000295 */
296 if (vcname) {
Akronec6bb8e2018-08-29 13:07:56 +0200297 vc.onMinimize = function () {
298 vcname.classList.remove('active');
Akroncd42a142019-07-12 18:55:37 +0200299 delete show['vc'];
Akronec6bb8e2018-08-29 13:07:56 +0200300 };
Nils Diewald6283d692015-04-23 20:32:53 +0000301
Akronec6bb8e2018-08-29 13:07:56 +0200302 vc.onOpen = function () {
303 vcname.classList.add('active');
Akroncfe8ecc2018-11-20 18:46:16 +0100304
305 var view = d.getElementById('vc-view');
306 if (!view.firstChild)
307 view.appendChild(this.element());
308
Akroncd42a142019-07-12 18:55:37 +0200309 show['vc'] = true;
Akronec6bb8e2018-08-29 13:07:56 +0200310 };
311
312 var vcclick = function () {
Akronec6bb8e2018-08-29 13:07:56 +0200313 if (vc.isOpen()) {
314 vc.minimize()
315 }
316 else {
Akronec6bb8e2018-08-29 13:07:56 +0200317 vc.open();
Akron19d97fe2016-09-06 20:47:05 +0200318 };
Nils Diewald58141332015-04-07 16:18:45 +0000319 };
Akron04671e72017-05-11 20:47:32 +0200320
Akron179c8ac2015-06-30 19:30:50 +0200321 vcname.onclick = vcclick;
Akron5c829e92017-05-12 18:10:00 +0200322
323 // Click, if the VC should be shown
Akroncd42a142019-07-12 18:55:37 +0200324 if (show['vc']) {
Akron19d97fe2016-09-06 20:47:05 +0200325 vcclick.apply();
Akron04671e72017-05-11 20:47:32 +0200326 };
Nils Diewald58141332015-04-07 16:18:45 +0000327 };
328
Akron19d97fe2016-09-06 20:47:05 +0200329
Nils Diewald58141332015-04-07 16:18:45 +0000330 /**
331 * Init Tutorial view
332 */
Akron0b489ad2018-02-02 16:49:32 +0100333 if (d.getElementById('view-tutorial')) {
Nils Diewaldfccfbcb2015-04-29 20:48:19 +0000334 window.tutorial = tutClass.create(
Akron0b489ad2018-02-02 16:49:32 +0100335 d.getElementById('view-tutorial'),
Akronf8035592018-05-24 20:40:51 +0200336 KorAP.session
Nils Diewaldfccfbcb2015-04-29 20:48:19 +0000337 );
338 obj.tutorial = window.tutorial;
339 }
Nils Diewald58141332015-04-07 16:18:45 +0000340
Nils Diewaldfccfbcb2015-04-29 20:48:19 +0000341 // Tutorial is in parent
342 else if (window.parent) {
343 obj.tutorial = window.parent.tutorial;
344 };
345
Akron0b489ad2018-02-02 16:49:32 +0100346 // Initialize queries for d
Akron6ed13992016-05-23 18:06:05 +0200347 if (obj.tutorial) {
Akron0b489ad2018-02-02 16:49:32 +0100348 obj.tutorial.initQueries(d);
Nils Diewaldfccfbcb2015-04-29 20:48:19 +0000349
Akron6ed13992016-05-23 18:06:05 +0200350 // Initialize documentation links
Akron0b489ad2018-02-02 16:49:32 +0100351 obj.tutorial.initDocLinks(d);
Akron6ed13992016-05-23 18:06:05 +0200352 };
Nils Diewald61e6ff52015-05-07 17:26:50 +0000353
Nils Diewald845282c2015-05-14 07:53:03 +0000354
Nils Diewald58141332015-04-07 16:18:45 +0000355 /**
Akronc1457bf2015-06-11 19:24:00 +0200356 * Add VC creation on submission.
357 */
Akron0b489ad2018-02-02 16:49:32 +0100358 var form = d.getElementById('searchform');
Akron792f58b2015-07-08 18:59:36 +0200359 if (form !== null) {
Akronc1457bf2015-06-11 19:24:00 +0200360 form.addEventListener('submit', function (e) {
Akron0b489ad2018-02-02 16:49:32 +0100361 var qf = d.getElementById('q-field');
Akron1be6c1c2020-01-07 15:29:58 +0100362
Akron19d97fe2016-09-06 20:47:05 +0200363 // No query was defined
364 if (qf.value === undefined || qf.value === '') {
365 qf.focus();
366 e.halt();
367 KorAP.log(700, "No query given");
368 return;
369 };
Akron1be6c1c2020-01-07 15:29:58 +0100370
Akron19d97fe2016-09-06 20:47:05 +0200371 // Store session information
Akronf8035592018-05-24 20:40:51 +0200372 KorAP.session.set("show", show);
Akron7716f012015-07-01 20:38:32 +0200373
Akron19d97fe2016-09-06 20:47:05 +0200374 if (vc !== undefined) {
375 input.value = vc.toQuery();
Akrond7ad9072019-12-09 07:08:20 +0100376 if (input.value == '')
377 input.removeAttribute('name');
Akron19d97fe2016-09-06 20:47:05 +0200378 }
379 else {
Akrond7ad9072019-12-09 07:08:20 +0100380 input.removeAttribute('value');
381 input.removeAttribute('name');
Akron19d97fe2016-09-06 20:47:05 +0200382 };
Akron1be6c1c2020-01-07 15:29:58 +0100383
384 // This would preferably set the query to be "disabled",
385 // but in that case the query wouldn't be submitted
386 // at all.
387 // Setting the cursor to "progress" fails in current versions
388 // of webkit.
389 qf.classList.add("loading");
390 d.getElementById('qsubmit').classList.add("loading");
Akronc1457bf2015-06-11 19:24:00 +0200391 });
392 };
hebasta5df796f2019-05-21 15:27:12 +0200393
394
395 //Starts the guided tour at the next page
396 if(KorAP.session.get("tour")){
397 tourClass.gTshowResults().start();
398 }
399
Akronc1457bf2015-06-11 19:24:00 +0200400 /**
Nils Diewald58141332015-04-07 16:18:45 +0000401 * Init hint helper
402 * has to be final because of
403 * reposition
404 */
Nils Diewald0e6992a2015-04-14 20:13:52 +0000405 // Todo: Pass an element, so this works with
406 // tutorial pages as well!
Akron00cd4d12016-05-31 21:01:11 +0200407 if (obj.hint === undefined)
408 obj.hint = hintClass.create();
Nils Diewald7148c6f2015-05-04 15:07:53 +0000409
Akron99713ef2017-06-28 18:19:28 +0200410 // Add the hinthelper to the KorAP object to make it manipulatable globally
Akron72f73572017-12-05 12:31:09 +0100411 KorAP.Hint = obj.hint;
Akron99713ef2017-06-28 18:19:28 +0200412
Akron2d0d96d2019-11-18 19:49:50 +0100413
414 /**
415 * Add query panel
416 */
417 var queryPanel = queryPanelClass.create();
418
419 // Get input field
420 var sform = d.getElementById("searchform");
421 var vcView = d.getElementById('vc-view')
422 if (sform && vcView) {
423 // The views are below the query bar
424 sform.insertBefore(queryPanel.element(), vcView);
Akron2d0d96d2019-11-18 19:49:50 +0100425 KorAP.Panel['query'] = queryPanel;
426 }
Akron24f48ea2020-07-01 09:37:19 +0200427
428 /**
429 * Initialize Plugin registry.
430 */
431 let p = KorAP.Plugins;
432 if (p && p.length > 0) {
433 // Load Plugin Server first
434 KorAP.Plugin = pluginClass.create();
435
436 // Add services container to head
437 d.head.appendChild(KorAP.Plugin.element());
438
439 // Add pipe form
440 KorAP.Pipe = pipeClass.create();
441 d.getElementById("searchform").appendChild(KorAP.Pipe.element());
442
443 try {
444
445 // Register all plugins
446 for (var i = 0; i < p.length; i++) {
447 KorAP.Plugin.register(p[i]);
448 }
449 }
450 catch (e) {
451 KorAP.log(0, e);
452 }
453 };
454
Nils Diewald58141332015-04-07 16:18:45 +0000455 return obj;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000456 });
hebasta75cfca52019-02-19 13:15:27 +0100457
Nils Diewald0e6992a2015-04-14 20:13:52 +0000458});