action-buttons
2 years ago
action-fields-map
2 years ago
action-modal
2 years ago
actions
2 years ago
block-conditions
2 years ago
blocks
2 years ago
components
2 years ago
context
2 years ago
dynamic.value
2 years ago
events
2 years ago
gateways
2 years ago
hooks
2 years ago
macros.button
2 years ago
migrations
2 years ago
preset
2 years ago
repeater
2 years ago
validation
2 years ago
manager.js
2 years ago
store.manager.js
2 years ago
tools.js
2 years ago
tools.js
255 lines
| 1 | const semverGt = require( 'semver/functions/gt' ); |
| 2 | const semverLt = require( 'semver/functions/lt' ); |
| 3 | const semverGte = require( 'semver/functions/gte' ); |
| 4 | const semverLte = require( 'semver/functions/lte' ); |
| 5 | |
| 6 | const { __ } = wp.i18n; |
| 7 | const { applyFilters } = wp.hooks; |
| 8 | |
| 9 | class Tools { |
| 10 | |
| 11 | static withPlaceholder( source, label = '--', value = '' ) { |
| 12 | return [ |
| 13 | { label, value }, |
| 14 | ...source, |
| 15 | ]; |
| 16 | } |
| 17 | |
| 18 | /** |
| 19 | * @deprecated 3.1.0 |
| 20 | * |
| 21 | * @param object |
| 22 | * @returns {boolean} |
| 23 | */ |
| 24 | static isEmptyObject( object ) { |
| 25 | console.warn( |
| 26 | 'Use JetFBActions.isEmpty insteadof JetFBActions.Tools.isEmptyObject', |
| 27 | ); |
| 28 | |
| 29 | return isEmpty( object ); |
| 30 | } |
| 31 | |
| 32 | static getRandomID() { |
| 33 | return Math.floor( Math.random() * 8999 ) + 1000; |
| 34 | }; |
| 35 | } |
| 36 | |
| 37 | export const event = name => { |
| 38 | const initializeCallbacksEvent = new Event( name ); |
| 39 | return () => document.dispatchEvent( initializeCallbacksEvent ); |
| 40 | }; |
| 41 | |
| 42 | export const listen = ( name, func ) => { |
| 43 | document.addEventListener( name, func ); |
| 44 | }; |
| 45 | |
| 46 | function getSemVerFunc( operator ) { |
| 47 | switch ( operator ) { |
| 48 | case '>': |
| 49 | return semverGt; |
| 50 | case '>=': |
| 51 | return semverGte; |
| 52 | case '<': |
| 53 | return semverLt; |
| 54 | case '<=': |
| 55 | return semverLte; |
| 56 | } |
| 57 | |
| 58 | return () => false; |
| 59 | } |
| 60 | |
| 61 | export function versionCompare( version1, version2, operator ) { |
| 62 | try { |
| 63 | return getSemVerFunc( operator )( version1, version2 ); |
| 64 | } |
| 65 | catch ( te ) { |
| 66 | return false; |
| 67 | } |
| 68 | } |
| 69 | |
| 70 | export function column( listArr, name ) { |
| 71 | if ( !listArr?.length ) { |
| 72 | return []; |
| 73 | } |
| 74 | |
| 75 | return listArr.map( current => { |
| 76 | return 'object' === typeof current ? current[ name ] : current; |
| 77 | } ); |
| 78 | } |
| 79 | |
| 80 | const convertSymbols = applyFilters( 'jet.fb.tools.convertSymbols', { |
| 81 | checkCyrRegex: /[а-яёїєґі]/i, |
| 82 | cyrRegex: /[а-яёїєґі]/gi, |
| 83 | charsMap: { |
| 84 | 'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd', |
| 85 | 'е': 'e', 'ё': 'io', 'ж': 'zh', 'з': 'z', 'и': 'i', |
| 86 | 'й': 'i', 'к': 'k', 'л': 'l', 'м': 'm', 'н': 'n', |
| 87 | 'о': 'o', 'п': 'p', 'р': 'r', 'с': 's', 'т': 't', |
| 88 | 'у': 'u', 'ф': 'f', '� |
| 89 | ': 'kh', 'ц': 'ts', 'ч': 'ch', |
| 90 | 'ш': 'sh', 'щ': 'shch', 'ы': 'y', 'э': 'e', 'ю': 'iu', |
| 91 | 'я': 'ia', 'ї': 'i', 'є': 'ie', 'ґ': 'g', 'і': 'i', |
| 92 | }, |
| 93 | } ); |
| 94 | |
| 95 | export function maybeCyrToLatin( str ) { |
| 96 | if ( convertSymbols.checkCyrRegex.test( str ) ) { |
| 97 | str = str.replace( convertSymbols.cyrRegex, function ( match ) { |
| 98 | |
| 99 | if ( undefined === convertSymbols.charsMap[ match ] ) { |
| 100 | return ''; |
| 101 | } |
| 102 | |
| 103 | return convertSymbols.charsMap[ match ]; |
| 104 | } ); |
| 105 | } |
| 106 | |
| 107 | return str; |
| 108 | } |
| 109 | |
| 110 | export function getConvertedName( valueToChange ) { |
| 111 | let slug = valueToChange.toLowerCase(); |
| 112 | |
| 113 | // Replace accents |
| 114 | slug = slug.normalize( 'NFD' ).replace( /[\u0300-\u036f]/g, '' ); |
| 115 | |
| 116 | // Replace cyrillic |
| 117 | slug = maybeCyrToLatin( slug ); |
| 118 | |
| 119 | // Get list of words |
| 120 | const slugParts = slug.match( /\b(\w+)\b/g ); |
| 121 | |
| 122 | slug = ''; |
| 123 | |
| 124 | for ( const [ slugIndex, slugPart ] of Object.entries( slugParts ) ) { |
| 125 | slug += ( |
| 126 | 0 === +slugIndex ? '' : '_' |
| 127 | ) + slugPart; |
| 128 | |
| 129 | const isLast = 1 + +slugIndex === slugParts.length; |
| 130 | |
| 131 | if ( slug.length > 60 ) { |
| 132 | return slug + ( |
| 133 | isLast ? '' : '__' |
| 134 | ); |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | return slug; |
| 139 | } |
| 140 | |
| 141 | export function classnames( ...additional ) { |
| 142 | const result = []; |
| 143 | |
| 144 | const parseValues = source => { |
| 145 | source.forEach( itemClass => { |
| 146 | if ( !itemClass ) { |
| 147 | return; |
| 148 | } |
| 149 | if ( Array.isArray( itemClass ) ) { |
| 150 | parseValues( itemClass ); |
| 151 | } |
| 152 | if ( 'string' === typeof itemClass ) { |
| 153 | result.push( itemClass.trim() ); |
| 154 | } |
| 155 | if ( 'object' === typeof itemClass ) { |
| 156 | for ( const itemClassKey in itemClass ) { |
| 157 | if ( itemClass[ itemClassKey ] ) { |
| 158 | result.push( ( |
| 159 | itemClassKey + '' |
| 160 | ).trim() ); |
| 161 | } |
| 162 | } |
| 163 | } |
| 164 | } ); |
| 165 | }; |
| 166 | |
| 167 | parseValues( additional ); |
| 168 | |
| 169 | return result.join( ' ' ); |
| 170 | } |
| 171 | |
| 172 | export function convertObjectToOptionsList( entries = [], { |
| 173 | usePlaceholder = true, |
| 174 | label = '--', |
| 175 | value = '', |
| 176 | } = {} ) { |
| 177 | const placeholder = { label, value }; |
| 178 | |
| 179 | if ( !entries ) { |
| 180 | return usePlaceholder ? [ placeholder ] : []; |
| 181 | } |
| 182 | |
| 183 | const options = Object.entries( entries ).map( ( [ value, label ] ) => { |
| 184 | return { value, label }; |
| 185 | } ); |
| 186 | |
| 187 | return usePlaceholder ? [ placeholder, ...options ] : options; |
| 188 | } |
| 189 | |
| 190 | export function assetUrl( url = '' ) { |
| 191 | return JetFormEditorData.assetsUrl + url; |
| 192 | } |
| 193 | |
| 194 | /** |
| 195 | * @since 3.1.0 |
| 196 | * |
| 197 | * @param obj |
| 198 | * @param path |
| 199 | * @param value |
| 200 | * @returns {*} |
| 201 | */ |
| 202 | export function set( obj, path, value ) { |
| 203 | // Create a shallow copy of the object |
| 204 | const newObj = JSON.parse( JSON.stringify( obj ) ); |
| 205 | |
| 206 | let currentObj = newObj; |
| 207 | let currentKey; |
| 208 | |
| 209 | // Traverse the object according to the path |
| 210 | for ( let i = 0; i < path.length; i++ ) { |
| 211 | currentKey = path[ i ]; |
| 212 | |
| 213 | // If the current key doesn't exist, create a new object at that key |
| 214 | if ( !currentObj[ currentKey ] ) { |
| 215 | currentObj[ currentKey ] = {}; |
| 216 | } |
| 217 | |
| 218 | // Update the current object and key |
| 219 | if ( i === path.length - 1 ) { |
| 220 | // If this is the last key in the path, set the value |
| 221 | currentObj[ currentKey ] = value; |
| 222 | } |
| 223 | else { |
| 224 | // Otherwise, continue traversing the object |
| 225 | currentObj[ currentKey ] = { ...currentObj[ currentKey ] }; |
| 226 | currentObj = currentObj[ currentKey ]; |
| 227 | } |
| 228 | } |
| 229 | |
| 230 | return newObj; |
| 231 | } |
| 232 | |
| 233 | /** |
| 234 | * @since 3.1.0 |
| 235 | * |
| 236 | * @param value |
| 237 | * @returns {boolean} |
| 238 | */ |
| 239 | export function isEmpty( value ) { |
| 240 | if ( null === value || undefined === value ) { |
| 241 | return true; |
| 242 | } |
| 243 | |
| 244 | if ( 'object' === typeof value && !Array.isArray( value ) ) { |
| 245 | return !Object.keys( value )?.length; |
| 246 | } |
| 247 | |
| 248 | if ( 'number' === typeof value ) { |
| 249 | return 0 === value; |
| 250 | } |
| 251 | |
| 252 | return !value?.length; |
| 253 | } |
| 254 | |
| 255 | export default Tools; |