commands
3 weeks ago
pro
3 weeks ago
acf-escaped-html-notice.asset.php
1 year ago
acf-escaped-html-notice.js
1 year ago
acf-escaped-html-notice.js.map
1 year ago
acf-escaped-html-notice.min.asset.php
8 months ago
acf-escaped-html-notice.min.js
8 months ago
acf-field-group.asset.php
3 months ago
acf-field-group.js
3 months ago
acf-field-group.js.map
3 months ago
acf-field-group.min.asset.php
3 months ago
acf-field-group.min.js
3 months ago
acf-input.asset.php
3 weeks ago
acf-input.js
3 weeks ago
acf-input.js.map
3 weeks ago
acf-input.min.asset.php
3 weeks ago
acf-input.min.js
3 weeks ago
acf-internal-post-type.asset.php
8 months ago
acf-internal-post-type.js
8 months ago
acf-internal-post-type.js.map
8 months ago
acf-internal-post-type.min.asset.php
8 months ago
acf-internal-post-type.min.js
8 months ago
acf.asset.php
7 months ago
acf.js
7 months ago
acf.js.map
7 months ago
acf.min.asset.php
7 months ago
acf.min.js
7 months ago
index.php
1 year ago
scf-bindings.asset.php
3 weeks ago
scf-bindings.js
3 weeks ago
scf-bindings.js.map
3 weeks ago
scf-bindings.min.asset.php
3 weeks ago
scf-bindings.min.js
3 weeks ago
scf-bindings.js
1134 lines
| 1 | /******/ (() => { // webpackBootstrap |
| 2 | /******/ "use strict"; |
| 3 | /******/ var __webpack_modules__ = ({ |
| 4 | |
| 5 | /***/ "./assets/src/js/bindings/block-editor.js": |
| 6 | /*!************************************************!*\ |
| 7 | !*** ./assets/src/js/bindings/block-editor.js ***! |
| 8 | \************************************************/ |
| 9 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 10 | |
| 11 | __webpack_require__.r(__webpack_exports__); |
| 12 | /* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element"); |
| 13 | /* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__); |
| 14 | /* harmony import */ var _wordpress_hooks__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/hooks */ "@wordpress/hooks"); |
| 15 | /* harmony import */ var _wordpress_hooks__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_hooks__WEBPACK_IMPORTED_MODULE_1__); |
| 16 | /* harmony import */ var _wordpress_compose__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/compose */ "@wordpress/compose"); |
| 17 | /* harmony import */ var _wordpress_compose__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_compose__WEBPACK_IMPORTED_MODULE_2__); |
| 18 | /* harmony import */ var _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @wordpress/block-editor */ "@wordpress/block-editor"); |
| 19 | /* harmony import */ var _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_3__); |
| 20 | /* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @wordpress/components */ "@wordpress/components"); |
| 21 | /* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_wordpress_components__WEBPACK_IMPORTED_MODULE_4__); |
| 22 | /* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); |
| 23 | /* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_5__); |
| 24 | /* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./constants */ "./assets/src/js/bindings/constants.js"); |
| 25 | /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./utils */ "./assets/src/js/bindings/utils.js"); |
| 26 | /* harmony import */ var _hooks__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./hooks */ "./assets/src/js/bindings/hooks.js"); |
| 27 | /** |
| 28 | * WordPress dependencies |
| 29 | */ |
| 30 | |
| 31 | |
| 32 | |
| 33 | |
| 34 | |
| 35 | |
| 36 | |
| 37 | /** |
| 38 | * Internal dependencies |
| 39 | */ |
| 40 | |
| 41 | |
| 42 | |
| 43 | |
| 44 | /** |
| 45 | * Add custom block binding controls to supported blocks. |
| 46 | * |
| 47 | * @since 6.5.0 |
| 48 | */ |
| 49 | const withCustomControls = (0,_wordpress_compose__WEBPACK_IMPORTED_MODULE_2__.createHigherOrderComponent)(BlockEdit => { |
| 50 | return props => { |
| 51 | const bindableAttributes = (0,_utils__WEBPACK_IMPORTED_MODULE_7__.getBindableAttributes)(props.name); |
| 52 | const { |
| 53 | updateBlockBindings, |
| 54 | removeAllBlockBindings |
| 55 | } = (0,_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_3__.useBlockBindingsUtils)(); |
| 56 | |
| 57 | // Get editor context |
| 58 | const { |
| 59 | isSiteEditor, |
| 60 | templatePostType |
| 61 | } = (0,_hooks__WEBPACK_IMPORTED_MODULE_8__.useSiteEditorContext)(); |
| 62 | |
| 63 | // Get fields based on editor context |
| 64 | const postEditorFields = (0,_hooks__WEBPACK_IMPORTED_MODULE_8__.usePostEditorFields)(); |
| 65 | const { |
| 66 | fields: siteEditorFields |
| 67 | } = (0,_hooks__WEBPACK_IMPORTED_MODULE_8__.useSiteEditorFields)(templatePostType); |
| 68 | |
| 69 | // Use appropriate fields based on context |
| 70 | const activeFields = isSiteEditor ? siteEditorFields : postEditorFields; |
| 71 | |
| 72 | // Convert fields to options format |
| 73 | const allFieldOptions = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => (0,_utils__WEBPACK_IMPORTED_MODULE_7__.fieldsToOptions)(activeFields), [activeFields]); |
| 74 | |
| 75 | // Track bound fields |
| 76 | const { |
| 77 | boundFields, |
| 78 | setBoundFields |
| 79 | } = (0,_hooks__WEBPACK_IMPORTED_MODULE_8__.useBoundFields)(props.attributes); |
| 80 | |
| 81 | // Get filtered field options for a specific attribute |
| 82 | const getAttributeFieldOptions = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.useCallback)((attribute = null) => { |
| 83 | return (0,_utils__WEBPACK_IMPORTED_MODULE_7__.getFilteredFieldOptions)(allFieldOptions, props.name, attribute); |
| 84 | }, [allFieldOptions, props.name]); |
| 85 | |
| 86 | // Check if all attributes can use unified binding mode |
| 87 | const canUseAllAttributesMode = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => (0,_utils__WEBPACK_IMPORTED_MODULE_7__.canUseUnifiedBinding)(props.name, bindableAttributes), [props.name, bindableAttributes]); |
| 88 | |
| 89 | // Handle field selection changes |
| 90 | const handleFieldChange = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.useCallback)((attribute, value) => { |
| 91 | if (Array.isArray(attribute)) { |
| 92 | // Handle multiple attributes at once |
| 93 | const newBoundFields = { |
| 94 | ...boundFields |
| 95 | }; |
| 96 | const bindings = {}; |
| 97 | attribute.forEach(attr => { |
| 98 | newBoundFields[attr] = value; |
| 99 | bindings[attr] = value ? { |
| 100 | source: _constants__WEBPACK_IMPORTED_MODULE_6__.BINDING_SOURCE, |
| 101 | args: { |
| 102 | key: value |
| 103 | } |
| 104 | } : undefined; |
| 105 | }); |
| 106 | setBoundFields(newBoundFields); |
| 107 | updateBlockBindings(bindings); |
| 108 | } else { |
| 109 | // Handle single attribute |
| 110 | setBoundFields(prev => ({ |
| 111 | ...prev, |
| 112 | [attribute]: value |
| 113 | })); |
| 114 | updateBlockBindings({ |
| 115 | [attribute]: value ? { |
| 116 | source: _constants__WEBPACK_IMPORTED_MODULE_6__.BINDING_SOURCE, |
| 117 | args: { |
| 118 | key: value |
| 119 | } |
| 120 | } : undefined |
| 121 | }); |
| 122 | } |
| 123 | }, [boundFields, setBoundFields, updateBlockBindings]); |
| 124 | |
| 125 | // Handle reset all bindings |
| 126 | const handleReset = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => { |
| 127 | removeAllBlockBindings(); |
| 128 | setBoundFields({}); |
| 129 | }, [removeAllBlockBindings, setBoundFields]); |
| 130 | |
| 131 | // Determine if we should show the panel |
| 132 | const shouldShowPanel = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => { |
| 133 | // In site editor, show panel if block has bindable attributes |
| 134 | if (isSiteEditor) { |
| 135 | return bindableAttributes && bindableAttributes.length > 0; |
| 136 | } |
| 137 | // In post editor, only show if we have fields available |
| 138 | return allFieldOptions.length > 0 && bindableAttributes && bindableAttributes.length > 0; |
| 139 | }, [isSiteEditor, allFieldOptions, bindableAttributes]); |
| 140 | if (!shouldShowPanel) { |
| 141 | return /*#__PURE__*/React.createElement(BlockEdit, props); |
| 142 | } |
| 143 | return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_3__.InspectorControls, props, /*#__PURE__*/React.createElement(_wordpress_components__WEBPACK_IMPORTED_MODULE_4__.__experimentalToolsPanel, { |
| 144 | label: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_5__.__)('Connect to a field', 'secure-custom-fields'), |
| 145 | resetAll: handleReset |
| 146 | }, canUseAllAttributesMode ? /*#__PURE__*/React.createElement(_wordpress_components__WEBPACK_IMPORTED_MODULE_4__.__experimentalToolsPanelItem, { |
| 147 | hasValue: () => !!boundFields[bindableAttributes[0]], |
| 148 | label: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_5__.__)('All attributes', 'secure-custom-fields'), |
| 149 | onDeselect: () => handleFieldChange(bindableAttributes, null), |
| 150 | isShownByDefault: true |
| 151 | }, /*#__PURE__*/React.createElement(_wordpress_components__WEBPACK_IMPORTED_MODULE_4__.ComboboxControl, { |
| 152 | label: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_5__.__)('Field', 'secure-custom-fields'), |
| 153 | placeholder: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_5__.__)('Select a field', 'secure-custom-fields'), |
| 154 | options: getAttributeFieldOptions(), |
| 155 | value: boundFields[bindableAttributes[0]] || '', |
| 156 | onChange: value => handleFieldChange(bindableAttributes, value), |
| 157 | __next40pxDefaultSize: true, |
| 158 | __nextHasNoMarginBottom: true |
| 159 | })) : bindableAttributes.map(attribute => /*#__PURE__*/React.createElement(_wordpress_components__WEBPACK_IMPORTED_MODULE_4__.__experimentalToolsPanelItem, { |
| 160 | key: `scf-binding-${attribute}`, |
| 161 | hasValue: () => !!boundFields[attribute], |
| 162 | label: attribute, |
| 163 | onDeselect: () => handleFieldChange(attribute, null), |
| 164 | isShownByDefault: true |
| 165 | }, /*#__PURE__*/React.createElement(_wordpress_components__WEBPACK_IMPORTED_MODULE_4__.ComboboxControl, { |
| 166 | label: attribute, |
| 167 | placeholder: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_5__.__)('Select a field', 'secure-custom-fields'), |
| 168 | options: getAttributeFieldOptions(attribute), |
| 169 | value: boundFields[attribute] || '', |
| 170 | onChange: value => handleFieldChange(attribute, value), |
| 171 | __next40pxDefaultSize: true, |
| 172 | __nextHasNoMarginBottom: true |
| 173 | }))))), /*#__PURE__*/React.createElement(BlockEdit, props)); |
| 174 | }; |
| 175 | }, 'withCustomControls'); |
| 176 | (0,_wordpress_hooks__WEBPACK_IMPORTED_MODULE_1__.addFilter)('editor.BlockEdit', 'secure-custom-fields/with-custom-controls', withCustomControls); |
| 177 | |
| 178 | /***/ }), |
| 179 | |
| 180 | /***/ "./assets/src/js/bindings/constants.js": |
| 181 | /*!*********************************************!*\ |
| 182 | !*** ./assets/src/js/bindings/constants.js ***! |
| 183 | \*********************************************/ |
| 184 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 185 | |
| 186 | __webpack_require__.r(__webpack_exports__); |
| 187 | /* harmony export */ __webpack_require__.d(__webpack_exports__, { |
| 188 | /* harmony export */ BINDING_SOURCE: () => (/* binding */ BINDING_SOURCE), |
| 189 | /* harmony export */ BLOCK_BINDINGS_CONFIG: () => (/* binding */ BLOCK_BINDINGS_CONFIG) |
| 190 | /* harmony export */ }); |
| 191 | /** |
| 192 | * Block binding configuration |
| 193 | * |
| 194 | * Defines which SCF field types can be bound to specific block attributes. |
| 195 | */ |
| 196 | const BLOCK_BINDINGS_CONFIG = { |
| 197 | 'core/paragraph': { |
| 198 | content: ['text', 'textarea', 'date_picker', 'number', 'range'] |
| 199 | }, |
| 200 | 'core/heading': { |
| 201 | content: ['text', 'textarea', 'date_picker', 'number', 'range'] |
| 202 | }, |
| 203 | 'core/image': { |
| 204 | id: ['image'], |
| 205 | url: ['image'], |
| 206 | title: ['image'], |
| 207 | alt: ['image'] |
| 208 | }, |
| 209 | 'core/button': { |
| 210 | url: ['url'], |
| 211 | text: ['text', 'checkbox', 'select', 'date_picker'], |
| 212 | linkTarget: ['text', 'checkbox', 'select'], |
| 213 | rel: ['text', 'checkbox', 'select'] |
| 214 | } |
| 215 | }; |
| 216 | |
| 217 | /** |
| 218 | * Binding source identifier |
| 219 | */ |
| 220 | const BINDING_SOURCE = 'acf/field'; |
| 221 | |
| 222 | /***/ }), |
| 223 | |
| 224 | /***/ "./assets/src/js/bindings/field-processing.js": |
| 225 | /*!****************************************************!*\ |
| 226 | !*** ./assets/src/js/bindings/field-processing.js ***! |
| 227 | \****************************************************/ |
| 228 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 229 | |
| 230 | __webpack_require__.r(__webpack_exports__); |
| 231 | /* harmony export */ __webpack_require__.d(__webpack_exports__, { |
| 232 | /* harmony export */ formatFieldLabel: () => (/* binding */ formatFieldLabel), |
| 233 | /* harmony export */ getFieldLabel: () => (/* binding */ getFieldLabel), |
| 234 | /* harmony export */ getSCFFields: () => (/* binding */ getSCFFields), |
| 235 | /* harmony export */ processFieldBinding: () => (/* binding */ processFieldBinding), |
| 236 | /* harmony export */ resolveImageAttribute: () => (/* binding */ resolveImageAttribute) |
| 237 | /* harmony export */ }); |
| 238 | /** |
| 239 | * Field processing utilities for block bindings |
| 240 | * |
| 241 | * @since 6.5.0 |
| 242 | */ |
| 243 | |
| 244 | /** |
| 245 | * Gets the SCF fields from the post entity. |
| 246 | * |
| 247 | * @since 6.5.0 |
| 248 | * |
| 249 | * @param {Object} post The post entity object. |
| 250 | * @return {Object} The SCF fields object with source data. |
| 251 | */ |
| 252 | function getSCFFields(post) { |
| 253 | if (!post?.acf) { |
| 254 | return {}; |
| 255 | } |
| 256 | |
| 257 | // Extract only the _source fields which contain the formatted data |
| 258 | const sourceFields = {}; |
| 259 | Object.entries(post.acf).forEach(([key, value]) => { |
| 260 | if (key.endsWith('_source')) { |
| 261 | // Remove the _source suffix to get the field name |
| 262 | const fieldName = key.replace('_source', ''); |
| 263 | sourceFields[fieldName] = value; |
| 264 | } |
| 265 | }); |
| 266 | return sourceFields; |
| 267 | } |
| 268 | |
| 269 | /** |
| 270 | * Resolves image attribute values from an image object. |
| 271 | * |
| 272 | * @since 6.5.0 |
| 273 | * |
| 274 | * @param {Object} imageObj The image object from SCF field data. |
| 275 | * @param {string} attribute The attribute to resolve (url, alt, title, id). |
| 276 | * @return {string|number} The resolved attribute value. |
| 277 | */ |
| 278 | function resolveImageAttribute(imageObj, attribute) { |
| 279 | if (!imageObj) { |
| 280 | return ''; |
| 281 | } |
| 282 | switch (attribute) { |
| 283 | case 'url': |
| 284 | return imageObj.url || ''; |
| 285 | case 'alt': |
| 286 | return imageObj.alt || ''; |
| 287 | case 'title': |
| 288 | return imageObj.title || ''; |
| 289 | case 'id': |
| 290 | return imageObj.id || imageObj.ID || ''; |
| 291 | default: |
| 292 | return ''; |
| 293 | } |
| 294 | } |
| 295 | |
| 296 | /** |
| 297 | * Processes a single field binding and returns its resolved value. |
| 298 | * |
| 299 | * @since 6.7.0 |
| 300 | * |
| 301 | * @param {string} attribute The attribute being bound. |
| 302 | * @param {Object} args The binding arguments. |
| 303 | * @param {Object} scfFields The SCF fields object. |
| 304 | * @return {string} The resolved field value. |
| 305 | */ |
| 306 | function processFieldBinding(attribute, args, scfFields) { |
| 307 | const fieldName = args?.key; |
| 308 | const fieldConfig = scfFields[fieldName]; |
| 309 | if (!fieldConfig) { |
| 310 | return ''; |
| 311 | } |
| 312 | const fieldType = fieldConfig.type; |
| 313 | const fieldValue = fieldConfig.formatted_value; |
| 314 | switch (fieldType) { |
| 315 | case 'image': |
| 316 | return resolveImageAttribute(fieldValue, attribute); |
| 317 | case 'checkbox': |
| 318 | // For checkbox fields, join array values or return as string |
| 319 | if (Array.isArray(fieldValue)) { |
| 320 | return fieldValue.join(', '); |
| 321 | } |
| 322 | return fieldValue ? String(fieldValue) : ''; |
| 323 | case 'number': |
| 324 | case 'range': |
| 325 | return fieldValue ? String(fieldValue) : ''; |
| 326 | case 'date_picker': |
| 327 | case 'text': |
| 328 | case 'textarea': |
| 329 | case 'url': |
| 330 | case 'email': |
| 331 | case 'select': |
| 332 | default: |
| 333 | return fieldValue ? String(fieldValue) : ''; |
| 334 | } |
| 335 | } |
| 336 | |
| 337 | /** |
| 338 | * Formats a field key into a human-readable label. |
| 339 | * |
| 340 | * @since 6.7.0 |
| 341 | * |
| 342 | * @param {string} fieldKey The field key (e.g., 'my_field_name'). |
| 343 | * @return {string} Formatted label (e.g., 'My Field Name'). |
| 344 | */ |
| 345 | function formatFieldLabel(fieldKey) { |
| 346 | if (!fieldKey) { |
| 347 | return ''; |
| 348 | } |
| 349 | return fieldKey.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' '); |
| 350 | } |
| 351 | |
| 352 | /** |
| 353 | * Gets the field label from metadata or formats the field key. |
| 354 | * |
| 355 | * @since 6.7.0 |
| 356 | * @param {string} fieldKey The field key. |
| 357 | * @param {Object} fieldMetadata Optional field metadata object. |
| 358 | * @param {string} defaultLabel Optional default label to use. |
| 359 | * @return {string} The field label. |
| 360 | */ |
| 361 | function getFieldLabel(fieldKey, fieldMetadata = null, defaultLabel = '') { |
| 362 | if (!fieldKey) { |
| 363 | return defaultLabel; |
| 364 | } |
| 365 | |
| 366 | // Try to get the label from the provided metadata |
| 367 | if (fieldMetadata && fieldMetadata[fieldKey]?.label) { |
| 368 | return fieldMetadata[fieldKey].label; |
| 369 | } |
| 370 | |
| 371 | // Fallback: format field key as a label |
| 372 | return formatFieldLabel(fieldKey); |
| 373 | } |
| 374 | |
| 375 | /***/ }), |
| 376 | |
| 377 | /***/ "./assets/src/js/bindings/fieldMetadataCache.js": |
| 378 | /*!******************************************************!*\ |
| 379 | !*** ./assets/src/js/bindings/fieldMetadataCache.js ***! |
| 380 | \******************************************************/ |
| 381 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 382 | |
| 383 | __webpack_require__.r(__webpack_exports__); |
| 384 | /* harmony export */ __webpack_require__.d(__webpack_exports__, { |
| 385 | /* harmony export */ addFieldMetadata: () => (/* binding */ addFieldMetadata), |
| 386 | /* harmony export */ clearFieldMetadata: () => (/* binding */ clearFieldMetadata), |
| 387 | /* harmony export */ getAllFieldMetadata: () => (/* binding */ getAllFieldMetadata), |
| 388 | /* harmony export */ getFieldMetadata: () => (/* binding */ getFieldMetadata), |
| 389 | /* harmony export */ hasFieldMetadata: () => (/* binding */ hasFieldMetadata), |
| 390 | /* harmony export */ setFieldMetadata: () => (/* binding */ setFieldMetadata) |
| 391 | /* harmony export */ }); |
| 392 | /** |
| 393 | * SCF Field Metadata Cache |
| 394 | * |
| 395 | * @since 6.7.0 |
| 396 | * Simple cache for field metadata used in block bindings. |
| 397 | */ |
| 398 | |
| 399 | let fieldMetadataCache = {}; |
| 400 | |
| 401 | /** |
| 402 | * Set field metadata, replacing all existing data. |
| 403 | * |
| 404 | * @param {Object} fields - Field metadata object keyed by field key. |
| 405 | */ |
| 406 | const setFieldMetadata = fields => { |
| 407 | fieldMetadataCache = fields || {}; |
| 408 | }; |
| 409 | |
| 410 | /** |
| 411 | * Add field metadata, merging with existing data. |
| 412 | * |
| 413 | * @param {Object} fields - Field metadata object keyed by field key. |
| 414 | */ |
| 415 | const addFieldMetadata = fields => { |
| 416 | fieldMetadataCache = { |
| 417 | ...fieldMetadataCache, |
| 418 | ...fields |
| 419 | }; |
| 420 | }; |
| 421 | |
| 422 | /** |
| 423 | * Clear all field metadata. |
| 424 | */ |
| 425 | const clearFieldMetadata = () => { |
| 426 | fieldMetadataCache = {}; |
| 427 | }; |
| 428 | |
| 429 | /** |
| 430 | * Get field metadata for a specific field. |
| 431 | * |
| 432 | * @param {string} fieldKey - The field key to retrieve metadata for. |
| 433 | * @return {Object|null} Field metadata object or null if not found. |
| 434 | */ |
| 435 | const getFieldMetadata = fieldKey => { |
| 436 | return fieldMetadataCache[fieldKey] || null; |
| 437 | }; |
| 438 | |
| 439 | /** |
| 440 | * Get all field metadata. |
| 441 | * |
| 442 | * @return {Object} All field metadata. |
| 443 | */ |
| 444 | const getAllFieldMetadata = () => { |
| 445 | return fieldMetadataCache; |
| 446 | }; |
| 447 | |
| 448 | /** |
| 449 | * Check if field metadata exists for a given key. |
| 450 | * |
| 451 | * @param {string} fieldKey - The field key to check. |
| 452 | * @return {boolean} True if metadata exists, false otherwise. |
| 453 | */ |
| 454 | const hasFieldMetadata = fieldKey => { |
| 455 | return !!fieldMetadataCache[fieldKey]; |
| 456 | }; |
| 457 | |
| 458 | /***/ }), |
| 459 | |
| 460 | /***/ "./assets/src/js/bindings/hooks.js": |
| 461 | /*!*****************************************!*\ |
| 462 | !*** ./assets/src/js/bindings/hooks.js ***! |
| 463 | \*****************************************/ |
| 464 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 465 | |
| 466 | __webpack_require__.r(__webpack_exports__); |
| 467 | /* harmony export */ __webpack_require__.d(__webpack_exports__, { |
| 468 | /* harmony export */ useBoundFields: () => (/* binding */ useBoundFields), |
| 469 | /* harmony export */ usePostEditorFields: () => (/* binding */ usePostEditorFields), |
| 470 | /* harmony export */ useSiteEditorContext: () => (/* binding */ useSiteEditorContext), |
| 471 | /* harmony export */ useSiteEditorFields: () => (/* binding */ useSiteEditorFields) |
| 472 | /* harmony export */ }); |
| 473 | /* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element"); |
| 474 | /* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__); |
| 475 | /* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/data */ "@wordpress/data"); |
| 476 | /* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_data__WEBPACK_IMPORTED_MODULE_1__); |
| 477 | /* harmony import */ var _wordpress_core_data__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/core-data */ "@wordpress/core-data"); |
| 478 | /* harmony import */ var _wordpress_core_data__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_core_data__WEBPACK_IMPORTED_MODULE_2__); |
| 479 | /* harmony import */ var _wordpress_editor__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @wordpress/editor */ "@wordpress/editor"); |
| 480 | /* harmony import */ var _wordpress_editor__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_wordpress_editor__WEBPACK_IMPORTED_MODULE_3__); |
| 481 | /* harmony import */ var _wordpress_api_fetch__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @wordpress/api-fetch */ "@wordpress/api-fetch"); |
| 482 | /* harmony import */ var _wordpress_api_fetch__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_wordpress_api_fetch__WEBPACK_IMPORTED_MODULE_4__); |
| 483 | /* harmony import */ var _wordpress_url__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @wordpress/url */ "@wordpress/url"); |
| 484 | /* harmony import */ var _wordpress_url__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_wordpress_url__WEBPACK_IMPORTED_MODULE_5__); |
| 485 | /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./utils */ "./assets/src/js/bindings/utils.js"); |
| 486 | /* harmony import */ var _fieldMetadataCache__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./fieldMetadataCache */ "./assets/src/js/bindings/fieldMetadataCache.js"); |
| 487 | /** |
| 488 | * Custom hooks for block bindings |
| 489 | */ |
| 490 | |
| 491 | |
| 492 | |
| 493 | |
| 494 | |
| 495 | |
| 496 | |
| 497 | |
| 498 | |
| 499 | |
| 500 | /** |
| 501 | * Custom hook to detect if we're in the site editor and get the template info. |
| 502 | * |
| 503 | * @since 6.7.0 |
| 504 | * @return {Object} Object containing isSiteEditor flag and templatePostType. |
| 505 | */ |
| 506 | function useSiteEditorContext() { |
| 507 | return (0,_wordpress_data__WEBPACK_IMPORTED_MODULE_1__.useSelect)(select => { |
| 508 | const { |
| 509 | getCurrentPostType, |
| 510 | getCurrentPostId |
| 511 | } = select(_wordpress_editor__WEBPACK_IMPORTED_MODULE_3__.store); |
| 512 | const { |
| 513 | getEditedEntityRecord |
| 514 | } = select(_wordpress_core_data__WEBPACK_IMPORTED_MODULE_2__.store); |
| 515 | const postType = getCurrentPostType(); |
| 516 | const postId = getCurrentPostId(); |
| 517 | const isSiteEditor = postType === 'wp_template'; |
| 518 | if (!isSiteEditor) { |
| 519 | return { |
| 520 | isSiteEditor: false, |
| 521 | templatePostType: null |
| 522 | }; |
| 523 | } |
| 524 | const template = getEditedEntityRecord('postType', 'wp_template', postId); |
| 525 | const templatePostType = (0,_utils__WEBPACK_IMPORTED_MODULE_6__.extractPostTypeFromTemplate)(template?.slug || ''); |
| 526 | return { |
| 527 | isSiteEditor: true, |
| 528 | templatePostType |
| 529 | }; |
| 530 | }, []); |
| 531 | } |
| 532 | |
| 533 | /** |
| 534 | * Custom hook to get SCF fields for the current post editor context. |
| 535 | * |
| 536 | * @since 6.7.0 |
| 537 | * @return {Object} Object containing the fields map. |
| 538 | */ |
| 539 | function usePostEditorFields() { |
| 540 | return (0,_wordpress_data__WEBPACK_IMPORTED_MODULE_1__.useSelect)(select => { |
| 541 | const { |
| 542 | getCurrentPostType, |
| 543 | getCurrentPostId |
| 544 | } = select(_wordpress_editor__WEBPACK_IMPORTED_MODULE_3__.store); |
| 545 | const { |
| 546 | getEditedEntityRecord |
| 547 | } = select(_wordpress_core_data__WEBPACK_IMPORTED_MODULE_2__.store); |
| 548 | const postType = getCurrentPostType(); |
| 549 | const postId = getCurrentPostId(); |
| 550 | if (!postType || !postId || postType === 'wp_template') { |
| 551 | return {}; |
| 552 | } |
| 553 | const record = getEditedEntityRecord('postType', postType, postId); |
| 554 | |
| 555 | // Extract fields that have '_source' counterparts |
| 556 | const sourcedFields = {}; |
| 557 | if (record?.acf) { |
| 558 | Object.entries(record.acf).forEach(([key, value]) => { |
| 559 | if (key.endsWith('_source')) { |
| 560 | const baseFieldName = key.replace('_source', ''); |
| 561 | if (Object.hasOwn(record.acf, baseFieldName)) { |
| 562 | sourcedFields[baseFieldName] = value; |
| 563 | } |
| 564 | } |
| 565 | }); |
| 566 | } |
| 567 | return sourcedFields; |
| 568 | }, []); |
| 569 | } |
| 570 | |
| 571 | /** |
| 572 | * Custom hook to fetch and manage SCF field groups from the REST API. |
| 573 | * |
| 574 | * @since 6.7.0 |
| 575 | * @param {string|null} postType The post type to fetch fields for. |
| 576 | * @return {Object} Object containing fields, isLoading, and error. |
| 577 | */ |
| 578 | function useSiteEditorFields(postType) { |
| 579 | const [fields, setFields] = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.useState)({}); |
| 580 | const [isLoading, setIsLoading] = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.useState)(false); |
| 581 | const [error, setError] = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.useState)(null); |
| 582 | (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => { |
| 583 | if (!postType) { |
| 584 | setFields({}); |
| 585 | setIsLoading(false); |
| 586 | setError(null); |
| 587 | return; |
| 588 | } |
| 589 | let isCancelled = false; |
| 590 | setIsLoading(true); |
| 591 | setError(null); |
| 592 | const fetchFields = async () => { |
| 593 | try { |
| 594 | const path = (0,_wordpress_url__WEBPACK_IMPORTED_MODULE_5__.addQueryArgs)(`/wp/v2/types/${postType}`, { |
| 595 | context: 'edit' |
| 596 | }); |
| 597 | const postTypeData = await _wordpress_api_fetch__WEBPACK_IMPORTED_MODULE_4___default()({ |
| 598 | path |
| 599 | }); |
| 600 | if (isCancelled) { |
| 601 | return; |
| 602 | } |
| 603 | const fieldsMap = (0,_utils__WEBPACK_IMPORTED_MODULE_6__.formatFieldGroupsData)(postTypeData.scf_field_groups); |
| 604 | |
| 605 | // Store field metadata in the data store |
| 606 | (0,_fieldMetadataCache__WEBPACK_IMPORTED_MODULE_7__.addFieldMetadata)(fieldsMap); |
| 607 | setFields(fieldsMap); |
| 608 | setIsLoading(false); |
| 609 | } catch (err) { |
| 610 | if (!isCancelled) { |
| 611 | setError(err); |
| 612 | setIsLoading(false); |
| 613 | } |
| 614 | } |
| 615 | }; |
| 616 | fetchFields(); |
| 617 | |
| 618 | // Cleanup function to prevent state updates after unmount |
| 619 | return () => { |
| 620 | isCancelled = true; |
| 621 | }; |
| 622 | }, [postType]); |
| 623 | return { |
| 624 | fields, |
| 625 | isLoading, |
| 626 | error |
| 627 | }; |
| 628 | } |
| 629 | |
| 630 | /** |
| 631 | * Custom hook to manage block bindings state. |
| 632 | * |
| 633 | * @since 6.7.0 |
| 634 | * @param {Object} blockAttributes The block attributes object. |
| 635 | * @return {Object} Object containing boundFields and sync function. |
| 636 | */ |
| 637 | function useBoundFields(blockAttributes) { |
| 638 | const [boundFields, setBoundFields] = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.useState)({}); |
| 639 | (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => { |
| 640 | const currentBindings = blockAttributes?.metadata?.bindings || {}; |
| 641 | const newBoundFields = {}; |
| 642 | Object.keys(currentBindings).forEach(attribute => { |
| 643 | if (currentBindings[attribute]?.args?.key) { |
| 644 | newBoundFields[attribute] = currentBindings[attribute].args.key; |
| 645 | } |
| 646 | }); |
| 647 | setBoundFields(newBoundFields); |
| 648 | }, [blockAttributes?.metadata?.bindings]); |
| 649 | return { |
| 650 | boundFields, |
| 651 | setBoundFields |
| 652 | }; |
| 653 | } |
| 654 | |
| 655 | /***/ }), |
| 656 | |
| 657 | /***/ "./assets/src/js/bindings/sources.js": |
| 658 | /*!*******************************************!*\ |
| 659 | !*** ./assets/src/js/bindings/sources.js ***! |
| 660 | \*******************************************/ |
| 661 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 662 | |
| 663 | __webpack_require__.r(__webpack_exports__); |
| 664 | /* harmony import */ var _wordpress_blocks__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/blocks */ "@wordpress/blocks"); |
| 665 | /* harmony import */ var _wordpress_blocks__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_blocks__WEBPACK_IMPORTED_MODULE_0__); |
| 666 | /* harmony import */ var _wordpress_core_data__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/core-data */ "@wordpress/core-data"); |
| 667 | /* harmony import */ var _wordpress_core_data__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_core_data__WEBPACK_IMPORTED_MODULE_1__); |
| 668 | /* harmony import */ var _wordpress_editor__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/editor */ "@wordpress/editor"); |
| 669 | /* harmony import */ var _wordpress_editor__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_editor__WEBPACK_IMPORTED_MODULE_2__); |
| 670 | /* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); |
| 671 | /* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__); |
| 672 | /* harmony import */ var _field_processing__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./field-processing */ "./assets/src/js/bindings/field-processing.js"); |
| 673 | /* harmony import */ var _fieldMetadataCache__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./fieldMetadataCache */ "./assets/src/js/bindings/fieldMetadataCache.js"); |
| 674 | /** |
| 675 | * WordPress dependencies |
| 676 | */ |
| 677 | |
| 678 | |
| 679 | |
| 680 | |
| 681 | |
| 682 | /** |
| 683 | * Internal dependencies |
| 684 | */ |
| 685 | |
| 686 | |
| 687 | |
| 688 | /** |
| 689 | * Register the SCF field binding source. |
| 690 | */ |
| 691 | (0,_wordpress_blocks__WEBPACK_IMPORTED_MODULE_0__.registerBlockBindingsSource)({ |
| 692 | name: 'acf/field', |
| 693 | label: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__.__)('SCF Fields', 'secure-custom-fields'), |
| 694 | getLabel({ |
| 695 | args, |
| 696 | select |
| 697 | }) { |
| 698 | const fieldKey = args?.key; |
| 699 | if (!fieldKey) { |
| 700 | return (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__.__)('SCF Fields', 'secure-custom-fields'); |
| 701 | } |
| 702 | const fieldMetadata = (0,_fieldMetadataCache__WEBPACK_IMPORTED_MODULE_5__.getFieldMetadata)(fieldKey); |
| 703 | if (fieldMetadata?.label) { |
| 704 | return fieldMetadata.label; |
| 705 | } |
| 706 | return (0,_field_processing__WEBPACK_IMPORTED_MODULE_4__.formatFieldLabel)(fieldKey); |
| 707 | }, |
| 708 | getValues({ |
| 709 | context, |
| 710 | bindings, |
| 711 | select |
| 712 | }) { |
| 713 | const { |
| 714 | getCurrentPostType |
| 715 | } = select(_wordpress_editor__WEBPACK_IMPORTED_MODULE_2__.store); |
| 716 | const currentPostType = getCurrentPostType(); |
| 717 | const isSiteEditor = currentPostType === 'wp_template'; |
| 718 | |
| 719 | // In site editor, return field labels as placeholder values |
| 720 | if (isSiteEditor) { |
| 721 | const result = {}; |
| 722 | Object.entries(bindings).forEach(([attribute, { |
| 723 | args |
| 724 | } = {}]) => { |
| 725 | const fieldKey = args?.key; |
| 726 | if (!fieldKey) { |
| 727 | result[attribute] = ''; |
| 728 | return; |
| 729 | } |
| 730 | const fieldMetadata = (0,_fieldMetadataCache__WEBPACK_IMPORTED_MODULE_5__.getFieldMetadata)(fieldKey); |
| 731 | result[attribute] = fieldMetadata?.label || (0,_field_processing__WEBPACK_IMPORTED_MODULE_4__.formatFieldLabel)(fieldKey); |
| 732 | }); |
| 733 | return result; |
| 734 | } |
| 735 | |
| 736 | // Regular post editor - get actual field values |
| 737 | const { |
| 738 | getEditedEntityRecord |
| 739 | } = select(_wordpress_core_data__WEBPACK_IMPORTED_MODULE_1__.store); |
| 740 | const post = context?.postType && context?.postId ? getEditedEntityRecord('postType', context.postType, context.postId) : undefined; |
| 741 | const scfFields = (0,_field_processing__WEBPACK_IMPORTED_MODULE_4__.getSCFFields)(post); |
| 742 | const result = {}; |
| 743 | Object.entries(bindings).forEach(([attribute, { |
| 744 | args |
| 745 | } = {}]) => { |
| 746 | const value = (0,_field_processing__WEBPACK_IMPORTED_MODULE_4__.processFieldBinding)(attribute, args, scfFields); |
| 747 | result[attribute] = value; |
| 748 | }); |
| 749 | return result; |
| 750 | }, |
| 751 | canUserEditValue() { |
| 752 | return false; |
| 753 | } |
| 754 | }); |
| 755 | |
| 756 | /***/ }), |
| 757 | |
| 758 | /***/ "./assets/src/js/bindings/utils.js": |
| 759 | /*!*****************************************!*\ |
| 760 | !*** ./assets/src/js/bindings/utils.js ***! |
| 761 | \*****************************************/ |
| 762 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 763 | |
| 764 | __webpack_require__.r(__webpack_exports__); |
| 765 | /* harmony export */ __webpack_require__.d(__webpack_exports__, { |
| 766 | /* harmony export */ canUseUnifiedBinding: () => (/* binding */ canUseUnifiedBinding), |
| 767 | /* harmony export */ extractPostTypeFromTemplate: () => (/* binding */ extractPostTypeFromTemplate), |
| 768 | /* harmony export */ fieldsToOptions: () => (/* binding */ fieldsToOptions), |
| 769 | /* harmony export */ formatFieldGroupsData: () => (/* binding */ formatFieldGroupsData), |
| 770 | /* harmony export */ getAllowedFieldTypes: () => (/* binding */ getAllowedFieldTypes), |
| 771 | /* harmony export */ getBindableAttributes: () => (/* binding */ getBindableAttributes), |
| 772 | /* harmony export */ getFilteredFieldOptions: () => (/* binding */ getFilteredFieldOptions) |
| 773 | /* harmony export */ }); |
| 774 | /* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./constants */ "./assets/src/js/bindings/constants.js"); |
| 775 | /** |
| 776 | * Utility functions for block bindings |
| 777 | */ |
| 778 | |
| 779 | |
| 780 | |
| 781 | /** |
| 782 | * Gets the bindable attributes for a given block. |
| 783 | * |
| 784 | * @since 6.7.0 |
| 785 | * @param {string} blockName The name of the block. |
| 786 | * @return {string[]} The bindable attributes for the block. |
| 787 | */ |
| 788 | function getBindableAttributes(blockName) { |
| 789 | const config = _constants__WEBPACK_IMPORTED_MODULE_0__.BLOCK_BINDINGS_CONFIG[blockName]; |
| 790 | return config ? Object.keys(config) : []; |
| 791 | } |
| 792 | |
| 793 | /** |
| 794 | * Gets the allowed field types for a specific block attribute. |
| 795 | * |
| 796 | * @since 6.7.0 |
| 797 | * @param {string} blockName The name of the block. |
| 798 | * @param {string|null} attribute The attribute name, or null for all types. |
| 799 | * @return {string[]|null} The allowed field types, or null if no restrictions. |
| 800 | */ |
| 801 | function getAllowedFieldTypes(blockName, attribute = null) { |
| 802 | const blockConfig = _constants__WEBPACK_IMPORTED_MODULE_0__.BLOCK_BINDINGS_CONFIG[blockName]; |
| 803 | if (!blockConfig) { |
| 804 | return null; |
| 805 | } |
| 806 | if (attribute) { |
| 807 | return blockConfig[attribute] || null; |
| 808 | } |
| 809 | |
| 810 | // Get all unique field types for the block |
| 811 | return [...new Set(Object.values(blockConfig).flat())]; |
| 812 | } |
| 813 | |
| 814 | /** |
| 815 | * Filters field options based on allowed field types. |
| 816 | * |
| 817 | * @since 6.7.0 |
| 818 | * @param {Array} fieldOptions Array of field option objects with value, label, and type. |
| 819 | * @param {string} blockName The name of the block. |
| 820 | * @param {string|null} attribute The attribute name, or null for all types. |
| 821 | * @return {Array} Filtered array of field options. |
| 822 | */ |
| 823 | function getFilteredFieldOptions(fieldOptions, blockName, attribute = null) { |
| 824 | if (!fieldOptions || fieldOptions.length === 0) { |
| 825 | return []; |
| 826 | } |
| 827 | const allowedTypes = getAllowedFieldTypes(blockName, attribute); |
| 828 | if (!allowedTypes) { |
| 829 | return fieldOptions; |
| 830 | } |
| 831 | return fieldOptions.filter(option => allowedTypes.includes(option.type)); |
| 832 | } |
| 833 | |
| 834 | /** |
| 835 | * Checks if all bindable attributes for a block support the same field types. |
| 836 | * |
| 837 | * @since 6.7.0 |
| 838 | * @param {string} blockName The name of the block. |
| 839 | * @param {string[]} bindableAttributes Array of bindable attribute names. |
| 840 | * @return {boolean} True if all attributes support the same field types. |
| 841 | */ |
| 842 | function canUseUnifiedBinding(blockName, bindableAttributes) { |
| 843 | if (!bindableAttributes || bindableAttributes.length <= 1) { |
| 844 | return false; |
| 845 | } |
| 846 | const blockConfig = _constants__WEBPACK_IMPORTED_MODULE_0__.BLOCK_BINDINGS_CONFIG[blockName]; |
| 847 | if (!blockConfig) { |
| 848 | return false; |
| 849 | } |
| 850 | const firstAttributeTypes = blockConfig[bindableAttributes[0]] || []; |
| 851 | return bindableAttributes.every(attr => { |
| 852 | const attrTypes = blockConfig[attr] || []; |
| 853 | return attrTypes.length === firstAttributeTypes.length && attrTypes.every(type => firstAttributeTypes.includes(type)); |
| 854 | }); |
| 855 | } |
| 856 | |
| 857 | /** |
| 858 | * Extracts the post type from a template slug. |
| 859 | * |
| 860 | * @since 6.7.0 |
| 861 | * @param {string} templateSlug The template slug (e.g., 'single-product', 'archive-post'). |
| 862 | * @return {string|null} The extracted post type, or null if not detected. |
| 863 | */ |
| 864 | function extractPostTypeFromTemplate(templateSlug) { |
| 865 | if (!templateSlug) { |
| 866 | return null; |
| 867 | } |
| 868 | |
| 869 | // Handle single templates |
| 870 | if (templateSlug.startsWith('single-')) { |
| 871 | return templateSlug.replace('single-', ''); |
| 872 | } |
| 873 | |
| 874 | // Handle archive templates |
| 875 | if (templateSlug.startsWith('archive-')) { |
| 876 | return templateSlug.replace('archive-', ''); |
| 877 | } |
| 878 | |
| 879 | // Default single template maps to 'post' |
| 880 | if (templateSlug === 'single') { |
| 881 | return 'post'; |
| 882 | } |
| 883 | return null; |
| 884 | } |
| 885 | |
| 886 | /** |
| 887 | * Formats field data from API response into a usable structure. |
| 888 | * |
| 889 | * @since 6.7.0 |
| 890 | * @param {Array} fieldGroups Array of field group objects from the API. |
| 891 | * @return {Object} Formatted fields map with field name as key. |
| 892 | */ |
| 893 | function formatFieldGroupsData(fieldGroups) { |
| 894 | const fieldsMap = {}; |
| 895 | if (!Array.isArray(fieldGroups)) { |
| 896 | return fieldsMap; |
| 897 | } |
| 898 | fieldGroups.forEach(group => { |
| 899 | if (Array.isArray(group.fields)) { |
| 900 | group.fields.forEach(field => { |
| 901 | fieldsMap[field.name] = { |
| 902 | label: field.label, |
| 903 | type: field.type |
| 904 | }; |
| 905 | }); |
| 906 | } |
| 907 | }); |
| 908 | return fieldsMap; |
| 909 | } |
| 910 | |
| 911 | /** |
| 912 | * Converts fields map to options array for ComboboxControl. |
| 913 | * |
| 914 | * @since 6.7.0 |
| 915 | * @param {Object} fieldsMap Object with field data. |
| 916 | * @return {Array} Array of option objects with value, label, and type. |
| 917 | */ |
| 918 | function fieldsToOptions(fieldsMap) { |
| 919 | if (!fieldsMap || Object.keys(fieldsMap).length === 0) { |
| 920 | return []; |
| 921 | } |
| 922 | return Object.entries(fieldsMap).map(([fieldName, fieldConfig]) => ({ |
| 923 | value: fieldName, |
| 924 | label: fieldConfig.label, |
| 925 | type: fieldConfig.type |
| 926 | })); |
| 927 | } |
| 928 | |
| 929 | /***/ }), |
| 930 | |
| 931 | /***/ "@wordpress/api-fetch": |
| 932 | /*!**********************************!*\ |
| 933 | !*** external ["wp","apiFetch"] ***! |
| 934 | \**********************************/ |
| 935 | /***/ ((module) => { |
| 936 | |
| 937 | module.exports = window["wp"]["apiFetch"]; |
| 938 | |
| 939 | /***/ }), |
| 940 | |
| 941 | /***/ "@wordpress/block-editor": |
| 942 | /*!*************************************!*\ |
| 943 | !*** external ["wp","blockEditor"] ***! |
| 944 | \*************************************/ |
| 945 | /***/ ((module) => { |
| 946 | |
| 947 | module.exports = window["wp"]["blockEditor"]; |
| 948 | |
| 949 | /***/ }), |
| 950 | |
| 951 | /***/ "@wordpress/blocks": |
| 952 | /*!********************************!*\ |
| 953 | !*** external ["wp","blocks"] ***! |
| 954 | \********************************/ |
| 955 | /***/ ((module) => { |
| 956 | |
| 957 | module.exports = window["wp"]["blocks"]; |
| 958 | |
| 959 | /***/ }), |
| 960 | |
| 961 | /***/ "@wordpress/components": |
| 962 | /*!************************************!*\ |
| 963 | !*** external ["wp","components"] ***! |
| 964 | \************************************/ |
| 965 | /***/ ((module) => { |
| 966 | |
| 967 | module.exports = window["wp"]["components"]; |
| 968 | |
| 969 | /***/ }), |
| 970 | |
| 971 | /***/ "@wordpress/compose": |
| 972 | /*!*********************************!*\ |
| 973 | !*** external ["wp","compose"] ***! |
| 974 | \*********************************/ |
| 975 | /***/ ((module) => { |
| 976 | |
| 977 | module.exports = window["wp"]["compose"]; |
| 978 | |
| 979 | /***/ }), |
| 980 | |
| 981 | /***/ "@wordpress/core-data": |
| 982 | /*!**********************************!*\ |
| 983 | !*** external ["wp","coreData"] ***! |
| 984 | \**********************************/ |
| 985 | /***/ ((module) => { |
| 986 | |
| 987 | module.exports = window["wp"]["coreData"]; |
| 988 | |
| 989 | /***/ }), |
| 990 | |
| 991 | /***/ "@wordpress/data": |
| 992 | /*!******************************!*\ |
| 993 | !*** external ["wp","data"] ***! |
| 994 | \******************************/ |
| 995 | /***/ ((module) => { |
| 996 | |
| 997 | module.exports = window["wp"]["data"]; |
| 998 | |
| 999 | /***/ }), |
| 1000 | |
| 1001 | /***/ "@wordpress/editor": |
| 1002 | /*!********************************!*\ |
| 1003 | !*** external ["wp","editor"] ***! |
| 1004 | \********************************/ |
| 1005 | /***/ ((module) => { |
| 1006 | |
| 1007 | module.exports = window["wp"]["editor"]; |
| 1008 | |
| 1009 | /***/ }), |
| 1010 | |
| 1011 | /***/ "@wordpress/element": |
| 1012 | /*!*********************************!*\ |
| 1013 | !*** external ["wp","element"] ***! |
| 1014 | \*********************************/ |
| 1015 | /***/ ((module) => { |
| 1016 | |
| 1017 | module.exports = window["wp"]["element"]; |
| 1018 | |
| 1019 | /***/ }), |
| 1020 | |
| 1021 | /***/ "@wordpress/hooks": |
| 1022 | /*!*******************************!*\ |
| 1023 | !*** external ["wp","hooks"] ***! |
| 1024 | \*******************************/ |
| 1025 | /***/ ((module) => { |
| 1026 | |
| 1027 | module.exports = window["wp"]["hooks"]; |
| 1028 | |
| 1029 | /***/ }), |
| 1030 | |
| 1031 | /***/ "@wordpress/i18n": |
| 1032 | /*!******************************!*\ |
| 1033 | !*** external ["wp","i18n"] ***! |
| 1034 | \******************************/ |
| 1035 | /***/ ((module) => { |
| 1036 | |
| 1037 | module.exports = window["wp"]["i18n"]; |
| 1038 | |
| 1039 | /***/ }), |
| 1040 | |
| 1041 | /***/ "@wordpress/url": |
| 1042 | /*!*****************************!*\ |
| 1043 | !*** external ["wp","url"] ***! |
| 1044 | \*****************************/ |
| 1045 | /***/ ((module) => { |
| 1046 | |
| 1047 | module.exports = window["wp"]["url"]; |
| 1048 | |
| 1049 | /***/ }) |
| 1050 | |
| 1051 | /******/ }); |
| 1052 | /************************************************************************/ |
| 1053 | /******/ // The module cache |
| 1054 | /******/ var __webpack_module_cache__ = {}; |
| 1055 | /******/ |
| 1056 | /******/ // The require function |
| 1057 | /******/ function __webpack_require__(moduleId) { |
| 1058 | /******/ // Check if module is in cache |
| 1059 | /******/ var cachedModule = __webpack_module_cache__[moduleId]; |
| 1060 | /******/ if (cachedModule !== undefined) { |
| 1061 | /******/ return cachedModule.exports; |
| 1062 | /******/ } |
| 1063 | /******/ // Create a new module (and put it into the cache) |
| 1064 | /******/ var module = __webpack_module_cache__[moduleId] = { |
| 1065 | /******/ // no module.id needed |
| 1066 | /******/ // no module.loaded needed |
| 1067 | /******/ exports: {} |
| 1068 | /******/ }; |
| 1069 | /******/ |
| 1070 | /******/ // Execute the module function |
| 1071 | /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); |
| 1072 | /******/ |
| 1073 | /******/ // Return the exports of the module |
| 1074 | /******/ return module.exports; |
| 1075 | /******/ } |
| 1076 | /******/ |
| 1077 | /************************************************************************/ |
| 1078 | /******/ /* webpack/runtime/compat get default export */ |
| 1079 | /******/ (() => { |
| 1080 | /******/ // getDefaultExport function for compatibility with non-harmony modules |
| 1081 | /******/ __webpack_require__.n = (module) => { |
| 1082 | /******/ var getter = module && module.__esModule ? |
| 1083 | /******/ () => (module['default']) : |
| 1084 | /******/ () => (module); |
| 1085 | /******/ __webpack_require__.d(getter, { a: getter }); |
| 1086 | /******/ return getter; |
| 1087 | /******/ }; |
| 1088 | /******/ })(); |
| 1089 | /******/ |
| 1090 | /******/ /* webpack/runtime/define property getters */ |
| 1091 | /******/ (() => { |
| 1092 | /******/ // define getter functions for harmony exports |
| 1093 | /******/ __webpack_require__.d = (exports, definition) => { |
| 1094 | /******/ for(var key in definition) { |
| 1095 | /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { |
| 1096 | /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); |
| 1097 | /******/ } |
| 1098 | /******/ } |
| 1099 | /******/ }; |
| 1100 | /******/ })(); |
| 1101 | /******/ |
| 1102 | /******/ /* webpack/runtime/hasOwnProperty shorthand */ |
| 1103 | /******/ (() => { |
| 1104 | /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) |
| 1105 | /******/ })(); |
| 1106 | /******/ |
| 1107 | /******/ /* webpack/runtime/make namespace object */ |
| 1108 | /******/ (() => { |
| 1109 | /******/ // define __esModule on exports |
| 1110 | /******/ __webpack_require__.r = (exports) => { |
| 1111 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { |
| 1112 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); |
| 1113 | /******/ } |
| 1114 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); |
| 1115 | /******/ }; |
| 1116 | /******/ })(); |
| 1117 | /******/ |
| 1118 | /************************************************************************/ |
| 1119 | var __webpack_exports__ = {}; |
| 1120 | // This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk. |
| 1121 | (() => { |
| 1122 | /*!*****************************************!*\ |
| 1123 | !*** ./assets/src/js/bindings/index.js ***! |
| 1124 | \*****************************************/ |
| 1125 | __webpack_require__.r(__webpack_exports__); |
| 1126 | /* harmony import */ var _sources_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./sources.js */ "./assets/src/js/bindings/sources.js"); |
| 1127 | /* harmony import */ var _block_editor_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./block-editor.js */ "./assets/src/js/bindings/block-editor.js"); |
| 1128 | |
| 1129 | |
| 1130 | })(); |
| 1131 | |
| 1132 | /******/ })() |
| 1133 | ; |
| 1134 | //# sourceMappingURL=scf-bindings.js.map |