/* * The Strangecode Codebase - a general application development framework for PHP * For details visit the project site: * Copyright © 2014 Strangecode, LLC * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // Codebase functions will be under the Strangecode namespace, unless they are added to the jQuery object for chaining. var Strangecode = Strangecode || {}; /* Emulates a sprintf function. Placeholders are {1}…{N}. Some versions of this function were zero-indexed; this one is not. --------------------------------------------------------------------- "{1} is dead, but {2} is alive! {1} {3}".format("ASP", "ASP.NET") outputs ASP is dead, but ASP.NET is alive! ASP {3} --------------------------------------------------------------------- * * @access public * @param string multiple Strings to pass to the formatted string. * @author http://stackoverflow.com/a/4673436/277303 * @version 1.0 * @since 30 May 2014 18:02:39 */ if (!String.prototype.format) { String.prototype.format = function () { var args = arguments; return this.replace(/{(\d+)}/g, function (match, number) { return typeof args[number-1] != 'undefined' ? args[number-1] : match; }); }; } /* * Displays 'user at domain dot com' as 'user@domain.com'. --------------------------------------------------------------------- --------------------------------------------------------------------- * * @access public * @version 2.0 * @since 30 Jun 2008 12:32:19 */ jQuery.fn.nospam = function () { return this.each(function (){ $(this).text($(this).text().replace(' at ', '@').replace(' dot ', '.')); if (this.href) { this.href = decodeURIComponent(this.href).replace(' at ', '@').replace(' dot ', '.'); } }); }; /* * Encode html entities by specific mapping table. * Decode HTML by proxying content via an in-memory div, setting its inner text which jQuery automatically encodes. Then we pull the encoded contents back out. The div never exists on the page. --------------------------------------------------------------------- $('input').val(Strangecode.htmlEncode(string)); --------------------------------------------------------------------- @access public @version 2.0 @since 30 Jun 2013 */ Strangecode.htmlEncode = function (str) { var entityMap = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''', '/': '/', '`': '`' }; return String(str).replace(/[&<>"'\/`]/g, function (s) { return entityMap[s]; }); }; Strangecode.htmlDecode = function (str) { return $('
').html(str).text(); }; /* * Set the user's timezone in a cookie (which is used in Codebase's $app->start() method). --------------------------------------------------------------------- Strangecode.setTimezoneCookie() --------------------------------------------------------------------- * @access public * @version 1.0 * @since 24 Jan 2019 */ Strangecode.setTimezoneCookie = function () { try { // use Intl API when available and returning valid time zone var tz = Intl.DateTimeFormat().resolvedOptions().timeZone; } catch (e) { // Intl unavailable, fall back to manual guessing. tz = (new Date().getTimezoneOffset()/-60); } if ('' != tz) { document.cookie = 'tz=' + tz + ';path=/;max-age=86400'; } } /* Returns a string with URL-unsafe characters removed. --------------------------------------------------------------------- var urlslug = $('.url').val().slug(); --------------------------------------------------------------------- * @access public * @version 1.0 * @since 30 Jun 2013 */ $.fn.slug = function () { str = this.text().trim().toLowerCase(); var from = 'áéíóúàèìòùäëïöüÁÉÍÓÚÀÈÌÒÙÄËÏÖÜâêîôûÂÊÎÔÛñçÇ@·/_,:;'; var to = 'aeiouaeiouaeiouAEIOUAEIOUAEIOUaeiouAEIOUncCa------'; for (var i=0, l=from.length; i (.1*.2) 0.020000000000000004 > (.1*.2).trim() 0.02 --------------------------------------------------------------------- * @access public * @version 1.0 * @since 24 Nov 2015 */ if (!Number.prototype.trim) { Number.prototype.trim = function (precision) { var precision = precision || 11; return Math.round(this * Math.pow(10, precision)) / Math.pow(10, precision); }; } /* Uppercase the first letter of string. --------------------------------------------------------------------- > 'hello world'.ucfirst() Hello world --------------------------------------------------------------------- * @access public * @version 1.0 * @since 24 Nov 2015 */ if (!String.prototype.ucfirst) { String.prototype.ucfirst = function () { return this.charAt(0).toUpperCase() + this.slice(1); }; } /* Returns a human readable amount of time for the given amount of seconds. Months are calculated using the real number of days in a year: 365.2422 / 12. @param int seconds Seconds of time. @param string max_unit Key value from the units array. @return string Value of units elapsed. --------------------------------------------------------------------- > Strangecode.humanTime(3600) 1 hour --------------------------------------------------------------------- * @access public * @version 1.0 * @since 06 Mar 2019 */ Strangecode.humanTime = function (seconds, max_unit) { // Units: array of seconds in the unit, singular and plural unit names. var units = { 'second': [1, 'second', 'seconds'], 'minute': [60, 'minute', 'minutes'], 'hour': [3600, 'hour', 'hours'], 'day': [86400, 'day', 'days'], 'week': [604800, 'week', 'weeks'], 'month': [2629743.84, 'month', 'months'], 'year': [31556926.08, 'year', 'years'], 'decade': [315569260.8, 'decade', 'decades'], 'century': [3155692608, 'century', 'centuries'], }; // Max unit to calculate. max_unit = typeof max_unit === 'string' && units[max_unit] ? max_unit : 'year'; var final_time = seconds; var final_unit = 'second'; for (var k in units) { if (seconds >= units[k][0]) { final_time = seconds / units[k][0]; final_unit = k; } if (max_unit == final_unit) { break; } } final_time = Number(final_time).toFixed(0); return '{1} {2}'.format(final_time, (1 == final_time ? units[final_unit][1] : units[final_unit][2])); } // https://github.com/benjamingr/RegExp.escape if(!RegExp.escape){ RegExp.escape = function (s){ return String(s).replace(/[\\^$*+?.()|[\]{}]/g, '\\$&'); }; } // Throttle will ensure that a function is called at most once // in a specified time period (for instance, once per 10 seconds). This means // throttling will prevent a function from running if it has run “recently”. // Throttling also ensures a function is run regularly at a fixed rate. // https://blog.bitsrc.io/understanding-throttling-and-debouncing-973131c1ba07 Strangecode.throttle = function (f, t) { return function (args) { let previousCall = this.lastCall; this.lastCall = Date.now(); if (typeof previousCall === 'undefined' || (this.lastCall - previousCall) > t) { // Throttle time has elapsed. f(args); } } } // Debounce will ignore all calls to it until the calls have stopped for a // specified time period. Only then will it call the original function. For // instance, if we specify the time as two seconds, and the debounced function is // called 10 times with an interval of one second between each call, the function // will not call the original function until two seconds after the last (tenth) // call. // https://blog.bitsrc.io/understanding-throttling-and-debouncing-973131c1ba07 Strangecode.debounce = function (f, t) { return function (args) { let previousCall = this.lastCall; this.lastCall = Date.now(); if (previousCall && ((this.lastCall - previousCall) <= t)) { clearTimeout(this.lastCallTimer); } this.lastCallTimer = setTimeout(() => f(args), t); } }