attributes.json
1 month ago
constants.js
1 month ago
edit.js
1 month ago
index.js
1 month ago
shortcode-attributes.js
1 month ago
shortcode-upgrader.js
1 month ago
shortcode-attributes.js
108 lines
| 1 | import { attrs } from '@wordpress/shortcode'; |
| 2 | |
| 3 | const BOOLEAN_ATTRIBUTES = new Set( [ |
| 4 | 'get-all-children', |
| 5 | 'group-numbers', |
| 6 | 'symbols-first', |
| 7 | 'back-to-top', |
| 8 | 'hide-empty', |
| 9 | 'hide-empty-terms', |
| 10 | ] ); |
| 11 | |
| 12 | const NUMBER_ATTRIBUTES = new Set( [ 'columns', 'grouping', 'parent-post' ] ); |
| 13 | |
| 14 | const ARRAY_NUMBER_ATTRIBUTES = new Set( [ 'exclude-posts' ] ); |
| 15 | const ARRAY_STRING_ATTRIBUTES = new Set( [ 'terms', 'exclude-terms' ] ); |
| 16 | |
| 17 | const isTruthy = ( value ) => { |
| 18 | if ( typeof value === 'boolean' ) { |
| 19 | return value; |
| 20 | } |
| 21 | |
| 22 | if ( typeof value === 'number' ) { |
| 23 | return value !== 0; |
| 24 | } |
| 25 | |
| 26 | if ( typeof value !== 'string' ) { |
| 27 | return false; |
| 28 | } |
| 29 | |
| 30 | const normalized = value.trim().toLowerCase(); |
| 31 | |
| 32 | return [ '1', 'true', 'yes', 'y', 'on' ].includes( normalized ); |
| 33 | }; |
| 34 | |
| 35 | const toArray = ( value ) => { |
| 36 | if ( Array.isArray( value ) ) { |
| 37 | return value; |
| 38 | } |
| 39 | |
| 40 | if ( typeof value !== 'string' ) { |
| 41 | return []; |
| 42 | } |
| 43 | |
| 44 | return value |
| 45 | .split( ',' ) |
| 46 | .map( ( item ) => item.trim() ) |
| 47 | .filter( Boolean ); |
| 48 | }; |
| 49 | |
| 50 | const normalizeAttributeValue = ( key, value ) => { |
| 51 | if ( key === 'post-type' ) { |
| 52 | const postTypes = toArray( value ); |
| 53 | |
| 54 | return postTypes.length > 0 ? postTypes.join( ',' ) : undefined; |
| 55 | } |
| 56 | |
| 57 | if ( BOOLEAN_ATTRIBUTES.has( key ) ) { |
| 58 | return isTruthy( value ); |
| 59 | } |
| 60 | |
| 61 | if ( NUMBER_ATTRIBUTES.has( key ) ) { |
| 62 | if ( key === 'grouping' && typeof value === 'string' && value.trim().toLowerCase() === 'numbers' ) { |
| 63 | return undefined; |
| 64 | } |
| 65 | |
| 66 | const parsed = parseInt( value, 10 ); |
| 67 | |
| 68 | return Number.isNaN( parsed ) ? undefined : parsed; |
| 69 | } |
| 70 | |
| 71 | if ( ARRAY_NUMBER_ATTRIBUTES.has( key ) ) { |
| 72 | return toArray( value ) |
| 73 | .map( ( item ) => parseInt( item, 10 ) ) |
| 74 | .filter( ( item ) => ! Number.isNaN( item ) ); |
| 75 | } |
| 76 | |
| 77 | if ( ARRAY_STRING_ATTRIBUTES.has( key ) ) { |
| 78 | return toArray( value ); |
| 79 | } |
| 80 | |
| 81 | return value; |
| 82 | }; |
| 83 | |
| 84 | const getNamedShortcodeAttributes = ( shortcodeText ) => { |
| 85 | const parsedAttributes = attrs( shortcodeText ); |
| 86 | return parsedAttributes?.named || parsedAttributes || {}; |
| 87 | }; |
| 88 | |
| 89 | export const parseShortcodeAttributes = ( shortcodeText ) => { |
| 90 | const namedAttributes = getNamedShortcodeAttributes( shortcodeText ); |
| 91 | |
| 92 | const attributes = Object.entries( namedAttributes ).reduce( ( parsed, [ key, value ] ) => { |
| 93 | const normalizedValue = normalizeAttributeValue( key, value ); |
| 94 | |
| 95 | if ( typeof normalizedValue !== 'undefined' ) { |
| 96 | parsed[ key ] = normalizedValue; |
| 97 | } |
| 98 | |
| 99 | return parsed; |
| 100 | }, {} ); |
| 101 | |
| 102 | if ( typeof namedAttributes.grouping === 'string' && namedAttributes.grouping.trim().toLowerCase() === 'numbers' ) { |
| 103 | attributes[ 'group-numbers' ] = true; |
| 104 | } |
| 105 | |
| 106 | return attributes; |
| 107 | }; |
| 108 |