Issues (994)

libs/js/utility.js (12 issues)

1
if (!(typeof module !== "undefined" && module.exports)) {
2
  /**
3
   * @todo Auto replace placeholder textarea newLines
4
   */
5
  var textAreas = document.getElementsByTagName("textarea");
6
  Array.prototype.forEach.call(textAreas, function (elem) {
7
    elem.placeholder = elem.placeholder.replace(/\\n/g, "\n");
8
  });
9
10
  /**
11
   * @todo Disable hotkey
12
   */
13
  $(document).bind("keydown", function (e) {
14
    e = e || window.event;
15
    if (e.ctrlKey && e.which == 83) {
16
      e.preventDefault();
17
      toastr.info("CTRL+S disabled", "Hotkey");
18
      return false;
19
    } else if ((e.keyCode == 82 && e.ctrlKey) || e.keyCode == 116) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if e.keyCode == 82 && e.ctrlKey || e.keyCode == 116 is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
20
      e.preventDefault();
21
      document.location.reload(true);
22
      return false;
23
    }
24
  });
25
26
  /**
27
   * @todo Textarea placeholders
28
   */
29
  $("textarea").each(function (index, el) {
30
    if ($(this).val().toString().length) return;
31
    var placeholder = $(this).attr("placeholder");
32
    $(this).removeAttr("placeholder");
33
    var id = $(this).attr("id");
34
    if (!id || id.length == 0) {
35
      id = makeid(5);
36
      $(this).attr("id", id);
37
    }
38
    $(this).val(formatNewLines(placeholder));
39
    tafocus("#" + id, placeholder);
40
  });
41
42
  /**
43
   * @todo datatables select2 jquery tooltip
44
   */
45
  $(document).ready(function () {
46
    /** Tooltip */
47
    if (jQuery.fn.tooltip && $('[data-toggle="tooltip"]')) {
48
      $("body").tooltip({
49
        selector: '[data-toggle="tooltip"]',
50
      });
51
      //$('[data-toggle="tooltip"]').tooltip();
52
53
      // colored tooltip
54
55
      $('[data-toggle="tooltip-primary"]').tooltip({
56
        template:
57
          '<div class="tooltip tooltip-primary" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>',
58
      });
59
60
      $('[data-toggle="tooltip-secondary"]').tooltip({
61
        template:
62
          '<div class="tooltip tooltip-secondary" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>',
63
      });
64
65
      $('[data-toggle="tooltip-danger"]').tooltip({
66
        template:
67
          '<div class="tooltip tooltip-danger" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>',
68
      });
69
    }
70
71
    /** datatables */
72
    if (jQuery.fn.DataTable && $("#datatable1").length) {
73
      $("#datatable1").DataTable({
74
        responsive: true,
75
        language: {
76
          searchPlaceholder: "Search...",
77
78
          sSearch: "",
79
          lengthMenu: "_MENU_ items/page",
80
        },
81
      });
82
    }
83
84
    /** Select2 */
85
    var ds = $(".dataTables_length select");
86
    if (typeof jQuery.fn.select2 != "undefined") {
87
      if (ds.length || ds.data("select2")) {
88
        ds.select2({
89
          minimumResultsForSearch: Infinity,
90
        });
91
      }
92
    }
93
  });
94
}
95
96
/**
97
 * textarea focus
98
 * @param {String} id
99
 * @param {String} placeholder
100
 */
101
function tafocus(id, placeholder) {
102
  var count_newlines = countNewLines(placeholder);
103
104
  $(id).on("focus", function (e) {
105
    var count_length = $(this).val().length;
106
    if (count_length === count_newlines || $(this).val() == placeholder) {
107
      $(this).val("");
108
    }
109
  });
110
111
  $(id).on("blur", function (e) {
112
    var count_length = $(this).val().length;
113
    if (!count_length) {
114
      $(this).val(formatNewLines(placeholder));
115
    }
116
  });
117
}
118
119
/**
120
 * format new lines
121
 * @param {String} placeholder
122
 */
123
function formatNewLines(placeholder) {
124
  for (let index = 0; index < 1000; index++) {
125
    if (!placeholder) break;
126
    placeholder = placeholder.replace("\\n", "\n");
127
    if (!placeholder.match(/\\n/g)) {
128
      break;
129
    }
130
  }
131
  return placeholder;
132
}
133
134
/**
135
 * Count newLines
136
 * @param {String} placeholder
137
 */
