blob: ebe9df914cddbc4713ae2396238e3c9f045be7bd [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 *
Akron2224dcf2024-11-19 13:28:44 +01005 * @author Nils Diewald, Helge Stallkamp, Uyen-Nhu Tran
Akron5cb9b2b2018-07-24 17:01:09 +02006 *
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
Uyen-Nhu Tran243fe732024-04-10 01:17:24 +020016 *
17 * TODO: After upgrading to ES 6
18 * - use optional chaining operator (for example see below)
Akron7524be12016-06-01 17:31:33 +020019 */
20
Akrone51eaa32020-11-10 09:35:53 +010021"use strict";
Nils Diewald0e6992a2015-04-14 20:13:52 +000022define([
23 'match',
24 'hint',
25 'vc',
26 'tutorial',
27 'lib/domReady',
Akron27ae9ec2015-06-23 00:43:21 +020028 'vc/array',
Nils Diewald7148c6f2015-05-04 15:07:53 +000029 'lib/alertify',
Akron7716f012015-07-01 20:38:32 +020030 'session',
Akronda32e7a2021-11-16 17:28:57 +010031 'state/manager',
Akron6bb71582016-06-10 20:41:08 +020032 'selectMenu',
Akron5cb9b2b2018-07-24 17:01:09 +020033 'panel/result',
Akron2d0d96d2019-11-18 19:49:50 +010034 'panel/query',
Akron644ad9f2021-07-26 16:12:59 +020035 'panel/pagination',
hebasta75cfca52019-02-19 13:15:27 +010036 'tour/tours',
Akron24f48ea2020-07-01 09:37:19 +020037 'plugin/server',
38 'pipe',
Nils Diewald7148c6f2015-05-04 15:07:53 +000039 'api',
Nils Diewaldc46003b2015-05-07 15:55:35 +000040 'mailToChiffre',
Akron858cbc82019-12-05 16:53:13 +010041 'util',
42 'state'
Nils Diewald0e6992a2015-04-14 20:13:52 +000043], function (matchClass,
Akron19d97fe2016-09-06 20:47:05 +020044 hintClass,
45 vcClass,
46 tutClass,
47 domReady,
Akron19d97fe2016-09-06 20:47:05 +020048 vcArray,
49 alertifyClass,
50 sessionClass,
Akronda32e7a2021-11-16 17:28:57 +010051 stateManagerClass,
Akron4d926f12018-07-16 15:30:25 +020052 selectMenuClass,
hebasta75cfca52019-02-19 13:15:27 +010053 resultPanelClass,
Akron2d0d96d2019-11-18 19:49:50 +010054 queryPanelClass,
Akron644ad9f2021-07-26 16:12:59 +020055 paginationPanelClass,
Akron24f48ea2020-07-01 09:37:19 +020056 tourClass,
57 pluginClass,
58 pipeClass) {
Nils Diewalda0defc42015-05-07 23:54:17 +000059
Nils Diewalda0defc42015-05-07 23:54:17 +000060 // Override KorAP.log
61 window.alertify = alertifyClass;
Akrone71bd6d2024-06-11 15:47:39 +020062 KorAP.log = function (code, msg, src, type) {
Akronc0a2da82018-07-04 15:27:37 +020063
64 if (src) {
65 msg += '<code class="src">'+src+'</code>';
66 };
Nils Diewalda0defc42015-05-07 23:54:17 +000067
68 // Use alertify to log errors
69 alertifyClass.log(
Akronf55504a2015-06-18 16:42:55 +020070 (code === 0 ? '' : code + ': ') +
Akron19d97fe2016-09-06 20:47:05 +020071 msg,
Akrone71bd6d2024-06-11 15:47:39 +020072 (type ? type : 'error'),
Akronf55504a2015-06-18 16:42:55 +020073 10000
Nils Diewalda0defc42015-05-07 23:54:17 +000074 );
75 };
76
Marc Kupietze78a1ca2026-02-14 19:14:18 +010077 // Apply configured VC helper field modifications from data-vc-helper-fields attribute
78 const vcFieldsConfig = document.body ? document.body.getAttribute('data-vc-helper-fields') : null;
79 if (vcFieldsConfig) {
80 const mods = vcFieldsConfig.split(',').map(s => s.trim()).filter(s => s.length > 0);
81 mods.forEach(mod => {
82 if (mod.startsWith('-')) {
83 // Remove field by name
84 const name = mod.substring(1);
85 const idx = vcArray.findIndex(f => f[0] === name);
86 if (idx >= 0) vcArray.splice(idx, 1);
87 } else if (mod.startsWith('+')) {
88 // Add field: +name:type
89 const spec = mod.substring(1);
90 const colonIdx = spec.indexOf(':');
91 if (colonIdx > 0) {
92 const name = spec.substring(0, colonIdx);
93 const type = spec.substring(colonIdx + 1);
94 if (!vcArray.some(f => f[0] === name)) {
95 vcArray.push([name, type]);
96 }
97 }
98 }
99 });
100 // Sort alphabetically by field name
101 vcArray.sort((a, b) => a[0].localeCompare(b[0]));
102 };
103
hebasta2758b582018-11-19 15:59:42 +0100104 KorAP.vc = vcClass.create(vcArray);
Akron690066c2021-01-22 17:39:18 +0100105
Nils Diewald0e6992a2015-04-14 20:13:52 +0000106 domReady(function (event) {
Akron006ddc62024-02-19 08:49:43 +0100107
108 const d = document;
109
110 // Set base URL
111 KorAP.URL = d.body.getAttribute('data-korap-url') || "";
Akron9bbd7702024-11-21 13:01:51 +0100112
113
114
Akron006ddc62024-02-19 08:49:43 +0100115 // Create suffix if KorAP is run in a subfolder
116 KorAP.session = sessionClass.create(
Akron9bbd7702024-11-21 13:01:51 +0100117 (KorAP.URL.length > 0 ? 'kalamarJS-' + KorAP.URL.slugify() : 'kalamarJS'),
118 KorAP.URL
Akron006ddc62024-02-19 08:49:43 +0100119 );
120
121 // Get koralQuery response
122 const kqe = d.getElementById('koralQuery');
123 if (kqe !== null) {
124 KorAP.koralQuery = JSON.parse(kqe.getAttribute('data-koralquery') || "");
125 };
126
Helge0d3630c2024-10-16 17:19:40 +0200127 let gt = document.getElementsByClassName('link-guided-tour');
128 if (gt.length != null){
129 for(let j = 0; j < gt.length; j++){
130 gt[j].setAttribute('href', '#');
131 gt[j].addEventListener('click', function(){
Uyen-Nhu Tran243fe732024-04-10 01:17:24 +0200132 tourClass.gTstartSearch().start();
Helge0d3630c2024-10-16 17:19:40 +0200133
Uyen-Nhu Tran243fe732024-04-10 01:17:24 +0200134 // Close the burger menu by simulating a click on the burger icon
135 const burgerIcon = document.querySelector('.burger-icon');
136 if (isBurgerMenuOpen) {
137 burgerIcon.click();
138 }
139 });
140 }
141
142 KorAP.tourshowR = function(){
143 tourClass.gTshowResults().start();
Akron006ddc62024-02-19 08:49:43 +0100144 };
Uyen-Nhu Tran243fe732024-04-10 01:17:24 +0200145 }
Akron006ddc62024-02-19 08:49:43 +0100146
Nils Diewald0e6992a2015-04-14 20:13:52 +0000147 var obj = {};
Akron71b91e42016-06-01 22:12:43 +0200148
Akron4d926f12018-07-16 15:30:25 +0200149 // What should be visible in the beginning?
Akronf8035592018-05-24 20:40:51 +0200150 var show = KorAP.session.get('show') || {};
hebasta043e96f2019-11-28 12:33:00 +0100151
152 KorAP.Panel = KorAP.Panel || {}
Nils Diewalda297f062015-04-02 00:23:46 +0000153
154 /**
Akronf55504a2015-06-18 16:42:55 +0200155 * Release notifications
156 */
Akroncb5c1712021-01-26 18:01:04 +0100157 d.querySelectorAll('#notifications div.notify').forEach(
158 function(e) {
159 let msg = e.textContent;
160
161 let src = e.getAttribute('data-src');
162 if (src) {
163 msg += '<code class="src">'+src+'</code>';
Akron8ea84292018-10-24 13:41:52 +0200164 };
Akroncb5c1712021-01-26 18:01:04 +0100165
166 let type = e.getAttribute('data-type') || "error";
167 alertifyClass.log(msg, type, 10000);
168 }
169 );
Akronf55504a2015-06-18 16:42:55 +0200170
Uyen-Nhu Tran243fe732024-04-10 01:17:24 +0200171 // Responsive navbar: hide and show burger menu
172 const burgerIcon = document.querySelector('.burger-icon');
Uyen-Nhu Trana17b08d2025-02-18 19:14:55 +0100173 const navbarGroup = document.querySelector('.navbar-group');
174
175 if (burgerIcon && navbarGroup) {
176 if (navbarGroup.innerHTML.trim() !== '') {
177 burgerIcon.classList.add('show');
178 }
179 }
180
Uyen-Nhu Tran243fe732024-04-10 01:17:24 +0200181 let isBurgerMenuOpen = false;
182
183 if (burgerIcon) {
184 burgerIcon.addEventListener('click', function() {
185 const navbar = document.querySelector('.navbar');
186 navbar.classList.toggle('show');
187
188 isBurgerMenuOpen = !isBurgerMenuOpen;
189 if (isBurgerMenuOpen) {
190 navbar.style.top = '0';
191 }
192 });
193 }
194
195 // Fallback solution for login dropdown visibility (if :focus-within is not supported)
196 document.addEventListener('DOMContentLoaded', function() {
197 const dropdown = document.querySelector('.dropdown');
198 const dropdownContent = document.querySelector('.dropdown-content');
199
200 dropdown.addEventListener('mouseenter', function() {
201 dropdownContent.style.display = 'block';
202 });
203
204 dropdown.addEventListener('mouseleave', function() {
205 // If no input inside the form is focused, then close dropdown content
206 if (!dropdown.contains(document.activeElement)) {
207 dropdownContent.style.display = 'none';
208 }
209 });
210
211 dropdownContent.addEventListener('focusin', function() {
212 dropdownContent.style.display = 'block';
213 });
214
215 dropdownContent.addEventListener('focusout', function(e) {
216 // If focus moved outside the dropdown content, then close it
217 if (!dropdownContent.contains(e.relatedTarget)) {
218 dropdownContent.style.display = 'none';
219 }
220 });
221 });
222
Akronf55504a2015-06-18 16:42:55 +0200223 /**
Akroncd42a142019-07-12 18:55:37 +0200224 * Replace Virtual Corpus field
Nils Diewald7148c6f2015-05-04 15:07:53 +0000225 */
Akron5c829e92017-05-12 18:10:00 +0200226 var vcname, vcchoose;
Akroncd42a142019-07-12 18:55:37 +0200227 var input = d.getElementById('cq');
Akron1f0521b2018-08-28 13:01:24 +0200228
hebasta2758b582018-11-19 15:59:42 +0100229 var vc = KorAP.vc;
hebasta48842cf2018-12-11 12:57:38 +0100230
Akron1f0521b2018-08-28 13:01:24 +0200231 // Add vc name object
Nils Diewald7148c6f2015-05-04 15:07:53 +0000232 if (input) {
233 input.style.display = 'none';
Akron0b489ad2018-02-02 16:49:32 +0100234 vcname = d.createElement('span');
Nils Diewald7148c6f2015-05-04 15:07:53 +0000235 vcname.setAttribute('id', 'vc-choose');
Akron6bb71582016-06-10 20:41:08 +0200236 vcname.classList.add('select');
Akron941551e2015-06-11 16:06:22 +0200237
Akron1f0521b2018-08-28 13:01:24 +0200238 // Load virtual corpus object
Akroncd42a142019-07-12 18:55:37 +0200239 // Supports "collection" for legacy reasons
240 if (KorAP.koralQuery !== undefined && (KorAP.koralQuery["collection"] || KorAP.koralQuery["corpus"])) {
Akron1f0521b2018-08-28 13:01:24 +0200241 try {
Akroncd42a142019-07-12 18:55:37 +0200242 vc.fromJson(KorAP.koralQuery["collection"] || KorAP.koralQuery["corpus"]);
Akron1f0521b2018-08-28 13:01:24 +0200243 }
244 catch (e) {
245 KorAP.log(0,e);
246 }
Akron27ae9ec2015-06-23 00:43:21 +0200247 };
248
Akron0b489ad2018-02-02 16:49:32 +0100249 vcchoose = vcname.addE('span');
Akronec6bb8e2018-08-29 13:07:56 +0200250 vcchoose.addT(vc.getName());
Akron27ae9ec2015-06-23 00:43:21 +0200251
Akron1f0521b2018-08-28 13:01:24 +0200252 if (vc.wasRewritten()) {
253 vcchoose.classList.add('rewritten');
254 };
255
Nils Diewald7148c6f2015-05-04 15:07:53 +0000256 input.parentNode.insertBefore(vcname, input);
257 };
258
Nils Diewald7148c6f2015-05-04 15:07:53 +0000259 /**
Nils Diewalda297f062015-04-02 00:23:46 +0000260 * Add actions to match entries
261 */
Akronb50964a2020-10-12 11:44:37 +0200262 var matchElements = d.querySelectorAll(
Akron3c390c42020-03-30 09:06:21 +0200263 '#search > ol > li'
Nils Diewald5c5a7472015-04-02 22:13:38 +0000264 );
Akron6a535d42015-08-26 20:16:58 +0200265
Akronb50964a2020-10-12 11:44:37 +0200266 matchElements.forEach(function(e) {
Akron3c390c42020-03-30 09:06:21 +0200267
268 // Define class for active elements
269 if (e.classList.contains('active')) {
Akrond769d702021-08-16 11:09:08 +0200270 if (e._match === undefined) {
Akron19d97fe2016-09-06 20:47:05 +0200271 // lazyLoad
Akron3c390c42020-03-30 09:06:21 +0200272 matchClass.create(e).init();
Akron19d97fe2016-09-06 20:47:05 +0200273 };
Akron3c390c42020-03-30 09:06:21 +0200274 }
275
276 // Define class for inactive elements
277 else {
278 e.addEventListener('click', function (e) {
Akron19d97fe2016-09-06 20:47:05 +0200279 if (this._match !== undefined)
Akron3c390c42020-03-30 09:06:21 +0200280 this._match.open();
Akron19d97fe2016-09-06 20:47:05 +0200281 else {
282 // lazyLoad
283 matchClass.create(this).open();
284 };
Akron3c390c42020-03-30 09:06:21 +0200285 // This would prevent the sidebar to go back
286 // e.halt();
287 });
288 e.addEventListener('keydown', function (e) {
289 var code = _codeFromEvent(e);
290
291 switch (code) {
292 case 32:
293 if (this._match !== undefined)
294 this._match.toggle();
295 else {
296 // lazyLoad
297 matchClass.create(this).open();
298 };
299 e.halt();
300 break;
301 };
302 });
303 };
Akrond769d702021-08-16 11:09:08 +0200304 });
Uyen-Nhu Trane1eba0c2024-12-10 17:06:39 +0100305
306 // Media Query for adjusting dynamically added elements (e.g. hint)
307 const isSmallScreen = window.matchMedia('(max-width: 768px)').matches;
Uyen-Nhu Trana7584e12025-06-17 18:45:09 +0200308
309 // Change styles for different lengths of logo add-on
310 const logoAddon = document.querySelector('.logoaddon');
Akron3c390c42020-03-30 09:06:21 +0200311
Uyen-Nhu Trana7584e12025-06-17 18:45:09 +0200312 if (logoAddon && logoAddon.textContent.length < 6) {
313 if (!isSmallScreen) {
314 logoAddon.style.right = '0.1rem';
315 } else {
316 logoAddon.style.right = '-0.3rem';
317 }
318 }
319
Uyen-Nhu Tran243fe732024-04-10 01:17:24 +0200320 // Function to toggle the shifted class on elements
321 function shiftContent() {
322 // Get elements to perform content shift when sidebar is active
323 const header = document.querySelector('header');
324 const main = document.querySelector('main');
325 const footer = document.querySelector('footer');
Uyen-Nhu Tran243fe732024-04-10 01:17:24 +0200326 const results = document.querySelector('.found');
327 const aside = document.querySelector('aside');
328
Uyen-Nhu Tran53698b32026-06-23 22:48:25 +0200329 if (aside && aside.classList.contains('active') && !aside.classList.contains('off') && !isSmallScreen) {
Uyen-Nhu Tran243fe732024-04-10 01:17:24 +0200330 header.classList.add('shifted');
331 if (!results) {
332 main.classList.add('shifted');
333 }
334 footer.classList.add('shifted');
Akron1c18f102024-11-19 16:31:06 +0100335 adjustHintPosition();
Uyen-Nhu Tran243fe732024-04-10 01:17:24 +0200336 } else {
337 header.classList.remove('shifted');
338 main.classList.remove('shifted');
339 footer.classList.remove('shifted');
Akron1c18f102024-11-19 16:31:06 +0100340 adjustHintPosition();
Uyen-Nhu Tran243fe732024-04-10 01:17:24 +0200341 }
342 }
343
Akron1c18f102024-11-19 16:31:06 +0100344 // Function to adjust the position of the annotation assistant bar (hint),
345 // when user types into the searchbar and clicks the sidebar (or anywhere
346 // outside the searchbar) afterwards
Uyen-Nhu Tran243fe732024-04-10 01:17:24 +0200347 function adjustHintPosition() {
Uyen-Nhu Trane1eba0c2024-12-10 17:06:39 +0100348 const hint = document.querySelector('#hint');
349 const searchInput = document.querySelector('#q-field');
350 const aside = document.querySelector('aside');
351
352 if (hint && searchInput) {
353 // Create a temporary span to measure the exact text width
354 const span = document.createElement('span');
355 span.style.visibility = 'hidden';
356 span.style.position = 'absolute';
357 span.style.whiteSpace = 'pre';
358 // Copy the input's font properties
359 const inputStyle = window.getComputedStyle(searchInput);
360 span.style.font = inputStyle.font;
361 span.style.fontSize = inputStyle.fontSize;
362 span.style.fontFamily = inputStyle.fontFamily;
363 span.textContent = searchInput.value;
364 document.body.appendChild(span);
365
366 // Get the actual width of the text
367 const inputWidth = searchInput.value.length > 0 ? span.offsetWidth : 0;
368 document.body.removeChild(span);
369 let hintLeftPosition = inputWidth;
370
Uyen-Nhu Tran53698b32026-06-23 22:48:25 +0200371 if (aside && aside.classList.contains('active') && !aside.classList.contains('off') && !isSmallScreen) {
Uyen-Nhu Trana17b08d2025-02-18 19:14:55 +0100372 const asideWidth = aside.getBoundingClientRect().width;
373 hintLeftPosition += asideWidth;
Uyen-Nhu Trane1eba0c2024-12-10 17:06:39 +0100374 }
375
376 hint.style.left = `${hintLeftPosition}px`;
377 }
378 }
379 //Can be solved more elegant witch ES6 (see optional chaining operator)
380 let qlf = document.querySelector('#q-field');
381 if(qlf != null){
382 qlf.addEventListener('blur', adjustHintPosition);
383 }
Uyen-Nhu Tran243fe732024-04-10 01:17:24 +0200384
385 // MutationObserver to detect when #hint is injected into the DOM
386 const observer = new MutationObserver((mutationsList, observer) => {
387 for (const mutation of mutationsList) {
388 if (mutation.type === 'childList') {
389 const hint = document.querySelector('#hint');
390 if (hint) {
Uyen-Nhu Trana17b08d2025-02-18 19:14:55 +0100391 if (window.location.pathname !== '/settings' && window.location.pathname !== '/settings/') {
392 shiftContent();
393 }
Uyen-Nhu Tran243fe732024-04-10 01:17:24 +0200394 observer.disconnect();
Akronbe2f9a02025-01-14 09:36:55 +0100395 KorAP.Hint.alert().show();
Uyen-Nhu Tran243fe732024-04-10 01:17:24 +0200396 }
397 }
398 }
399 });
400
401 observer.observe(document.body, { childList: true, subtree: true });
402
Akrone0c32c72017-04-25 22:38:23 +0200403 // Add focus listener to aside
Akron0b489ad2018-02-02 16:49:32 +0100404 var aside = d.getElementsByTagName('aside')[0];
Akrone0c32c72017-04-25 22:38:23 +0200405
406 if (aside && aside.classList.contains('active') == false) {
Akron1885ce92017-04-26 23:10:01 +0200407
Akron5258d462017-04-26 23:32:57 +0200408 // Horrible lock to deal with sidebar clicks
409 var asideClicked = false;
Uyen-Nhu Tran243fe732024-04-10 01:17:24 +0200410
411 shiftContent();
412
Akron1885ce92017-04-26 23:10:01 +0200413 // Make aside active on focus
Uyen-Nhu Tran243fe732024-04-10 01:17:24 +0200414 aside.addEventListener('focus', function (e) {
Uyen-Nhu Tran53698b32026-06-23 22:48:25 +0200415 if (!this.classList.contains('off')) {
416 this.classList.add('active');
417 shiftContent();
418 }
Akrone0c32c72017-04-25 22:38:23 +0200419 });
420
Akron1885ce92017-04-26 23:10:01 +0200421 // Deactivate focus when clicking anywhere else
Akron0b489ad2018-02-02 16:49:32 +0100422 var body = d.getElementsByTagName('body')[0];
Akron1885ce92017-04-26 23:10:01 +0200423 if (body !== null) {
Uyen-Nhu Tran243fe732024-04-10 01:17:24 +0200424 body.addEventListener('click', function () {
Akron5258d462017-04-26 23:32:57 +0200425 if (!asideClicked) {
426 aside.classList.remove('active');
Uyen-Nhu Tran243fe732024-04-10 01:17:24 +0200427 shiftContent();
428 } else {
Akron5258d462017-04-26 23:32:57 +0200429 asideClicked = false;
Uyen-Nhu Tran243fe732024-04-10 01:17:24 +0200430 }
Akron1885ce92017-04-26 23:10:01 +0200431 });
Uyen-Nhu Tran243fe732024-04-10 01:17:24 +0200432 }
Akron1885ce92017-04-26 23:10:01 +0200433
434 /* Stop click event on aside
435 * (to not trickle down to body)
436 */
Uyen-Nhu Tran243fe732024-04-10 01:17:24 +0200437 aside.addEventListener('click', function (e) {
Akron5258d462017-04-26 23:32:57 +0200438 asideClicked = true;
Akrone0c32c72017-04-25 22:38:23 +0200439 });
Uyen-Nhu Tran243fe732024-04-10 01:17:24 +0200440 }
Akronb9cdb102017-04-25 00:52:31 +0200441
Uyen-Nhu Trana17b08d2025-02-18 19:14:55 +0100442 if (window.location.pathname === '/settings' || window.location.pathname === '/settings/') {
443 const header = document.querySelector('header');
444 const main = document.querySelector('main');
445 const footer = document.querySelector('footer');
446
447 aside.style.display = 'none';
448
449 if (header) header.style.setProperty('padding-left', '0', 'important');
450 if (main) main.style.setProperty('padding-left', '0', 'important');
451 if (footer) footer.style.setProperty('padding-left', '0', 'important');
452 }
453
Akron6bb71582016-06-10 20:41:08 +0200454 // Replace QL select menus with KorAP menus
Akron0b489ad2018-02-02 16:49:32 +0100455 var qlField = d.getElementById('ql-field');
Akronaba7a5a2016-08-15 21:58:33 +0200456 if (qlField !== null) {
Akron086fe5d2017-11-13 14:01:45 +0100457 KorAP.QLmenu = selectMenuClass.create(
Akron0b489ad2018-02-02 16:49:32 +0100458 d.getElementById('ql-field').parentNode
Marc Kupietz95455822023-09-19 20:14:31 +0200459 ).limit(10);
Akronaba7a5a2016-08-15 21:58:33 +0200460 };
Akron6bb71582016-06-10 20:41:08 +0200461
Akron4d926f12018-07-16 15:30:25 +0200462 var resultInfo = d.getElementById('resultinfo');
463
Akron4d926f12018-07-16 15:30:25 +0200464 /**
465 * Add result panel
466 */
Akron5cb9b2b2018-07-24 17:01:09 +0200467 var resultPanel = resultPanelClass.create(show);
Akron644ad9f2021-07-26 16:12:59 +0200468
Akron4d926f12018-07-16 15:30:25 +0200469 if (resultInfo != null) {
Akron4d926f12018-07-16 15:30:25 +0200470
471 // Move buttons to resultinfo
Akron37ea1192021-07-28 10:40:14 +0200472 resultInfo.appendChild(resultPanel.actions().element());
Akron4d926f12018-07-16 15:30:25 +0200473
Akrone6538cd2018-07-16 17:52:33 +0200474 // The views are at the top of the search results
Akron4d926f12018-07-16 15:30:25 +0200475 var sb = d.getElementById('search');
476 sb.insertBefore(resultPanel.element(), sb.firstChild);
Akron4d926f12018-07-16 15:30:25 +0200477 };
478
479
Akron179c8ac2015-06-30 19:30:50 +0200480 // There is a koralQuery
Akron4d926f12018-07-16 15:30:25 +0200481 if (KorAP.koralQuery !== undefined) {
Akron5cb9b2b2018-07-24 17:01:09 +0200482
483 // Add KoralQuery view to result panel
Akron4d926f12018-07-16 15:30:25 +0200484 if (resultInfo !== null) {
Akron5cb9b2b2018-07-24 17:01:09 +0200485 resultPanel.addKqAction()
Akron179c8ac2015-06-30 19:30:50 +0200486 };
Akron7716f012015-07-01 20:38:32 +0200487
Akron00cd4d12016-05-31 21:01:11 +0200488 if (KorAP.koralQuery["errors"]) {
Akron678c26f2020-10-09 08:52:50 +0200489 KorAP.koralQuery["errors"].forEach(function(e) {
Akronf0c31ed2016-06-11 11:27:01 +0200490
Akron19d97fe2016-09-06 20:47:05 +0200491 // Malformed query
Akron4a24b722020-10-13 12:44:25 +0200492 if (e[0] === 302 && e[2] !== undefined) {
Akron19d97fe2016-09-06 20:47:05 +0200493 obj.hint = hintClass.create();
Akron678c26f2020-10-09 08:52:50 +0200494 obj.hint.alert(e[2], e[1]);
Akron19d97fe2016-09-06 20:47:05 +0200495 }
Akronf0c31ed2016-06-11 11:27:01 +0200496
Akron19d97fe2016-09-06 20:47:05 +0200497 // no query
Akron678c26f2020-10-09 08:52:50 +0200498 else if (e[0] === 301) {
Akron19d97fe2016-09-06 20:47:05 +0200499 obj.hint = hintClass.create();
Akron678c26f2020-10-09 08:52:50 +0200500 obj.hint.alert(0, e[1]);
Akron19d97fe2016-09-06 20:47:05 +0200501 }
Akron678c26f2020-10-09 08:52:50 +0200502 });
Akron00cd4d12016-05-31 21:01:11 +0200503 };
Akron179c8ac2015-06-30 19:30:50 +0200504 };
505
Akron5cb9b2b2018-07-24 17:01:09 +0200506
507 /*
508 * There is more than 0 matches, so allow for
509 * alignment toggling (left <=> right)
510 */
Akronb50964a2020-10-12 11:44:37 +0200511 if (matchElements.length > 0)
Akron5cb9b2b2018-07-24 17:01:09 +0200512 resultPanel.addAlignAction();
Nils Diewald7148c6f2015-05-04 15:07:53 +0000513
hebasta043e96f2019-11-28 12:33:00 +0100514 KorAP.Panel['result'] = resultPanel;
Akron5cb9b2b2018-07-24 17:01:09 +0200515 /*
Akroncd42a142019-07-12 18:55:37 +0200516 * Toggle the Virtual Corpus builder
Nils Diewald7148c6f2015-05-04 15:07:53 +0000517 */
518 if (vcname) {
Akronec6bb8e2018-08-29 13:07:56 +0200519 vc.onMinimize = function () {
520 vcname.classList.remove('active');
Akroncd42a142019-07-12 18:55:37 +0200521 delete show['vc'];
Akronec6bb8e2018-08-29 13:07:56 +0200522 };
Nils Diewald6283d692015-04-23 20:32:53 +0000523
Akronec6bb8e2018-08-29 13:07:56 +0200524 vc.onOpen = function () {
525 vcname.classList.add('active');
Akroncfe8ecc2018-11-20 18:46:16 +0100526
527 var view = d.getElementById('vc-view');
528 if (!view.firstChild)
529 view.appendChild(this.element());
530
Akroncd42a142019-07-12 18:55:37 +0200531 show['vc'] = true;
Akronec6bb8e2018-08-29 13:07:56 +0200532 };
533
534 var vcclick = function () {
Akronec6bb8e2018-08-29 13:07:56 +0200535 if (vc.isOpen()) {
536 vc.minimize()
537 }
538 else {
Akronec6bb8e2018-08-29 13:07:56 +0200539 vc.open();
Akron19d97fe2016-09-06 20:47:05 +0200540 };
Nils Diewald58141332015-04-07 16:18:45 +0000541 };
Akron04671e72017-05-11 20:47:32 +0200542
Akron179c8ac2015-06-30 19:30:50 +0200543 vcname.onclick = vcclick;
Akron5c829e92017-05-12 18:10:00 +0200544
545 // Click, if the VC should be shown
Akroncd42a142019-07-12 18:55:37 +0200546 if (show['vc']) {
Akron19d97fe2016-09-06 20:47:05 +0200547 vcclick.apply();
Akron04671e72017-05-11 20:47:32 +0200548 };
Nils Diewald58141332015-04-07 16:18:45 +0000549 };
550
Akron19d97fe2016-09-06 20:47:05 +0200551
Nils Diewald58141332015-04-07 16:18:45 +0000552 /**
553 * Init Tutorial view
554 */
Akron0b489ad2018-02-02 16:49:32 +0100555 if (d.getElementById('view-tutorial')) {
Nils Diewaldfccfbcb2015-04-29 20:48:19 +0000556 window.tutorial = tutClass.create(
Akron0b489ad2018-02-02 16:49:32 +0100557 d.getElementById('view-tutorial'),
Akronf8035592018-05-24 20:40:51 +0200558 KorAP.session
Nils Diewaldfccfbcb2015-04-29 20:48:19 +0000559 );
560 obj.tutorial = window.tutorial;
561 }
Nils Diewald58141332015-04-07 16:18:45 +0000562
Nils Diewaldfccfbcb2015-04-29 20:48:19 +0000563 // Tutorial is in parent
564 else if (window.parent) {
565 obj.tutorial = window.parent.tutorial;
566 };
567
Akron0b489ad2018-02-02 16:49:32 +0100568 // Initialize queries for d
Akron6ed13992016-05-23 18:06:05 +0200569 if (obj.tutorial) {
Akron0b489ad2018-02-02 16:49:32 +0100570 obj.tutorial.initQueries(d);
Nils Diewaldfccfbcb2015-04-29 20:48:19 +0000571
Akron6ed13992016-05-23 18:06:05 +0200572 // Initialize documentation links
Akron0b489ad2018-02-02 16:49:32 +0100573 obj.tutorial.initDocLinks(d);
Akron6ed13992016-05-23 18:06:05 +0200574 };
Nils Diewald61e6ff52015-05-07 17:26:50 +0000575
Nils Diewald845282c2015-05-14 07:53:03 +0000576
Nils Diewald58141332015-04-07 16:18:45 +0000577 /**
Akronc1457bf2015-06-11 19:24:00 +0200578 * Add VC creation on submission.
579 */
Akron0b489ad2018-02-02 16:49:32 +0100580 var form = d.getElementById('searchform');
Akron792f58b2015-07-08 18:59:36 +0200581 if (form !== null) {
Akronc1457bf2015-06-11 19:24:00 +0200582 form.addEventListener('submit', function (e) {
Akron0b489ad2018-02-02 16:49:32 +0100583 var qf = d.getElementById('q-field');
Akron1be6c1c2020-01-07 15:29:58 +0100584
Akron19d97fe2016-09-06 20:47:05 +0200585 // No query was defined
586 if (qf.value === undefined || qf.value === '') {
587 qf.focus();
588 e.halt();
589 KorAP.log(700, "No query given");
590 return;
591 };
Akron1be6c1c2020-01-07 15:29:58 +0100592
Akron19d97fe2016-09-06 20:47:05 +0200593 // Store session information
Akronf8035592018-05-24 20:40:51 +0200594 KorAP.session.set("show", show);
Akron7716f012015-07-01 20:38:32 +0200595
Akron19d97fe2016-09-06 20:47:05 +0200596 if (vc !== undefined) {
597 input.value = vc.toQuery();
Akrond7ad9072019-12-09 07:08:20 +0100598 if (input.value == '')
599 input.removeAttribute('name');
Akron19d97fe2016-09-06 20:47:05 +0200600 }
601 else {
Akrond7ad9072019-12-09 07:08:20 +0100602 input.removeAttribute('value');
603 input.removeAttribute('name');
Akron19d97fe2016-09-06 20:47:05 +0200604 };
Akron1be6c1c2020-01-07 15:29:58 +0100605
Akronaa3dcfe2024-12-10 15:29:40 +0100606 if (KorAP.States != null) {
607 const statesE = KorAP.States.element();
608 if (statesE.value == "")
609 statesE.removeAttribute('name');
610 };
611
612 if (KorAP.Pipe != null) {
613 const pipeE = KorAP.Pipe.element();
614 if (pipeE.value == "")
615 pipeE.removeAttribute("name");
616 };
617
Akron910828a2025-06-27 15:38:48 +0200618 if (KorAP.ResponsePipe != null) {
619 const pipeE = KorAP.ResponsePipe.element();
620 if (pipeE.value == "")
621 pipeE.removeAttribute("name");
622 };
623
624
Akron1be6c1c2020-01-07 15:29:58 +0100625 // This would preferably set the query to be "disabled",
626 // but in that case the query wouldn't be submitted
627 // at all.
628 // Setting the cursor to "progress" fails in current versions
629 // of webkit.
630 qf.classList.add("loading");
631 d.getElementById('qsubmit').classList.add("loading");
Akronaa3dcfe2024-12-10 15:29:40 +0100632
633 // Alternatively the submission could be prevented early
634 // and the formData API could be used instead:
635 // e.preventDefault();
636 // const formData = new FormData(this);
637 // const queryString = new URLSearchParams(formData).toString();
638 // window.location.href = `${this.action}?${queryString}`;
Akronc1457bf2015-06-11 19:24:00 +0200639 });
640 };
hebasta5df796f2019-05-21 15:27:12 +0200641
642
643 //Starts the guided tour at the next page
644 if(KorAP.session.get("tour")){
645 tourClass.gTshowResults().start();
646 }
647
Akronc1457bf2015-06-11 19:24:00 +0200648 /**
Nils Diewald58141332015-04-07 16:18:45 +0000649 * Init hint helper
650 * has to be final because of
651 * reposition
652 */
Nils Diewald0e6992a2015-04-14 20:13:52 +0000653 // Todo: Pass an element, so this works with
654 // tutorial pages as well!
Akron00cd4d12016-05-31 21:01:11 +0200655 if (obj.hint === undefined)
656 obj.hint = hintClass.create();
Nils Diewald7148c6f2015-05-04 15:07:53 +0000657
Akron99713ef2017-06-28 18:19:28 +0200658 // Add the hinthelper to the KorAP object to make it manipulatable globally
Akron72f73572017-12-05 12:31:09 +0100659 KorAP.Hint = obj.hint;
Akron99713ef2017-06-28 18:19:28 +0200660
Akron2d0d96d2019-11-18 19:49:50 +0100661
662 /**
663 * Add query panel
664 */
665 var queryPanel = queryPanelClass.create();
666
667 // Get input field
Akron2d0d96d2019-11-18 19:49:50 +0100668 var vcView = d.getElementById('vc-view')
Akron96b97d62023-11-07 15:56:54 +0100669 if (form && vcView) {
Akron2d0d96d2019-11-18 19:49:50 +0100670 // The views are below the query bar
Akron96b97d62023-11-07 15:56:54 +0100671 form.insertBefore(queryPanel.element(), vcView);
Akron2d0d96d2019-11-18 19:49:50 +0100672 KorAP.Panel['query'] = queryPanel;
Akron644ad9f2021-07-26 16:12:59 +0200673 };
674
675
676 /**
677 * Add pagination panel
678 */
679 const paginationPanel = paginationPanelClass.create();
680
681 if (paginationPanel) {
682 paginationPanel.addRandomPage();
683 KorAP.Panel['pagination'] = paginationPanel;
684 };
Akron24f48ea2020-07-01 09:37:19 +0200685
Akrona9c55802021-06-15 11:41:29 +0200686
687 /**
688 * Initialize password toggle.
689 */
690 initCopyToClipboard(d);
691
692
Akron24f48ea2020-07-01 09:37:19 +0200693 /**
Akron116eace2021-06-14 18:02:37 +0200694 * Initialize password toggle.
695 */
Akron1cfde272021-06-14 18:32:39 +0200696 initTogglePwdVisibility(d);
Akron116eace2021-06-14 18:02:37 +0200697
698 /**
Akron24f48ea2020-07-01 09:37:19 +0200699 * Initialize Plugin registry.
700 */
Akron8dda1c62021-01-20 10:27:32 +0100701 let pe;
702 if (pe = d.getElementById("kalamar-plugins")) {
703 let url = pe.getAttribute('data-plugins');
704 if (url !== undefined) {
705 KorAP.API.getPluginList(url, function (json) {
706 if (json && json.length > 0) {
Akronda32e7a2021-11-16 17:28:57 +0100707
708 // Add state manager
Akron96b97d62023-11-07 15:56:54 +0100709 form = d.getElementById("searchform");
710 if (!form) {
711 return;
712 };
713
714 const input = form.addE("input");
Akroned223be2024-12-10 13:01:46 +0100715 input.setAttribute("type","text");
Akronda32e7a2021-11-16 17:28:57 +0100716 input.setAttribute("name","state");
Akron3d232342025-12-03 22:46:47 +0100717 input.setAttribute("id","state");
Akroned223be2024-12-10 13:01:46 +0100718
719 const url = new URL(window.location.href);
720
721 // Access the query parameters to check for states
722 const state = new URLSearchParams(url.search).get('state');
723 if (state != null && state != "") {
724 input.setAttribute("value", state);
725 };
726
Akronda32e7a2021-11-16 17:28:57 +0100727 KorAP.States = stateManagerClass.create(input);
728
Akron8dda1c62021-01-20 10:27:32 +0100729 // Load Plugin Server first
730 KorAP.Plugin = pluginClass.create();
Akron24f48ea2020-07-01 09:37:19 +0200731
Akron8dda1c62021-01-20 10:27:32 +0100732 // Add services container to head
733 d.head.appendChild(KorAP.Plugin.element());
Akron24f48ea2020-07-01 09:37:19 +0200734
Akron8dda1c62021-01-20 10:27:32 +0100735 // Add pipe form
Akron910828a2025-06-27 15:38:48 +0200736 KorAP.Pipe = pipeClass.create("pipe");
737 let searchF = d.getElementById("searchform");
738 searchF.appendChild(KorAP.Pipe.element());
739
740 // Add pipe form
741 KorAP.ResponsePipe = pipeClass.create("response-pipe");
742 searchF.appendChild(KorAP.ResponsePipe.element());
Akronda32e7a2021-11-16 17:28:57 +0100743
Akron8dda1c62021-01-20 10:27:32 +0100744 try {
745
746 // Register all plugins
747 json.forEach(i => KorAP.Plugin.register(i));
748 }
749 catch (e) {
750 KorAP.log(0, e);
751 }
752 }
753 });
754 };
Akron24f48ea2020-07-01 09:37:19 +0200755 };
Akronf7f75a92024-09-24 11:15:43 +0200756
757 window.dispatchEvent(new Event("ui-ready"));
Akron8dda1c62021-01-20 10:27:32 +0100758
Nils Diewald58141332015-04-07 16:18:45 +0000759 return obj;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000760 });
hebasta75cfca52019-02-19 13:15:27 +0100761
Nils Diewald0e6992a2015-04-14 20:13:52 +0000762});