1. 1 : /* eslint-disable @typescript-eslint/no-unused-vars */
  2. 2 : /* eslint-disable @typescript-eslint/no-var-requires */
  3. 3 : /* eslint-disable prefer-rest-params */
  4. 4 : /* eslint-disable @typescript-eslint/triple-slash-reference */
  5. 5 : /// <reference path="globals.d.ts" />
  6. 6 :
  7. 7 : /**
  8. 8 : * Strings
  9. 9 : */
  10. 10 : interface String {
  11. 11 : /**
  12. 12 : * Truncate string
  13. 13 : * @param n sequence number to cut the next sentence
  14. 14 : * @param useWordBoundary true ? subString.substr(0, subString.lastIndexOf(" "))
  15. 15 : * @see https://stackoverflow.com/questions/1199352/smart-way-to-truncate-long-strings
  16. 16 : */
  17. 17 : truncate: (n: number, useWordBoundary: boolean | null) => string;
  18. 18 :
  19. 19 : /**
  20. 20 : * Easy String Match Boolean
  21. 21 : * @description String match result as boolean
  22. 22 : * @param pattern regex or string
  23. 23 : * @returns true or false
  24. 24 : */
  25. 25 : isMatch: (pattern: RegExp | string) => boolean;
  26. 26 :
  27. 27 : /**
  28. 28 : * Replace all occurrences of a string
  29. 29 : * * Shim ES2021 prototype
  30. 30 : * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll}
  31. 31 : */
  32. 32 : replaceAll: (search: string | RegExp, replacement: string) => string;
  33. 33 :
  34. 34 : /**
  35. 35 : * Printf
  36. 36 : * @see {@link https://stackoverflow.com/a/46078375}
  37. 37 : * @example
  38. 38 : * console.log("Hello I am " + "%s %s".printf(["foo", "bar"]));
  39. 39 : */
  40. 40 : printf: (obj: any[] | string) => string;
  41. 41 :
  42. 42 : /**
  43. 43 : * Matches a string an object that supports being matched against, and returns an array containing the results of
  44. 44 : * that search.
  45. 45 : * @param matcher An object that supports being matched against.
  46. 46 : */
  47. 47 : match(matcher: { [Symbol.match](string: string): RegExpMatchArray | null }): RegExpMatchArray | null;
  48. 48 :
  49. 49 : /**
  50. 50 : * Replaces text in a string, using an object that supports replacement within a string.
  51. 51 : * @param searchValue A object can search for and replace matches within a string.
  52. 52 : * @param replaceValue A string containing the text to replace for every successful match of searchValue in this
  53. 53 : * string.
  54. 54 : */
  55. 55 : replace(
  56. 56 : searchValue: {
  57. 57 : [Symbol.replace](string: string, replaceValue: string): string;
  58. 58 : },
  59. 59 : replaceValue: string
  60. 60 : ): string;
  61. 61 :
  62. 62 : /**
  63. 63 : * Replaces text in a string, using an object that supports replacement within a string.
  64. 64 : * @param searchValue A object can search for and replace matches within a string.
  65. 65 : * @param replacer A function that returns the replacement text.
  66. 66 : */
  67. 67 : replace(
  68. 68 : searchValue: {
  69. 69 : [Symbol.replace](string: string, replacer: (substring: string, ...args: any[]) => string): string;
  70. 70 : },
  71. 71 : replacer: (substring: string, ...args: any[]) => string
  72. 72 : ): string;
  73. 73 :
  74. 74 : /**
  75. 75 : * Finds the first substring match in a regular expression search.
  76. 76 : * @param searcher An object which supports searching within a string.
  77. 77 : */
  78. 78 : search(searcher: { [Symbol.search](string: string): number }): number;
  79. 79 :
  80. 80 : /**
  81. 81 : * Split a string into substrings using the specified separator and return them as an array.
  82. 82 : * @param splitter An object that can split a string.
  83. 83 : * @param limit A value used to limit the number of elements returned in the array.
  84. 84 : */
  85. 85 : split(splitter: { [Symbol.split](string: string, limit?: number): string[] }, limit?: number): string[];
  86. 86 :
  87. 87 : /**
  88. 88 : * Parse url into part object
  89. 89 : */
  90. 90 : parse_url(): {
  91. 91 : protocol: string;
  92. 92 : host: string;
  93. 93 : hostname: string;
  94. 94 : port: string;
  95. 95 : pathname: string;
  96. 96 : search: string;
  97. 97 : searchObject: Record<any, any>;
  98. 98 : hash: string;
  99. 99 : protohost: string;
  100. 100 : };
  101. 101 :
  102. 102 : /**
  103. 103 : * Call css from url/path
  104. 104 : */
  105. 105 : CSS(): void;
  106. 106 :
  107. 107 : /**
  108. 108 : * Hex encrypt
  109. 109 : */
  110. 110 : hexE(): string;
  111. 111 :
  112. 112 : /**
  113. 113 : * Hex Decrypt
  114. 114 : */
  115. 115 : hexD(): string;
  116. 116 :
  117. 117 : /**
  118. 118 : * Capitalize all first character string
  119. 119 : * @example [PHP] ucwords($string)
  120. 120 : */
  121. 121 : capitalize(): string;
  122. 122 :
  123. 123 : /**
  124. 124 : * PHP str_rot13 equivalent
  125. 125 : */
  126. 126 : rot13(): string;
  127. 127 :
  128. 128 : /**
  129. 129 : * Check if string empty or blank
  130. 130 : */
  131. 131 : isEmpty(): boolean;
  132. 132 :
  133. 133 : /**
  134. 134 : * Replace string by array pattern
  135. 135 : * @param array
  136. 136 : * @param replacement
  137. 137 : */
  138. 138 : replaceArr(array: string[], replacement: string): string;
  139. 139 :
  140. 140 : /**
  141. 141 : * Convert a string to HTML entities
  142. 142 : * @see {@link https://stackoverflow.com/a/27020300}
  143. 143 : * @example
  144. 144 : * "Test´†®¥¨©˙∫ø…ˆƒ∆÷∑™ƒ∆æøπ£¨ ƒ™en tést".toHtmlEntities();
  145. 145 : * console.log("Entities:", str);
  146. 146 : */
  147. 147 : toHtmlEntities(): string;
  148. 148 :
  149. 149 : /**
  150. 150 : * Check if string contains some text from array of substrings
  151. 151 : * @see {@link https://stackoverflow.com/a/5582621}
  152. 152 : * @param arrayStr
  153. 153 : */
  154. 154 : includesArray(arrayStr: string[]): boolean;
  155. 155 : }
  156. 156 :
  157. 157 : interface StringConstructor {
  158. 158 : /**
  159. 159 : * Create string from HTML entities
  160. 160 : * @see {@link https://stackoverflow.com/a/27020300}
  161. 161 : * @example
  162. 162 : * var str = "Test´†®¥¨©˙∫ø…ˆƒ∆÷∑™ƒ∆æøπ£¨ ƒ™en tést".toHtmlEntities();
  163. 163 : * console.log("String:", String.fromHtmlEntities(str));
  164. 164 : */
  165. 165 : fromHtmlEntities(str: string): string;
  166. 166 : }
  167. 167 :
  168. 168 : String.prototype.printf = function (obj) {
  169. 169 : /*const isNode = new Function(
  170. 170 : "try {return this===global;}catch(e){return false;}"
  171. 171 : );
  172. 172 :
  173. 173 : if (isNode()) {
  174. 174 : const util = require("util");
  175. 175 : return util.format(this, obj);
  176. 176 : }*/
  177. 177 :
  178. 178 : let useArguments = false;
  179. 179 : const _arguments = arguments;
  180. 180 : let i = -1;
  181. 181 : if (typeof _arguments[0] == 'string') {
  182. 182 : useArguments = true;
  183. 183 : }
  184. 184 : if (obj instanceof Array || useArguments) {
  185. 185 : return this.replace(/%s/g, function (a, b) {
  186. 186 : i++;
  187. 187 : if (useArguments) {
  188. 188 : if (typeof _arguments[i] == 'string') {
  189. 189 : return _arguments[i];
  190. 190 : } else {
  191. 191 : throw new Error('Arguments element is an invalid type');
  192. 192 : }
  193. 193 : }
  194. 194 : return obj[i];
  195. 195 : });
  196. 196 : } else {
  197. 197 : return this.replace(/{([^{}]*)}/g, function (a, b) {
  198. 198 : const r = obj[b];
  199. 199 : return typeof r === 'string' || typeof r === 'number' ? r : a;
  200. 200 : });
  201. 201 : }
  202. 202 : };
  203. 203 :
  204. 204 : String.prototype.parse_url = function () {
  205. 205 : let parser: URL | HTMLAnchorElement;
  206. 206 : if (typeof module != 'undefined' && module.exports) {
  207. 207 : parser = new URL(this);
  208. 208 : } else if (typeof document != 'undefined') {
  209. 209 : parser = document.createElement('a');
  210. 210 : }
  211. 211 : const searchObject: Array<Record<any, any> | any> = [];
  212. 212 : let split: Array<Record<any, any> | any> = [];
  213. 213 : let queries: string[] = [];
  214. 214 : // Let the browser do the work
  215. 215 : parser.href = this.toString();
  216. 216 : // Convert query string to object
  217. 217 : queries = parser.search.replace(/^\?/, '').split('&');
  218. 218 : for (let i = 0; i < queries.length; i++) {
  219. 219 : split = queries[i].split('=');
  220. 220 : if (split.length) searchObject[split[0]] = split[1];
  221. 221 : }
  222. 222 : return {
  223. 223 : protocol: parser.protocol,
  224. 224 : host: parser.host,
  225. 225 : hostname: parser.hostname,
  226. 226 : port: parser.port,
  227. 227 : pathname: parser.pathname,
  228. 228 : search: parser.search,
  229. 229 : searchObject: searchObject,
  230. 230 : hash: parser.hash,
  231. 231 : protohost: parser.protocol + '//' + parser.host,
  232. 232 : };
  233. 233 : };
  234. 234 :
  235. 235 : /**
  236. 236 : * Load css
  237. 237 : */
  238. 238 : String.prototype.CSS = function () {
  239. 239 : const e = document.createElement('link');
  240. 240 : e.rel = 'stylesheet';
  241. 241 :
  242. 242 : e.href = this.toString();
  243. 243 : const n = document.getElementsByTagName('head')[0];
  244. 244 : window.addEventListener
  245. 245 : ? window.addEventListener(
  246. 246 : 'load',
  247. 247 : function () {
  248. 248 : n.parentNode.insertBefore(e, n);
  249. 249 : },
  250. 250 : !1
  251. 251 : )
  252. 252 : : window.attachEvent
  253. 253 : ? window.attachEvent('onload', function () {
  254. 254 : n.parentNode.insertBefore(e, n);
  255. 255 : })
  256. 256 : : (window.onload = function () {
  257. 257 : n.parentNode.insertBefore(e, n);
  258. 258 : });
  259. 259 : };
  260. 260 :
  261. 261 : String.prototype.trim = function () {
  262. 262 : return this.replace(/^\s+|\s+$/gm, '');
  263. 263 : };
  264. 264 :
  265. 265 : String.prototype.hexE = function () {
  266. 266 : let hex: string, i: number;
  267. 267 :
  268. 268 : let result = '';
  269. 269 : for (i = 0; i < this.length; i++) {
  270. 270 : hex = this.charCodeAt(i).toString(16);
  271. 271 : result += ('000' + hex).slice(-4);
  272. 272 : }
  273. 273 :
  274. 274 : return result;
  275. 275 : };
  276. 276 :
  277. 277 : String.prototype.hexD = function () {
  278. 278 : let j: number;
  279. 279 : const hexes = this.match(/.{1,4}/g) || [];
  280. 280 : let back = '';
  281. 281 : for (j = 0; j < hexes.length; j++) {
  282. 282 : back += String.fromCharCode(parseInt(hexes[j], 16));
  283. 283 : }
  284. 284 :
  285. 285 : return back;
  286. 286 : };
  287. 287 :
  288. 288 : String.prototype.capitalize = function () {
  289. 289 : return this.charAt(0).toUpperCase() + this.slice(1);
  290. 290 : };
  291. 291 :
  292. 292 : String.prototype.rot13 = function () {
  293. 293 : return this.replace(/[a-zA-Z]/g, function (c: any) {
  294. 294 : return String.fromCharCode((c <= 'Z' ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);
  295. 295 : });
  296. 296 : };
  297. 297 :
  298. 298 : String.prototype.truncate = function (n: number, useWordBoundary: boolean | null) {
  299. 299 : if (this.length <= n) {
  300. 300 : return this;
  301. 301 : }
  302. 302 : const subString = this.substr(0, n - 1); // the original check
  303. 303 : return (useWordBoundary ? subString.substr(0, subString.lastIndexOf(' ')) : subString) + '&hellip;';
  304. 304 : };
  305. 305 :
  306. 306 : String.prototype.isEmpty = function () {
  307. 307 : if (this != null || typeof this != 'undefined') {
  308. 308 : return this.length === 0 || !this.trim();
  309. 309 : }
  310. 310 : return false;
  311. 311 : };
  312. 312 :
  313. 313 : String.prototype.replaceArr = function (this: string, array: string[], replacement: string) {
  314. 314 : // eslint-disable-next-line @typescript-eslint/no-this-alias
  315. 315 : let ori = this;
  316. 316 : array.map((str) => {
  317. 317 : ori = ori.replace(str, replacement);
  318. 318 : });
  319. 319 : return ori;
  320. 320 : };
  321. 321 :
  322. 322 : String.prototype.toHtmlEntities = function () {
  323. 323 : return this.replace(/./gm, function (s) {
  324. 324 : // return "&#" + s.charCodeAt(0) + ";";
  325. 325 : return s.match(/[a-z0-9\s]+/i) ? s : '&#' + s.charCodeAt(0) + ';';
  326. 326 : });
  327. 327 : };
  328. 328 :
  329. 329 : String.fromHtmlEntities = function (str) {
  330. 330 : return (str + '').replace(/&#\d+;/gm, function (s) {
  331. 331 : const m = s.match(/\d+/gm)[0];
  332. 332 : return String.fromCharCode(<any>m);
  333. 333 : });
  334. 334 : };
  335. 335 :
  336. 336 : String.prototype.includesArray = function (substrings) {
  337. 337 : return substrings.some((v) => this.includes(v));
  338. 338 : };
  339. 339 :
  340. 340 : const ___global = (typeof window != 'undefined' ? window : global) /* node */ as any;
  341. 341 :
  342. 342 : /**
  343. 343 : * easy regex match
  344. 344 : * @param str
  345. 345 : * @param pattern
  346. 346 : * @returns
  347. 347 : */
  348. 348 : function strMatch(str: string, pattern: RegExp | string) {
  349. 349 : let regex: RegExp;
  350. 350 : if (typeof pattern == 'string') {
  351. 351 : regex = new RegExp(pattern, 'gm');
  352. 352 : } else {
  353. 353 : regex = pattern;
  354. 354 : }
  355. 355 : const match = str.match(regex) || false;
  356. 356 : if (Array.isArray(match)) {
  357. 357 : if (match.length > 0) return true;
  358. 358 : }
  359. 359 : return false;
  360. 360 : }
  361. 361 : ___global.strMatch = strMatch;
  362. 362 :
  363. 363 : String.prototype.isMatch = function (this: string, pattern) {
  364. 364 : return strMatch(this, pattern);
  365. 365 : };
  366. 366 :
  367. 367 : if (typeof ''.replaceAll != 'function') {
  368. 368 : String.prototype.replaceAll = function (search, replacement) {
  369. 369 : const find = typeof search == 'string' ? new RegExp(search, 'gm') : search;
  370. 370 : return this.replace(find, replacement);
  371. 371 : };
  372. 372 : }