Rev 1000 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
982 | daniel-mar | 1 | /* |
2 | * OIDplus 2.0 |
||
3 | * Copyright 2019 - 2022 Daniel Marschall, ViaThinkSoft |
||
4 | * |
||
5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
||
6 | * you may not use this file except in compliance with the License. |
||
7 | * You may obtain a copy of the License at |
||
8 | * |
||
9 | * http://www.apache.org/licenses/LICENSE-2.0 |
||
10 | * |
||
11 | * Unless required by applicable law or agreed to in writing, software |
||
12 | * distributed under the License is distributed on an "AS IS" BASIS, |
||
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||
14 | * See the License for the specific language governing permissions and |
||
15 | * limitations under the License. |
||
16 | */ |
||
17 | |||
18 | /*jshint esversion: 6 */ |
||
19 | |||
20 | /* Misc functions */ |
||
21 | |||
22 | function htmlDecodeWithLineBreaks(html) { |
||
23 | // https://stackoverflow.com/questions/4502673/jquery-text-function-loses-line-breaks-in-ie |
||
996 | daniel-mar | 24 | // Added ".replace(/ /g,'')" because of GitHub bug #3 |
982 | daniel-mar | 25 | var breakToken = '_______break_______'; |
1000 | daniel-mar | 26 | var lineBreakedHtml = html.replace(/ /g,' ').replace(/ /g,' ').replace(/<br\s?\/?>/gi, breakToken).replace(/<p\.*?>(.*?)<\/p>/gi, breakToken + '$1' + breakToken); |
982 | daniel-mar | 27 | return $('<div>').html(lineBreakedHtml).text().replace(new RegExp(breakToken, 'g'), '\n'); |
28 | } |
||
29 | |||
30 | function copyToClipboard(elem) { |
||
31 | // Source: https://stackoverflow.com/questions/22581345/click-button-copy-to-clipboard-using-jquery |
||
32 | // Modified (see below) |
||
33 | |||
985 | daniel-mar | 34 | // TODO: this function causes the page to scroll! |
35 | |||
982 | daniel-mar | 36 | // create hidden text element, if it doesn't already exist |
37 | var targetId = "_hiddenCopyText_"; |
||
38 | var isInput = elem.tagName === "INPUT" || elem.tagName === "TEXTAREA"; |
||
39 | var origSelectionStart, origSelectionEnd; |
||
40 | if (isInput) { |
||
41 | // can just use the original source element for the selection and copy |
||
42 | target = elem; |
||
43 | origSelectionStart = elem.selectionStart; |
||
44 | origSelectionEnd = elem.selectionEnd; |
||
45 | } else { |
||
46 | // must use a temporary form element for the selection and copy |
||
47 | target = document.getElementById(targetId); |
||
48 | if (!target) { |
||
49 | var target = document.createElement("textarea"); |
||
50 | target.style.position = "absolute"; |
||
51 | target.style.left = "-9999px"; |
||
52 | target.style.top = "0"; |
||
53 | target.id = targetId; |
||
54 | document.body.appendChild(target); |
||
55 | } |
||
56 | |||
57 | // Changed by Daniel Marschall, 3 Oct 2022 |
||
58 | // "textContent" will swallow the line breaks of a <div>xx<br>xx</div> |
||
59 | // htmlDecodeWithLineBreaks convert <br> to linebreaks but strips the other |
||
60 | // HTML tags. |
||
61 | // target.textContent = elem.textContent; |
||
62 | target.textContent = htmlDecodeWithLineBreaks(elem.innerHTML); |
||
63 | } |
||
64 | // select the content |
||
65 | var currentFocus = document.activeElement; |
||
66 | target.focus(); |
||
67 | target.setSelectionRange(0, target.value.length); |
||
68 | |||
69 | // copy the selection |
||
70 | var succeed; |
||
71 | try { |
||
72 | succeed = document.execCommand("copy"); |
||
73 | } catch(e) { |
||
74 | succeed = false; |
||
75 | } |
||
76 | // restore original focus |
||
77 | if (currentFocus && typeof currentFocus.focus === "function") { |
||
78 | currentFocus.focus(); |
||
79 | } |
||
80 | |||
81 | if (isInput) { |
||
82 | // restore prior selection |
||
83 | elem.setSelectionRange(origSelectionStart, origSelectionEnd); |
||
84 | } else { |
||
85 | // clear temporary content |
||
86 | target.textContent = ""; |
||
87 | } |
||
88 | return succeed; |
||
89 | } |
||
90 | |||
91 | function isInternetExplorer() { |
||
92 | // see also includes/functions.inc.php |
||
93 | var ua = window.navigator.userAgent; |
||
94 | return ((ua.indexOf("MSIE ") > 0) || (ua.indexOf("Trident/") > 0)); |
||
95 | } |
||
96 | |||
97 | function getMeta(metaName) { |
||
98 | const metas = $('meta[name='+metaName+']'); |
||
99 | return (metas.length == 0) ? '' : metas[0].content; |
||
100 | } |
||
101 | |||
102 | String.prototype.explode = function (separator, limit) { |
||
103 | // https://stackoverflow.com/questions/4514323/javascript-equivalent-to-php-explode |
||
104 | const array = this.split(separator); |
||
105 | if (limit !== undefined && array.length >= limit) { |
||
106 | array.push(array.splice(limit - 1).join(separator)); |
||
107 | } |
||
108 | return array; |
||
109 | }; |
||
110 | |||
111 | String.prototype.htmlentities = function () { |
||
112 | return this.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');//" |
||
113 | }; |
||
114 | |||
115 | String.prototype.html_entity_decode = function () { |
||
116 | return $('<textarea />').html(this).text(); |
||
117 | }; |
||
118 | |||
119 | if (!String.prototype.replaceAll) { |
||
120 | /** |
||
121 | * String.prototype.replaceAll() polyfill |
||
122 | * https://gomakethings.com/how-to-replace-a-section-of-a-string-with-another-one-with-vanilla-js/ |
||
123 | * @author Chris Ferdinandi |
||
124 | * @license MIT |
||
125 | */ |
||
126 | String.prototype.replaceAll = function(str, newStr){ |
||
127 | // If a regex pattern |
||
128 | if (Object.prototype.toString.call(str).toLowerCase() === '[object regexp]') { |
||
129 | return this.replace(str, newStr); |
||
130 | } |
||
131 | // If a string |
||
132 | return this.replace(new RegExp(str, 'g'), newStr); |
||
133 | }; |
||
134 | } |
||
135 | |||
136 | if (!String.prototype.startsWith) { |
||
137 | // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith#polyfill |
||
138 | Object.defineProperty(String.prototype, 'startsWith', { |
||
139 | value: function(search, rawPos) { |
||
140 | var pos = rawPos > 0 ? rawPos|0 : 0; |
||
141 | return this.substring(pos, pos + search.length) === search; |
||
142 | } |
||
143 | }); |
||
144 | } |
||
145 | |||
146 | |||
147 | |||
148 | |||
149 | function jumpToAnchor(anchor) { |
||
150 | window.location.href = "#" + anchor; |
||
151 | } |
||
152 | |||
153 | function getCookie(cname) { |
||
154 | // Source: https://www.w3schools.com/js/js_cookies.asp |
||
155 | var name = cname + "="; |
||
156 | var decodedCookie = decodeURIComponent(document.cookie); |
||
157 | var ca = decodedCookie.split(';'); |
||
158 | for(var i = 0; i <ca.length; i++) { |
||
159 | var c = ca[i]; |
||
160 | while (c.charAt(0) == ' ') { |
||
161 | c = c.substring(1); |
||
162 | } |
||
163 | if (c.indexOf(name) == 0) { |
||
164 | return c.substring(name.length, c.length); |
||
165 | } |
||
166 | } |
||
167 | return undefined; |
||
168 | } |
||
169 | |||
170 | function setCookie(cname, cvalue, exdays, path) { |
||
171 | var d = new Date(); |
||
172 | d.setTime(d.getTime() + (exdays*24*60*60*1000)); |
||
173 | var expires = exdays == 0 ? "" : "; expires="+d.toUTCString(); |
||
174 | document.cookie = cname + "=" + cvalue + expires + ";path=" + path + ";SameSite=" + samesite_policy; |
||
175 | } |
||
176 | |||
177 | |||
178 | |||
179 | function isNull(val, def) { |
||
180 | // For compatibility with Internet Explorer, use isNull(a,b) instead of a??b |
||
181 | if (val == null) { |
||
182 | // since null==undefined, this also works with undefined |
||
183 | return def; |
||
184 | } else { |
||
185 | return val; |
||
186 | } |
||
187 | } |
||
188 | |||
189 | function btoa(bin) { |
||
190 | var tableStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
||
191 | var table = tableStr.split(""); |
||
192 | for (var i = 0, j = 0, len = bin.length / 3, base64 = []; i < len; ++i) { |
||
193 | var a = bin.charCodeAt(j++), b = bin.charCodeAt(j++), c = bin.charCodeAt(j++); |
||
194 | if ((a | b | c) > 255) throw new Error(_L('String contains an invalid character')); |
||
195 | base64[base64.length] = table[a >> 2] + table[((a << 4) & 63) | (b >> 4)] + |
||
196 | (isNaN(b) ? "=" : table[((b << 2) & 63) | (c >> 6)]) + |
||
197 | (isNaN(b + c) ? "=" : table[c & 63]); |
||
198 | } |
||
199 | return base64.join(""); |
||
200 | }; |
||
201 | |||
202 | function hexToBase64(str) { |
||
203 | return btoa(String.fromCharCode.apply(null, |
||
204 | str.replace(/\r|\n/g, "").replace(/([\da-fA-F]{2}) ?/g, "0x$1 ").replace(/ +$/, "").split(" "))); |
||
205 | } |
||
206 | |||
207 | function _b64EncodeUnicode(str) { |
||
208 | if (str == "") { |
||
209 | return "''"; |
||
210 | } else { |
||
211 | return "base64_decode('"+b64EncodeUnicode(str)+"')"; |
||
212 | } |
||
213 | } |
||
214 | |||
215 | function b64EncodeUnicode(str) { |
||
216 | // first we use encodeURIComponent to get percent-encoded UTF-8, |
||
217 | // then we convert the percent encodings into raw bytes which |
||
218 | // can be fed into btoa. |
||
219 | return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, |
||
220 | function toSolidBytes(match, p1) { |
||
221 | return String.fromCharCode('0x' + p1); |
||
222 | })); |
||
223 | } |
||
224 | |||
225 | function generateRandomString(length) { |
||
226 | var charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", |
||
227 | retVal = ""; |
||
228 | for (var i = 0, n = charset.length; i < length; ++i) { |
||
229 | retVal += charset.charAt(Math.floor(Math.random() * n)); |
||
230 | } |
||
231 | return retVal; |
||
232 | } |
||
233 | |||
234 | function RemoveLastDirectoryPartOf(the_url) { |
||
235 | var the_arr = the_url.split('/'); |
||
236 | if (the_arr.pop() == '') the_arr.pop(); |
||
237 | return( the_arr.join('/') ); |
||
238 | } |
||
239 | |||
1173 | daniel-mar | 240 | function jsString(str) { |
241 | return "'" + str.replace("'", "\\'") + "'"; |
||
242 | } |