@craftercms/studio-ui
Version:
Services, components, models & utils to build CrafterCMS authoring extensions.
277 lines (275 loc) • 9.01 kB
JavaScript
/*
* Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3 as published by
* the Free Software Foundation.
*
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as published by
* the Free Software Foundation.
*
* 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 <http://www.gnu.org/licenses/>.
*/
/**
* Converts a string separated by dashes into a
* camelCase equivalent. For instance, 'foo-bar'
* would be converted to 'fooBar'.
**/
export function camelize(str) {
return str.replace(/-+(.)?/g, function (match, chr) {
return chr ? chr.toUpperCase() : '';
});
}
/**
* Capitalizes the first letter of a string and down-cases all the others.
**/
export function capitalize(str) {
return `${str.charAt(0).toUpperCase()}${str.substr(1)}`;
}
/**
* Converts a camelized string into a series of words separated by an underscore (_).
**/
export function underscore(str) {
return str
.replace(/::/g, '/')
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
.replace(/([a-z\d])([A-Z])/g, '$1_$2')
.replace(/-/g, '_')
.toLowerCase();
}
/**
* Replaces every instance of the underscore character "_" by a dash "-".
**/
export function dasherize(str) {
return str.replace(/_/g, '-');
}
export function removeSpaces(str) {
return str.replace(/\s+/g, '');
}
export function removeLastPiece(str, splitChar = '.') {
return (str = `${str}`).substr(0, str.lastIndexOf(splitChar));
}
export function popPiece(str, splitChar = '.') {
return String(str).split(splitChar).pop();
}
export function isJSON(str) {
throw new Error('[isJSON] Not implemented.');
}
export function hasUppercaseChars(str) {
return /[A-Z]/.test(str);
}
export function getInitials(str) {
if (!str) {
return '';
} else if (typeof str === 'string') {
return (str ?? '')
.split(' ')
.map((str) => str.charAt(0))
.join('')
.toUpperCase();
} else {
return `${str.firstName.charAt(0)}${str.lastName.charAt(0)}`.toUpperCase();
}
}
export function formatBytes(bytes, decimals = 2) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
export function isBlank(str) {
return (str ?? '').trim() === '';
}
export function dataUriToBlob(dataURI) {
// convert base64 to raw binary data held in a string
// doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
const byteString = atob(dataURI.split(',')[1]);
// separate out the mime component
const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to an ArrayBuffer
const ab = new ArrayBuffer(byteString.length);
// create a view into the buffer
const ia = new Uint8Array(ab);
// set the bytes of the buffer to the correct values
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
// write the ArrayBuffer to a blob, and you're done
const blob = new Blob([ab], { type: mimeString });
return blob;
}
export function fileNameFromPath(path) {
return path.substr(path.lastIndexOf('/') + 1).replace(/\.xml/, '');
}
export function escapeHTML(str) {
const element = document.createElement('textarea');
element.textContent = str;
return element.innerHTML;
}
export function unescapeHTML(html) {
const element = document.createElement('textarea');
element.innerHTML = html;
return element.textContent;
}
export function legacyEscapeXml(value) {
if (typeof value === 'string') {
return value.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
}
return value;
}
export function legacyUnescapeXml(value) {
if (typeof value === 'string') {
return value
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/&/g, '&');
}
return value;
}
export function bytesToSize(bytes, separator = '') {
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
if (bytes === 0) return 'n/a';
const i = parseInt(`${Math.floor(Math.log(bytes) / Math.log(1024))}`, 10);
if (i === 0) return `${bytes}${separator}${sizes[i]}`;
return `${(bytes / 1024 ** i).toFixed(1)}${separator}${sizes[i]}`;
}
/**
* Removes double slashes from urls
* @param url {string} The URL to clean up
*/
export function ensureSingleSlash(url) {
return /^(http|https):\/\//g.test(url) ? url.replace(/([^:]\/)\/+/g, '$1') : url.replace(/\/+/g, '/');
}
export function getSimplifiedVersion(version, options = {}) {
if (!version) {
return version;
}
const { minor = true, patch = false } = options;
const pieces = version.split('.');
!patch && pieces.pop();
!minor && pieces.pop();
return pieces.join('.');
}
export function preFill(str, minLength = 2, char = '0') {
str = `${str}`;
return str.length >= minLength ? str : `${new Array(minLength - str.length).fill(char).join('')}${str}`;
}
export function postFill(str, minLength = 2, char = '0') {
str = `${str}`;
return str.length >= minLength ? str : `${str}${new Array(minLength - str.length).fill(char).join('')}`;
}
export const isSimple = (str, separator = '.') => String(str).split(separator).length === 1;
export const isSymmetricCombination = (string1, string2, separator = '.') =>
String(string1).split(separator).length === String(string2).split(separator).length;
export function stripCData(str) {
return str.replace(/<!\[CDATA\[|\]\]>/gi, '');
}
export function toColor(str) {
var hash = 0;
for (let i = 0; i < str.length; i++) {
hash = str.charCodeAt(i) + ((hash << 5) - hash);
}
var color = '#';
for (let j = 0; j < 3; j++) {
var value = (hash >> (j * 8)) & 0xff;
color += ('00' + value.toString(16)).substr(-2);
}
return color;
}
export const replaceAccentedVowels = (input) => {
const accentsMap = {
á: 'a',
é: 'e',
í: 'i',
ó: 'o',
ú: 'u',
Á: 'A',
É: 'E',
Í: 'I',
Ó: 'O',
Ú: 'U',
à: 'a',
è: 'e',
ì: 'i',
ò: 'o',
ù: 'u',
À: 'A',
È: 'E',
Ì: 'I',
Ò: 'O',
Ù: 'U',
â: 'a',
ê: 'e',
î: 'i',
ô: 'o',
û: 'u',
Â: 'A',
Ê: 'E',
Î: 'I',
Ô: 'O',
Û: 'U',
ä: 'a',
ë: 'e',
ï: 'i',
ö: 'o',
ü: 'u',
Ä: 'A',
Ë: 'E',
Ï: 'I',
Ö: 'O',
Ü: 'U'
};
return input.replace(/[áéíóúÁÉÍÓÚàèìòùÀÈÌÒÙâêîôûÂÊÎÔÛäëïöüÄËÏÖÜ]/g, (match) => accentsMap[match]);
};
export function isPath(str) {
return /^\/(?:[^/]+\/)*[^/]*$/.test(str);
}
export function isUUID(str) {
return /^[a-f\d]{8}-[a-f\d]{4}-[a-f\d]{4}-[a-f\d]{4}-[a-f\d]{12}$/i.test(str);
}
/**
* Takes a string in any of our possible version formats and converts it to a number that can be compared coherently
* with other versions that went through this process. Examples:
* 4.2.22 => 004.002.022 => 4002022
* 5.0.0E => 005.000.000 => 5000000
* 4.3.0-SNAPSHOT => 004.003.000 => 4003000
* @param versionStr {string} The version string to convert
* @return {number} The version converted to a number
**/
export function versionStringToInt(versionStr) {
// Use a regular expression to extract the three groups of digits
const match = versionStr.match(/(\d+)\.(\d+)\.(\d+)/);
if (!match) {
console.error('Version string does not match the expected format');
return 0;
}
// Destructure the matched groups: match[1] is major, match[2] is minor, match[3] is patch
let [, major, minor, patch] = match;
// Pad each number with leading zeros to ensure three digits
major = major.padStart(3, '0');
minor = minor.padStart(3, '0');
patch = patch.padStart(3, '0');
// Concatenate the padded strings & convert to a number
return Number(major + minor + patch);
}