common-0.0.1.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /**
  2. * @description Set of short commonly used methods for handling HTML elements
  3. * @author Ylian Saint-Hilaire
  4. * @version v0.0.1b
  5. */
  6. // Add startsWith for IE browser
  7. if (!String.prototype.startsWith) { String.prototype.startsWith = function (str) { return this.lastIndexOf(str, 0) === 0; }; }
  8. if (!String.prototype.endsWith) { String.prototype.endsWith = function (str) { return this.indexOf(str, this.length - str.length) !== -1; }; }
  9. // Quick UI functions, a bit of a replacement for jQuery
  10. //function Q(x) { if (document.getElementById(x) == null) { console.log('Invalid element: ' + x); } return document.getElementById(x); } // "Q"
  11. function Q(x) { return document.getElementById(x); } // "Q"
  12. function QS(x) { try { return Q(x).style; } catch (x) { } } // "Q" style
  13. function QE(x, y) { try { Q(x).disabled = !y; } catch (x) { } } // "Q" enable
  14. function QV(x, y) { try { QS(x).display = (y ? '' : 'none'); } catch (x) { } } // "Q" visible
  15. function QA(x, y) { Q(x).innerHTML += y; } // "Q" append
  16. function QH(x, y) { Q(x).innerHTML = y; } // "Q" html
  17. function QC(x) { try { return Q(x).classList; } catch (x) { } } // "Q" class
  18. function QVH(x, y) { try { y ? Q(x).classList.remove('visually-hidden') : Q(x).classList.add('visually-hidden'); } catch (x) { } } // "Q" visibility
  19. // Move cursor to end of input box
  20. function inputBoxFocus(x) { Q(x).focus(); var v = Q(x).value; Q(x).value = ''; Q(x).value = v; }
  21. // Binary encoding and decoding functions
  22. function ReadShort(v, p) { return (v.charCodeAt(p) << 8) + v.charCodeAt(p + 1); }
  23. function ReadShortX(v, p) { return (v.charCodeAt(p + 1) << 8) + v.charCodeAt(p); }
  24. function ReadInt(v, p) { return (v.charCodeAt(p) * 0x1000000) + (v.charCodeAt(p + 1) << 16) + (v.charCodeAt(p + 2) << 8) + v.charCodeAt(p + 3); } // We use "*0x1000000" instead of "<<24" because the shift converts the number to signed int32.
  25. function ReadSInt(v, p) { return (v.charCodeAt(p) << 24) + (v.charCodeAt(p + 1) << 16) + (v.charCodeAt(p + 2) << 8) + v.charCodeAt(p + 3); }
  26. function ReadIntX(v, p) { return (v.charCodeAt(p + 3) * 0x1000000) + (v.charCodeAt(p + 2) << 16) + (v.charCodeAt(p + 1) << 8) + v.charCodeAt(p); }
  27. function ShortToStr(v) { return String.fromCharCode((v >> 8) & 0xFF, v & 0xFF); }
  28. function ShortToStrX(v) { return String.fromCharCode(v & 0xFF, (v >> 8) & 0xFF); }
  29. function IntToStr(v) { return String.fromCharCode((v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF); }
  30. function IntToStrX(v) { return String.fromCharCode(v & 0xFF, (v >> 8) & 0xFF, (v >> 16) & 0xFF, (v >> 24) & 0xFF); }
  31. function MakeToArray(v) { if (!v || v == null || typeof v == 'object') return v; return [v]; }
  32. function SplitArray(v) { return v.split(','); }
  33. function Clone(v) { return JSON.parse(JSON.stringify(v)); }
  34. function EscapeHtml(x) { if (typeof x == 'string') return x.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;'); if (typeof x == 'boolean') return x; if (typeof x == 'number') return x; }
  35. function EscapeHtmlBreaks(x) { if (typeof x == 'string') return x.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;').replace(/\r/g, '<br />').replace(/\n/g, '').replace(/\t/g, '&nbsp;&nbsp;'); if (typeof x == 'boolean') return x; if (typeof x == 'number') return x; }
  36. // Move an element from one position in an array to a new position
  37. function ArrayElementMove(arr, from, to) { arr.splice(to, 0, arr.splice(from, 1)[0]); };
  38. // Print object for HTML
  39. function ObjectToStringEx(x, c) {
  40. var r = "";
  41. if (x != 0 && (!x || x == null)) return '(Null)';
  42. if (x instanceof Array) { for (var i in x) { r += '<br />' + gap(c) + 'Item #' + i + ": " + ObjectToStringEx(x[i], c + 1); } }
  43. else if (x instanceof Object) { for (var i in x) { r += '<br />' + gap(c) + i + ' = ' + ObjectToStringEx(x[i], c + 1); } }
  44. else { r += EscapeHtml(x); }
  45. return r;
  46. }
  47. // Print object for console
  48. function ObjectToStringEx2(x, c) {
  49. var r = '';
  50. if (x != 0 && (!x || x == null)) return '(Null)';
  51. if (x instanceof Array) { for (var i in x) { r += '\r\n' + gap2(c) + 'Item #' + i + ': ' + ObjectToStringEx2(x[i], c + 1); } }
  52. else if (x instanceof Object) { for (var i in x) { r += '\r\n' + gap2(c) + i + ' = ' + ObjectToStringEx2(x[i], c + 1); } }
  53. else { r += EscapeHtml(x); }
  54. return r;
  55. }
  56. // Create an ident gap
  57. function gap(c) { var x = ''; for (var i = 0; i < (c * 4) ; i++) { x += '&nbsp;'; } return x; }
  58. function gap2(c) { var x = ''; for (var i = 0; i < (c * 4) ; i++) { x += ' '; } return x; }
  59. // Print an object in html
  60. function ObjectToString(x) { return ObjectToStringEx(x, 0); }
  61. function ObjectToString2(x) { return ObjectToStringEx2(x, 0); }
  62. // Convert a hex string to a raw string
  63. function hex2rstr(d) {
  64. if (typeof d != 'string' || d.length == 0) return '';
  65. var r = '', m = ('' + d).match(/../g), t;
  66. while (t = m.shift()) r += String.fromCharCode('0x' + t);
  67. return r
  68. }
  69. // Convert decimal to hex
  70. function char2hex(i) { return (i + 0x100).toString(16).substr(-2).toUpperCase(); }
  71. // Convert a raw string to a hex string
  72. function rstr2hex(input) { var r = '', i; for (i = 0; i < input.length; i++) { r += char2hex(input.charCodeAt(i)); } return r; }
  73. // UTF-8 encoding & decoding functions
  74. function encode_utf8(s) { return unescape(encodeURIComponent(s)); }
  75. function decode_utf8(s) { return decodeURIComponent(escape(s)); }
  76. // Convert a string into a blob
  77. function data2blob(data) {
  78. var bytes = new Array(data.length);
  79. for (var i = 0; i < data.length; i++) bytes[i] = data.charCodeAt(i);
  80. return new Blob([new Uint8Array(bytes)]);
  81. }
  82. // Convert a UTF8 string into a blob
  83. function utf2blob(str) {
  84. var bytes = [], utf8 = unescape(encodeURIComponent(str));
  85. for (var i = 0; i < utf8.length; i++) { bytes.push(utf8.charCodeAt(i)); }
  86. return new Blob([new Uint8Array(bytes)]);
  87. }
  88. // Generate random numbers
  89. function random(max) { return Math.floor(Math.random() * max); }
  90. // Trademarks
  91. function trademarks(x) { return x.replace(/\(R\)/g, '&reg;').replace(/\(TM\)/g, '&trade;'); }
  92. // Pad a number with zeros on the left
  93. function zeroPad(num, c) { if (c == null) { c = 2; } var s = '00000000' + num; return s.substr(s.length - c); }
  94. // String validation
  95. function isAlphaNumeric(str) { if (typeof str == 'number') { return true; } return (str.match(/^[A-Za-z0-9]+$/) != null); };
  96. function isSafeString(str) { return ((typeof str == 'string') && (str.indexOf('<') == -1) && (str.indexOf('>') == -1) && (str.indexOf('&') == -1) && (str.indexOf('"') == -1) && (str.indexOf('\'') == -1) && (str.indexOf('+') == -1) && (str.indexOf('(') == -1) && (str.indexOf(')') == -1) && (str.indexOf('#') == -1) && (str.indexOf('%') == -1) && (str.indexOf(':') == -1)) };
  97. function isSafeString2(str) { return ((typeof str == 'string') && (str.indexOf('<') == -1) && (str.indexOf('>') == -1) && (str.indexOf('&') == -1) && (str.indexOf('"') == -1) && (str.indexOf('\'') == -1) && (str.indexOf('+') == -1) && (str.indexOf('(') == -1) && (str.indexOf(')') == -1) && (str.indexOf('#') == -1) && (str.indexOf('%') == -1)) };
  98. // Parse URL arguments, only keep safe values
  99. function parseUriArgs(decodeUrl) {
  100. var href = window.document.location.href;
  101. if (href.endsWith('#')) { href = href.substring(0, href.length - 1); }
  102. var name, r = {}, parsedUri = href.split(/[\?&|]/);
  103. parsedUri.splice(0, 1);
  104. for (var j in parsedUri) {
  105. var arg = parsedUri[j], i = arg.indexOf('=');
  106. name = arg.substring(0, i);
  107. r[name] = arg.substring(i + 1);
  108. if (decodeUrl) { r[name] = decodeURIComponent(arg.substring(i + 1)); }
  109. if (!isSafeString2(r[name])) { delete r[name]; } else { var x = parseInt(r[name]); if (x == r[name]) { r[name] = x; } }
  110. }
  111. return r;
  112. }
  113. // check_webp_feature:
  114. // 'feature' can be one of 'lossy', 'lossless', 'alpha' or 'animation'.
  115. // 'callback(feature, isSupported)' will be passed back the detection result (in an asynchronous way!)
  116. // From: https://stackoverflow.com/questions/5573096/detecting-webp-support
  117. function check_webp_feature(feature, callback) {
  118. var kTestImages = {
  119. lossy: 'UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA'//,
  120. //lossless: 'UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==',
  121. //alpha: 'UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==',
  122. //animation: 'UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA'
  123. };
  124. var img = new Image();
  125. img.onload = function () {
  126. var result = (img.width > 0) && (img.height > 0);
  127. callback(feature, result);
  128. };
  129. img.onerror = function () {
  130. callback(feature, false);
  131. };
  132. img.src = 'data:image/webp;base64,' + kTestImages[feature];
  133. }
  134. // camelCase converter for JSON
  135. function jsonToCamel(o) {
  136. var newO, origKey, newKey, value
  137. if (o instanceof Array) {
  138. return o.map(function(value) {
  139. if (typeof value === "object") {
  140. value = jsonToCamel(value)
  141. }
  142. return value
  143. })
  144. } else {
  145. newO = {}
  146. for (origKey in o) {
  147. if (o.hasOwnProperty(origKey)) {
  148. newKey = (origKey.charAt(0).toLowerCase() + origKey.slice(1) || origKey).toString()
  149. value = o[origKey]
  150. if (value instanceof Array || (value !== null && value.constructor === Object)) {
  151. value = jsonToCamel(value)
  152. }
  153. newO[newKey] = value
  154. }
  155. }
  156. }
  157. return newO
  158. }
  159. function joinPaths() {
  160. var x = [];
  161. for (var i in arguments) {
  162. var w = arguments[i];
  163. if ((w != null) && (w != '')) {
  164. while (w.endsWith('/') || w.endsWith('\\')) {
  165. w = w.substring(0, w.length - 1);
  166. }
  167. x.push(w);
  168. }
  169. }
  170. return x.join('/');
  171. }