blob: 3a8c65e3442da96f28e91ba7a6cee4104241d775 [file] [log] [blame]
Helgee8a39b12026-04-16 13:37:09 +02001window.KorAP = window.KorAP || {};
2const KorAP = window.KorAP;
3
4// Don't let events bubble up
5if (Event.halt === undefined) {
6 // Don't let events bubble up
7 Event.prototype.halt = function () {
8 this.stopPropagation();
9 this.preventDefault();
10 };
11};
12
13const _quoteRE = new RegExp("([\"\\\\])", 'g');
14String.prototype.quote = function () {
15 return '"' + this.replace(_quoteRE, '\\$1') + '"';
16};
17
18const _escapeRE = new RegExp("([\/\\\\])", 'g');
19String.prototype.escapeRegex = function () {
20 return this.replace(_escapeRE, '\\$1');
21};
22
23const _slug1RE = new RegExp("[^-a-zA-Z0-9_\\s]+", 'g');
24const _slug2RE = new RegExp("[-\\s]+", 'g');
25String.prototype.slugify = function () {
26 return this.toLowerCase().replace(_slug1RE, '').replace(_slug2RE, '-');
27};
28
29/**
30 * Upgrade this object to another object,
31 * while private data stays intact.
32 *
33 * @param {Object} An object with properties.
34 */
35Object.defineProperty(Object.prototype, 'upgradeTo', {
36 value: function (props) {
37 for (let prop in props) {
38 this[prop] = props[prop];
39 };
40 return this;
41 },
42 enumerable: false,
43 configurable: true,
44 writable: true
45});
46
47
48// Add toggleClass method similar to jquery
49HTMLElement.prototype.toggleClass = function (c1, c2) {
50 const cl = this.classList;
51 if (cl.contains(c1)) {
52 cl.add(c2);
53 cl.remove(c1);
54 }
55 else {
56 cl.remove(c2);
57 cl.add(c1);
58 };
59};
60
61// Append element by tag name
62HTMLElement.prototype.addE = function (tag) {
63 return this.appendChild(document.createElement(tag));
64};
65
66// Append text node
67HTMLElement.prototype.addT = function (text) {
68 return this.appendChild(document.createTextNode(text));
69};
70
71
72// Utility for removing all children of a node
73function _removeChildren (node) {
74 // Remove everything underneath
75 while (node.firstChild)
76 node.removeChild(node.firstChild);
77};
78
79
80// Utility to get either the charCode
81// or the keyCode of an event
82function _codeFromEvent (e) {
83 if ((e.charCode) && (e.keyCode==0))
84 return e.charCode
85 return e.keyCode;
86};
87
88function _dec2hex (dec) {
89 return ('0' + dec.toString(16)).substr(-2)
90};
91
92
93/**
94 * Create random identifiers
95 */
96/*
97 * code based on
98 * https://stackoverflow.com/questions/1349404/generate-random-string-characters-in-javascript#8084248
99 */
100function randomID (len) {
101 const arr = new Uint8Array((len || 40) / 2)
102 window.crypto.getRandomValues(arr)
103 return Array.from(arr, _dec2hex).join('')
104};
105
106
107/**
108 * Add option to show passwords.
109 */
110function initTogglePwdVisibility (element) {
111 const el = element.querySelectorAll("input[type=password].show-pwd");
112 for (let x = 0; x < el.length; x++) {
113 const pwd = el[x];
114
115 const a = document.createElement('a');
116 a.classList.add('show-pwd');
117 a.addEventListener('click', function () {
118 if (pwd.getAttribute("type") === "password") {
119 pwd.setAttribute("type", "text");
120 a.classList.add('hide');
121 return;
122 };
123 pwd.setAttribute("type", "password");
124 a.classList.remove('hide');
125 });
126 pwd.parentNode.insertBefore(a, pwd.nextSibling);
127 };
128};
129
130
131/**
132 * Add option to copy to clipboard.
133 */
134function initCopyToClipboard (element) {
135 const el = element.querySelectorAll("input.copy-to-clipboard");
136 for (let x = 0; x < el.length; x++) {
137 const text = el[x];
138 const a = document.createElement('a');
139 a.classList.add('copy-to-clipboard');
140 a.addEventListener('click', function () {
141 let back = false;
142 if (text.getAttribute("type") === 'password') {
143 text.setAttribute("type", "text");
144 back = true;
145 };
146 text.select();
147 text.setSelectionRange(0, 99999);
148 document.execCommand("copy");
149 if (back) {
150 text.setAttribute("type", "password");
151 };
152 });
153 text.parentNode.insertBefore(a, text.nextSibling);
154 };
155};
156
157
158// Todo: That's double now!
159KorAP.API = KorAP.API || {};
160KorAP.Locale = KorAP.Locale || {};
161
162const loc = KorAP.Locale;
163loc.OR = loc.OR || 'or';
164loc.AND = loc.AND || 'and';
165
166// Add new stylesheet object lazily to document
167KorAP.newStyleSheet = function () {
168 if (KorAP._sheet === undefined) {
169 const sElem = document.createElement('style');
170 document.head.appendChild(sElem);
171 KorAP._sheet = sElem.sheet;
172 };
173 return KorAP._sheet;
174};
175
176
177// Default log message
178KorAP.log = KorAP.log || function (type, msg, src) {
179 if (src)
180 msg += ' from ' + src;
181 console.log(type + ": " + msg);
182};
183
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;
218};
219
220export {
221 _removeChildren as removeChildren,
222 _codeFromEvent as codeFromEvent,
223 randomID,
224 initTogglePwdVisibility,
225 initCopyToClipboard,
226 directElementChildrenByTagName,
227 directElementChildrenByClassName
228};
229
230export default KorAP;