/**
* Utils module
* @module Utils
*/
import jQ from 'jquery';
import Settings from './settings';
import Globals from './globals';
import InstantSearchUtils from "./utils/instant-search-utils";
import FilterTreeUtils from "./utils/filter-tree-utils";
import FilterResultUtils from "./utils/filter-result-utils";
// Get the suitable size of image to optimize the speed of page load
const optimizeImage = (imageUrl, size) => {
// If url is null, get default image
if (imageUrl === null) imageUrl = boostPFSConfig.general.no_image_url;
// Get the suitable size
var size = typeof size !== 'undefined' ? size : 'large';
var ext = Settings.getSettingValue('general.imageExtension');
for (var k = 0; k < ext.length; k++) {
imageUrl = imageUrl.replace('.' + ext[k] + '?', '_' + size + '.' + ext[k] + '?');
}
return imageUrl;
};
// Get the first image of a product
// If null, return default image
const getFeaturedImage = (images, size) => {
var size = typeof size !== 'undefined' ? size : 'large';
var featuredImage = optimizeImage(boostPFSConfig.general.no_image_url, size);
if (images.length > 0) {
featuredImage = typeof images[0] === 'object' ? optimizeImage(images[0]['src'], size) : optimizeImage(images[0], size);
}
return featuredImage;
};
/* -- Start Money Utils -- */
/**
* Format money based on setting in Shopify
* @param {String} money The money number
* @param {String} [format] The format string of Money: <br />
* - {{ amount }}: $1,999.99<br />
* - {{ amount_no_decimals }}: $1,999<br />
* - {{ amount_with_comma_separator }}: 1.999,99₫<br />
* - {{ amount_no_decimals_with_comma_separator }}: 1.999₫<br />
* - {{ amount_with_space_separator_no_comma }}: $1,999.99
* @param {Boolean} [withoutTrailingZeros] - Disable decimals number if it is zero
*/
const formatMoney = (money, format, withoutTrailingZeros) => {
if (typeof format == 'undefined') var format = Globals.moneyFormat;
if (typeof withoutTrailingZeros == 'undefined') var withoutTrailingZeros = false;
// if (typeof Shopify.formatMoney === 'function') { return Shopify.formatMoney(money, format); }
if (typeof money == 'string') { money = money.replace('.', ''); }
var value = '';
var placeholderRegex = /\{\{\s*(\w+)\s*\}\}/;
var formatString = format || '${{amount}}';
function defaultOption(opt, def) {
return (typeof opt == 'undefined' ? def : opt);
}
function formatWithDelimiters(number, precision, thousands, decimal) {
precision = defaultOption(precision, 2);
thousands = defaultOption(thousands, ',');
decimal = defaultOption(decimal, '.');
if (isNaN(number) || number == null) { return 0; }
number = parseFloat(number).toFixed(precision);
var parts = number.split('.');
var dollars = parts[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1' + thousands);
var money = parts[1] ? (decimal + parts[1]) : '';
return withoutTrailingZeros == true ? (dollars + money).replace(/((\,00)|(\.00))$/g, '') : dollars + money;
}
switch(formatString.match(placeholderRegex)[1]) {
case 'amount':
value = formatWithDelimiters(money, 2);
break;
case 'amount_no_decimals':
value = formatWithDelimiters(money, 0);
break;
case 'amount_with_comma_separator':
value = formatWithDelimiters(money, 2, '.', ',');
break;
case 'amount_no_decimals_with_comma_separator':
value = formatWithDelimiters(money, 0, '.', ',');
break;
case 'amount_with_space_separator_no_comma':
value = formatWithDelimiters(money, 2);
break;
default:
value = formatWithDelimiters(money, 2);
break;
}
formatString = formatString.replace(placeholderRegex, value);
return moneyWrapper(formatString);
};
const moneyWrapper = (money) => {
var htmlTemplate = '<span class="money">{{money}}</span>';
return htmlTemplate.replace(/{{money}}/g, stripHtml(money));
}
/**
* Format a number separator
* @param {Number} number - Number to Format
* @param {Number} precision - Integer.
* @param {string} thousand - Thousand separator
* @param {string} decimal - Decimal separator
* @param {boolean} withoutTrailingZeros - Removes .00 or .0
* @return {string}
*/
const formatNumberWithSeparator = (number, precision, thousand, decimal, withoutTrailingZeros) => {
if (isNaN(number)) number = 0;
if (isNaN(precision)) precision = 0;
if (!decimal) {
if (thousand == '.') {
decimal = ',';
} else {
decimal = '.';
}
}
number = parseFloat(number).toFixed(precision);
var parts = number.toString().split('.');
var beforeDecimalString = parts[0];
var afterDecimalString = parts[1] ? parts[1] : '';
if (thousand) {
beforeDecimalString = beforeDecimalString.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1' + thousand);
}
if (decimal && afterDecimalString) {
if (withoutTrailingZeros && /0+/.test(afterDecimalString)) {
afterDecimalString = '';
} else {
afterDecimalString = decimal + afterDecimalString;
}
}
return beforeDecimalString + afterDecimalString;
}
/**
* Get currency symbol of store
* @example
* Utils.getCurrency('<span class="money">${{amount}}</span>');
* // return '$'
*/
const getCurrency = () => {
var moneyFormat = jQ('<p>' + boostPFSConfig.shop.money_format + '</p>').text();
return moneyFormat.replace(/{{[^}]*}}/g, '');
};
/**
* Remove currency symbol from price
* @param {String} price The price string
* @returns {String} The price string without currency
*/
const removeCurrencySymbol = (price) => {
// Remove html from price
price = jQ('<p>' + price + '</p>').text();
// Remove currency from price
// return price.replace(/[^\d\.\,]/g, '');
var currencyElements = getCurrency().split(' ');
for (var k = 0; k < currencyElements.length; k++) {
price = price.replace(currencyElements[k].trim(), '');
}
return price.trim();
};
/**
* Get Range of rounding
* @param {Boolean} isMax TRUE if want to return the max value or range
*/
const getRoundingRange = (isMax) => {
if (typeof isMax == 'undefined') isMax = false;
// Get the rounding rule
var roundRuleList = [0.25, 0.5, 0.75, 0.9, 0.95, 0.99, 1, 25, 50, 75, 90, 95, 99, 100, 250, 500, 750, 900, 950, 999, 1000];
var currentCurrency = boostPFSAppConfig.general.current_currency.toLowerCase().trim();
var roundRules = Settings.getSettingValue('currencyRoundingRules');
var roundRule = roundRules && currentCurrency && roundRules.hasOwnProperty(currentCurrency) ? parseFloat(roundRules[currentCurrency]) : 0;
var mulNum = false;
if (roundRule > 0 && jQ.inArray(roundRule, roundRuleList) !== -1) {
var mulNum = 0.99;
if (roundRule > 100) {
mulNum = 999;
} else if (roundRule > 10) {
mulNum = 99;
} else if (roundRule > 1) {
mulNum = 9;
}
if (isMax) {
mulNum = roundRule > 1 ? mulNum + 1: mulNum + 0.01;
}
}
return mulNum;
}
/**
* Apply shopify rounding rule to product pice
* @param {Number} price the product price
*/
const roundedPrice = (price) => {
price = parseFloat(price).toFixed(2);
// Get round rule
var currentCurrency = boostPFSAppConfig.general.current_currency.toLowerCase().trim();
var roundRules = Settings.getSettingValue('currencyRoundingRules');
var roundRule = roundRules && currentCurrency && roundRules.hasOwnProperty(currentCurrency) ? roundRules[currentCurrency] : 0;
// Get the max rounding rule (1, 100, 1000)
var maxRounding = getRoundingRange(true);
// Rounded the price
if (maxRounding) {
// Convert the price to useing decimal rounding: [xxx JPY] / 100, [xx.xxx VND] / 1000
var roundRuleTmp = parseFloat(roundRule);
roundRuleTmp = roundRuleTmp / maxRounding;
price = price / maxRounding;
// Rounded the price
if (roundRuleTmp == 1) roundRuleTmp = 0;
var priceInt = Math.floor(price);
var priceDeci = (price - priceInt).toFixed(2);
price = (priceDeci > roundRuleTmp) ? priceInt + 1 : priceInt
price = price * maxRounding;
// Fixed round rule
if (roundRuleTmp == 0) roundRule = 0;
price = price + parseFloat(roundRule);
}
return price;
}
/**
* Convert price to the active currency
* @param {Number} price - The product price
* @param {Boolean} isRounded - TRUE if want to apply rounding rule
*/
const convertPriceBasedOnActiveCurrency = (price, isRounded) => {
if (typeof isRounded == 'undefined') isRounded = true;
if (price === null) return price;
if (isEnableShopifyMultipleCurrencies() === true) {
var convertPrice = price * Shopify.currency.rate;
if (isRounded) {
price = roundedPrice(convertPrice);
} else {
price = convertPrice;
}
}
return parseFloat(price);
}
/**
* Revert price to the default currency
* @param {Number} price - The product price
* @param {Boolean} isMin - TRUE if revert price based on the min-range of rounding
*/
const revertPriceToDefaultCurrency = (price, isMin) => {
if(isEnableShopifyMultipleCurrencies() === true) {
price = roundedPrice(price);
if (isMin) {
var minRound = getRoundingRange();
if (minRound) {
price = price - minRound;
}
}
price = price / Shopify.currency.rate;
return price.toFixed(8);
}
return price;
}
/* -- End Money Utils -- */
var windowWidth = null;
/**
* Return true if the screen-width lesser then mobile break-point
*/
const isMobile = () => {
if (!windowWidth) {
// We don't want to re-calculate the width every time because it causes a style recalculation everytime.
// So we store it
windowWidth = jQ(window).width();
// Calculate the width on resize
jQ(window).on('resize', () => {
windowWidth = jQ(window).width();
})
}
return windowWidth <= Settings.getSettingValue('general.breakpointMobile');
};
/**
* Check if the devivce is Mobile Device or not
*/
const isMobileDevice = () => {
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
};
/**
* Check if a device is iOS or not
*/
const isiOS = () => {
return /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
};
/**
* Check if a browser is Safari or not
*/
const isSafari = () => {
return /Safari/.test(navigator.userAgent);
};
/**
* Check if page is loaded by back button
*/
const isBackButton = () => {
// NOTE: Doesn't work on iOS
return window.performance && window.performance.navigation && window.performance.navigation.type == 2;
};
/**
* Check whether the Boost params exist
*/
const checkExistBCParam = () => {
return Globals.queryParams.hasOwnProperty('_') && Globals.queryParams['_'] == Globals.prefix;
};
/**
* Chech whether collection param exist
* @param {String} type Type of filter option
*/
const isCollectionParam = (type) => {
if (type != 'collection' || (type == 'collection' && isSearchPage())) {
return false;
}
return true;
};
/**
* Check if the current page is Vendor page
*/
const isVendorPage = () => {
return window.location.pathname.indexOf('/collections/vendors') > -1 ? true : false;
};
/**
* Check if the current page is Type page
*/
const isTypePage = () => {
return window.location.pathname.indexOf('/collections/types') > -1 ? true : false;
};
/**
* Check if the current page is Tag page
*/
const isTagPage = () => {
if (typeof Globals.currentTags !== 'undefined' && Globals.currentTags !== null && Globals.currentTags.length > 0) return true;
return false;
};
/**
* Check if the current page is Search page
*/
const isSearchPage = () => {
// An URL of Google cache will look like this: webcache.googleusercontent.com/search?q=cache:xxx:https://xxx.xxx/search?xxx
// Google cache URL
if (Utils.getWindowLocation().href.includes('webcache.googleusercontent.com')) {
return Utils.getWindowLocation().search.indexOf('search?') > -1;
// Normal URL
} else {
return window.location.pathname.indexOf('/search') > -1;
}
};
/**
* Check if the current page is Cart page
*/
const isCartPage = () => {
return window.location.pathname.indexOf('/cart') > -1;
};
/**
* Check if the current page is Product page
*/
const isProductPage = () => {
return window.location.pathname.indexOf('/products') > -1;
};
/**
* Get the current search term
*/
const getSearchTerm = () => {
return getParam(Globals.searchTermKey);
};
/**
* Remove decimals from a number
* @param {(String|Number)} value The number value
* @param {String} delimiter Delimiter symbol
*/
const removeDecimal = (value, delimiter) => {
var delimiter = typeof delimiter !== 'undefined' ? delimiter : Settings.getSettingValue('general.decimalDelimiter');
var reg = new RegExp("(\\" + delimiter + "\\d+)+", "gi");
return value.replace(reg, '');
};
/**
* Slugify a string (convert a string to slug)
* @param {String} text The string that need to slugify
*/
const slugify = (text) => {
if (text == null || typeof text == 'object') return '';
if (typeof text != 'string') {
if (typeof text.toString != 'function'){
return '';
}
else {
text = text.toString();
}
}
// return text.toString().toLowerCase()
// .replace(/[\s\/]+/g, '-') // Replace spaces with -
// .replace(/[^\w\-]+/g, '') // Remove all non-word chars
// .replace(/\-\-+/g, '-') // Replace multiple - with single -
// .replace(/^-+/, '') // Trim - from start of text
// .replace(/-+$/, '') // Trim - from end of text
text = text.toLowerCase();
// Remove Latin
var from = "àáäâãèéëêẽìíïîĩòóöôõùúüûũñç·/_,:;";
var to = "aaaaaeeeeeiiiiiooooouuuuunc--_---";
for (var i = 0, l = from.length; i < l; i++)
text = text.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));
// Remove Czech, Finnish special characters
var specialCzechChars = 'ÁáÄäČčĎďÉéěÍíŇňÓóÖöŘřŠšŤťÚúůÝýŽž';
var asciiCzechChars = 'AaAaCcDdEeeIiNnOoOoRrSsTtUuuYyZz';
var specialCzechCharsLength = specialCzechChars.length;
for (var j = 0; j < specialCzechCharsLength; j++) {
text = text.replace(new RegExp(specialCzechChars.charAt(j), "g"), asciiCzechChars.charAt(j));
}
// Remove Norway special characters
var specialNorwayChars = 'ÆæØøÅå';
var asciiNorwayChars = ['AE', 'ae', 'O', 'o', 'A', 'a'];
var specialNorwayCharsLength = specialNorwayChars.length;
for (var k = 0; k < specialNorwayCharsLength; k++) {
text = text.replace(new RegExp(specialNorwayChars.charAt(k), "g"), asciiNorwayChars[k]);
}
// Remove quotes
text = text.replace(/'/g, '').replace(/"/g, '');
return text.replace(/[\s\/]+/g, '-') // Replace spaces with -
.replace(/[`~!@#$%^&*()|+\-=?;:'",.<>\{\}\[\]\\\/]/g, '-') // Replace all special characters with -
.replace(/\-\-+/g, '-') // Replace multiple - with single -
.replace(/^-+/, '') // Trim - from start of text
.replace(/-+$/, ''); // Trim - from end of text
};
/**
* Convert a slug to string
* @param {String} slug The slug string
* @param {String} divide The divide character
*/
const textify = (slug, divide) => {
var divide = typeof divide !== 'undefined' ? divide : '-';
var arr = slug.split(divide);
var text = '';
for (var k = 0; k < arr.length; k++) {
text += arr[k].charAt(0).toUpperCase() + arr[k].slice(1);
if (k < arr.length - 1) {
text += ' ';
}
}
return text;
};
/**
* Escape a HTML string to displayed it
* @param {String} string A string that contains HTML element.
* @param {Boolean} preserveCR Set true if the end of line is carriage returns
*/
const escape = (string, preserveCR) => {
preserveCR = preserveCR ? ' ' : '\n';
return ('' + string) /* Forces the conversion to string. */
.replace(/&/g, '&') /* This MUST be the 1st replacement. */
.replace(/'/g, ''') /* The 4 other predefined entities, required. */
.replace(/"/g, '"')
.replace(/</g, '<')
.replace(/>/g, '>')
/*
You may add other replacements here for HTML only
(but it's not necessary).
Or for XML, only if the named entities are defined in its DTD.
*/
.replace(/\r\n/g, preserveCR) /* Must be before the next replacement. */
.replace(/[\r\n]/g, preserveCR);
};
/**
* Convert a object to array
* @param {Object} obj The Object that needs to convert
*/
const convertObjectToArray = (obj) => {
return Object.keys(obj).map(function (key) { return obj[key]; });
}
/**
* Sort array of object by field
* @param {Array} arr The array that needs to sort
* @param {*} field The field of array which will be sorted by
*/
const sortArrayObject = (arr, field) => {
if (typeof field !== 'undefined') {
arr.sort(function (a, b) {
var string1 = a[field], string2 = b[field];
if (typeof string1 == 'string') { string1 = string1.toLowerCase(); }
if (typeof string2 == 'string') { string2 = string2.toLowerCase(); }
if (string1 < string2) return -1;
if (string1 > string2) return 1;
return 0;
});
}
}
/**
* Get the URL param by name from URL
* @param {String} name The name of URL param
* @param {String} [url] The URL that needs to get param
*/
const getParam = (name, url) => {
if (!url) {
url = Utils.getWindowLocation().href;
}
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)");
var results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
// Merge two objects
const mergeObject = (obj1, obj2) => {
for (var p in obj2) {
try {
// Property in destination object set; update its value.
obj1[p] = obj2[p].constructor == Object ? mergeObject(obj1[p], obj2[p]) : obj2[p];
} catch (e) {
// Property in destination object not set; create it and set its value.
obj1[p] = obj2[p];
}
}
return obj1;
}
/**
* Capitalize a string
* @param {String} string The string that needs to Capitalize
* @param {Boolean} [isLower] Set true if needs to Lowercase all before Capitalize
* @param {Boolean} [onlyFirstLetter] Set true if just needs to Capitalize the first character
*/
const capitalize = (string, isLower, onlyFirstLetter) => {
var isLower = typeof isLower !== 'undefined' ? isLower : false;
var onlyFirstLetter = typeof onlyFirstLetter !== 'undefined' ? onlyFirstLetter : false;
if (isLower) string = string.toLowerCase();
if (onlyFirstLetter) {
return string.charAt(0).toUpperCase() + string.slice(1);
} else {
return string.replace(/(?:^|\s)\S/g, function (a) { return a.toUpperCase(); });
}
}
/**
* Find index of a value in array
* @param {String} findValue The searched value
* @param {Array} arr The Array
* @param {String} key The searched key
* @param {Boolean} sensitive Set true for case sensitive
*/
const findIndexArray = (findValue, arr, key, sensitive) => {
if (typeof key !== 'undefined' && key !== null) {
for (var i = 0; i < arr.length; i++) {
if (typeof sensitive !== 'undefined' && sensitive == false) {
arr[i][key] = arr[i][key].toLowerCase();
findValue = findValue.toLowerCase();
}
if (arr[i][key] == findValue) return i;
}
} else {
for (var i = 0; i < arr.length; i++) {
if (typeof sensitive !== 'undefined' && sensitive == false) {
arr[i] = arr[i].toLowerCase();
findValue = findValue.toLowerCase();
}
if (arr[i] == findValue) return i;
}
}
return -1;
};
/**
* Get a value of an attribute in an element of an array of object
* @param {String} findValue The searched value
* @param {Array} arr The Array
* @param {String} findKey The searched key
* @param {String} destKey
*/
const getValueInObjectArray = (findValue, arr, findKey, destKey) => {
if (typeof findKey === 'undefined') findKey = 'key';
if (typeof destKey === 'undefined') destKey = 'values';
var index = findIndexArray(findValue, arr, findKey);
if (index > -1 && arr[index].hasOwnProperty(destKey)) return arr[index][destKey];
return '';
}
/**
* Get file path
* @param {String} fileName The file mane
* @param {*} extension The file extension
* @param {*} version The version of file
*/
const getFilePath = (fileName, extension, version) => {
var extension = typeof extension !== 'undefined' ? extension : 'png';
var version = typeof version !== 'undefined' ? version : '';
var filePath = Globals.fileUrl.split('?')[0];
filePath += fileName + '.' + extension + (version ? ('?v=' + version) : '');
return filePath;
}
/**
* Check if the number is Interger
* @param {Number} n The number value
*/
const isInt = (n) => {
return Number(n) === n && n % 1 === 0;
}
/**
* Check if the number is Float
* @param {Number} n
*/
const isFloat = (n) => {
return Number(n) === n && n % 1 !== 0;
}
/**
* Retrieve number of decimals
* @param {Number} n The number that needs to get decimals
*/
const getNumberDecimals = (n) => {
var splittedNumber = n.toString().split('.');
if (splittedNumber.length > 1) {
return splittedNumber[1].length;
} else {
return 0;
}
}
/**
* Removes duplicate values from an array
* @param {Array} arr The array value
*/
const uniq = (arr) => {
return arr.filter(function (value, index, self) {
return self.indexOf(value) === index;
});
}
/**
* Strip all HTML tags from a string
* @param {String} string The string that contains HTML tags
*/
const stripHtml = (string) => {
return jQ('<p>' + string + '</p>').text();
}
/**
* Remove all Script in a string
* @param {String} string The string that contains Script tags
*/
const stripScriptTag = (string) => {
if (string) return string.replace(/<script[^>]*>.*?<\/script>/gi, '');
}
/**
* Add ellipsis to too long text (keep whole word)
* @param str
* @param limit
* @param delimiter
* @return {*}
*/
const truncateByWord = (str, limit, delimiter) => {
if (typeof delimiter === 'undefined') delimiter = '...';
str = (str.split(' ')).length > limit ? str.split(' ').splice(0, limit).join(' ') + delimiter : str.split(' ').splice(0, limit).join(' ');
return str;
};
/**
* Return true if the active currency is not default
*/
const isShopifyActiveCurrency = () => {
return typeof Shopify !== 'undefined'
&& Shopify.hasOwnProperty('currency')
&& Shopify.currency.hasOwnProperty('rate')
&& Shopify.currency.rate != 1.0;
}
/**
* Return whether or not Shopify Multi-currencies is enabled
*/
const isEnableShopifyMultipleCurrencies = () => {
return Settings.hasOwnProperty('general')
&& Settings.general.hasOwnProperty('currencies')
&& Settings.general.currencies.length > 1
&& isShopifyActiveCurrency();
}
/**
* Re-Build URL with locale
* @param {String} url - The URL
*/
const reBuildUrlBaseOnLocale = (url) => {
// remove http or https
url = url.replace('https://', '').replace('http://', '');
var currentLocale = Settings.getSettingValue('general.current_locale');
var publishedLocales = Settings.getSettingValue('general.published_locales');
var publishedLocaleKeys = Object.keys(publishedLocales);
var currentLocaleIndex = publishedLocaleKeys.indexOf(currentLocale);
// If the locale isnt in the published list, or is default locale, return the normal url
if (currentLocaleIndex < 0 || publishedLocales[currentLocale] == true) return url;
var urlArr = url.split('/');
if (urlArr.length > 1 && publishedLocaleKeys.length && currentLocale.length) {
var isUrlHasLocaleString = publishedLocaleKeys.indexOf(urlArr[1]) > -1;
if (isUrlHasLocaleString) {
urlArr[1] = currentLocale;
} else {
urlArr.splice(1, 0, currentLocale);
}
}
return urlArr.join('/');
}
/**
* Check if app is loaded in google lighthouse mobile
*/
const isGLHMobile = () => {
return navigator && navigator.userAgent && navigator.userAgent.includes(atob('TGlnaHRob3VzZQ==')) && Utils.isMobile() && !Utils.isSearchPage();
}
const getWindowLocation = () => {
// Escape window.location.href
var href = window.location.href;
var escapedHref = href.replace(/%3C/g, '<').replace(/%3E/g, '>');
// Rebuild window.location.href
var rebuildHrefArr = [];
for (var i = 0; i < escapedHref.length; i++) {
rebuildHrefArr.push(escapedHref.charAt(i));
}
var rebuildHref = rebuildHrefArr.join('').split('<').join('%3C').split('>').join('%3E');
// Rebuild window.location.search
var rebuildSearch = "";
var hrefWithoutHash = rebuildHref.replace(/#.*$/, '');
if (hrefWithoutHash.split('?').length > 1) {
rebuildSearch = hrefWithoutHash.split('?')[1];
if (rebuildSearch.length > 0) {
rebuildSearch = '?' + rebuildSearch;
}
}
return {
pathname: window.location.pathname,
href: rebuildHref,
search: rebuildSearch
}
}
const setWindowLocation = (url) => {
window.location.href = url;
}
const Utils = {
// General Utils
escape: escape,
findIndexArray: findIndexArray,
getParam: getParam,
getSearchTerm: getSearchTerm,
getValueInObjectArray: getValueInObjectArray,
getFilePath: getFilePath,
getNumberDecimals: getNumberDecimals,
isMobile: isMobile,
isMobileDevice: isMobileDevice,
isiOS: isiOS,
isSafari: isSafari,
isBackButton: isBackButton,
isCartPage: isCartPage,
isProductPage: isProductPage,
isSearchPage: isSearchPage,
isVendorPage: isVendorPage,
isTagPage: isTagPage,
isTypePage: isTypePage,
isGLHMobile: isGLHMobile,
mergeObject: mergeObject,
optimizeImage: optimizeImage,
getFeaturedImage: getFeaturedImage,
slugify: slugify,
capitalize: capitalize,
textify: textify,
stripHtml: stripHtml,
stripScriptTag: stripScriptTag,
truncateByWord: truncateByWord,
removeDecimal: removeDecimal,
formatMoney: formatMoney,
moneyWrapper: moneyWrapper,
formatNumberWithSeparator: formatNumberWithSeparator,
getCurrency: getCurrency,
removeCurrencySymbol: removeCurrencySymbol,
isShopifyActiveCurrency: isShopifyActiveCurrency,
isEnableShopifyMultipleCurrencies: isEnableShopifyMultipleCurrencies,
roundedPrice: roundedPrice,
convertPriceBasedOnActiveCurrency: convertPriceBasedOnActiveCurrency,
revertPriceToDefaultCurrency: revertPriceToDefaultCurrency,
reBuildUrlBaseOnLocale: reBuildUrlBaseOnLocale,
getWindowLocation: getWindowLocation,
setWindowLocation: setWindowLocation,
/**
* Utils of Instant search <br />
* @example
* var isFullWidth = Utils.InstantSearch.isFullWidthMobile();
* @alias module:Utils.InstantSearch
* @see module:Utils/InstantSearchUtils
*/
InstantSearch: InstantSearchUtils,
isFullWidthMobile: InstantSearchUtils.isFullWidthMobile,
isStyle2: InstantSearchUtils.isStyle2,
/**
* Utils of Filter tree
* @alias module:Utils.FilterTree
* @see module:Utils/FilterTreeUtils
*/
FilterTree: FilterTreeUtils,
checkExistFilterOptionParam: FilterTreeUtils.checkExistFilterOptionParam,
encodeURIParamValue: FilterTreeUtils.encodeURIParamValue,
/**
* Utils of Filter tree
* @alias module:Utils.FilterResult
* @see module:Utils/FilterResultUtils
*/
FilterResult: FilterResultUtils,
buildProductItemUrl: FilterResultUtils.buildProductItemUrl,
removePageParamFromUrl: FilterResultUtils.removePageParamFromUrl,
removeCollectionScopeParamFromUrl: FilterResultUtils.removeCollectionScopeParamFromUrl,
buildToolbarLink: FilterResultUtils.buildToolbarLink,
isDefaultPaginationType: FilterResultUtils.isDefaultPaginationType,
isLoadMorePaginationType: FilterResultUtils.isLoadMorePaginationType,
isInfiniteLoadingPaginationType: FilterResultUtils.isInfiniteLoadingPaginationType,
isLoadPreviousPagePaginationType: FilterResultUtils.isLoadPreviousPagePaginationType,
getSortingList: FilterResultUtils.getSortingList,
getProductMetafield: FilterResultUtils.getProductMetafield,
isNoFilterResult: FilterResultUtils.isNoFilterResult
}
export default Utils;