138
function countNewLines(placeholder) {
139
  if (!placeholder) return placeholder;
140
  var match = placeholder.match(/\\n/g) || "";
141
  return placeholder.length - match.length;
142
}
143
144
/**
145
 * find duplicate array
146
 * @param {Array<any>} arr
147
 * @param {Function} callback
148
 */
149
function findDups(arr, callback) {
150
  var sorted_arr = arr.slice().sort();
151
  var results = [];
152
  for (var i = 0; i < sorted_arr.length - 1; i++) {
153
    if (sorted_arr[i + 1] == sorted_arr[i]) {
154
      results[i] = sorted_arr[i];
155
    }
156
  }
157
  if (typeof callback == "function") {
158
    return callback(results);
159
  } else {
160
    return results;
161
  }
162
}
163
164
//=========== Auto id
165
/**
166
 * Auto Generate ID
167
 * @param {Number} length
168
 */
169
function makeid(length) {
170
  var result = "";
171
  var characters =
172
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
173
  var charactersLength = characters.length;
174
  for (var i = 0; i < length; i++) {
175
    result += characters.charAt(Math.floor(Math.random() * charactersLength));
176
  }
177
  return result;
178
}
179
180
//=========== RECAPTCHA
181
/**
182
 * load or refreshing google recaptcha
183
 */
184
function gexec(action, retry, callback) {
185
  recaptcha().exec(action, retry, callback);
186
}
187
/**
188
 * Get token recaptcha
189
 */
190
function geToken() {
191
  return recaptcha().get();
192
}
193
194
/**
195
 * Javascript caller
196
 * @param {String} url
197
 * @param {Function} callback
198
 */
199
function JavaScriptCaller(url, callback) {
200
  var script = document.createElement("script");
201
  script.type = "text/javascript";
202
203 View Code Duplication
  if (script.readyState) {
204
    //IE
205
    script.onreadystatechange = function () {
206
      if (script.readyState == "loaded" || script.readyState == "complete") {
207
        script.onreadystatechange = null;
208
        if (typeof callback == "function") {
209
          callback();
210
        }
211
      }
212
    };
213
  } else {
214
    //Others
215
    script.onload = function () {
216
      if (typeof callback == "function") {
217
        callback();
218
      }
219
    };
220
  }
221
222
  script.src = url;
223
  document.getElementsByTagName("head")[0].appendChild(script);
224
}
225
226
/**
227
 * Function initialization
228
 */
229
230
if (!isnode()) {
231
  if ($("#logout").length) {
232
    $(document).one("click", "#logout", function (e) {
233
      e.preventDefault();
234
      jQuery.post(
235
        location.href,
236
        {
237
          logout: true,
238
        },
239
        function () {
240
          jQuery.get($(this).attr("href"));
241
242
          window.location.reload(1);
243
        }
244
      );
245
    });
246
  }
247
248
  /** Query URL */
249
  function getLocationHash() {
0 ignored issues
show
The function getLocationHash is declared conditionally. This is not supported by all runtimes. Consider moving it to root scope or using var getLocationHash = function() { /* ... */ }; instead.
Loading history...
250
    var hash = window.location.hash.substr(1);
251
252
    var result = hash.split("&").reduce(function (result, item) {
253
      var parts = item.split("=");
254
      result[parts[0]] = parts[1];
255
      return result;
256
    }, {});
257
258
    if (hash.length > 1) {
259
      console.log(result);
0 ignored issues
show
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
260
    }
261
  }
262
263
  /** datetime-local */
264
  if (
265
    typeof dimas == "object" &&
266
    typeof framework().datetimelocal != "undefined"
267
  ) {
268
    framework().datetimelocal(undefined);
269
  }
270
271
  /** Progress bar */
272
  var elm = $("[countdown]");
273
  if (elm.length) {
274
    elm.each(function (e) {
275
      var t = $(this);
276
      framework().pctd(t);
277
    });
278
  }
279
280
  /** document body listener */
281
  $(document.body).on("click", "[data-redirect]", function (E) {
282
    var red = $(this).attr("data-redirect").toString();
283
    if (red && red.trim() != "") {
284
      window.open(red, location.host).focus();
285
    }
286
  });
287
288
  /** Linkify */
289
  if (typeof mask_link != "undefined") {
290
    /**
291
     * @type {JQuery<HTMLElement>} L
292
     */
293
    var L = $("[data-linkify]").length ? $("[data-linkify]") : $(document.body);
294
    window.onload = function () {
295
      L.linkify({
296
        target: "_blank",
297
        attributes: null,
298
        className: "linkified",
299
300
        format: function (value, type) {
301
          return value;
302
        },
303
304
        formatHref: function (href, type) {
305
          return (
306
            "/youtube/s/" +
307
            btoa(
308
              CryptoJS.AES.encrypt(
309
                href,
310
                typeof hash_pass != "undefined" ? hash_pass : location.host
311
              )
312
            )
313
          );
314
        },
315
      });
316
    };
317
  }
318
319
  /**
320
   * links new tab form submit
321
   */
322
  var aform = $("[form]");
323
  if (aform.length > 1) {
324
    aform.click(function (e) {
325
      e.preventDefault();
326
      var id_form = $(this).attr("form");
327
      if (typeof id_form != "undefined") {
328
        var winame = document.getElementById(id_form).getAttribute("target"); //reduce caching
329
        console.log("Submiting Form ID#" + id_form);
0 ignored issues
show
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
330
        window.open("", winame.length ? winame : "FormDynamic").focus();
331
        document.getElementById($(this).attr("form")).submit();
332
      }
333
      //w = window.open('', 'bagas31-post');
334
      //$('form#' + $(this).attr('form')).submit();
335
      //w.focus();
336
    });
337
  }
338
}
339
340
/**
341
 * get currency symbol from navigator
342
 */
