blob: e227c67d22932e43371fbceca9d7fcecd95c072c [file] [log] [blame]
Akrone51eaa32020-11-10 09:35:53 +01001"use strict";
2
Akronc1457bf2015-06-11 19:24:00 +02003window.KorAP = window.KorAP || {};
4
Nils Diewald0e6992a2015-04-14 20:13:52 +00005// Don't let events bubble up
6if (Event.halt === undefined) {
7 // Don't let events bubble up
8 Event.prototype.halt = function () {
9 this.stopPropagation();
10 this.preventDefault();
11 };
12};
13
Akron0c4cd222019-07-19 16:33:34 +020014const _quoteRE = new RegExp("([\"\\\\])", 'g');
Nils Diewald7c8ced22015-04-15 19:21:00 +000015String.prototype.quote = function () {
Akron0c4cd222019-07-19 16:33:34 +020016 return '"' + this.replace(_quoteRE, '\\$1') + '"';
Nils Diewald7c8ced22015-04-15 19:21:00 +000017};
18
Akron0c4cd222019-07-19 16:33:34 +020019const _escapeRE = new RegExp("([\/\\\\])", 'g');
Akron8778f5d2017-06-30 21:25:55 +020020String.prototype.escapeRegex = function () {
21 return this.replace(_escapeRE, '\\$1');
22};
23
Akron0c4cd222019-07-19 16:33:34 +020024const _slug1RE = new RegExp("[^-a-zA-Z0-9_\\s]+", 'g');
25const _slug2RE = new RegExp("[-\\s]+", 'g');
26String.prototype.slugify = function () {
27 return this.toLowerCase().replace(_slug1RE, '').replace(_slug2RE, '-');
28};
29
Akronb7a005a2021-09-21 17:43:02 +020030/**
31 * Upgrade this object to another object,
32 * while private data stays intact.
33 *
34 * @param {Object} An object with properties.
35 */
36Object.prototype.upgradeTo = function (props) {
37 for (let prop in props) {
38 this[prop] = props[prop];
39 };
40 return this;
41};
42
43
Nils Diewald0e6992a2015-04-14 20:13:52 +000044// Add toggleClass method similar to jquery
45HTMLElement.prototype.toggleClass = function (c1, c2) {
Akrondf90c592020-10-20 08:42:50 +020046 const cl = this.classList;
Nils Diewald0e6992a2015-04-14 20:13:52 +000047 if (cl.contains(c1)) {
48 cl.add(c2);
49 cl.remove(c1);
50 }
51 else {
52 cl.remove(c2);
53 cl.add(c1);
54 };
55};
56
Akron0b489ad2018-02-02 16:49:32 +010057// Append element by tag name
Akron151bc872018-02-02 14:04:15 +010058HTMLElement.prototype.addE = function (tag) {
59 return this.appendChild(document.createElement(tag));
60};
61
Akron0b489ad2018-02-02 16:49:32 +010062// Append text node
Akron151bc872018-02-02 14:04:15 +010063HTMLElement.prototype.addT = function (text) {
64 return this.appendChild(document.createTextNode(text));
65};
66
67
Nils Diewald0e6992a2015-04-14 20:13:52 +000068// Utility for removing all children of a node
69function _removeChildren (node) {
70 // Remove everything underneath
71 while (node.firstChild)
72 node.removeChild(node.firstChild);
73};
74
Akron151bc872018-02-02 14:04:15 +010075
Akron6a535d42015-08-26 20:16:58 +020076// Utility to get either the charCode
77// or the keyCode of an event
78function _codeFromEvent (e) {
79 if ((e.charCode) && (e.keyCode==0))
80 return e.charCode
81 return e.keyCode;
82};
83
Akrona6c32b92018-07-02 18:39:42 +020084function _dec2hex (dec) {
85 return ('0' + dec.toString(16)).substr(-2)
86};
87
88
89/**
90 * Create random identifiers
91 */
92/*
93 * code based on
94 * https://stackoverflow.com/questions/1349404/generate-random-string-characters-in-javascript#8084248
95 */
96function randomID (len) {
Akrondf90c592020-10-20 08:42:50 +020097 const arr = new Uint8Array((len || 40) / 2)
Akrona6c32b92018-07-02 18:39:42 +020098 window.crypto.getRandomValues(arr)
99 return Array.from(arr, _dec2hex).join('')
100};
101
Nils Diewald0e6992a2015-04-14 20:13:52 +0000102
Akron116eace2021-06-14 18:02:37 +0200103/**
104 * Add option to show passwords.
105 */
Akron1cfde272021-06-14 18:32:39 +0200106function initTogglePwdVisibility (element) {
107 const el = element.querySelectorAll("input[type=password].show-pwd");
Akron116eace2021-06-14 18:02:37 +0200108 for (let x = 0; x < el.length; x++) {
109 const pwd = el[x];
110
111 const a = document.createElement('a');
Akron1cfde272021-06-14 18:32:39 +0200112 a.classList.add('show-pwd');
Akron116eace2021-06-14 18:02:37 +0200113 a.addEventListener('click', function () {
114 if (pwd.getAttribute("type") === "password") {
115 pwd.setAttribute("type", "text");
116 a.classList.add('hide');
117 return;
118 };
119 pwd.setAttribute("type", "password");
120 a.classList.remove('hide');
121 });
122 pwd.parentNode.insertBefore(a, pwd.nextSibling);
123 };
124};
125
126
Akrona9c55802021-06-15 11:41:29 +0200127/**
128 * Add option to copy to clipboard.
129 */
130function initCopyToClipboard (element) {
131 const el = element.querySelectorAll("input.copy-to-clipboard");
132 for (let x = 0; x < el.length; x++) {
133 const text = el[x];
134 const a = document.createElement('a');
135 a.classList.add('copy-to-clipboard');
136 a.addEventListener('click', function () {
Akron131a8282021-06-18 07:57:52 +0200137 let back = false;
138 if (text.getAttribute("type") === 'password') {
139 text.setAttribute("type", "text");
140 back = true;
141 };
Akrona9c55802021-06-15 11:41:29 +0200142 text.select();
143 text.setSelectionRange(0, 99999);
144 document.execCommand("copy");
Akron131a8282021-06-18 07:57:52 +0200145 if (back) {
146 text.setAttribute("type", "password");
147 };
Akrona9c55802021-06-15 11:41:29 +0200148 });
149 text.parentNode.insertBefore(a, text.nextSibling);
150 };
151};
152
153
Nils Diewald0e6992a2015-04-14 20:13:52 +0000154define(function () {
Akronc1457bf2015-06-11 19:24:00 +0200155 // Todo: That's double now!
Nils Diewald0e6992a2015-04-14 20:13:52 +0000156 KorAP.API = KorAP.API || {};
Akronc1457bf2015-06-11 19:24:00 +0200157 KorAP.Locale = KorAP.Locale || {};
Nils Diewald0e6992a2015-04-14 20:13:52 +0000158
Akron0b489ad2018-02-02 16:49:32 +0100159 const loc = KorAP.Locale;
Nils Diewald359a72c2015-04-20 17:40:29 +0000160 loc.OR = loc.OR || 'or';
161 loc.AND = loc.AND || 'and';
162
163 // Add new stylesheet object lazily to document
164 KorAP.newStyleSheet = function () {
165 if (KorAP._sheet === undefined) {
Akrondf90c592020-10-20 08:42:50 +0200166 const sElem = document.createElement('style');
Nils Diewald359a72c2015-04-20 17:40:29 +0000167 document.head.appendChild(sElem);
168 KorAP._sheet = sElem.sheet;
169 };
170 return KorAP._sheet;
171 };
172
173
Nils Diewald0e6992a2015-04-14 20:13:52 +0000174 // Default log message
Akronc0a2da82018-07-04 15:27:37 +0200175 KorAP.log = KorAP.log || function (type, msg, src) {
Akrondf90c592020-10-20 08:42:50 +0200176 if (src)
177 msg += ' from ' + src;
Nils Diewald0e6992a2015-04-14 20:13:52 +0000178 console.log(type + ": " + msg);
179 };
180
181 return KorAP;
182});
Leo Reppdedcf1a2021-08-18 18:57:47 +0200183
184/**
185 * A Method for generating an array of nodes, that are direct descendants of the passed
186 * element node, using a tag tagName as a parameter. Supposed to be used by the specification only.
187 * @param {HTMLNode} element The HTMLNode / element object whose children we are fetching
188 * @param {String} tagName The tag the children are looked for by
189 * @returns An array of children nodes with tag tagName
190 */
191function directElementChildrenByTagName (element, tagName) {
192 const tagElementsCollection=element.getElementsByTagName(tagName);
193 //var tagElements = Array.from(tagElementsCollection);
194 //var tagElements = [...tagElementsCollection];
195 //This one has the best compatability:
196 var tagElements = Array.prototype.slice.call(tagElementsCollection);
197 //filter by actually being direct child node
198 tagElements = tagElements.filter(subElement => subElement.parentNode === element);
199 return tagElements;
200};
201
202/**
203 * A Method for generating an array of nodes, that are direct descendants of the passed
204 * element node, using a class className as a parameter. Supposed to be used by the specification only.
205 * @param {HTMLNode} element The HTMLNode / element object whose children we are fetching
206 * @param {String} className The class the children are looked for by
207 * @returns An array of children nodes with class className
208 */
209 function directElementChildrenByClassName (element, className) {
210 const classElementsCollection=element.getElementsByTagName(className);
211 //var classElements = Array.from(classElementsCollection);
212 //var classElements = [...classElementsCollection];
213 //This one has the best compatability:
214 var classElements = Array.prototype.slice.call(classElementsCollection);
215 //filter by actually being direct child node
216 classElements = classElements.filter(subElement => subElement.parentNode === element);
217 return classElements;
Akronb7a005a2021-09-21 17:43:02 +0200218};