343
function get_currency_symbol() {
344
  var amount = 0;
345
  var ident = navigator.language;
346
  var currency_type;
347
  switch (ident) {
348
    case "de-DE":
349
      currency_type = "EUR";
350
      break;
351
    case "id-ID":
352
      currency_type = "IDR";
353
      break;
354
    default:
355
      currency_type = "USD";
356
      break;
357
  }
358
  var format = amount.toLocaleString(ident, {
359
    style: "currency",
360
    currency: currency_type,
361
  });
362
  return format.toString().replace("0,00", "");
363
}
364
365
/**
366
 * Create JSON
367
 * @param {any} jsObj
368
 * @param {boolean} tabs
369
 */
370
function createJSON(jsObj, tabs) {
371
  if (tabs) {
372
    return JSON.stringify(jsObj, null, "\t"); // stringify with tabs inserted at each level
373
  } else {
374
    return JSON.stringify(jsObj, null, 4); // stringify with 4 spaces at each level}
375
  }
376
}
377
378
function loadingio(text, callback, mode) {
379
  if (typeof text == "undefined" || typeof text == "boolean" || !text) {
380
    text = "Please wait";
381
  }
382
  text.toString().toUpperCase();
383
  if (document.getElementById("loadingio-wrapper")) {
384
    if (mode == "disabled" || mode == "disable") {
385
      document.getElementById("loadingio-wrapper").classList.remove("running");
386
    } else if (
387
      typeof mode == "undefined" ||
388
      (typeof mode != "undefined" && (mode == "enable" || mode == "enabled"))
389
    ) {
390
      document.getElementById("loadingio-text").innerHTML = text;
391
      document.getElementById("loadingio-wrapper").classList.toggle("running");
392
    }
393
  } else {
394
    var elemDiv = document.createElement("div");
395
    elemDiv.innerHTML =
396
      '<div id="loadingio-wrapper" class="ld-over-full running"><span class="ld"><span class="ld ld-ball ld-bounce"></span><span id="loadingio-text" class="text pt-3">' +
397
      text +
398
      '<div class="spinner"><div class="bounce1"></div><div class="bounce2"></div><div class="bounce3"></div></div></span></span></div>';
399
    document.body.appendChild(elemDiv);
400
  }
401
402
  if (typeof callback == "function") {
403
    callback(arguments);
404
  }
405
}
406
407
/**
408
function target(a) {
409
    alert(a);
410
}
411
412
var o = {
413
    suffix: " World",
414
    target: function(s) { alert(s + this.suffix); }
415
};
416
417
__call("target", "Hello");
418
419
__call.call(o, "target", "Hello");
420
 */
421
422
/**
423
 * parse proxy from string
424
 * @param {string} str
425
 * @return {Array<any>} proxy list filtered
426
 */
427
function parse_proxy(str) {
428
  var matchs,
0 ignored issues
show
The variable matchs seems to be never used. Consider removing it.
Loading history...
429
    px = [];
430
  loadingio("Parsing proxies", function () {
431
    /*
432
    while (match = /([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}):?([0-9]{1,6})?/g.exec(str)) {
433
      console.log('Match: "' + match[0] + '" first group: -> "' + match[1] + '" second group -> ' + match[2]);
434
      if (typeof match[0] != 'undefined' && typeof match[2] != 'undefined' && !inArray(match[0], px)) {
435
        px.push(match[0]);
436
      }
437
    }
438
    */
439
    if (typeof str == "string") {
440
      var regex = /[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\:[0-9]{1,6}/gm,
441
        match,
442
        proxyMatch;
443
      while ((match = regex.exec(str))) {
444
        proxyMatch = match[0];
445
        //console.log(proxyMatch);
446
        if (proxyMatch.includes(":") && !inArray(proxyMatch, px)) {
447
          px.push(proxyMatch);
448
        }
449
      }
450
      var regex = /Proxy\([\'\"]([a-zA-Z0-9\=]*)[\'\"]\)/gm,
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable regex already seems to be declared on line 440. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
451
        match,
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable match already seems to be declared on line 441. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
452
        proxyMatch;
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable proxyMatch already seems to be declared on line 442. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
453
      while ((match = regex.exec(str))) {
454
        proxyMatch = atob(match[1]);
455
        //console.log(proxyMatch);
456
        if (proxyMatch.includes(":") && !inArray(proxyMatch, px)) {
457
          px.push(proxyMatch);
458
        }
459
      }
460
    }
461
    loadingio(null, null, "disabled");
462
    return px;
463
  });
464
465
  return array_shuffle(array_unique(px));
466
}
467
468
/**
469
 * Add class if not exists
470
 * @param {Element} element element from DOM
471
 * @param {string} className class name
472
 */
473
function toogleClass(element, className) {
474
  return element.classList.toggle(className);
475
}
476
477
function UNIQUE_ID() {
478
  // Math.random should be unique because of its seeding algorithm.
479
  // Convert it to base 36 (numbers + letters), and grab the first 9 characters
480
  // after the decimal.
481
  return "_" + Math.random().toString(36).substr(2, 9);
482
}
483
484
/**
485
 * jQuery pseudo builder
486
 * @param {string} string
487
 */
488
function pseudo_builder(string) {
489
  if (string) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if string is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
490
    return string.replace(/[\W\s]/gm, "");
491
  }
492
}
493
494
/**
495
 * Loop key value of object
496
 * @param {Object} object
497
 * @param {Function} callback
498
 */
499
function foreach(object, callback) {
500
  var key, value;
0 ignored issues
show
The variable value seems to be never used. Consider removing it.
Loading history...
501
  Object.keys(object).forEach(function (key) {
502
    if (typeof callback == "function") {
503
      callback(key, object[key]);
504
    }
505
  });
506
  /*
507
    for ([key, value] of Object.entries(object)) {
508
      if (typeof callback == 'function'){
509
        callback(key, value);
510
      } else {
511
        console.log(key, value);
512
      }
513
    }
514
  */
515
}
516
517
/**
518
 * Get multiple random element from array
519
 * @param {Array<any>} arr array sources
520
 * @param {Number} n maximum element to be in result
521
 * @param {Function} callback function to process result
522
 */
523
function getRandom(arr, n, callback) {
524
  var result = new Array(n),
525
    len = arr.length,
526
    taken = new Array(len);
0 ignored issues
show
Coding Style Best Practice introduced by
Using the Array constructor is generally discouraged. Consider using an array literal instead.
Loading history...
527
  if (n > len) {
528
    var msg = "getRandom: more elements taken than available";
529
    alert(msg);
0 ignored issues
show
Debugging Code Best Practice introduced by
The alert UI element is often considered obtrusive and is generally only used as a temporary measure. Consider replacing it with another UI element.
Loading history...
530
    throw new RangeError(msg);
531
  }
532
  while (n--) {
533
    var x = Math.floor(Math.random() * len);
534
    result[n] = arr[x in taken ? taken[x] : x];
535
    taken[x] = --len in taken ? taken[len] : len;
536
  }
537
  if (typeof callback == "function") {
538
    return callback(result);
539
  } else {
540
    return result;
541
  }
542
}
543