PluginProbe ʕ •ᴥ•ʔ
Secure Custom Fields / 6.9.4
Secure Custom Fields v6.9.4
6.9.5 6.9.4 6.9.3 6.9.2 6.9.1 6.9.0 6.8.9 6.8.7 6.8.8 6.8.6 6.8.4 6.8.5 trunk 6.4.0-beta1 6.4.0-beta2 6.4.1 6.4.1-beta3 6.4.1-beta4 6.4.1-beta5 6.4.1-beta6 6.4.1-beta7 6.4.2 6.5.0 6.5.1 6.5.2 6.5.3 6.5.4 6.5.5 6.5.6 6.5.7 6.6.0 6.7.0 6.7.1 6.8.0 6.8.1 6.8.2 6.8.3
secure-custom-fields / assets / build / js / acf-input.js
secure-custom-fields / assets / build / js Last commit date
commands 1 month ago pro 2 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 4 months ago acf-field-group.js 4 months ago acf-field-group.js.map 4 months ago acf-field-group.min.asset.php 4 months ago acf-field-group.min.js 4 months ago acf-input.asset.php 2 weeks ago acf-input.js 2 weeks ago acf-input.js.map 2 weeks ago acf-input.min.asset.php 2 weeks ago acf-input.min.js 2 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 2 weeks ago acf.js 2 weeks ago acf.js.map 2 weeks ago acf.min.asset.php 2 weeks ago acf.min.js 2 weeks ago index.php 1 year ago scf-bindings.asset.php 1 month ago scf-bindings.js 1 month ago scf-bindings.js.map 1 month ago scf-bindings.min.asset.php 1 month ago scf-bindings.min.js 1 month ago
acf-input.js
12192 lines
1 /******/ (() => { // webpackBootstrap
2 /******/ var __webpack_modules__ = ({
3
4 /***/ "./assets/src/js/_acf-compatibility.js":
5 /*!*********************************************!*\
6 !*** ./assets/src/js/_acf-compatibility.js ***!
7 \*********************************************/
8 /***/ (() => {
9
10 (function ($, undefined) {
11 /**
12 * acf.newCompatibility
13 *
14 * Inserts a new __proto__ object compatibility layer
15 *
16 * @date 15/2/18
17 * @since ACF 5.6.9
18 *
19 * @param object instance The object to modify.
20 * @param object compatibilty Optional. The compatibility layer.
21 * @return object compatibilty
22 */
23
24 acf.newCompatibility = function (instance, compatibilty) {
25 // defaults
26 compatibilty = compatibilty || {};
27
28 // inherit __proto_-
29 compatibilty.__proto__ = instance.__proto__;
30
31 // inject
32 instance.__proto__ = compatibilty;
33
34 // reference
35 instance.compatibility = compatibilty;
36
37 // return
38 return compatibilty;
39 };
40
41 /**
42 * acf.getCompatibility
43 *
44 * Returns the compatibility layer for a given instance
45 *
46 * @date 13/3/18
47 * @since ACF 5.6.9
48 *
49 * @param object instance The object to look in.
50 * @return object|null compatibility The compatibility object or null on failure.
51 */
52
53 acf.getCompatibility = function (instance) {
54 return instance.compatibility || null;
55 };
56
57 /**
58 * acf (compatibility)
59 *
60 * Compatibility layer for the acf object
61 *
62 * @date 15/2/18
63 * @since ACF 5.6.9
64 *
65 * @param void
66 * @return void
67 */
68
69 var _acf = acf.newCompatibility(acf, {
70 // storage
71 l10n: {},
72 o: {},
73 fields: {},
74 // changed function names
75 update: acf.set,
76 add_action: acf.addAction,
77 remove_action: acf.removeAction,
78 do_action: acf.doAction,
79 add_filter: acf.addFilter,
80 remove_filter: acf.removeFilter,
81 apply_filters: acf.applyFilters,
82 parse_args: acf.parseArgs,
83 disable_el: acf.disable,
84 disable_form: acf.disable,
85 enable_el: acf.enable,
86 enable_form: acf.enable,
87 update_user_setting: acf.updateUserSetting,
88 prepare_for_ajax: acf.prepareForAjax,
89 is_ajax_success: acf.isAjaxSuccess,
90 remove_el: acf.remove,
91 remove_tr: acf.remove,
92 str_replace: acf.strReplace,
93 render_select: acf.renderSelect,
94 get_uniqid: acf.uniqid,
95 serialize_form: acf.serialize,
96 esc_html: acf.strEscape,
97 str_sanitize: acf.strSanitize
98 });
99 _acf._e = function (k1, k2) {
100 // defaults
101 k1 = k1 || '';
102 k2 = k2 || '';
103
104 // compatibility
105 var compatKey = k2 ? k1 + '.' + k2 : k1;
106 var compats = {
107 'image.select': 'Select Image',
108 'image.edit': 'Edit Image',
109 'image.update': 'Update Image'
110 };
111 if (compats[compatKey]) {
112 return acf.__(compats[compatKey]);
113 }
114
115 // try k1
116 var string = this.l10n[k1] || '';
117
118 // try k2
119 if (k2) {
120 string = string[k2] || '';
121 }
122
123 // return
124 return string;
125 };
126 _acf.get_selector = function (s) {
127 // vars
128 var selector = '.acf-field';
129
130 // bail early if no search
131 if (!s) {
132 return selector;
133 }
134
135 // compatibility with object
136 if ($.isPlainObject(s)) {
137 if ($.isEmptyObject(s)) {
138 return selector;
139 } else {
140 for (var k in s) {
141 s = s[k];
142 break;
143 }
144 }
145 }
146
147 // append
148 selector += '-' + s;
149
150 // replace underscores (split/join replaces all and is faster than regex!)
151 selector = acf.strReplace('_', '-', selector);
152
153 // remove potential double up
154 selector = acf.strReplace('field-field-', 'field-', selector);
155
156 // return
157 return selector;
158 };
159 _acf.get_fields = function (s, $el, all) {
160 // args
161 var args = {
162 is: s || '',
163 parent: $el || false,
164 suppressFilters: all || false
165 };
166
167 // change 'field_123' to '.acf-field-123'
168 if (args.is) {
169 args.is = this.get_selector(args.is);
170 }
171
172 // return
173 return acf.findFields(args);
174 };
175 _acf.get_field = function (s, $el) {
176 // get fields
177 var $fields = this.get_fields.apply(this, arguments);
178
179 // return
180 if ($fields.length) {
181 return $fields.first();
182 } else {
183 return false;
184 }
185 };
186 _acf.get_closest_field = function ($el, s) {
187 return $el.closest(this.get_selector(s));
188 };
189 _acf.get_field_wrap = function ($el) {
190 return $el.closest(this.get_selector());
191 };
192 _acf.get_field_key = function ($field) {
193 return $field.data('key');
194 };
195 _acf.get_field_type = function ($field) {
196 return $field.data('type');
197 };
198 _acf.get_data = function ($el, defaults) {
199 return acf.parseArgs($el.data(), defaults);
200 };
201 _acf.maybe_get = function (obj, key, value) {
202 // default
203 if (value === undefined) {
204 value = null;
205 }
206
207 // get keys
208 keys = String(key).split('.');
209
210 // acf.isget
211 for (var i = 0; i < keys.length; i++) {
212 if (!obj.hasOwnProperty(keys[i])) {
213 return value;
214 }
215 obj = obj[keys[i]];
216 }
217 return obj;
218 };
219
220 /**
221 * hooks
222 *
223 * Modify add_action and add_filter functions to add compatibility with changed $field parameter
224 * Using the acf.add_action() or acf.add_filter() functions will interpret new field parameters as jQuery $field
225 *
226 * @date 12/5/18
227 * @since ACF 5.6.9
228 *
229 * @param void
230 * @return void
231 */
232
233 var compatibleArgument = function (arg) {
234 return arg instanceof acf.Field ? arg.$el : arg;
235 };
236 var compatibleArguments = function (args) {
237 return acf.arrayArgs(args).map(compatibleArgument);
238 };
239 var compatibleCallback = function (origCallback) {
240 return function () {
241 // convert to compatible arguments
242 if (arguments.length) {
243 var args = compatibleArguments(arguments);
244
245 // add default argument for 'ready', 'append' and 'load' events
246 } else {
247 var args = [$(document)];
248 }
249
250 // return
251 return origCallback.apply(this, args);
252 };
253 };
254 _acf.add_action = function (action, callback, priority, context) {
255 // handle multiple actions
256 var actions = action.split(' ');
257 var length = actions.length;
258 if (length > 1) {
259 for (var i = 0; i < length; i++) {
260 action = actions[i];
261 _acf.add_action.apply(this, arguments);
262 }
263 return this;
264 }
265
266 // single
267 var callback = compatibleCallback(callback);
268 return acf.addAction.apply(this, arguments);
269 };
270 _acf.add_filter = function (action, callback, priority, context) {
271 var callback = compatibleCallback(callback);
272 return acf.addFilter.apply(this, arguments);
273 };
274
275 /*
276 * acf.model
277 *
278 * This model acts as a scaffold for action.event driven modules
279 *
280 * @type object
281 * @date 8/09/2014
282 * @since ACF 5.0.0
283 *
284 * @param (object)
285 * @return (object)
286 */
287
288 _acf.model = {
289 actions: {},
290 filters: {},
291 events: {},
292 extend: function (args) {
293 // extend
294 var model = $.extend({}, this, args);
295
296 // setup actions
297 $.each(model.actions, function (name, callback) {
298 model._add_action(name, callback);
299 });
300
301 // setup filters
302 $.each(model.filters, function (name, callback) {
303 model._add_filter(name, callback);
304 });
305
306 // setup events
307 $.each(model.events, function (name, callback) {
308 model._add_event(name, callback);
309 });
310
311 // return
312 return model;
313 },
314 _add_action: function (name, callback) {
315 // split
316 var model = this,
317 data = name.split(' ');
318
319 // add missing priority
320 var name = data[0] || '',
321 priority = data[1] || 10;
322
323 // add action
324 acf.add_action(name, model[callback], priority, model);
325 },
326 _add_filter: function (name, callback) {
327 // split
328 var model = this,
329 data = name.split(' ');
330
331 // add missing priority
332 var name = data[0] || '',
333 priority = data[1] || 10;
334
335 // add action
336 acf.add_filter(name, model[callback], priority, model);
337 },
338 _add_event: function (name, callback) {
339 // vars
340 var model = this,
341 i = name.indexOf(' '),
342 event = i > 0 ? name.substr(0, i) : name,
343 selector = i > 0 ? name.substr(i + 1) : '';
344
345 // event
346 var fn = function (e) {
347 // append $el to event object
348 e.$el = $(this);
349
350 // append $field to event object (used in field group)
351 if (acf.field_group) {
352 e.$field = e.$el.closest('.acf-field-object');
353 }
354
355 // event
356 if (typeof model.event === 'function') {
357 e = model.event(e);
358 }
359
360 // callback
361 model[callback].apply(model, arguments);
362 };
363
364 // add event
365 if (selector) {
366 $(document).on(event, selector, fn);
367 } else {
368 $(document).on(event, fn);
369 }
370 },
371 get: function (name, value) {
372 // defaults
373 value = value || null;
374
375 // get
376 if (typeof this[name] !== 'undefined') {
377 value = this[name];
378 }
379
380 // return
381 return value;
382 },
383 set: function (name, value) {
384 // set
385 this[name] = value;
386
387 // function for 3rd party
388 if (typeof this['_set_' + name] === 'function') {
389 this['_set_' + name].apply(this);
390 }
391
392 // return for chaining
393 return this;
394 }
395 };
396
397 /*
398 * field
399 *
400 * This model sets up many of the field's interactions
401 *
402 * @type function
403 * @date 21/02/2014
404 * @since ACF 3.5.1
405 *
406 * @param n/a
407 * @return n/a
408 */
409
410 _acf.field = acf.model.extend({
411 type: '',
412 o: {},
413 $field: null,
414 _add_action: function (name, callback) {
415 // vars
416 var model = this;
417
418 // update name
419 name = name + '_field/type=' + model.type;
420
421 // add action
422 acf.add_action(name, function ($field) {
423 // focus
424 model.set('$field', $field);
425
426 // callback
427 model[callback].apply(model, arguments);
428 });
429 },
430 _add_filter: function (name, callback) {
431 // vars
432 var model = this;
433
434 // update name
435 name = name + '_field/type=' + model.type;
436
437 // add action
438 acf.add_filter(name, function ($field) {
439 // focus
440 model.set('$field', $field);
441
442 // callback
443 model[callback].apply(model, arguments);
444 });
445 },
446 _add_event: function (name, callback) {
447 // vars
448 var model = this,
449 event = name.substr(0, name.indexOf(' ')),
450 selector = name.substr(name.indexOf(' ') + 1),
451 context = acf.get_selector(model.type);
452
453 // add event
454 $(document).on(event, context + ' ' + selector, function (e) {
455 // vars
456 var $el = $(this);
457 var $field = acf.get_closest_field($el, model.type);
458
459 // bail early if no field
460 if (!$field.length) return;
461
462 // focus
463 if (!$field.is(model.$field)) {
464 model.set('$field', $field);
465 }
466
467 // append to event
468 e.$el = $el;
469 e.$field = $field;
470
471 // callback
472 model[callback].apply(model, [e]);
473 });
474 },
475 _set_$field: function () {
476 // callback
477 if (typeof this.focus === 'function') {
478 this.focus();
479 }
480 },
481 // depreciated
482 doFocus: function ($field) {
483 return this.set('$field', $field);
484 }
485 });
486
487 /**
488 * validation
489 *
490 * description
491 *
492 * @date 15/2/18
493 * @since ACF 5.6.9
494 *
495 * @param type $var Description. Default.
496 * @return type Description.
497 */
498
499 var _validation = acf.newCompatibility(acf.validation, {
500 remove_error: function ($field) {
501 acf.getField($field).removeError();
502 },
503 add_warning: function ($field, message) {
504 acf.getField($field).showNotice({
505 text: message,
506 type: 'warning',
507 timeout: 1000
508 });
509 },
510 fetch: acf.validateForm,
511 enableSubmit: acf.enableSubmit,
512 disableSubmit: acf.disableSubmit,
513 showSpinner: acf.showSpinner,
514 hideSpinner: acf.hideSpinner,
515 unlockForm: acf.unlockForm,
516 lockForm: acf.lockForm
517 });
518
519 /**
520 * tooltip
521 *
522 * description
523 *
524 * @date 15/2/18
525 * @since ACF 5.6.9
526 *
527 * @param type $var Description. Default.
528 * @return type Description.
529 */
530
531 _acf.tooltip = {
532 tooltip: function (text, $el) {
533 var tooltip = acf.newTooltip({
534 text: text,
535 target: $el
536 });
537
538 // return
539 return tooltip.$el;
540 },
541 temp: function (text, $el) {
542 var tooltip = acf.newTooltip({
543 text: text,
544 target: $el,
545 timeout: 250
546 });
547 },
548 confirm: function ($el, callback, text, button_y, button_n) {
549 var tooltip = acf.newTooltip({
550 confirm: true,
551 text: text,
552 target: $el,
553 confirm: function () {
554 callback(true);
555 },
556 cancel: function () {
557 callback(false);
558 }
559 });
560 },
561 confirm_remove: function ($el, callback) {
562 var tooltip = acf.newTooltip({
563 confirmRemove: true,
564 target: $el,
565 confirm: function () {
566 callback(true);
567 },
568 cancel: function () {
569 callback(false);
570 }
571 });
572 }
573 };
574
575 /**
576 * tooltip
577 *
578 * description
579 *
580 * @date 15/2/18
581 * @since ACF 5.6.9
582 *
583 * @param type $var Description. Default.
584 * @return type Description.
585 */
586
587 _acf.media = new acf.Model({
588 activeFrame: false,
589 actions: {
590 new_media_popup: 'onNewMediaPopup'
591 },
592 frame: function () {
593 return this.activeFrame;
594 },
595 onNewMediaPopup: function (popup) {
596 this.activeFrame = popup.frame;
597 },
598 popup: function (props) {
599 // update props
600 if (props.mime_types) {
601 props.allowedTypes = props.mime_types;
602 }
603 if (props.id) {
604 props.attachment = props.id;
605 }
606
607 // new
608 var popup = acf.newMediaPopup(props);
609
610 // append
611 /*
612 if( props.selected ) {
613 popup.selected = props.selected;
614 }
615 */
616
617 // return
618 return popup.frame;
619 }
620 });
621
622 /**
623 * Select2
624 *
625 * description
626 *
627 * @date 11/6/18
628 * @since ACF 5.6.9
629 *
630 * @param type $var Description. Default.
631 * @return type Description.
632 */
633
634 _acf.select2 = {
635 init: function ($select, args, $field) {
636 // compatible args
637 if (args.allow_null) {
638 args.allowNull = args.allow_null;
639 }
640 if (args.ajax_action) {
641 args.ajaxAction = args.ajax_action;
642 }
643 if ($field) {
644 args.field = acf.getField($field);
645 }
646
647 // return
648 return acf.newSelect2($select, args);
649 },
650 destroy: function ($select) {
651 return acf.getInstance($select).destroy();
652 }
653 };
654
655 /**
656 * postbox
657 *
658 * description
659 *
660 * @date 11/6/18
661 * @since ACF 5.6.9
662 *
663 * @param type $var Description. Default.
664 * @return type Description.
665 */
666
667 _acf.postbox = {
668 render: function (args) {
669 // compatible args
670 if (args.edit_url) {
671 args.editLink = args.edit_url;
672 }
673 if (args.edit_title) {
674 args.editTitle = args.edit_title;
675 }
676
677 // return
678 return acf.newPostbox(args);
679 }
680 };
681
682 /**
683 * acf.screen
684 *
685 * description
686 *
687 * @date 11/6/18
688 * @since ACF 5.6.9
689 *
690 * @param type $var Description. Default.
691 * @return type Description.
692 */
693
694 acf.newCompatibility(acf.screen, {
695 update: function () {
696 return this.set.apply(this, arguments);
697 },
698 fetch: acf.screen.check
699 });
700 _acf.ajax = acf.screen;
701 })(jQuery);
702
703 /***/ }),
704
705 /***/ "./assets/src/js/_acf-condition-types.js":
706 /*!***********************************************!*\
707 !*** ./assets/src/js/_acf-condition-types.js ***!
708 \***********************************************/
709 /***/ (() => {
710
711 (function ($, undefined) {
712 const __ = acf.__;
713 const parseString = function (val) {
714 return val ? '' + val : '';
715 };
716 const isEqualTo = function (v1, v2) {
717 return parseString(v1).toLowerCase() === parseString(v2).toLowerCase();
718 };
719
720 /**
721 * Checks if rule and selection are equal numbers.
722 *
723 * @param {string} v1 - The rule value to expect.
724 * @param {number|string|Array} v2 - The selected value to compare.
725 * @returns {boolean} Returns true if the values are equal numbers, otherwise returns false.
726 */
727 const isEqualToNumber = function (v1, v2) {
728 if (v2 instanceof Array) {
729 return v2.length === 1 && isEqualToNumber(v1, v2[0]);
730 }
731 return parseFloat(v1) === parseFloat(v2);
732 };
733 const isGreaterThan = function (v1, v2) {
734 return parseFloat(v1) > parseFloat(v2);
735 };
736 const isLessThan = function (v1, v2) {
737 return parseFloat(v1) < parseFloat(v2);
738 };
739 const inArray = function (v1, array) {
740 // cast all values as string
741 array = array.map(function (v2) {
742 return parseString(v2);
743 });
744 return array.indexOf(v1) > -1;
745 };
746 const containsString = function (haystack, needle) {
747 return parseString(haystack).indexOf(parseString(needle)) > -1;
748 };
749 const matchesPattern = function (v1, pattern) {
750 const regexp = new RegExp(parseString(pattern), 'gi');
751 return parseString(v1).match(regexp);
752 };
753 const conditionalSelect2 = function (field, type) {
754 const $select = $('<select></select>');
755 let queryAction = `acf/fields/${type}/query`;
756 if (type === 'user') {
757 queryAction = 'acf/ajax/query_users';
758 }
759 const ajaxData = {
760 action: queryAction,
761 field_key: field.data.key,
762 s: '',
763 type: field.data.key
764 };
765 const typeAttr = acf.escAttr(type);
766 const template = function (selection) {
767 return `<span class="acf-${typeAttr}-select-name acf-conditional-select-name">` + acf.strEscape(selection.text) + '</span>';
768 };
769 const resultsTemplate = function (results) {
770 let classes = results.text.startsWith('- ') ? `acf-${typeAttr}-select-name acf-${typeAttr}-select-sub-item` : `acf-${typeAttr}-select-name`;
771 return '<span class="' + classes + '">' + acf.strEscape(results.text) + '</span>' + `<span class="acf-${typeAttr}-select-id acf-conditional-select-id">` + (results.id ? results.id : '') + '</span>';
772 };
773 const select2Props = {
774 field: false,
775 ajax: true,
776 ajaxAction: queryAction,
777 ajaxData: function (data) {
778 ajaxData.paged = data.paged;
779 ajaxData.s = data.s;
780 ajaxData.conditional_logic = true;
781 ajaxData.include = $.isNumeric(data.s) ? Number(data.s) : '';
782 return acf.prepareForAjax(ajaxData);
783 },
784 escapeMarkup: function (markup) {
785 return acf.escHtml(markup);
786 },
787 templateSelection: template,
788 templateResult: resultsTemplate
789 };
790 $select.data('acfSelect2Props', select2Props);
791 return $select;
792 };
793 /**
794 * Adds condition for Page Link having Page Link equal to.
795 *
796 * @since ACF 6.3
797 */
798 const HasPageLink = acf.Condition.extend({
799 type: 'hasPageLink',
800 operator: '==',
801 label: __('Page is equal to'),
802 fieldTypes: ['page_link'],
803 match: function (rule, field) {
804 return isEqualTo(rule.value, field.val());
805 },
806 choices: function (fieldObject) {
807 return conditionalSelect2(fieldObject, 'page_link');
808 }
809 });
810 acf.registerConditionType(HasPageLink);
811
812 /**
813 * Adds condition for Page Link not equal to.
814 *
815 * @since ACF 6.3
816 */
817 const HasPageLinkNotEqual = acf.Condition.extend({
818 type: 'hasPageLinkNotEqual',
819 operator: '!==',
820 label: __('Page is not equal to'),
821 fieldTypes: ['page_link'],
822 match: function (rule, field) {
823 return !isEqualTo(rule.value, field.val());
824 },
825 choices: function (fieldObject) {
826 return conditionalSelect2(fieldObject, 'page_link');
827 }
828 });
829 acf.registerConditionType(HasPageLinkNotEqual);
830
831 /**
832 * Adds condition for Page Link containing a specific Page Link.
833 *
834 * @since ACF 6.3
835 */
836 const containsPageLink = acf.Condition.extend({
837 type: 'containsPageLink',
838 operator: '==contains',
839 label: __('Pages contain'),
840 fieldTypes: ['page_link'],
841 match: function (rule, field) {
842 const val = field.val();
843 const ruleVal = rule.value;
844 let match = false;
845 if (val instanceof Array) {
846 match = val.includes(ruleVal);
847 } else {
848 match = val === ruleVal;
849 }
850 return match;
851 },
852 choices: function (fieldObject) {
853 return conditionalSelect2(fieldObject, 'page_link');
854 }
855 });
856 acf.registerConditionType(containsPageLink);
857
858 /**
859 * Adds condition for Page Link not containing a specific Page Link.
860 *
861 * @since ACF 6.3
862 */
863 const containsNotPageLink = acf.Condition.extend({
864 type: 'containsNotPageLink',
865 operator: '!=contains',
866 label: __('Pages do not contain'),
867 fieldTypes: ['page_link'],
868 match: function (rule, field) {
869 const val = field.val();
870 const ruleVal = rule.value;
871 let match = true;
872 if (val instanceof Array) {
873 match = !val.includes(ruleVal);
874 } else {
875 match = val !== ruleVal;
876 }
877 return match;
878 },
879 choices: function (fieldObject) {
880 return conditionalSelect2(fieldObject, 'page_link');
881 }
882 });
883 acf.registerConditionType(containsNotPageLink);
884
885 /**
886 * Adds condition for when any page link is selected.
887 *
888 * @since ACF 6.3
889 */
890 const HasAnyPageLink = acf.Condition.extend({
891 type: 'hasAnyPageLink',
892 operator: '!=empty',
893 label: __('Has any page selected'),
894 fieldTypes: ['page_link'],
895 match: function (rule, field) {
896 let val = field.val();
897 if (val instanceof Array) {
898 val = val.length;
899 }
900 return !!val;
901 },
902 choices: function () {
903 return '<input type="text" disabled />';
904 }
905 });
906 acf.registerConditionType(HasAnyPageLink);
907
908 /**
909 * Adds condition for when no page link is selected.
910 *
911 * @since ACF 6.3
912 */
913 const HasNoPageLink = acf.Condition.extend({
914 type: 'hasNoPageLink',
915 operator: '==empty',
916 label: __('Has no page selected'),
917 fieldTypes: ['page_link'],
918 match: function (rule, field) {
919 let val = field.val();
920 if (val instanceof Array) {
921 val = val.length;
922 }
923 return !val;
924 },
925 choices: function () {
926 return '<input type="text" disabled />';
927 }
928 });
929 acf.registerConditionType(HasNoPageLink);
930
931 /**
932 * Adds condition for user field having user equal to.
933 *
934 * @since ACF 6.3
935 */
936 const HasUser = acf.Condition.extend({
937 type: 'hasUser',
938 operator: '==',
939 label: __('User is equal to'),
940 fieldTypes: ['user'],
941 match: function (rule, field) {
942 return isEqualToNumber(rule.value, field.val());
943 },
944 choices: function (fieldObject) {
945 return conditionalSelect2(fieldObject, 'user');
946 }
947 });
948 acf.registerConditionType(HasUser);
949
950 /**
951 * Adds condition for user field having user not equal to.
952 *
953 * @since ACF 6.3
954 */
955 const HasUserNotEqual = acf.Condition.extend({
956 type: 'hasUserNotEqual',
957 operator: '!==',
958 label: __('User is not equal to'),
959 fieldTypes: ['user'],
960 match: function (rule, field) {
961 return !isEqualToNumber(rule.value, field.val());
962 },
963 choices: function (fieldObject) {
964 return conditionalSelect2(fieldObject, 'user');
965 }
966 });
967 acf.registerConditionType(HasUserNotEqual);
968
969 /**
970 * Adds condition for user field containing a specific user.
971 *
972 * @since ACF 6.3
973 */
974 const containsUser = acf.Condition.extend({
975 type: 'containsUser',
976 operator: '==contains',
977 label: __('Users contain'),
978 fieldTypes: ['user'],
979 match: function (rule, field) {
980 const val = field.val();
981 const ruleVal = rule.value;
982 let match = false;
983 if (val instanceof Array) {
984 match = val.includes(ruleVal);
985 } else {
986 match = val === ruleVal;
987 }
988 return match;
989 },
990 choices: function (fieldObject) {
991 return conditionalSelect2(fieldObject, 'user');
992 }
993 });
994 acf.registerConditionType(containsUser);
995
996 /**
997 * Adds condition for user field not containing a specific user.
998 *
999 * @since ACF 6.3
1000 */
1001 const containsNotUser = acf.Condition.extend({
1002 type: 'containsNotUser',
1003 operator: '!=contains',
1004 label: __('Users do not contain'),
1005 fieldTypes: ['user'],
1006 match: function (rule, field) {
1007 const val = field.val();
1008 const ruleVal = rule.value;
1009 let match = true;
1010 if (val instanceof Array) {
1011 match = !val.includes(ruleVal);
1012 } else {
1013 match = !val === ruleVal;
1014 }
1015 },
1016 choices: function (fieldObject) {
1017 return conditionalSelect2(fieldObject, 'user');
1018 }
1019 });
1020 acf.registerConditionType(containsNotUser);
1021
1022 /**
1023 * Adds condition for when any user is selected.
1024 *
1025 * @since ACF 6.3
1026 */
1027 const HasAnyUser = acf.Condition.extend({
1028 type: 'hasAnyUser',
1029 operator: '!=empty',
1030 label: __('Has any user selected'),
1031 fieldTypes: ['user'],
1032 match: function (rule, field) {
1033 let val = field.val();
1034 if (val instanceof Array) {
1035 val = val.length;
1036 }
1037 return !!val;
1038 },
1039 choices: function () {
1040 return '<input type="text" disabled />';
1041 }
1042 });
1043 acf.registerConditionType(HasAnyUser);
1044
1045 /**
1046 * Adds condition for when no user is selected.
1047 *
1048 * @since ACF 6.3
1049 */
1050 const HasNoUser = acf.Condition.extend({
1051 type: 'hasNoUser',
1052 operator: '==empty',
1053 label: __('Has no user selected'),
1054 fieldTypes: ['user'],
1055 match: function (rule, field) {
1056 let val = field.val();
1057 if (val instanceof Array) {
1058 val = val.length;
1059 }
1060 return !val;
1061 },
1062 choices: function () {
1063 return '<input type="text" disabled />';
1064 }
1065 });
1066 acf.registerConditionType(HasNoUser);
1067
1068 /**
1069 * Adds condition for Relationship having Relationship equal to.
1070 *
1071 * @since ACF 6.3
1072 */
1073 const HasRelationship = acf.Condition.extend({
1074 type: 'hasRelationship',
1075 operator: '==',
1076 label: __('Relationship is equal to'),
1077 fieldTypes: ['relationship'],
1078 match: function (rule, field) {
1079 return isEqualToNumber(rule.value, field.val());
1080 },
1081 choices: function (fieldObject) {
1082 return conditionalSelect2(fieldObject, 'relationship');
1083 }
1084 });
1085 acf.registerConditionType(HasRelationship);
1086
1087 /**
1088 * Adds condition for selection having Relationship not equal to.
1089 *
1090 * @since ACF 6.3
1091 */
1092 const HasRelationshipNotEqual = acf.Condition.extend({
1093 type: 'hasRelationshipNotEqual',
1094 operator: '!==',
1095 label: __('Relationship is not equal to'),
1096 fieldTypes: ['relationship'],
1097 match: function (rule, field) {
1098 return !isEqualToNumber(rule.value, field.val());
1099 },
1100 choices: function (fieldObject) {
1101 return conditionalSelect2(fieldObject, 'relationship');
1102 }
1103 });
1104 acf.registerConditionType(HasRelationshipNotEqual);
1105
1106 /**
1107 * Adds condition for Relationship containing a specific Relationship.
1108 *
1109 * @since ACF 6.3
1110 */
1111 const containsRelationship = acf.Condition.extend({
1112 type: 'containsRelationship',
1113 operator: '==contains',
1114 label: __('Relationships contain'),
1115 fieldTypes: ['relationship'],
1116 match: function (rule, field) {
1117 const val = field.val();
1118 // Relationships are stored as strings, use float to compare to field's rule value.
1119 const ruleVal = parseInt(rule.value);
1120 let match = false;
1121 if (val instanceof Array) {
1122 match = val.includes(ruleVal);
1123 }
1124 return match;
1125 },
1126 choices: function (fieldObject) {
1127 return conditionalSelect2(fieldObject, 'relationship');
1128 }
1129 });
1130 acf.registerConditionType(containsRelationship);
1131
1132 /**
1133 * Adds condition for Relationship not containing a specific Relationship.
1134 *
1135 * @since ACF 6.3
1136 */
1137 const containsNotRelationship = acf.Condition.extend({
1138 type: 'containsNotRelationship',
1139 operator: '!=contains',
1140 label: __('Relationships do not contain'),
1141 fieldTypes: ['relationship'],
1142 match: function (rule, field) {
1143 const val = field.val();
1144 // Relationships are stored as strings, use float to compare to field's rule value.
1145 const ruleVal = parseInt(rule.value);
1146 let match = true;
1147 if (val instanceof Array) {
1148 match = !val.includes(ruleVal);
1149 }
1150 return match;
1151 },
1152 choices: function (fieldObject) {
1153 return conditionalSelect2(fieldObject, 'relationship');
1154 }
1155 });
1156 acf.registerConditionType(containsNotRelationship);
1157
1158 /**
1159 * Adds condition for when any relation is selected.
1160 *
1161 * @since ACF 6.3
1162 */
1163 const HasAnyRelation = acf.Condition.extend({
1164 type: 'hasAnyRelation',
1165 operator: '!=empty',
1166 label: __('Has any relationship selected'),
1167 fieldTypes: ['relationship'],
1168 match: function (rule, field) {
1169 let val = field.val();
1170 if (val instanceof Array) {
1171 val = val.length;
1172 }
1173 return !!val;
1174 },
1175 choices: function () {
1176 return '<input type="text" disabled />';
1177 }
1178 });
1179 acf.registerConditionType(HasAnyRelation);
1180
1181 /**
1182 * Adds condition for when no relation is selected.
1183 *
1184 * @since ACF 6.3
1185 */
1186 const HasNoRelation = acf.Condition.extend({
1187 type: 'hasNoRelation',
1188 operator: '==empty',
1189 label: __('Has no relationship selected'),
1190 fieldTypes: ['relationship'],
1191 match: function (rule, field) {
1192 let val = field.val();
1193 if (val instanceof Array) {
1194 val = val.length;
1195 }
1196 return !val;
1197 },
1198 choices: function () {
1199 return '<input type="text" disabled />';
1200 }
1201 });
1202 acf.registerConditionType(HasNoRelation);
1203
1204 /**
1205 * Adds condition for having post equal to.
1206 *
1207 * @since ACF 6.3
1208 */
1209 const HasPostObject = acf.Condition.extend({
1210 type: 'hasPostObject',
1211 operator: '==',
1212 label: __('Post is equal to'),
1213 fieldTypes: ['post_object'],
1214 match: function (rule, field) {
1215 return isEqualToNumber(rule.value, field.val());
1216 },
1217 choices: function (fieldObject) {
1218 return conditionalSelect2(fieldObject, 'post_object');
1219 }
1220 });
1221 acf.registerConditionType(HasPostObject);
1222
1223 /**
1224 * Adds condition for selection having post not equal to.
1225 *
1226 * @since ACF 6.3
1227 */
1228 const HasPostObjectNotEqual = acf.Condition.extend({
1229 type: 'hasPostObjectNotEqual',
1230 operator: '!==',
1231 label: __('Post is not equal to'),
1232 fieldTypes: ['post_object'],
1233 match: function (rule, field) {
1234 return !isEqualToNumber(rule.value, field.val());
1235 },
1236 choices: function (fieldObject) {
1237 return conditionalSelect2(fieldObject, 'post_object');
1238 }
1239 });
1240 acf.registerConditionType(HasPostObjectNotEqual);
1241
1242 /**
1243 * Adds condition for Relationship containing a specific Relationship.
1244 *
1245 * @since ACF 6.3
1246 */
1247 const containsPostObject = acf.Condition.extend({
1248 type: 'containsPostObject',
1249 operator: '==contains',
1250 label: __('Posts contain'),
1251 fieldTypes: ['post_object'],
1252 match: function (rule, field) {
1253 const val = field.val();
1254 const ruleVal = rule.value;
1255 let match = false;
1256 if (val instanceof Array) {
1257 match = val.includes(ruleVal);
1258 } else {
1259 match = val === ruleVal;
1260 }
1261 return match;
1262 },
1263 choices: function (fieldObject) {
1264 return conditionalSelect2(fieldObject, 'post_object');
1265 }
1266 });
1267 acf.registerConditionType(containsPostObject);
1268
1269 /**
1270 * Adds condition for Relationship not containing a specific Relationship.
1271 *
1272 * @since ACF 6.3
1273 */
1274 const containsNotPostObject = acf.Condition.extend({
1275 type: 'containsNotPostObject',
1276 operator: '!=contains',
1277 label: __('Posts do not contain'),
1278 fieldTypes: ['post_object'],
1279 match: function (rule, field) {
1280 const val = field.val();
1281 const ruleVal = rule.value;
1282 let match = true;
1283 if (val instanceof Array) {
1284 match = !val.includes(ruleVal);
1285 } else {
1286 match = val !== ruleVal;
1287 }
1288 return match;
1289 },
1290 choices: function (fieldObject) {
1291 return conditionalSelect2(fieldObject, 'post_object');
1292 }
1293 });
1294 acf.registerConditionType(containsNotPostObject);
1295
1296 /**
1297 * Adds condition for when any post is selected.
1298 *
1299 * @since ACF 6.3
1300 */
1301 const HasAnyPostObject = acf.Condition.extend({
1302 type: 'hasAnyPostObject',
1303 operator: '!=empty',
1304 label: __('Has any post selected'),
1305 fieldTypes: ['post_object'],
1306 match: function (rule, field) {
1307 let val = field.val();
1308 if (val instanceof Array) {
1309 val = val.length;
1310 }
1311 return !!val;
1312 },
1313 choices: function () {
1314 return '<input type="text" disabled />';
1315 }
1316 });
1317 acf.registerConditionType(HasAnyPostObject);
1318
1319 /**
1320 * Adds condition for when no post is selected.
1321 *
1322 * @since ACF 6.3
1323 */
1324 const HasNoPostObject = acf.Condition.extend({
1325 type: 'hasNoPostObject',
1326 operator: '==empty',
1327 label: __('Has no post selected'),
1328 fieldTypes: ['post_object'],
1329 match: function (rule, field) {
1330 let val = field.val();
1331 if (val instanceof Array) {
1332 val = val.length;
1333 }
1334 return !val;
1335 },
1336 choices: function () {
1337 return '<input type="text" disabled />';
1338 }
1339 });
1340 acf.registerConditionType(HasNoPostObject);
1341
1342 /**
1343 * Adds condition for taxonomy having term equal to.
1344 *
1345 * @since ACF 6.3
1346 */
1347 const HasTerm = acf.Condition.extend({
1348 type: 'hasTerm',
1349 operator: '==',
1350 label: __('Term is equal to'),
1351 fieldTypes: ['taxonomy'],
1352 match: function (rule, field) {
1353 return isEqualToNumber(rule.value, field.val());
1354 },
1355 choices: function (fieldObject) {
1356 return conditionalSelect2(fieldObject, 'taxonomy');
1357 }
1358 });
1359 acf.registerConditionType(HasTerm);
1360
1361 /**
1362 * Adds condition for taxonomy having term not equal to.
1363 *
1364 * @since ACF 6.3
1365 */
1366 const hasTermNotEqual = acf.Condition.extend({
1367 type: 'hasTermNotEqual',
1368 operator: '!==',
1369 label: __('Term is not equal to'),
1370 fieldTypes: ['taxonomy'],
1371 match: function (rule, field) {
1372 return !isEqualToNumber(rule.value, field.val());
1373 },
1374 choices: function (fieldObject) {
1375 return conditionalSelect2(fieldObject, 'taxonomy');
1376 }
1377 });
1378 acf.registerConditionType(hasTermNotEqual);
1379
1380 /**
1381 * Adds condition for taxonomy containing a specific term.
1382 *
1383 * @since ACF 6.3
1384 */
1385 const containsTerm = acf.Condition.extend({
1386 type: 'containsTerm',
1387 operator: '==contains',
1388 label: __('Terms contain'),
1389 fieldTypes: ['taxonomy'],
1390 match: function (rule, field) {
1391 const val = field.val();
1392 const ruleVal = rule.value;
1393 let match = false;
1394 if (val instanceof Array) {
1395 match = val.includes(ruleVal);
1396 }
1397 return match;
1398 },
1399 choices: function (fieldObject) {
1400 return conditionalSelect2(fieldObject, 'taxonomy');
1401 }
1402 });
1403 acf.registerConditionType(containsTerm);
1404
1405 /**
1406 * Adds condition for taxonomy not containing a specific term.
1407 *
1408 * @since ACF 6.3
1409 */
1410 const containsNotTerm = acf.Condition.extend({
1411 type: 'containsNotTerm',
1412 operator: '!=contains',
1413 label: __('Terms do not contain'),
1414 fieldTypes: ['taxonomy'],
1415 match: function (rule, field) {
1416 const val = field.val();
1417 const ruleVal = rule.value;
1418 let match = true;
1419 if (val instanceof Array) {
1420 match = !val.includes(ruleVal);
1421 }
1422 return match;
1423 },
1424 choices: function (fieldObject) {
1425 return conditionalSelect2(fieldObject, 'taxonomy');
1426 }
1427 });
1428 acf.registerConditionType(containsNotTerm);
1429
1430 /**
1431 * Adds condition for when any term is selected.
1432 *
1433 * @since ACF 6.3
1434 */
1435 const HasAnyTerm = acf.Condition.extend({
1436 type: 'hasAnyTerm',
1437 operator: '!=empty',
1438 label: __('Has any term selected'),
1439 fieldTypes: ['taxonomy'],
1440 match: function (rule, field) {
1441 let val = field.val();
1442 if (val instanceof Array) {
1443 val = val.length;
1444 }
1445 return !!val;
1446 },
1447 choices: function () {
1448 return '<input type="text" disabled />';
1449 }
1450 });
1451 acf.registerConditionType(HasAnyTerm);
1452
1453 /**
1454 * Adds condition for when no term is selected.
1455 *
1456 * @since ACF 6.3
1457 */
1458 const HasNoTerm = acf.Condition.extend({
1459 type: 'hasNoTerm',
1460 operator: '==empty',
1461 label: __('Has no term selected'),
1462 fieldTypes: ['taxonomy'],
1463 match: function (rule, field) {
1464 let val = field.val();
1465 if (val instanceof Array) {
1466 val = val.length;
1467 }
1468 return !val;
1469 },
1470 choices: function () {
1471 return '<input type="text" disabled />';
1472 }
1473 });
1474 acf.registerConditionType(HasNoTerm);
1475
1476 /**
1477 * hasValue
1478 *
1479 * @date 1/2/18
1480 * @since ACF 5.6.5
1481 *
1482 * @param void
1483 * @return void
1484 */
1485 const HasValue = acf.Condition.extend({
1486 type: 'hasValue',
1487 operator: '!=empty',
1488 label: __('Has any value'),
1489 fieldTypes: ['text', 'textarea', 'number', 'range', 'email', 'url', 'password', 'image', 'file', 'wysiwyg', 'oembed', 'select', 'checkbox', 'radio', 'button_group', 'link', 'google_map', 'date_picker', 'date_time_picker', 'time_picker', 'color_picker', 'icon_picker'],
1490 match: function (rule, field) {
1491 let val = field.val();
1492 if (val instanceof Array) {
1493 val = val.length;
1494 }
1495 return val ? true : false;
1496 },
1497 choices: function (fieldObject) {
1498 return '<input type="text" disabled />';
1499 }
1500 });
1501 acf.registerConditionType(HasValue);
1502
1503 /**
1504 * hasValue
1505 *
1506 * @date 1/2/18
1507 * @since ACF 5.6.5
1508 *
1509 * @param void
1510 * @return void
1511 */
1512 const HasNoValue = HasValue.extend({
1513 type: 'hasNoValue',
1514 operator: '==empty',
1515 label: __('Has no value'),
1516 match: function (rule, field) {
1517 return !HasValue.prototype.match.apply(this, arguments);
1518 }
1519 });
1520 acf.registerConditionType(HasNoValue);
1521
1522 /**
1523 * EqualTo
1524 *
1525 * @date 1/2/18
1526 * @since ACF 5.6.5
1527 *
1528 * @param void
1529 * @return void
1530 */
1531 const EqualTo = acf.Condition.extend({
1532 type: 'equalTo',
1533 operator: '==',
1534 label: __('Value is equal to'),
1535 fieldTypes: ['text', 'textarea', 'number', 'range', 'email', 'url', 'password'],
1536 match: function (rule, field) {
1537 if (acf.isNumeric(rule.value)) {
1538 return isEqualToNumber(rule.value, field.val());
1539 } else {
1540 return isEqualTo(rule.value, field.val());
1541 }
1542 },
1543 choices: function (fieldObject) {
1544 return '<input type="text" />';
1545 }
1546 });
1547 acf.registerConditionType(EqualTo);
1548
1549 /**
1550 * NotEqualTo
1551 *
1552 * @date 1/2/18
1553 * @since ACF 5.6.5
1554 *
1555 * @param void
1556 * @return void
1557 */
1558 const NotEqualTo = EqualTo.extend({
1559 type: 'notEqualTo',
1560 operator: '!=',
1561 label: __('Value is not equal to'),
1562 match: function (rule, field) {
1563 return !EqualTo.prototype.match.apply(this, arguments);
1564 }
1565 });
1566 acf.registerConditionType(NotEqualTo);
1567
1568 /**
1569 * PatternMatch
1570 *
1571 * @date 1/2/18
1572 * @since ACF 5.6.5
1573 *
1574 * @param void
1575 * @return void
1576 */
1577 const PatternMatch = acf.Condition.extend({
1578 type: 'patternMatch',
1579 operator: '==pattern',
1580 label: __('Value matches pattern'),
1581 fieldTypes: ['text', 'textarea', 'email', 'url', 'password', 'wysiwyg'],
1582 match: function (rule, field) {
1583 return matchesPattern(field.val(), rule.value);
1584 },
1585 choices: function (fieldObject) {
1586 return '<input type="text" placeholder="[a-z0-9]" />';
1587 }
1588 });
1589 acf.registerConditionType(PatternMatch);
1590
1591 /**
1592 * Contains
1593 *
1594 * @date 1/2/18
1595 * @since ACF 5.6.5
1596 *
1597 * @param void
1598 * @return void
1599 */
1600 const Contains = acf.Condition.extend({
1601 type: 'contains',
1602 operator: '==contains',
1603 label: __('Value contains'),
1604 fieldTypes: ['text', 'textarea', 'number', 'email', 'url', 'password', 'wysiwyg', 'oembed', 'select'],
1605 match: function (rule, field) {
1606 return containsString(field.val(), rule.value);
1607 },
1608 choices: function (fieldObject) {
1609 return '<input type="text" />';
1610 }
1611 });
1612 acf.registerConditionType(Contains);
1613
1614 /**
1615 * TrueFalseEqualTo
1616 *
1617 * @date 1/2/18
1618 * @since ACF 5.6.5
1619 *
1620 * @param void
1621 * @return void
1622 */
1623 const TrueFalseEqualTo = EqualTo.extend({
1624 type: 'trueFalseEqualTo',
1625 choiceType: 'select',
1626 fieldTypes: ['true_false'],
1627 choices: function (field) {
1628 return [{
1629 id: 1,
1630 text: __('Checked')
1631 }];
1632 }
1633 });
1634 acf.registerConditionType(TrueFalseEqualTo);
1635
1636 /**
1637 * TrueFalseNotEqualTo
1638 *
1639 * @date 1/2/18
1640 * @since ACF 5.6.5
1641 *
1642 * @param void
1643 * @return void
1644 */
1645 const TrueFalseNotEqualTo = NotEqualTo.extend({
1646 type: 'trueFalseNotEqualTo',
1647 choiceType: 'select',
1648 fieldTypes: ['true_false'],
1649 choices: function (field) {
1650 return [{
1651 id: 1,
1652 text: __('Checked')
1653 }];
1654 }
1655 });
1656 acf.registerConditionType(TrueFalseNotEqualTo);
1657
1658 /**
1659 * SelectEqualTo
1660 *
1661 * @date 1/2/18
1662 * @since ACF 5.6.5
1663 *
1664 * @param void
1665 * @return void
1666 */
1667 const SelectEqualTo = acf.Condition.extend({
1668 type: 'selectEqualTo',
1669 operator: '==',
1670 label: __('Value is equal to'),
1671 fieldTypes: ['select', 'checkbox', 'radio', 'button_group'],
1672 match: function (rule, field) {
1673 const val = field.val();
1674 if (val instanceof Array) {
1675 return inArray(rule.value, val);
1676 } else {
1677 return isEqualTo(rule.value, val);
1678 }
1679 },
1680 choices: function (fieldObject) {
1681 // vars
1682 const choices = [];
1683 const lines = fieldObject.$setting('choices textarea').val().split('\n');
1684
1685 // allow null
1686 if (fieldObject.$input('allow_null').prop('checked')) {
1687 choices.push({
1688 id: '',
1689 text: __('Null')
1690 });
1691 }
1692
1693 // loop
1694 lines.map(function (line) {
1695 // split
1696 line = line.split(':');
1697
1698 // default label to value
1699 line[1] = line[1] || line[0];
1700
1701 // append
1702 choices.push({
1703 id: line[0].trim(),
1704 text: line[1].trim()
1705 });
1706 });
1707
1708 // return
1709 return choices;
1710 }
1711 });
1712 acf.registerConditionType(SelectEqualTo);
1713
1714 /**
1715 * SelectNotEqualTo
1716 *
1717 * @date 1/2/18
1718 * @since ACF 5.6.5
1719 *
1720 * @param void
1721 * @return void
1722 */
1723 const SelectNotEqualTo = SelectEqualTo.extend({
1724 type: 'selectNotEqualTo',
1725 operator: '!=',
1726 label: __('Value is not equal to'),
1727 match: function (rule, field) {
1728 return !SelectEqualTo.prototype.match.apply(this, arguments);
1729 }
1730 });
1731 acf.registerConditionType(SelectNotEqualTo);
1732
1733 /**
1734 * GreaterThan
1735 *
1736 * @date 1/2/18
1737 * @since ACF 5.6.5
1738 *
1739 * @param void
1740 * @return void
1741 */
1742 const GreaterThan = acf.Condition.extend({
1743 type: 'greaterThan',
1744 operator: '>',
1745 label: __('Value is greater than'),
1746 fieldTypes: ['number', 'range'],
1747 match: function (rule, field) {
1748 let val = field.val();
1749 if (val instanceof Array) {
1750 val = val.length;
1751 }
1752 return isGreaterThan(val, rule.value);
1753 },
1754 choices: function (fieldObject) {
1755 return '<input type="number" />';
1756 }
1757 });
1758 acf.registerConditionType(GreaterThan);
1759
1760 /**
1761 * LessThan
1762 *
1763 * @date 1/2/18
1764 * @since ACF 5.6.5
1765 *
1766 * @param void
1767 * @return void
1768 */
1769 const LessThan = GreaterThan.extend({
1770 type: 'lessThan',
1771 operator: '<',
1772 label: __('Value is less than'),
1773 match: function (rule, field) {
1774 let val = field.val();
1775 if (val instanceof Array) {
1776 val = val.length;
1777 }
1778 if (val === undefined || val === null || val === false) {
1779 return true;
1780 }
1781 return isLessThan(val, rule.value);
1782 },
1783 choices: function (fieldObject) {
1784 return '<input type="number" />';
1785 }
1786 });
1787 acf.registerConditionType(LessThan);
1788
1789 /**
1790 * SelectedGreaterThan
1791 *
1792 * @date 1/2/18
1793 * @since ACF 5.6.5
1794 *
1795 * @param void
1796 * @return void
1797 */
1798 const SelectionGreaterThan = GreaterThan.extend({
1799 type: 'selectionGreaterThan',
1800 label: __('Selection is greater than'),
1801 fieldTypes: ['checkbox', 'select', 'post_object', 'page_link', 'relationship', 'taxonomy', 'user']
1802 });
1803 acf.registerConditionType(SelectionGreaterThan);
1804
1805 /**
1806 * SelectionLessThan
1807 *
1808 * @date 1/2/18
1809 * @since ACF 5.6.5
1810 *
1811 * @param void
1812 * @return void
1813 */
1814 const SelectionLessThan = LessThan.extend({
1815 type: 'selectionLessThan',
1816 label: __('Selection is less than'),
1817 fieldTypes: ['checkbox', 'select', 'post_object', 'page_link', 'relationship', 'taxonomy', 'user']
1818 });
1819 acf.registerConditionType(SelectionLessThan);
1820 })(jQuery);
1821
1822 /***/ }),
1823
1824 /***/ "./assets/src/js/_acf-condition.js":
1825 /*!*****************************************!*\
1826 !*** ./assets/src/js/_acf-condition.js ***!
1827 \*****************************************/
1828 /***/ (() => {
1829
1830 (function ($, undefined) {
1831 // vars
1832 var storage = [];
1833
1834 /**
1835 * acf.Condition
1836 *
1837 * description
1838 *
1839 * @date 23/3/18
1840 * @since ACF 5.6.9
1841 *
1842 * @param type $var Description. Default.
1843 * @return type Description.
1844 */
1845
1846 acf.Condition = acf.Model.extend({
1847 type: '',
1848 // used for model name
1849 operator: '==',
1850 // rule operator
1851 label: '',
1852 // label shown when editing fields
1853 choiceType: 'input',
1854 // input, select
1855 fieldTypes: [],
1856 // auto connect this conditions with these field types
1857
1858 data: {
1859 conditions: false,
1860 // the parent instance
1861 field: false,
1862 // the field which we query against
1863 rule: {} // the rule [field, operator, value]
1864 },
1865 events: {
1866 change: 'change',
1867 keyup: 'change',
1868 enableField: 'change',
1869 disableField: 'change'
1870 },
1871 setup: function (props) {
1872 $.extend(this.data, props);
1873 },
1874 getEventTarget: function ($el, event) {
1875 return $el || this.get('field').$el;
1876 },
1877 change: function (e, $el) {
1878 this.get('conditions').change(e);
1879 },
1880 match: function (rule, field) {
1881 return false;
1882 },
1883 calculate: function () {
1884 return this.match(this.get('rule'), this.get('field'));
1885 },
1886 choices: function (field) {
1887 return '<input type="text" />';
1888 }
1889 });
1890
1891 /**
1892 * acf.newCondition
1893 *
1894 * description
1895 *
1896 * @date 1/2/18
1897 * @since ACF 5.6.5
1898 *
1899 * @param type $var Description. Default.
1900 * @return type Description.
1901 */
1902
1903 acf.newCondition = function (rule, conditions) {
1904 // currently setting up conditions for fieldX, this field is the 'target'
1905 var target = conditions.get('field');
1906
1907 // use the 'target' to find the 'trigger' field.
1908 // - this field is used to setup the conditional logic events
1909 var field = target.getField(rule.field);
1910
1911 // bail early if no target or no field (possible if field doesn't exist due to HTML error)
1912 if (!target || !field) {
1913 return false;
1914 }
1915
1916 // vars
1917 var args = {
1918 rule: rule,
1919 target: target,
1920 conditions: conditions,
1921 field: field
1922 };
1923
1924 // vars
1925 var fieldType = field.get('type');
1926 var operator = rule.operator;
1927
1928 // get available conditions
1929 var conditionTypes = acf.getConditionTypes({
1930 fieldType: fieldType,
1931 operator: operator
1932 });
1933
1934 // instantiate
1935 var model = conditionTypes[0] || acf.Condition;
1936
1937 // instantiate
1938 var condition = new model(args);
1939
1940 // return
1941 return condition;
1942 };
1943
1944 /**
1945 * mid
1946 *
1947 * Calculates the model ID for a field type
1948 *
1949 * @date 15/12/17
1950 * @since ACF 5.6.5
1951 *
1952 * @param string type
1953 * @return string
1954 */
1955
1956 var modelId = function (type) {
1957 return acf.strPascalCase(type || '') + 'Condition';
1958 };
1959
1960 /**
1961 * acf.registerConditionType
1962 *
1963 * description
1964 *
1965 * @date 1/2/18
1966 * @since ACF 5.6.5
1967 *
1968 * @param type $var Description. Default.
1969 * @return type Description.
1970 */
1971
1972 acf.registerConditionType = function (model) {
1973 // vars
1974 var proto = model.prototype;
1975 var type = proto.type;
1976 var mid = modelId(type);
1977
1978 // store model
1979 acf.models[mid] = model;
1980
1981 // store reference
1982 storage.push(type);
1983 };
1984
1985 /**
1986 * acf.getConditionType
1987 *
1988 * description
1989 *
1990 * @date 1/2/18
1991 * @since ACF 5.6.5
1992 *
1993 * @param type $var Description. Default.
1994 * @return type Description.
1995 */
1996
1997 acf.getConditionType = function (type) {
1998 var mid = modelId(type);
1999 return acf.models[mid] || false;
2000 };
2001
2002 /**
2003 * acf.registerConditionForFieldType
2004 *
2005 * description
2006 *
2007 * @date 1/2/18
2008 * @since ACF 5.6.5
2009 *
2010 * @param type $var Description. Default.
2011 * @return type Description.
2012 */
2013
2014 acf.registerConditionForFieldType = function (conditionType, fieldType) {
2015 // get model
2016 var model = acf.getConditionType(conditionType);
2017
2018 // append
2019 if (model) {
2020 model.prototype.fieldTypes.push(fieldType);
2021 }
2022 };
2023
2024 /**
2025 * acf.getConditionTypes
2026 *
2027 * description
2028 *
2029 * @date 1/2/18
2030 * @since ACF 5.6.5
2031 *
2032 * @param type $var Description. Default.
2033 * @return type Description.
2034 */
2035
2036 acf.getConditionTypes = function (args) {
2037 // defaults
2038 args = acf.parseArgs(args, {
2039 fieldType: '',
2040 operator: ''
2041 });
2042
2043 // clone available types
2044 var types = [];
2045
2046 // loop
2047 storage.map(function (type) {
2048 // vars
2049 var model = acf.getConditionType(type);
2050 var ProtoFieldTypes = model.prototype.fieldTypes;
2051 var ProtoOperator = model.prototype.operator;
2052
2053 // check fieldType
2054 if (args.fieldType && ProtoFieldTypes.indexOf(args.fieldType) === -1) {
2055 return;
2056 }
2057
2058 // check operator
2059 if (args.operator && ProtoOperator !== args.operator) {
2060 return;
2061 }
2062
2063 // append
2064 types.push(model);
2065 });
2066
2067 // return
2068 return types;
2069 };
2070 })(jQuery);
2071
2072 /***/ }),
2073
2074 /***/ "./assets/src/js/_acf-conditions.js":
2075 /*!******************************************!*\
2076 !*** ./assets/src/js/_acf-conditions.js ***!
2077 \******************************************/
2078 /***/ (() => {
2079
2080 (function ($, undefined) {
2081 // vars
2082 var CONTEXT = 'conditional_logic';
2083
2084 /**
2085 * conditionsManager
2086 *
2087 * description
2088 *
2089 * @date 1/2/18
2090 * @since ACF 5.6.5
2091 *
2092 * @param type $var Description. Default.
2093 * @return type Description.
2094 */
2095
2096 var conditionsManager = new acf.Model({
2097 id: 'conditionsManager',
2098 priority: 20,
2099 // run actions later
2100
2101 actions: {
2102 new_field: 'onNewField'
2103 },
2104 onNewField: function (field) {
2105 if (field.has('conditions')) {
2106 field.getConditions().render();
2107 }
2108 }
2109 });
2110
2111 /**
2112 * acf.Field.prototype.getField
2113 *
2114 * Finds a field that is related to another field
2115 *
2116 * @date 1/2/18
2117 * @since ACF 5.6.5
2118 *
2119 * @param type $var Description. Default.
2120 * @return type Description.
2121 */
2122
2123 var getSiblingField = function (field, key) {
2124 // find sibling (very fast)
2125 var fields = acf.getFields({
2126 key: key,
2127 sibling: field.$el,
2128 suppressFilters: true
2129 });
2130
2131 // find sibling-children (fast)
2132 // needed for group fields, accordions, etc
2133 if (!fields.length) {
2134 fields = acf.getFields({
2135 key: key,
2136 parent: field.$el.parent(),
2137 suppressFilters: true
2138 });
2139 }
2140
2141 // Check for fields on other settings tabs (probably less fast).
2142 if (!fields.length && $('.acf-field-settings').length) {
2143 fields = acf.getFields({
2144 key: key,
2145 parent: field.$el.parents('.acf-field-settings:first'),
2146 suppressFilters: true
2147 });
2148 }
2149 if (!fields.length && $('#acf-basic-settings').length) {
2150 fields = acf.getFields({
2151 key: key,
2152 parent: $('#acf-basic-settings'),
2153 suppressFilters: true
2154 });
2155 }
2156
2157 // return
2158 if (fields.length) {
2159 return fields[0];
2160 }
2161 return false;
2162 };
2163 acf.Field.prototype.getField = function (key) {
2164 // get sibling field
2165 var field = getSiblingField(this, key);
2166
2167 // return early
2168 if (field) {
2169 return field;
2170 }
2171
2172 // move up through each parent and try again
2173 var parents = this.parents();
2174 for (var i = 0; i < parents.length; i++) {
2175 // get sibling field
2176 field = getSiblingField(parents[i], key);
2177
2178 // return early
2179 if (field) {
2180 return field;
2181 }
2182 }
2183
2184 // return
2185 return false;
2186 };
2187
2188 /**
2189 * acf.Field.prototype.getConditions
2190 *
2191 * Returns the field's conditions instance
2192 *
2193 * @date 1/2/18
2194 * @since ACF 5.6.5
2195 *
2196 * @param type $var Description. Default.
2197 * @return type Description.
2198 */
2199
2200 acf.Field.prototype.getConditions = function () {
2201 // instantiate
2202 if (!this.conditions) {
2203 this.conditions = new Conditions(this);
2204 }
2205
2206 // return
2207 return this.conditions;
2208 };
2209
2210 /**
2211 * Conditions
2212 *
2213 * description
2214 *
2215 * @date 1/2/18
2216 * @since ACF 5.6.5
2217 *
2218 * @param type $var Description. Default.
2219 * @return type Description.
2220 */
2221 var timeout = false;
2222 var Conditions = acf.Model.extend({
2223 id: 'Conditions',
2224 data: {
2225 field: false,
2226 // The field with "data-conditions" (target).
2227 timeStamp: false,
2228 // Reference used during "change" event.
2229 groups: [] // The groups of condition instances.
2230 },
2231 setup: function (field) {
2232 // data
2233 this.data.field = field;
2234
2235 // vars
2236 var conditions = field.get('conditions');
2237
2238 // detect groups
2239 if (conditions instanceof Array) {
2240 // detect groups
2241 if (conditions[0] instanceof Array) {
2242 // loop
2243 conditions.map(function (rules, i) {
2244 this.addRules(rules, i);
2245 }, this);
2246
2247 // detect rules
2248 } else {
2249 this.addRules(conditions);
2250 }
2251
2252 // detect rule
2253 } else {
2254 this.addRule(conditions);
2255 }
2256 },
2257 change: function (e) {
2258 // this function may be triggered multiple times per event due to multiple condition classes
2259 // compare timestamp to allow only 1 trigger per event
2260 if (this.get('timeStamp') === e.timeStamp) {
2261 return false;
2262 } else {
2263 this.set('timeStamp', e.timeStamp, true);
2264 }
2265
2266 // render condition and store result
2267 var changed = this.render();
2268 },
2269 render: function () {
2270 return this.calculate() ? this.show() : this.hide();
2271 },
2272 show: function () {
2273 return this.get('field').showEnable(this.cid, CONTEXT);
2274 },
2275 hide: function () {
2276 return this.get('field').hideDisable(this.cid, CONTEXT);
2277 },
2278 calculate: function () {
2279 // vars
2280 var pass = false;
2281
2282 // loop
2283 this.getGroups().map(function (group) {
2284 // ignore this group if another group passed
2285 if (pass) return;
2286
2287 // find passed
2288 var passed = group.filter(function (condition) {
2289 return condition.calculate();
2290 });
2291
2292 // if all conditions passed, update the global var
2293 if (passed.length == group.length) {
2294 pass = true;
2295 }
2296 });
2297 return pass;
2298 },
2299 hasGroups: function () {
2300 return this.data.groups != null;
2301 },
2302 getGroups: function () {
2303 return this.data.groups;
2304 },
2305 addGroup: function () {
2306 var group = [];
2307 this.data.groups.push(group);
2308 return group;
2309 },
2310 hasGroup: function (i) {
2311 return this.data.groups[i] != null;
2312 },
2313 getGroup: function (i) {
2314 return this.data.groups[i];
2315 },
2316 removeGroup: function (i) {
2317 this.data.groups[i].delete;
2318 return this;
2319 },
2320 addRules: function (rules, group) {
2321 rules.map(function (rule) {
2322 this.addRule(rule, group);
2323 }, this);
2324 },
2325 addRule: function (rule, group) {
2326 // defaults
2327 group = group || 0;
2328
2329 // vars
2330 var groupArray;
2331
2332 // get group
2333 if (this.hasGroup(group)) {
2334 groupArray = this.getGroup(group);
2335 } else {
2336 groupArray = this.addGroup();
2337 }
2338
2339 // instantiate
2340 var condition = acf.newCondition(rule, this);
2341
2342 // bail early if condition failed (field did not exist)
2343 if (!condition) {
2344 return false;
2345 }
2346
2347 // add rule
2348 groupArray.push(condition);
2349 },
2350 hasRule: function () {},
2351 getRule: function (rule, group) {
2352 // defaults
2353 rule = rule || 0;
2354 group = group || 0;
2355 return this.data.groups[group][rule];
2356 },
2357 removeRule: function () {}
2358 });
2359 })(jQuery);
2360
2361 /***/ }),
2362
2363 /***/ "./assets/src/js/_acf-field-accordion.js":
2364 /*!***********************************************!*\
2365 !*** ./assets/src/js/_acf-field-accordion.js ***!
2366 \***********************************************/
2367 /***/ (() => {
2368
2369 (function ($, undefined) {
2370 var i = 0;
2371 var Field = acf.Field.extend({
2372 type: 'accordion',
2373 wait: '',
2374 $control: function () {
2375 return this.$('.acf-fields:first');
2376 },
2377 initialize: function () {
2378 // Bail early if this is a duplicate of an existing initialized accordion.
2379 if (this.$el.hasClass('acf-accordion')) {
2380 return;
2381 }
2382
2383 // bail early if is cell
2384 if (this.$el.is('td')) return;
2385
2386 // endpoint
2387 if (this.get('endpoint')) {
2388 return this.remove();
2389 }
2390
2391 // vars
2392 var $field = this.$el;
2393 var $label = this.$labelWrap();
2394 var $input = this.$inputWrap();
2395 var $wrap = this.$control();
2396 var $instructions = $input.children('.description');
2397
2398 // force description into label
2399 if ($instructions.length) {
2400 $label.append($instructions);
2401 }
2402
2403 // table
2404 if (this.$el.is('tr')) {
2405 // vars
2406 var $table = this.$el.closest('table');
2407 var $newLabel = $('<div class="acf-accordion-title"/>');
2408 var $newInput = $('<div class="acf-accordion-content"/>');
2409 var $newTable = $('<table class="' + $table.attr('class') + '"/>');
2410 var $newWrap = $('<tbody/>');
2411
2412 // dom
2413 $newLabel.append($label.html());
2414 $newTable.append($newWrap);
2415 $newInput.append($newTable);
2416 $input.append($newLabel);
2417 $input.append($newInput);
2418
2419 // modify
2420 $label.remove();
2421 $wrap.remove();
2422 $input.attr('colspan', 2);
2423
2424 // update vars
2425 $label = $newLabel;
2426 $input = $newInput;
2427 $wrap = $newWrap;
2428 }
2429
2430 // add classes
2431 $field.addClass('acf-accordion');
2432 $label.addClass('acf-accordion-title');
2433 $input.addClass('acf-accordion-content');
2434
2435 // index
2436 i++;
2437
2438 // multi-expand
2439 if (this.get('multi_expand')) {
2440 $field.attr('multi-expand', 1);
2441 }
2442
2443 // open
2444 var order = acf.getPreference('this.accordions') || [];
2445 if (order[i - 1] !== undefined) {
2446 this.set('open', order[i - 1]);
2447 }
2448 if (this.get('open')) {
2449 $field.addClass('-open');
2450 $input.css('display', 'block'); // needed for accordion to close smoothly
2451 }
2452
2453 // add icon
2454 $label.prepend(accordionManager.iconHtml({
2455 open: this.get('open')
2456 }));
2457 $label.attr({
2458 tabindex: 0,
2459 role: 'button',
2460 'aria-expanded': this.get('open') ? 'true' : 'false'
2461 });
2462 $input.attr({
2463 role: 'region'
2464 });
2465
2466 // classes
2467 // - remove 'inside' which is a #poststuff WP class
2468 var $parent = $field.parent();
2469 $wrap.addClass($parent.hasClass('-left') ? '-left' : '');
2470 $wrap.addClass($parent.hasClass('-clear') ? '-clear' : '');
2471
2472 // append
2473 $wrap.append($field.nextUntil('.acf-field-accordion', '.acf-field'));
2474
2475 // clean up
2476 $wrap.removeAttr('data-open data-multi_expand data-endpoint');
2477 }
2478 });
2479 acf.registerFieldType(Field);
2480
2481 /**
2482 * accordionManager
2483 *
2484 * Events manager for the acf accordion
2485 *
2486 * @date 14/2/18
2487 * @since ACF 5.6.9
2488 *
2489 * @param void
2490 * @return void
2491 */
2492
2493 var accordionManager = new acf.Model({
2494 actions: {
2495 unload: 'onUnload'
2496 },
2497 events: {
2498 'click .acf-accordion-title': 'onClick',
2499 'keydown .acf-accordion-title': 'onKeydown',
2500 'invalidField .acf-accordion': 'onInvalidField'
2501 },
2502 isOpen: function ($el) {
2503 return $el.hasClass('-open');
2504 },
2505 toggle: function ($el) {
2506 if (this.isOpen($el)) {
2507 this.close($el);
2508 } else {
2509 this.open($el);
2510 }
2511 },
2512 iconHtml: function (props) {
2513 // Use SVG inside Gutenberg editor.
2514 if (acf.isGutenberg()) {
2515 if (props.open) {
2516 return '<svg width="24px" height="24px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" class="acf-accordion-icon components-panel__arrow" aria-hidden="true" focusable="false"><path d="M6.5 12.4L12 8l5.5 4.4-.9 1.2L12 10l-4.5 3.6-1-1.2z"></path></svg>';
2517 } else {
2518 return '<svg width="24px" height="24px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" class=" acf-accordion-icon components-panel__arrow" aria-hidden="true" focusable="false"><path d="M17.5 11.6L12 16l-5.5-4.4.9-1.2L12 14l4.5-3.6 1 1.2z"></path></svg>';
2519 }
2520 } else {
2521 if (props.open) {
2522 return '<i class="acf-accordion-icon dashicons dashicons-arrow-down"></i>';
2523 } else {
2524 return '<i class="acf-accordion-icon dashicons dashicons-arrow-right"></i>';
2525 }
2526 }
2527 },
2528 open: function ($el) {
2529 var duration = acf.isGutenberg() ? 0 : 300;
2530
2531 // open
2532 $el.find('.acf-accordion-content:first').slideDown(duration).css('display', 'block');
2533 $el.find('.acf-accordion-icon:first').replaceWith(this.iconHtml({
2534 open: true
2535 }));
2536 $el.addClass('-open');
2537 $el.find('.acf-accordion-title:first').attr('aria-expanded', 'true');
2538
2539 // action
2540 acf.doAction('show', $el);
2541
2542 // close siblings
2543 if (!$el.attr('multi-expand')) {
2544 $el.siblings('.acf-accordion.-open').each(function () {
2545 accordionManager.close($(this));
2546 });
2547 }
2548 },
2549 close: function ($el) {
2550 var duration = acf.isGutenberg() ? 0 : 300;
2551
2552 // close
2553 $el.find('.acf-accordion-content:first').slideUp(duration);
2554 $el.find('.acf-accordion-icon:first').replaceWith(this.iconHtml({
2555 open: false
2556 }));
2557 $el.removeClass('-open');
2558 $el.find('.acf-accordion-title:first').attr('aria-expanded', 'false');
2559
2560 // action
2561 acf.doAction('hide', $el);
2562 },
2563 onClick: function (e, $el) {
2564 // prevent Default
2565 e.preventDefault();
2566
2567 // open close
2568 this.toggle($el.parent());
2569 },
2570 onKeydown: function (e, $el) {
2571 // check for enter or space
2572 if (13 === e.which) {
2573 // prevent Default
2574 e.preventDefault();
2575 // open close
2576 this.toggle($el.parent());
2577 }
2578 },
2579 onInvalidField: function (e, $el) {
2580 // bail early if already focused
2581 if (this.busy) {
2582 return;
2583 }
2584
2585 // disable functionality for 1sec (allow next validation to work)
2586 this.busy = true;
2587 this.setTimeout(function () {
2588 this.busy = false;
2589 }, 1000);
2590
2591 // open accordion
2592 this.open($el);
2593 },
2594 onUnload: function (e) {
2595 // vars
2596 var order = [];
2597
2598 // loop
2599 $('.acf-accordion').each(function () {
2600 var open = $(this).hasClass('-open') ? 1 : 0;
2601 order.push(open);
2602 });
2603
2604 // set
2605 if (order.length) {
2606 acf.setPreference('this.accordions', order);
2607 }
2608 }
2609 });
2610 })(jQuery);
2611
2612 /***/ }),
2613
2614 /***/ "./assets/src/js/_acf-field-button-group.js":
2615 /*!**************************************************!*\
2616 !*** ./assets/src/js/_acf-field-button-group.js ***!
2617 \**************************************************/
2618 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2619
2620 "use strict";
2621 __webpack_require__.r(__webpack_exports__);
2622
2623 (function ($, undefined) {
2624 const Field = acf.Field.extend({
2625 type: 'button_group',
2626 events: {
2627 'click input[type="radio"]': 'onClick',
2628 'keydown label': 'onKeyDown'
2629 },
2630 $control: function () {
2631 return this.$('.acf-button-group');
2632 },
2633 $input: function () {
2634 return this.$('input:checked');
2635 },
2636 initialize: function () {
2637 this.updateButtonStates();
2638 },
2639 setValue: function (val) {
2640 this.$('input[value="' + val + '"]').prop('checked', true).trigger('change');
2641 this.updateButtonStates();
2642 },
2643 updateButtonStates: function () {
2644 const labels = this.$control().find('label');
2645 const input = this.$input();
2646 labels.removeClass('selected').attr('aria-checked', 'false').attr('tabindex', '-1');
2647 if (input.length) {
2648 // If there's a checked input, mark its parent label as selected
2649 input.parent('label').addClass('selected').attr('aria-checked', 'true').attr('tabindex', '0');
2650 } else {
2651 labels.first().attr('tabindex', '0');
2652 }
2653 },
2654 onClick: function (e, $el) {
2655 this.selectButton($el.parent('label'));
2656 },
2657 onKeyDown: function (event, label) {
2658 const key = event.which;
2659
2660 // Space or Enter: select the button
2661 if (key === 13 || key === 32) {
2662 event.preventDefault();
2663 this.selectButton(label);
2664 return;
2665 }
2666
2667 // Arrow keys: move focus between buttons
2668 if (key === 37 || key === 39 || key === 38 || key === 40) {
2669 event.preventDefault();
2670 const labels = this.$control().find('label');
2671 const currentIndex = labels.index(label);
2672 let nextIndex;
2673
2674 // Left/Up arrow: move to previous, wrap to last if at start
2675 if (key === 37 || key === 38) {
2676 nextIndex = currentIndex > 0 ? currentIndex - 1 : labels.length - 1;
2677 }
2678 // Right/Down arrow: move to next, wrap to first if at end
2679 else {
2680 nextIndex = currentIndex < labels.length - 1 ? currentIndex + 1 : 0;
2681 }
2682 const nextLabel = labels.eq(nextIndex);
2683 labels.attr('tabindex', '-1');
2684 nextLabel.attr('tabindex', '0').trigger('focus');
2685 }
2686 },
2687 selectButton: function (element) {
2688 const inputRadio = element.find('input[type="radio"]');
2689 const isSelected = element.hasClass('selected');
2690 inputRadio.prop('checked', true).trigger('change');
2691 if (this.get('allow_null') && isSelected) {
2692 inputRadio.prop('checked', false).trigger('change');
2693 }
2694 this.updateButtonStates();
2695 }
2696 });
2697 acf.registerFieldType(Field);
2698 })(jQuery);
2699
2700 /***/ }),
2701
2702 /***/ "./assets/src/js/_acf-field-checkbox.js":
2703 /*!**********************************************!*\
2704 !*** ./assets/src/js/_acf-field-checkbox.js ***!
2705 \**********************************************/
2706 /***/ (() => {
2707
2708 (function ($, undefined) {
2709 var Field = acf.Field.extend({
2710 type: 'checkbox',
2711 events: {
2712 'change input': 'onChange',
2713 'click .acf-add-checkbox': 'onClickAdd',
2714 'click .acf-checkbox-toggle': 'onClickToggle',
2715 'click .acf-checkbox-custom': 'onClickCustom',
2716 'keydown input[type="checkbox"]': 'onKeyDownInput'
2717 },
2718 $control: function () {
2719 return this.$('.acf-checkbox-list');
2720 },
2721 $toggle: function () {
2722 return this.$('.acf-checkbox-toggle');
2723 },
2724 $input: function () {
2725 return this.$('input[type="hidden"]');
2726 },
2727 $inputs: function () {
2728 return this.$('input[type="checkbox"]').not('.acf-checkbox-toggle');
2729 },
2730 setValue: function (val) {
2731 if (!Array.isArray(val)) {
2732 val = val ? [val] : [];
2733 }
2734 this.$inputs().each(function () {
2735 const $input = $(this);
2736 const checked = val.includes($input.val());
2737 $input.prop('checked', checked);
2738 if (checked) {
2739 $input.parent('label').addClass('selected');
2740 } else {
2741 $input.parent('label').removeClass('selected');
2742 }
2743 });
2744 const $toggle = this.$toggle();
2745 if ($toggle.length) {
2746 const checked = this.$inputs().not(':checked').length === 0;
2747 $toggle.prop('checked', checked);
2748 }
2749 },
2750 getValue: function () {
2751 var val = [];
2752 this.$(':checked').each(function () {
2753 val.push($(this).val());
2754 });
2755 return val.length ? val : false;
2756 },
2757 onChange: function (e, $el) {
2758 // Vars.
2759 var checked = $el.prop('checked');
2760 var $label = $el.parent('label');
2761 var $toggle = this.$toggle();
2762
2763 // Add or remove "selected" class.
2764 if (checked) {
2765 $label.addClass('selected');
2766 } else {
2767 $label.removeClass('selected');
2768 }
2769
2770 // Update toggle state if all inputs are checked.
2771 if ($toggle.length) {
2772 var $inputs = this.$inputs();
2773
2774 // all checked
2775 if ($inputs.not(':checked').length == 0) {
2776 $toggle.prop('checked', true);
2777 } else {
2778 $toggle.prop('checked', false);
2779 }
2780 }
2781 },
2782 onClickAdd: function (e, $el) {
2783 var html = '<li><input class="acf-checkbox-custom" type="checkbox" checked="checked" /><input type="text" name="' + this.getInputName() + '[]" /></li>';
2784 $el.parent('li').before(html);
2785 $el.parent('li').parent().find('input[type="text"]').last().trigger('focus');
2786 },
2787 onClickToggle: function (e, $el) {
2788 var $inputs = this.$inputs();
2789 var checked = $el.prop('checked');
2790 $inputs.prop('checked', checked).trigger('change');
2791 },
2792 onClickCustom: function (e, $el) {
2793 var checked = $el.prop('checked');
2794 var $text = $el.next('input[type="text"]');
2795
2796 // checked
2797 if (checked) {
2798 $text.prop('disabled', false);
2799
2800 // not checked
2801 } else {
2802 $text.prop('disabled', true);
2803
2804 // remove
2805 if ($text.val() == '') {
2806 $el.parent('li').remove();
2807 }
2808 }
2809 },
2810 onKeyDownInput: function (e, $el) {
2811 // Check if Enter key (keyCode 13) was pressed
2812 if (e.which === 13) {
2813 // Prevent default form submission
2814 e.preventDefault();
2815
2816 // Toggle the checkbox state and trigger change event
2817 $el.prop('checked', !$el.prop('checked')).trigger('change');
2818
2819 // If this is the "Select All" toggle checkbox, run the toggle logic
2820 if ($el.is('.acf-checkbox-toggle')) {
2821 this.onClickToggle(e, $el);
2822 }
2823 }
2824 }
2825 });
2826 acf.registerFieldType(Field);
2827 })(jQuery);
2828
2829 /***/ }),
2830
2831 /***/ "./assets/src/js/_acf-field-color-picker.js":
2832 /*!**************************************************!*\
2833 !*** ./assets/src/js/_acf-field-color-picker.js ***!
2834 \**************************************************/
2835 /***/ (() => {
2836
2837 (function ($, undefined) {
2838 var Field = acf.Field.extend({
2839 type: 'color_picker',
2840 wait: 'load',
2841 events: {
2842 duplicateField: 'onDuplicate'
2843 },
2844 $control: function () {
2845 return this.$('.acf-color-picker');
2846 },
2847 $input: function () {
2848 return this.$('input[type="hidden"]');
2849 },
2850 $inputText: function () {
2851 return this.$('input[type="text"]');
2852 },
2853 setValue: function (val) {
2854 // update input (with change)
2855 acf.val(this.$input(), val);
2856
2857 // update iris
2858 this.$inputText().iris('color', val);
2859 },
2860 initialize: function () {
2861 // vars
2862 var $input = this.$input();
2863 var $inputText = this.$inputText();
2864
2865 // event
2866 var onChange = function (e) {
2867 // timeout is required to ensure the $input val is correct
2868 setTimeout(function () {
2869 acf.val($input, $inputText.val());
2870 }, 1);
2871 };
2872
2873 // args
2874 var args = {
2875 defaultColor: false,
2876 palettes: true,
2877 hide: true,
2878 change: onChange,
2879 clear: onChange
2880 };
2881 if ('custom' === $inputText.data('acf-palette-type')) {
2882 const paletteColor = $inputText.data('acf-palette-colors').match(/#(?:[0-9a-fA-F]{3}){1,2}|rgba?\([\s*(\d|.)+\s*,]+\)/g);
2883 if (paletteColor) {
2884 let trimmed = paletteColor.map(color => color.trim());
2885 args.palettes = trimmed;
2886 }
2887 }
2888
2889 // filter
2890 var args = acf.applyFilters('color_picker_args', args, this);
2891 if (Array.isArray(args.palettes) && args.palettes.length > 10) {
2892 // Add class for large custom palette styling
2893 this.$control().addClass('acf-color-picker-large-custom-palette');
2894 }
2895 // initialize
2896 $inputText.wpColorPicker(args);
2897 },
2898 onDuplicate: function (e, $el, $duplicate) {
2899 // The wpColorPicker library does not provide a destroy method.
2900 // Manually reset DOM by replacing elements back to their original state.
2901 $colorPicker = $duplicate.find('.wp-picker-container');
2902 $inputText = $duplicate.find('input[type="text"]');
2903 $colorPicker.replaceWith($inputText);
2904 }
2905 });
2906 acf.registerFieldType(Field);
2907 })(jQuery);
2908
2909 /***/ }),
2910
2911 /***/ "./assets/src/js/_acf-field-date-picker.js":
2912 /*!*************************************************!*\
2913 !*** ./assets/src/js/_acf-field-date-picker.js ***!
2914 \*************************************************/
2915 /***/ (() => {
2916
2917 (function ($, undefined) {
2918 var Field = acf.Field.extend({
2919 type: 'date_picker',
2920 events: {
2921 'blur input[type="text"]': 'onBlur',
2922 duplicateField: 'onDuplicate'
2923 },
2924 $control: function () {
2925 return this.$('.acf-date-picker');
2926 },
2927 $input: function () {
2928 return this.$('input[type="hidden"]');
2929 },
2930 $inputText: function () {
2931 return this.$('input[type="text"]');
2932 },
2933 initialize: function () {
2934 // save_format: compatibility with ACF < 5.0.0
2935 if (this.has('save_format')) {
2936 return this.initializeCompatibility();
2937 }
2938
2939 // vars
2940 var $input = this.$input();
2941 var $inputText = this.$inputText();
2942
2943 // args
2944 var args = {
2945 dateFormat: this.get('date_format'),
2946 altField: $input,
2947 altFormat: 'yymmdd',
2948 changeYear: true,
2949 yearRange: '-100:+100',
2950 changeMonth: true,
2951 showButtonPanel: true,
2952 firstDay: this.get('first_day')
2953 };
2954
2955 // filter
2956 args = acf.applyFilters('date_picker_args', args, this);
2957
2958 // add date picker
2959 acf.newDatePicker($inputText, args);
2960
2961 // Check if default to today is enabled and field is empty
2962 if ($inputText.data('default-to-today') === 1 && !$input.val()) {
2963 // Get current date
2964 const currentDate = new Date();
2965
2966 // Format display date
2967 const displayDate = $.datepicker.formatDate(args.dateFormat, currentDate);
2968
2969 // Set the display input value (what user sees)
2970 $inputText.val(`${displayDate}`);
2971
2972 // Format hidden field date (for database storage)
2973 const hiddenDate = $.datepicker.formatDate('yymmdd', currentDate);
2974
2975 // Set the hidden input value (what gets saved)
2976 $input.val(`${hiddenDate}`);
2977 }
2978 acf.doAction('date_picker_init', $inputText, args, this);
2979 },
2980 initializeCompatibility: function () {
2981 // vars
2982 var $input = this.$input();
2983 var $inputText = this.$inputText();
2984
2985 // get and set value from alt field
2986 $inputText.val($input.val());
2987
2988 // args
2989 var args = {
2990 dateFormat: this.get('date_format'),
2991 altField: $input,
2992 altFormat: this.get('save_format'),
2993 changeYear: true,
2994 yearRange: '-100:+100',
2995 changeMonth: true,
2996 showButtonPanel: true,
2997 firstDay: this.get('first_day')
2998 };
2999
3000 // filter for 3rd party customization
3001 args = acf.applyFilters('date_picker_args', args, this);
3002
3003 // backup
3004 var dateFormat = args.dateFormat;
3005
3006 // change args.dateFormat
3007 args.dateFormat = this.get('save_format');
3008
3009 // add date picker
3010 acf.newDatePicker($inputText, args);
3011
3012 // now change the format back to how it should be.
3013 $inputText.datepicker('option', 'dateFormat', dateFormat);
3014
3015 // action for 3rd party customization
3016 acf.doAction('date_picker_init', $inputText, args, this);
3017 },
3018 setValue: function (val) {
3019 acf.val(this.$input(), val);
3020 const $inputText = this.$inputText();
3021 if (val && $inputText.length) {
3022 try {
3023 const date = $.datepicker.parseDate('yymmdd', val);
3024 const dateFormat = this.get('date_format') || $inputText.datepicker('option', 'dateFormat');
3025 $inputText.val($.datepicker.formatDate(dateFormat, date));
3026 } catch (e) {
3027 $inputText.val(val);
3028 }
3029 } else {
3030 $inputText.val('');
3031 }
3032 },
3033 onBlur: function () {
3034 if (!this.$inputText().val()) {
3035 acf.val(this.$input(), '');
3036 }
3037 },
3038 onDuplicate: function (e, $el, $duplicate) {
3039 $duplicate.find('input[type="text"]').removeClass('hasDatepicker').removeAttr('id');
3040 }
3041 });
3042 acf.registerFieldType(Field);
3043
3044 // manager
3045 var datePickerManager = new acf.Model({
3046 priority: 5,
3047 wait: 'ready',
3048 initialize: function () {
3049 // vars
3050 var locale = acf.get('locale');
3051 var rtl = acf.get('rtl');
3052 var l10n = acf.get('datePickerL10n');
3053
3054 // bail early if no l10n
3055 if (!l10n) {
3056 return false;
3057 }
3058
3059 // bail early if no datepicker library
3060 if (typeof $.datepicker === 'undefined') {
3061 return false;
3062 }
3063
3064 // rtl
3065 l10n.isRTL = rtl;
3066
3067 // append
3068 $.datepicker.regional[locale] = l10n;
3069 $.datepicker.setDefaults(l10n);
3070 }
3071 });
3072
3073 // add
3074 acf.newDatePicker = function ($input, args) {
3075 // bail early if no datepicker library
3076 if (typeof $.datepicker === 'undefined') {
3077 return false;
3078 }
3079
3080 // defaults
3081 args = args || {};
3082
3083 // initialize
3084 $input.datepicker(args);
3085
3086 // wrap the datepicker (only if it hasn't already been wrapped)
3087 if ($('body > #ui-datepicker-div').exists()) {
3088 $('body > #ui-datepicker-div').wrap('<div class="acf-ui-datepicker" />');
3089 }
3090 };
3091 })(jQuery);
3092
3093 /***/ }),
3094
3095 /***/ "./assets/src/js/_acf-field-date-time-picker.js":
3096 /*!******************************************************!*\
3097 !*** ./assets/src/js/_acf-field-date-time-picker.js ***!
3098 \******************************************************/
3099 /***/ (() => {
3100
3101 (function ($, undefined) {
3102 var Field = acf.models.DatePickerField.extend({
3103 type: 'date_time_picker',
3104 $control: function () {
3105 return this.$('.acf-date-time-picker');
3106 },
3107 setValue: function (val) {
3108 acf.val(this.$input(), val);
3109 const $inputText = this.$inputText();
3110 if (val && $inputText.length) {
3111 try {
3112 const parts = val.split(' ');
3113 const dateValue = parts[0] || '';
3114 const timeValue = parts[1] || '';
3115 const date = $.datepicker.parseDate('yy-mm-dd', dateValue);
3116 const dateFormat = this.get('date_format') || $inputText.datetimepicker('option', 'dateFormat');
3117 const timeFormat = this.get('time_format') || $inputText.datetimepicker('option', 'timeFormat');
3118 const dateText = $.datepicker.formatDate(dateFormat, date);
3119 let timeText = timeValue;
3120 const matches = timeValue.match(/^(\d{2}):(\d{2}):(\d{2})$/);
3121 if (matches && $.datepicker.formatTime) {
3122 timeText = $.datepicker.formatTime(timeFormat, {
3123 hour: parseInt(matches[1], 10),
3124 minute: parseInt(matches[2], 10),
3125 second: parseInt(matches[3], 10)
3126 });
3127 }
3128 $inputText.val(dateText + ' ' + timeText);
3129 } catch (e) {
3130 $inputText.val(val);
3131 }
3132 } else {
3133 $inputText.val('');
3134 }
3135 },
3136 initialize: function () {
3137 // vars
3138 var $input = this.$input();
3139 var $inputText = this.$inputText();
3140
3141 // args
3142 var args = {
3143 dateFormat: this.get('date_format'),
3144 timeFormat: this.get('time_format'),
3145 altField: $input,
3146 altFieldTimeOnly: false,
3147 altFormat: 'yy-mm-dd',
3148 altTimeFormat: 'HH:mm:ss',
3149 changeYear: true,
3150 yearRange: '-100:+100',
3151 changeMonth: true,
3152 showButtonPanel: true,
3153 firstDay: this.get('first_day'),
3154 controlType: 'select',
3155 oneLine: true
3156 };
3157
3158 // filter
3159 args = acf.applyFilters('date_time_picker_args', args, this);
3160
3161 // add date time picker
3162 acf.newDateTimePicker($inputText, args);
3163
3164 // Check if default to today is enabled and field is empty
3165 if ($inputText.data('default-to-today') === 1 && !$input.val()) {
3166 // Get current date
3167 const currentDate = new Date();
3168
3169 // Format display date and time
3170 const displayDate = $.datepicker.formatDate(args.dateFormat, currentDate);
3171 const displayTime = $.datepicker.formatTime(args.timeFormat, {
3172 hour: currentDate.getHours(),
3173 minute: currentDate.getMinutes(),
3174 second: currentDate.getSeconds()
3175 });
3176
3177 // Set the display input value (what user sees)
3178 $inputText.val(`${displayDate} ${displayTime}`);
3179
3180 // Format hidden field date and time (for database storage)
3181 const hiddenDate = $.datepicker.formatDate('yy-mm-dd', currentDate);
3182 const hiddenTime = $.datepicker.formatTime('hh:mm:ss', {
3183 hour: currentDate.getHours(),
3184 minute: currentDate.getMinutes(),
3185 second: currentDate.getSeconds()
3186 });
3187
3188 // Set the hidden input value (what gets saved)
3189 $input.val(`${hiddenDate} ${hiddenTime}`);
3190 }
3191
3192 // action
3193 acf.doAction('date_time_picker_init', $inputText, args, this);
3194 }
3195 });
3196 acf.registerFieldType(Field);
3197
3198 // manager
3199 var dateTimePickerManager = new acf.Model({
3200 priority: 5,
3201 wait: 'ready',
3202 initialize: function () {
3203 // vars
3204 var locale = acf.get('locale');
3205 var rtl = acf.get('rtl');
3206 var l10n = acf.get('dateTimePickerL10n');
3207
3208 // bail early if no l10n
3209 if (!l10n) {
3210 return false;
3211 }
3212
3213 // bail early if no datepicker library
3214 if (typeof $.timepicker === 'undefined') {
3215 return false;
3216 }
3217
3218 // rtl
3219 l10n.isRTL = rtl;
3220
3221 // append
3222 $.timepicker.regional[locale] = l10n;
3223 $.timepicker.setDefaults(l10n);
3224 }
3225 });
3226
3227 // add
3228 acf.newDateTimePicker = function ($input, args) {
3229 // bail early if no datepicker library
3230 if (typeof $.timepicker === 'undefined') {
3231 return false;
3232 }
3233
3234 // defaults
3235 args = args || {};
3236
3237 // initialize
3238 $input.datetimepicker(args);
3239
3240 // wrap the datepicker (only if it hasn't already been wrapped)
3241 if ($('body > #ui-datepicker-div').exists()) {
3242 $('body > #ui-datepicker-div').wrap('<div class="acf-ui-datepicker" />');
3243 }
3244 };
3245 })(jQuery);
3246
3247 /***/ }),
3248
3249 /***/ "./assets/src/js/_acf-field-file.js":
3250 /*!******************************************!*\
3251 !*** ./assets/src/js/_acf-field-file.js ***!
3252 \******************************************/
3253 /***/ (() => {
3254
3255 (function ($, undefined) {
3256 const Field = acf.models.ImageField.extend({
3257 type: 'file',
3258 $control: function () {
3259 return this.$('.acf-file-uploader');
3260 },
3261 $input: function () {
3262 return this.$('input[type="hidden"]:first');
3263 },
3264 events: {
3265 'click a[data-name="add"]': 'onClickAdd',
3266 'click a[data-name="edit"]': 'onClickEdit',
3267 'click a[data-name="remove"]': 'onClickRemove',
3268 'change input[type="file"]': 'onChange',
3269 'keydown .file-wrap': 'onImageWrapKeydown'
3270 },
3271 validateAttachment: function (attachment) {
3272 // defaults
3273 attachment = attachment || {};
3274
3275 // WP attachment
3276 if (attachment.id !== undefined) {
3277 attachment = attachment.attributes;
3278 }
3279
3280 // args
3281 attachment = acf.parseArgs(attachment, {
3282 url: '',
3283 alt: '',
3284 title: '',
3285 filename: '',
3286 filesizeHumanReadable: '',
3287 icon: '/wp-includes/images/media/default.png'
3288 });
3289
3290 // return
3291 return attachment;
3292 },
3293 render: function (attachment) {
3294 // vars
3295 attachment = this.validateAttachment(attachment);
3296
3297 // update image
3298 this.$('img').attr({
3299 src: attachment.icon,
3300 alt: attachment.alt,
3301 title: attachment.title
3302 });
3303
3304 // update elements
3305 this.$('[data-name="title"]').text(attachment.title);
3306 this.$('[data-name="filename"]').text(attachment.filename).attr('href', attachment.url);
3307 this.$('[data-name="filesize"]').text(attachment.filesizeHumanReadable);
3308
3309 // vars
3310 const val = attachment.id || '';
3311
3312 // update val
3313 acf.val(this.$input(), val);
3314 if (val) {
3315 // update class
3316 this.$control().addClass('has-value');
3317 const fileWrap = this.$('.file-wrap');
3318 if (fileWrap.length) {
3319 fileWrap.trigger('focus');
3320 }
3321 } else {
3322 this.$control().removeClass('has-value');
3323 }
3324 },
3325 setValue: function (val) {
3326 val = val ? String(val) : '';
3327 if (acf.val(this.$input(), val, true) === false) {
3328 return;
3329 }
3330 if (val) {
3331 if (window.wp && wp.media && wp.media.attachment) {
3332 const attachment = wp.media.attachment(val);
3333 attachment.fetch().then($.proxy(function () {
3334 this.render(attachment);
3335 }, this));
3336 } else {
3337 this.$control().addClass('has-value');
3338 }
3339 } else {
3340 this.render(false);
3341 }
3342 },
3343 selectAttachment: function () {
3344 // vars
3345 const parent = this.parent();
3346 const multiple = parent && parent.get('type') === 'repeater';
3347
3348 // new frame
3349 const frame = acf.newMediaPopup({
3350 mode: 'select',
3351 title: acf.__('Select File'),
3352 field: this.get('key'),
3353 multiple: multiple,
3354 library: this.get('library'),
3355 allowedTypes: this.get('mime_types'),
3356 select: $.proxy(function (attachment, i) {
3357 if (i > 0) {
3358 this.append(attachment, parent);
3359 } else {
3360 this.render(attachment);
3361 }
3362 }, this)
3363 });
3364 },
3365 editAttachment: function (button) {
3366 // vars
3367 const val = this.val();
3368
3369 // bail early if no val
3370 if (!val) {
3371 return false;
3372 }
3373
3374 // popup
3375 var frame = acf.newMediaPopup({
3376 mode: 'edit',
3377 title: acf.__('Edit File'),
3378 button: acf.__('Update File'),
3379 attachment: val,
3380 field: this.get('key'),
3381 select: $.proxy(function (attachment) {
3382 this.render(attachment);
3383 }, this),
3384 close: $.proxy(function () {
3385 if ('edit-button' === button) {
3386 const edit = this.$el.find('a[data-name="edit"]');
3387 if (edit.length) {
3388 edit.trigger('focus');
3389 }
3390 } else {
3391 const imageWrap = this.$el.find('.image-wrap');
3392 if (imageWrap.length) {
3393 imageWrap.trigger('focus');
3394 }
3395 }
3396 }, this)
3397 });
3398 }
3399 });
3400 acf.registerFieldType(Field);
3401 })(jQuery);
3402
3403 /***/ }),
3404
3405 /***/ "./assets/src/js/_acf-field-google-map.js":
3406 /*!************************************************!*\
3407 !*** ./assets/src/js/_acf-field-google-map.js ***!
3408 \************************************************/
3409 /***/ (() => {
3410
3411 (function ($, undefined) {
3412 var Field = acf.Field.extend({
3413 type: 'google_map',
3414 map: false,
3415 wait: 'load',
3416 events: {
3417 'click button[data-name="clear"]': 'onClickClear',
3418 'click button[data-name="locate"]': 'onClickLocate',
3419 'click button[data-name="search"]': 'onClickSearch',
3420 'keydown .search': 'onKeydownSearch',
3421 'keyup .search': 'onKeyupSearch',
3422 'focus .search': 'onFocusSearch',
3423 'blur .search': 'onBlurSearch',
3424 showField: 'onShow'
3425 },
3426 $control: function () {
3427 return this.$('.acf-google-map');
3428 },
3429 $search: function () {
3430 return this.$('.search');
3431 },
3432 $canvas: function () {
3433 return this.$('.canvas');
3434 },
3435 setState: function (state) {
3436 // Remove previous state classes.
3437 this.$control().removeClass('-value -loading -searching');
3438
3439 // Determine auto state based of current value.
3440 if (state === 'default') {
3441 state = this.val() ? 'value' : '';
3442 }
3443
3444 // Update state class.
3445 if (state) {
3446 this.$control().addClass('-' + state);
3447 }
3448 },
3449 getValue: function () {
3450 var val = this.$input().val();
3451 if (val) {
3452 return JSON.parse(val);
3453 } else {
3454 return false;
3455 }
3456 },
3457 setValue: function (val, silent) {
3458 // Convert input value.
3459 var valAttr = '';
3460 if (val) {
3461 valAttr = JSON.stringify(val);
3462 }
3463
3464 // Update input (with change).
3465 acf.val(this.$input(), valAttr);
3466
3467 // Bail early if silent update.
3468 if (silent) {
3469 return;
3470 }
3471
3472 // Render.
3473 this.renderVal(val);
3474
3475 /**
3476 * Fires immediately after the value has changed.
3477 *
3478 * @date 12/02/2014
3479 * @since ACF 5.0.0
3480 *
3481 * @param object|string val The new value.
3482 * @param object map The Google Map instance.
3483 * @param object field The field instance.
3484 */
3485 acf.doAction('google_map_change', val, this.map, this);
3486 },
3487 renderVal: function (val) {
3488 // Value.
3489 if (val) {
3490 this.setState('value');
3491 this.$search().val(val.address);
3492 this.setPosition(val.lat, val.lng);
3493
3494 // No value.
3495 } else {
3496 this.setState('');
3497 this.$search().val('');
3498 this.map.marker.setVisible(false);
3499 }
3500 },
3501 newLatLng: function (lat, lng) {
3502 return new google.maps.LatLng(parseFloat(lat), parseFloat(lng));
3503 },
3504 setPosition: function (lat, lng) {
3505 // Update marker position.
3506 this.map.marker.setPosition({
3507 lat: parseFloat(lat),
3508 lng: parseFloat(lng)
3509 });
3510
3511 // Show marker.
3512 this.map.marker.setVisible(true);
3513
3514 // Center map.
3515 this.center();
3516 },
3517 center: function () {
3518 // Find marker position.
3519 var position = this.map.marker.getPosition();
3520 if (position) {
3521 var lat = position.lat();
3522 var lng = position.lng();
3523
3524 // Or find default settings.
3525 } else {
3526 var lat = this.get('lat');
3527 var lng = this.get('lng');
3528 }
3529
3530 // Center map.
3531 this.map.setCenter({
3532 lat: parseFloat(lat),
3533 lng: parseFloat(lng)
3534 });
3535 },
3536 initialize: function () {
3537 // Ensure Google API is loaded and then initialize map.
3538 withAPI(this.initializeMap.bind(this));
3539 },
3540 initializeMap: function () {
3541 // Get value ignoring conditional logic status.
3542 var val = this.getValue();
3543
3544 // Construct default args.
3545 var args = acf.parseArgs(val, {
3546 zoom: this.get('zoom'),
3547 lat: this.get('lat'),
3548 lng: this.get('lng')
3549 });
3550
3551 // Create Map.
3552 var mapArgs = {
3553 scrollwheel: false,
3554 zoom: parseInt(args.zoom),
3555 center: {
3556 lat: parseFloat(args.lat),
3557 lng: parseFloat(args.lng)
3558 },
3559 mapTypeId: google.maps.MapTypeId.ROADMAP,
3560 marker: {
3561 draggable: true,
3562 raiseOnDrag: true
3563 },
3564 autocomplete: {}
3565 };
3566 mapArgs = acf.applyFilters('google_map_args', mapArgs, this);
3567 var map = new google.maps.Map(this.$canvas()[0], mapArgs);
3568
3569 // Create Marker.
3570 var markerArgs = acf.parseArgs(mapArgs.marker, {
3571 draggable: true,
3572 raiseOnDrag: true,
3573 map: map
3574 });
3575 markerArgs = acf.applyFilters('google_map_marker_args', markerArgs, this);
3576 var marker = new google.maps.Marker(markerArgs);
3577
3578 // Maybe Create Autocomplete.
3579 var autocomplete = false;
3580 if (acf.isset(google, 'maps', 'places', 'Autocomplete')) {
3581 var autocompleteArgs = mapArgs.autocomplete || {};
3582 autocompleteArgs = acf.applyFilters('google_map_autocomplete_args', autocompleteArgs, this);
3583 autocomplete = new google.maps.places.Autocomplete(this.$search()[0], autocompleteArgs);
3584 autocomplete.bindTo('bounds', map);
3585 }
3586
3587 // Add map events.
3588 this.addMapEvents(this, map, marker, autocomplete);
3589
3590 // Append references.
3591 map.acf = this;
3592 map.marker = marker;
3593 map.autocomplete = autocomplete;
3594 this.map = map;
3595
3596 // Set position.
3597 if (val) {
3598 this.setPosition(val.lat, val.lng);
3599 }
3600
3601 /**
3602 * Fires immediately after the Google Map has been initialized.
3603 *
3604 * @date 12/02/2014
3605 * @since ACF 5.0.0
3606 *
3607 * @param object map The Google Map instance.
3608 * @param object marker The Google Map marker isntance.
3609 * @param object field The field instance.
3610 */
3611 acf.doAction('google_map_init', map, marker, this);
3612 },
3613 addMapEvents: function (field, map, marker, autocomplete) {
3614 // Click map.
3615 google.maps.event.addListener(map, 'click', function (e) {
3616 var lat = e.latLng.lat();
3617 var lng = e.latLng.lng();
3618 field.searchPosition(lat, lng);
3619 });
3620
3621 // Drag marker.
3622 google.maps.event.addListener(marker, 'dragend', function () {
3623 var lat = this.getPosition().lat();
3624 var lng = this.getPosition().lng();
3625 field.searchPosition(lat, lng);
3626 });
3627
3628 // Autocomplete search.
3629 if (autocomplete) {
3630 google.maps.event.addListener(autocomplete, 'place_changed', function () {
3631 var place = this.getPlace();
3632 field.searchPlace(place);
3633 });
3634 }
3635
3636 // Detect zoom change.
3637 google.maps.event.addListener(map, 'zoom_changed', function () {
3638 var val = field.val();
3639 if (val) {
3640 val.zoom = map.getZoom();
3641 field.setValue(val, true);
3642 }
3643 });
3644 },
3645 searchPosition: function (lat, lng) {
3646 //console.log('searchPosition', lat, lng );
3647
3648 // Start Loading.
3649 this.setState('loading');
3650
3651 // Query Geocoder.
3652 var latLng = {
3653 lat: lat,
3654 lng: lng
3655 };
3656 geocoder.geocode({
3657 location: latLng
3658 }, function (results, status) {
3659 //console.log('searchPosition', arguments );
3660
3661 // End Loading.
3662 this.setState('');
3663
3664 // Status failure.
3665 if (status !== 'OK') {
3666 this.showNotice({
3667 text: acf.__('Location not found: %s').replace('%s', status),
3668 type: 'warning'
3669 });
3670
3671 // Success.
3672 } else {
3673 var val = this.parseResult(results[0]);
3674
3675 // Override lat/lng to match user defined marker location.
3676 // Avoids issue where marker "snaps" to nearest result.
3677 val.lat = lat;
3678 val.lng = lng;
3679 this.val(val);
3680 }
3681 }.bind(this));
3682 },
3683 searchPlace: function (place) {
3684 //console.log('searchPlace', place );
3685
3686 // Bail early if no place.
3687 if (!place) {
3688 return;
3689 }
3690
3691 // Selecting from the autocomplete dropdown will return a rich PlaceResult object.
3692 // Be sure to over-write the "formatted_address" value with the one displayed to the user for best UX.
3693 if (place.geometry) {
3694 place.formatted_address = this.$search().val();
3695 var val = this.parseResult(place);
3696 this.val(val);
3697
3698 // Searching a custom address will return an empty PlaceResult object.
3699 } else if (place.name) {
3700 this.searchAddress(place.name);
3701 }
3702 },
3703 searchAddress: function (address) {
3704 //console.log('searchAddress', address );
3705
3706 // Bail early if no address.
3707 if (!address) {
3708 return;
3709 }
3710
3711 // Allow "lat,lng" search.
3712 var latLng = address.split(',');
3713 if (latLng.length == 2) {
3714 var lat = parseFloat(latLng[0]);
3715 var lng = parseFloat(latLng[1]);
3716 if (lat && lng) {
3717 return this.searchPosition(lat, lng);
3718 }
3719 }
3720
3721 // Start Loading.
3722 this.setState('loading');
3723
3724 // Query Geocoder.
3725 geocoder.geocode({
3726 address: address
3727 }, function (results, status) {
3728 //console.log('searchPosition', arguments );
3729
3730 // End Loading.
3731 this.setState('');
3732
3733 // Status failure.
3734 if (status !== 'OK') {
3735 this.showNotice({
3736 text: acf.__('Location not found: %s').replace('%s', status),
3737 type: 'warning'
3738 });
3739
3740 // Success.
3741 } else {
3742 var val = this.parseResult(results[0]);
3743
3744 // Override address data with parameter allowing custom address to be defined in search.
3745 val.address = address;
3746
3747 // Update value.
3748 this.val(val);
3749 }
3750 }.bind(this));
3751 },
3752 searchLocation: function () {
3753 //console.log('searchLocation' );
3754
3755 // Check HTML5 geolocation.
3756 if (!navigator.geolocation) {
3757 return alert(acf.__('Sorry, this browser does not support geolocation'));
3758 }
3759
3760 // Start Loading.
3761 this.setState('loading');
3762
3763 // Query Geolocation.
3764 navigator.geolocation.getCurrentPosition(
3765 // Success.
3766 function (results) {
3767 // End Loading.
3768 this.setState('');
3769
3770 // Search position.
3771 var lat = results.coords.latitude;
3772 var lng = results.coords.longitude;
3773 this.searchPosition(lat, lng);
3774 }.bind(this),
3775 // Failure.
3776 function (error) {
3777 this.setState('');
3778 }.bind(this));
3779 },
3780 /**
3781 * parseResult
3782 *
3783 * Returns location data for the given GeocoderResult object.
3784 *
3785 * @date 15/10/19
3786 * @since ACF 5.8.6
3787 *
3788 * @param object obj A GeocoderResult object.
3789 * @return object
3790 */
3791 parseResult: function (obj) {
3792 // Construct basic data.
3793 var result = {
3794 address: obj.formatted_address,
3795 lat: obj.geometry.location.lat(),
3796 lng: obj.geometry.location.lng()
3797 };
3798
3799 // Add zoom level.
3800 result.zoom = this.map.getZoom();
3801
3802 // Add place ID.
3803 if (obj.place_id) {
3804 result.place_id = obj.place_id;
3805 }
3806
3807 // Add place name.
3808 if (obj.name) {
3809 result.name = obj.name;
3810 }
3811
3812 // Create search map for address component data.
3813 var map = {
3814 street_number: ['street_number'],
3815 street_name: ['street_address', 'route'],
3816 city: ['locality', 'postal_town'],
3817 state: ['administrative_area_level_1', 'administrative_area_level_2', 'administrative_area_level_3', 'administrative_area_level_4', 'administrative_area_level_5'],
3818 post_code: ['postal_code'],
3819 country: ['country']
3820 };
3821
3822 // Loop over map.
3823 for (var k in map) {
3824 var keywords = map[k];
3825
3826 // Loop over address components.
3827 for (var i = 0; i < obj.address_components.length; i++) {
3828 var component = obj.address_components[i];
3829 var component_type = component.types[0];
3830
3831 // Look for matching component type.
3832 if (keywords.indexOf(component_type) !== -1) {
3833 // Append to result.
3834 result[k] = component.long_name;
3835
3836 // Append short version.
3837 if (component.long_name !== component.short_name) {
3838 result[k + '_short'] = component.short_name;
3839 }
3840 }
3841 }
3842 }
3843
3844 /**
3845 * Filters the parsed result.
3846 *
3847 * @date 18/10/19
3848 * @since ACF 5.8.6
3849 *
3850 * @param object result The parsed result value.
3851 * @param object obj The GeocoderResult object.
3852 */
3853 return acf.applyFilters('google_map_result', result, obj, this.map, this);
3854 },
3855 onClickClear: function () {
3856 this.val(false);
3857 },
3858 onClickLocate: function () {
3859 this.searchLocation();
3860 },
3861 onClickSearch: function () {
3862 this.searchAddress(this.$search().val());
3863 },
3864 onFocusSearch: function (event, searchInput) {
3865 const currentValue = this.val();
3866 const currentAddress = currentValue ? currentValue.address : '';
3867 if (searchInput.val() !== currentAddress) {
3868 this.setState('searching');
3869 }
3870 },
3871 onBlurSearch: function (e, $el) {
3872 // Get saved address value.
3873 var val = this.val();
3874 var address = val ? val.address : '';
3875
3876 // Remove 'is-searching' if value has not changed.
3877 if ($el.val() === address) {
3878 this.setState('default');
3879 }
3880 },
3881 onKeyupSearch: function (e, $el) {
3882 const val = this.val();
3883 const address = val ? val.address : '';
3884 if ($el.val()) {
3885 // If search input has value
3886 if ($el.val() !== address) {
3887 this.setState('searching');
3888 } else {
3889 this.setState('default');
3890 }
3891 } else {
3892 // If search input is empty
3893 this.val(false);
3894 this.setState('default');
3895 }
3896 },
3897 // Prevent form from submitting.
3898 onKeydownSearch: function (e, $el) {
3899 if (e.which == 13) {
3900 e.preventDefault();
3901 $el.blur();
3902 }
3903 },
3904 // Center map once made visible.
3905 onShow: function () {
3906 if (this.map) {
3907 this.setTimeout(this.center);
3908 }
3909 }
3910 });
3911 acf.registerFieldType(Field);
3912
3913 // Vars.
3914 var loading = false;
3915 var geocoder = false;
3916
3917 /**
3918 * withAPI
3919 *
3920 * Loads the Google Maps API library and triggers callback.
3921 *
3922 * @date 28/3/19
3923 * @since ACF 5.7.14
3924 *
3925 * @param function callback The callback to execute.
3926 * @return void
3927 */
3928
3929 function withAPI(callback) {
3930 // Check if geocoder exists.
3931 if (geocoder) {
3932 return callback();
3933 }
3934
3935 // Check if geocoder API exists.
3936 if (acf.isset(window, 'google', 'maps', 'Geocoder')) {
3937 geocoder = new google.maps.Geocoder();
3938 return callback();
3939 }
3940
3941 // Geocoder will need to be loaded. Hook callback to action.
3942 acf.addAction('google_map_api_loaded', callback);
3943
3944 // Bail early if already loading API.
3945 if (loading) {
3946 return;
3947 }
3948
3949 // load api
3950 var url = acf.get('google_map_api');
3951 if (url) {
3952 // Set loading status.
3953 loading = true;
3954
3955 // Load API
3956 $.ajax({
3957 url: url,
3958 dataType: 'script',
3959 cache: true,
3960 success: function () {
3961 geocoder = new google.maps.Geocoder();
3962 acf.doAction('google_map_api_loaded');
3963 }
3964 });
3965 }
3966 }
3967 })(jQuery);
3968
3969 /***/ }),
3970
3971 /***/ "./assets/src/js/_acf-field-icon-picker.js":
3972 /*!*************************************************!*\
3973 !*** ./assets/src/js/_acf-field-icon-picker.js ***!
3974 \*************************************************/
3975 /***/ (() => {
3976
3977 (function ($, undefined) {
3978 const Field = acf.Field.extend({
3979 type: 'icon_picker',
3980 wait: 'load',
3981 events: {
3982 showField: 'scrollToSelectedIcon',
3983 'input .acf-icon_url': 'onUrlChange',
3984 'click .acf-icon-picker-list-icon': 'onIconClick',
3985 'focus .acf-icon-picker-list-icon-radio': 'onIconRadioFocus',
3986 'blur .acf-icon-picker-list-icon-radio': 'onIconRadioBlur',
3987 'keydown .acf-icon-picker-list-icon-radio': 'onIconKeyDown',
3988 'input .acf-icon-list-search-input': 'onIconSearch',
3989 'keydown .acf-icon-list-search-input': 'onIconSearchKeyDown',
3990 'click .acf-icon-picker-media-library-button': 'onMediaLibraryButtonClick',
3991 'click .acf-icon-picker-media-library-preview': 'onMediaLibraryButtonClick'
3992 },
3993 $typeInput() {
3994 return this.$('input[type="hidden"][data-hidden-type="type"]:first');
3995 },
3996 $valueInput() {
3997 return this.$('input[type="hidden"][data-hidden-type="value"]:first');
3998 },
3999 $tabButton() {
4000 return this.$('.acf-tab-button');
4001 },
4002 $selectedIcon() {
4003 return this.$('.acf-icon-picker-list-icon.active');
4004 },
4005 $selectedRadio() {
4006 return this.$('.acf-icon-picker-list-icon.active input');
4007 },
4008 $iconsList() {
4009 return this.$('.acf-icon-list:visible');
4010 },
4011 $mediaLibraryButton() {
4012 return this.$('.acf-icon-picker-media-library-button');
4013 },
4014 $mediaLibraryPreviewImg() {
4015 return this.$('.acf-icon-picker-media-library-preview-img img');
4016 },
4017 getValue() {
4018 return {
4019 type: this.$typeInput().val(),
4020 value: this.$valueInput().val()
4021 };
4022 },
4023 setValue(val) {
4024 if (!val || typeof val !== 'object') {
4025 val = {
4026 type: '',
4027 value: ''
4028 };
4029 }
4030 const type = val.type || '';
4031 const value = val.value || '';
4032 this.updateTypeAndValue(type, value);
4033 if (type) {
4034 this.$tabButton().filter(`[data-unique-tab-key="${type}"]`).trigger('click');
4035 const $iconsList = this.$(`.acf-icon-list[data-parent-tab="${type}"]`);
4036 if ($iconsList.length) {
4037 $iconsList.find('.acf-icon-picker-list-icon.active').removeClass('active');
4038 $iconsList.find('input:checked').prop('checked', false);
4039 const $icon = $iconsList.find(`.acf-icon-picker-list-icon[data-icon="${value}"]`);
4040 if ($icon.length) {
4041 $icon.addClass('active');
4042 $icon.find('input').prop('checked', true);
4043 this.set('selectedIcon', value);
4044 }
4045 }
4046 }
4047 if (type === 'url') {
4048 this.$('.acf-icon_url').val(value);
4049 }
4050 if (type === 'media_library' && value && window.wp?.media?.attachment) {
4051 const attachment = wp.media.attachment(value);
4052 attachment.fetch().then(() => {
4053 const url = attachment.get('url');
4054 if (url) {
4055 this.set('mediaLibraryPreviewUrl', url);
4056 this.$mediaLibraryPreviewImg().attr('src', url);
4057 }
4058 });
4059 }
4060 },
4061 initialize() {
4062 // Set up actions hook callbacks.
4063 this.addActions();
4064
4065 // Initialize the state of the icon picker.
4066 let typeAndValue = {
4067 type: this.$typeInput().val(),
4068 value: this.$valueInput().val()
4069 };
4070
4071 // Store the type and value object.
4072 this.set('typeAndValue', typeAndValue);
4073 if (typeAndValue.type === 'media_library') {
4074 const previewUrl = this.$mediaLibraryPreviewImg().attr('src');
4075 if (previewUrl) {
4076 this.set('mediaLibraryPreviewUrl', previewUrl);
4077 }
4078 }
4079
4080 // Any time any acf tab is clicked, we will re-scroll to the selected icon.
4081 $('.acf-tab-button').on('click', () => {
4082 this.initializeIconLists(this.get('typeAndValue'));
4083 });
4084
4085 // Fire the action which lets people know the state has been updated.
4086 acf.doAction(this.get('name') + '/type_and_value_change', typeAndValue);
4087 this.initializeIconLists(typeAndValue);
4088 this.alignMediaLibraryTabToCurrentValue(typeAndValue);
4089 },
4090 addActions() {
4091 // Set up an action listener for when the type and value changes.
4092 acf.addAction(this.get('name') + '/type_and_value_change', newTypeAndValue => {
4093 const currentType = this.$typeInput().val();
4094 const currentValue = this.$valueInput().val();
4095 if (currentType === newTypeAndValue.type && currentValue === newTypeAndValue.value) {
4096 this.alignIconListTabsToCurrentValue(newTypeAndValue);
4097 this.alignMediaLibraryTabToCurrentValue(newTypeAndValue);
4098 this.alignUrlTabToCurrentValue(newTypeAndValue);
4099 } else {
4100 const currentTypeAndValue = this.get('typeAndValue');
4101 if (currentTypeAndValue) {
4102 this.alignIconListTabsToCurrentValue(currentTypeAndValue);
4103 this.alignMediaLibraryTabToCurrentValue(currentTypeAndValue);
4104 this.alignUrlTabToCurrentValue(currentTypeAndValue);
4105 }
4106 }
4107 });
4108 },
4109 updateTypeAndValue(type, value) {
4110 const typeAndValue = {
4111 type,
4112 value
4113 };
4114
4115 // Update the values in the hidden fields, which are what will actually be saved.
4116 acf.val(this.$typeInput(), type);
4117 acf.val(this.$valueInput(), value);
4118
4119 // Set the state.
4120 this.set('typeAndValue', typeAndValue);
4121
4122 // Fire an action to let each tab set itself according to the typeAndValue state.
4123 acf.doAction(this.get('name') + '/type_and_value_change', typeAndValue);
4124 },
4125 scrollToSelectedIcon() {
4126 const innerElement = this.$selectedIcon();
4127
4128 // If no icon is selected, do nothing.
4129 if (innerElement.length === 0) {
4130 return;
4131 }
4132 const scrollingDiv = innerElement.closest('.acf-icon-list');
4133 scrollingDiv.scrollTop(0);
4134 const distance = innerElement.position().top - 50;
4135 if (distance === 0) {
4136 return;
4137 }
4138 scrollingDiv.scrollTop(distance);
4139 },
4140 initializeIconLists(typeAndValue) {
4141 const self = this;
4142 this.$('.acf-icon-list').each(function (i) {
4143 const tabName = $(this).data('parent-tab');
4144 const icons = self.getIconsList(tabName) || [];
4145 self.set(tabName, icons);
4146 self.renderIconList($(this));
4147 if (typeAndValue.type === tabName) {
4148 // Select the correct icon.
4149 self.selectIcon($(this), typeAndValue.value, false).then(() => {
4150 // Scroll to the selected icon.
4151 self.scrollToSelectedIcon();
4152 });
4153 }
4154 });
4155 },
4156 alignIconListTabsToCurrentValue(typeAndValue) {
4157 const icons = this.$('.acf-icon-list').filter(function () {
4158 return $(this).data('parent-tab') !== typeAndValue.type;
4159 });
4160 const self = this;
4161 icons.each(function () {
4162 self.unselectIcon($(this));
4163 });
4164 },
4165 renderIconHTML(tabName, icon) {
4166 const id = `${this.get('name')}-${icon.key}`;
4167 let style = '';
4168 if ('dashicons' !== tabName) {
4169 style = `background: center / contain url( ${acf.strEscape(icon.url)} ) no-repeat;`;
4170 }
4171 return `<div class="${tabName} ${acf.strEscape(icon.key)} acf-icon-picker-list-icon" role="radio" data-icon="${acf.strEscape(icon.key)}" style="${style}" title="${acf.strEscape(icon.label)}">
4172 <label for="${acf.strEscape(id)}">${acf.strEscape(icon.label)}</label>
4173 <input id="${acf.strEscape(id)}" type="radio" class="acf-icon-picker-list-icon-radio" name="acf-icon-picker-list-icon-radio" value="${acf.strEscape(icon.key)}">
4174 </div>`;
4175 },
4176 renderIconList($el) {
4177 const tabName = $el.data('parent-tab');
4178 const icons = this.get(tabName);
4179 $el.empty();
4180 if (icons) {
4181 icons.forEach(icon => {
4182 const iconHTML = this.renderIconHTML(tabName, icon);
4183 $el.append(iconHTML);
4184 });
4185 }
4186 },
4187 getIconsList(tabName) {
4188 let icons;
4189 if ('dashicons' === tabName) {
4190 const iconPickeri10n = acf.get('iconPickeri10n') || [];
4191 icons = Object.entries(iconPickeri10n).map(([key, label]) => ({
4192 key,
4193 label
4194 }));
4195 } else {
4196 const iconList = this.$(`.acf-icon-list[data-parent-tab="${tabName}"]`);
4197 if (iconList.length !== 0) {
4198 const iconsData = iconList.data('icons');
4199 icons = Array.isArray(iconsData) ? iconsData : [];
4200 }
4201 }
4202 return icons;
4203 },
4204 getIconsBySearch(searchTerm, tabName) {
4205 const lowercaseSearchTerm = searchTerm.toLowerCase();
4206 const icons = this.getIconsList(tabName);
4207 const filteredIcons = icons.filter(function (icon) {
4208 const lowercaseIconLabel = icon.label.toLowerCase();
4209 return lowercaseIconLabel.indexOf(lowercaseSearchTerm) > -1;
4210 });
4211 return filteredIcons;
4212 },
4213 selectIcon($el, icon, setFocus = true) {
4214 this.set('selectedIcon', icon);
4215
4216 // Select the new one.
4217 const $newIcon = $el.find('.acf-icon-picker-list-icon[data-icon="' + icon + '"]');
4218 $newIcon.addClass('active');
4219 const $input = $newIcon.find('input');
4220 const thePromise = $input.prop('checked', true).promise();
4221 if (setFocus) {
4222 $input.trigger('focus');
4223 }
4224 this.updateTypeAndValue($el.data('parent-tab'), icon);
4225 return thePromise;
4226 },
4227 unselectIcon($el) {
4228 // Remove the currently active dashicon, if any.
4229 $el.find('.acf-icon-picker-list-icon').removeClass('active');
4230 this.set('selectedIcon', false);
4231 },
4232 onIconRadioFocus(e) {
4233 const icon = e.target.value;
4234 const $tabs = this.$(e.target).closest('.acf-icon-picker-tabs');
4235 const $iconsList = $tabs.find('.acf-icon-list');
4236 const $newIcon = $iconsList.find('.acf-icon-picker-list-icon[data-icon="' + icon + '"]');
4237 $newIcon.addClass('focus');
4238
4239 // If this is a different icon than previously selected, select it.
4240 if (this.get('selectedIcon') !== icon) {
4241 this.unselectIcon($iconsList);
4242 this.selectIcon($iconsList, icon);
4243 }
4244 },
4245 onIconRadioBlur(e) {
4246 const icon = this.$(e.target);
4247 const iconParent = icon.parent();
4248 iconParent.removeClass('focus');
4249 },
4250 onIconClick(e) {
4251 e.preventDefault();
4252 const $iconList = this.$(e.target).closest('.acf-icon-list');
4253 const $iconElement = this.$(e.target);
4254 const icon = $iconElement.find('input').val();
4255 const $newIconElement = $iconList.find('.acf-icon-picker-list-icon[data-icon="' + icon + '"]');
4256
4257 // By forcing focus on the input, we fire onIconRadioFocus.
4258 $newIconElement.find('input').prop('checked', true).trigger('focus');
4259 },
4260 onIconSearch(e) {
4261 const $tabs = this.$(e.target).closest('.acf-icon-picker-tabs');
4262 const $iconList = $tabs.find('.acf-icon-list');
4263 const tabName = $tabs.data('tab');
4264 const searchTerm = e.target.value;
4265 const filteredIcons = this.getIconsBySearch(searchTerm, tabName);
4266 if (filteredIcons.length > 0 || !searchTerm) {
4267 this.set(tabName, filteredIcons);
4268 $tabs.find('.acf-icon-list-empty').hide();
4269 $tabs.find('.acf-icon-list ').show();
4270 this.renderIconList($iconList);
4271
4272 // Announce change of data to screen readers.
4273 wp.a11y.speak(acf.get('iconPickerA11yStrings').newResultsFoundForSearchTerm, 'polite');
4274 } else {
4275 // Truncate the search term if it's too long.
4276 const visualSearchTerm = searchTerm.length > 30 ? searchTerm.substring(0, 30) + '&hellip;' : searchTerm;
4277 $tabs.find('.acf-icon-list ').hide();
4278 $tabs.find('.acf-icon-list-empty').find('.acf-invalid-icon-list-search-term').text(visualSearchTerm);
4279 $tabs.find('.acf-icon-list-empty').css('display', 'flex');
4280 $tabs.find('.acf-icon-list-empty').show();
4281
4282 // Announce change of data to screen readers.
4283 wp.a11y.speak(acf.get('iconPickerA11yStrings').noResultsForSearchTerm, 'polite');
4284 }
4285 },
4286 onIconSearchKeyDown(e) {
4287 // Check if the pressed key is Enter (key code 13)
4288 if (e.which === 13) {
4289 // Prevent submitting the entire form if someone presses enter after searching.
4290 e.preventDefault();
4291 }
4292 },
4293 onIconKeyDown(e) {
4294 if (e.which === 13) {
4295 // If someone presses enter while an icon is focused, prevent the form from submitting.
4296 e.preventDefault();
4297 }
4298 },
4299 alignMediaLibraryTabToCurrentValue(typeAndValue) {
4300 const type = typeAndValue.type;
4301 const value = typeAndValue.value;
4302 if (type !== 'media_library' && type !== 'dashicons') {
4303 // Hide the preview container on the media library tab.
4304 this.$('.acf-icon-picker-media-library-preview').hide();
4305 }
4306 if (type === 'media_library') {
4307 const previewUrl = this.get('mediaLibraryPreviewUrl');
4308 // Set the image file preview src.
4309 this.$('.acf-icon-picker-media-library-preview-img img').attr('src', previewUrl);
4310
4311 // Hide the dashicon preview.
4312 this.$('.acf-icon-picker-media-library-preview-dashicon').hide();
4313
4314 // Show the image file preview.
4315 this.$('.acf-icon-picker-media-library-preview-img').show();
4316
4317 // Show the preview container (it may have been hidden if nothing was ever selected yet).
4318 this.$('.acf-icon-picker-media-library-preview').show();
4319 }
4320 if (type === 'dashicons') {
4321 // Set the dashicon preview class.
4322 this.$('.acf-icon-picker-media-library-preview-dashicon .dashicons').attr('class', 'dashicons ' + value);
4323
4324 // Hide the image file preview.
4325 this.$('.acf-icon-picker-media-library-preview-img').hide();
4326
4327 // Show the dashicon preview.
4328 this.$('.acf-icon-picker-media-library-preview-dashicon').show();
4329
4330 // Show the preview container (it may have been hidden if nothing was ever selected yet).
4331 this.$('.acf-icon-picker-media-library-preview').show();
4332 }
4333 },
4334 async onMediaLibraryButtonClick(e) {
4335 e.preventDefault();
4336 await this.selectAndReturnAttachment().then(attachment => {
4337 // When an attachment is selected, update the preview and the hidden fields.
4338 this.set('mediaLibraryPreviewUrl', attachment.attributes.url);
4339 this.updateTypeAndValue('media_library', attachment.id);
4340 });
4341 },
4342 selectAndReturnAttachment() {
4343 return new Promise(resolve => {
4344 acf.newMediaPopup({
4345 mode: 'select',
4346 type: 'image',
4347 title: acf.__('Select Image'),
4348 field: this.get('key'),
4349 multiple: false,
4350 library: 'all',
4351 allowedTypes: 'image',
4352 select: resolve
4353 });
4354 });
4355 },
4356 alignUrlTabToCurrentValue(typeAndValue) {
4357 if (typeAndValue.type !== 'url') {
4358 this.$('.acf-icon_url').val('');
4359 }
4360 },
4361 onUrlChange(event) {
4362 const currentValue = event.target.value;
4363 this.updateTypeAndValue('url', currentValue);
4364 }
4365 });
4366 acf.registerFieldType(Field);
4367 })(jQuery);
4368
4369 /***/ }),
4370
4371 /***/ "./assets/src/js/_acf-field-image.js":
4372 /*!*******************************************!*\
4373 !*** ./assets/src/js/_acf-field-image.js ***!
4374 \*******************************************/
4375 /***/ (() => {
4376
4377 (function ($) {
4378 const Field = acf.Field.extend({
4379 type: 'image',
4380 $control: function () {
4381 return this.$('.acf-image-uploader');
4382 },
4383 $input: function () {
4384 return this.$('input[type="hidden"]:first');
4385 },
4386 events: {
4387 'click a[data-name="add"]': 'onClickAdd',
4388 'click a[data-name="edit"]': 'onClickEdit',
4389 'click a[data-name="remove"]': 'onClickRemove',
4390 'change input[type="file"]': 'onChange',
4391 'keydown .image-wrap': 'onImageWrapKeydown'
4392 },
4393 initialize: function () {
4394 // add attribute to form
4395 if (this.get('uploader') === 'basic') {
4396 this.$el.closest('form').attr('enctype', 'multipart/form-data');
4397 }
4398 },
4399 validateAttachment: function (attachment) {
4400 // Use WP attachment attributes when available.
4401 if (attachment && attachment.attributes) {
4402 attachment = attachment.attributes;
4403 }
4404
4405 // Apply defaults.
4406 attachment = acf.parseArgs(attachment, {
4407 id: 0,
4408 url: '',
4409 alt: '',
4410 title: '',
4411 caption: '',
4412 description: '',
4413 width: 0,
4414 height: 0
4415 });
4416
4417 // Override with "preview size".
4418 const size = acf.isget(attachment, 'sizes', this.get('preview_size'));
4419 if (size) {
4420 attachment.url = size.url;
4421 attachment.width = size.width;
4422 attachment.height = size.height;
4423 }
4424
4425 // Return.
4426 return attachment;
4427 },
4428 render: function (attachment) {
4429 attachment = this.validateAttachment(attachment);
4430
4431 // Update value.
4432 acf.val(this.$input(), String(attachment.id || ''), true);
4433
4434 // Update DOM.
4435 this.$('img').attr({
4436 src: attachment.url,
4437 alt: attachment.alt
4438 });
4439 if (attachment.id) {
4440 this.$control().addClass('has-value');
4441 const imageWrap = this.$('.image-wrap');
4442 if (imageWrap.length) {
4443 imageWrap.trigger('focus');
4444 }
4445 } else {
4446 this.$control().removeClass('has-value');
4447 }
4448 },
4449 // create a new repeater row and render value
4450 append: function (attachment, parent) {
4451 // create function to find next available field within parent
4452 const getNext = function (field, parent) {
4453 // find existing file fields within parent
4454 const fields = acf.getFields({
4455 key: field.get('key'),
4456 parent: parent.$el
4457 });
4458
4459 // find the first field with no value
4460 for (let i = 0; i < fields.length; i++) {
4461 if (!fields[i].val()) {
4462 return fields[i];
4463 }
4464 }
4465
4466 // return
4467 return false;
4468 };
4469
4470 // find existing file fields within parent
4471 let field = getNext(this, parent);
4472
4473 // add new row if no available field
4474 if (!field) {
4475 parent.$('.acf-button:last').trigger('click');
4476 field = getNext(this, parent);
4477 }
4478
4479 // render
4480 if (field) {
4481 acf.val(field.$input(), String(attachment.id || attachment.attributes?.id || ''));
4482 field.render(attachment);
4483 }
4484 },
4485 selectAttachment: function () {
4486 // vars
4487 const parent = this.parent();
4488 const multiple = parent && parent.get('type') === 'repeater';
4489
4490 // new frame
4491 const frame = acf.newMediaPopup({
4492 mode: 'select',
4493 type: 'image',
4494 title: acf.__('Select Image'),
4495 field: this.get('key'),
4496 multiple: multiple,
4497 library: this.get('library'),
4498 allowedTypes: this.get('mime_types'),
4499 select: $.proxy(function (attachment, i) {
4500 if (i > 0) {
4501 this.append(attachment, parent);
4502 } else {
4503 acf.val(this.$input(), String(attachment.id || attachment.attributes?.id || ''));
4504 this.render(attachment);
4505 }
4506 }, this)
4507 });
4508 },
4509 editAttachment: function (attachment) {
4510 // vars
4511 const val = this.val();
4512 if (val) {
4513 // popup
4514 var frame = acf.newMediaPopup({
4515 mode: 'edit',
4516 title: acf.__('Edit Image'),
4517 button: acf.__('Update Image'),
4518 attachment: val,
4519 field: this.get('key'),
4520 select: $.proxy(function (attachment) {
4521 acf.val(this.$input(), String(attachment.id || attachment.attributes?.id || ''));
4522 this.render(attachment);
4523 }, this),
4524 close: $.proxy(function () {
4525 if ('edit-button' === attachment) {
4526 const edit = this.$el.find('a[data-name="edit"]');
4527 if (edit.length) {
4528 edit.trigger('focus');
4529 }
4530 } else {
4531 const imageWrap = this.$('.image-wrap');
4532 if (imageWrap.length) {
4533 imageWrap.trigger('focus');
4534 }
4535 }
4536 }, this)
4537 });
4538 }
4539 },
4540 removeAttachment: function () {
4541 acf.val(this.$input(), '');
4542 this.render(false);
4543 },
4544 onClickAdd: function (e, $el) {
4545 this.selectAttachment();
4546 },
4547 onClickEdit: function (e, $el) {
4548 this.editAttachment('edit-button');
4549 },
4550 onClickRemove: function (e, $el) {
4551 this.removeAttachment();
4552 },
4553 onChange: function (e, $el) {
4554 const $hiddenInput = this.$input();
4555 if (!$el.val()) {
4556 $hiddenInput.val('');
4557 }
4558 acf.getFileInputData($el, function (data) {
4559 $hiddenInput.val($.param(data));
4560 });
4561 },
4562 setValue: function (val) {
4563 val = val ? String(val) : '';
4564 if (acf.val(this.$input(), val, true) === false) {
4565 return;
4566 }
4567 if (val) {
4568 if (window.wp && wp.media && wp.media.attachment) {
4569 const attachment = wp.media.attachment(val);
4570 attachment.fetch().then($.proxy(function () {
4571 this.render(attachment);
4572 }, this));
4573 } else {
4574 this.$control().addClass('has-value');
4575 }
4576 } else {
4577 this.render(false);
4578 }
4579 },
4580 onImageWrapKeydown: function (event, imageWrapElement) {
4581 // Check if Enter key was pressed (keycode 13)
4582 if (event.which === 13) {
4583 // Check if the event target is the imageWrapElement itself
4584 if (event.target === imageWrapElement[0]) {
4585 // Prevent the default Enter key behavior
4586 event.preventDefault();
4587
4588 // Check if the field has a value
4589 if (this.val()) {
4590 // Check if the uploader is NOT the basic uploader
4591 if (this.get('uploader') !== 'basic') {
4592 // Open the edit attachment dialog
4593 this.editAttachment();
4594 }
4595 }
4596 }
4597 }
4598 }
4599 });
4600 acf.registerFieldType(Field);
4601 })(jQuery);
4602
4603 /***/ }),
4604
4605 /***/ "./assets/src/js/_acf-field-link.js":
4606 /*!******************************************!*\
4607 !*** ./assets/src/js/_acf-field-link.js ***!
4608 \******************************************/
4609 /***/ (() => {
4610
4611 (function ($, undefined) {
4612 var Field = acf.Field.extend({
4613 type: 'link',
4614 events: {
4615 'click a[data-name="add"]': 'onClickEdit',
4616 'click a[data-name="edit"]': 'onClickEdit',
4617 'click a[data-name="remove"]': 'onClickRemove',
4618 'change .link-node': 'onChange'
4619 },
4620 $control: function () {
4621 return this.$('.acf-link');
4622 },
4623 $node: function () {
4624 return this.$('.link-node');
4625 },
4626 getValue: function () {
4627 // vars
4628 var $node = this.$node();
4629
4630 // return false if empty
4631 if (!$node.attr('href')) {
4632 return false;
4633 }
4634
4635 // return
4636 return {
4637 title: $node.html(),
4638 url: $node.attr('href'),
4639 target: $node.attr('target')
4640 };
4641 },
4642 setValue: function (val) {
4643 // default
4644 val = acf.parseArgs(val, {
4645 title: '',
4646 url: '',
4647 target: ''
4648 });
4649
4650 // vars
4651 var $div = this.$control();
4652 var $node = this.$node();
4653
4654 // remove class
4655 $div.removeClass('-value -external');
4656
4657 // add class
4658 if (val.url) $div.addClass('-value');
4659 if (val.target === '_blank') $div.addClass('-external');
4660
4661 // update text
4662 this.$('.link-title').html(val.title);
4663 this.$('.link-url').attr('href', val.url).text(val.url);
4664
4665 // update node
4666 $node.html(val.title);
4667 $node.attr('href', val.url);
4668 $node.attr('target', val.target);
4669
4670 // update inputs
4671 this.$('.input-title').val(val.title);
4672 this.$('.input-target').val(val.target);
4673 this.$('.input-url').val(val.url).trigger('change');
4674 },
4675 onClickEdit: function (e, $el) {
4676 acf.wpLink.open(this.$node());
4677 },
4678 onClickRemove: function (e, $el) {
4679 this.setValue(false);
4680 },
4681 onChange: function (e, $el) {
4682 // get the changed value
4683 var val = this.getValue();
4684
4685 // update inputs
4686 this.setValue(val);
4687 }
4688 });
4689 acf.registerFieldType(Field);
4690
4691 // manager
4692 acf.wpLink = new acf.Model({
4693 getNodeValue: function () {
4694 var $node = this.get('node');
4695 return {
4696 title: acf.decode($node.html()),
4697 url: $node.attr('href'),
4698 target: $node.attr('target')
4699 };
4700 },
4701 setNodeValue: function (val) {
4702 var $node = this.get('node');
4703 $node.text(val.title);
4704 $node.attr('href', val.url);
4705 $node.attr('target', val.target);
4706 $node.trigger('change');
4707 },
4708 getInputValue: function () {
4709 return {
4710 title: $('#wp-link-text').val(),
4711 url: $('#wp-link-url').val(),
4712 target: $('#wp-link-target').prop('checked') ? '_blank' : ''
4713 };
4714 },
4715 setInputValue: function (val) {
4716 $('#wp-link-text').val(val.title);
4717 $('#wp-link-url').val(val.url);
4718 $('#wp-link-target').prop('checked', val.target === '_blank');
4719 },
4720 open: function ($node) {
4721 // add events
4722 this.on('wplink-open', 'onOpen');
4723 this.on('wplink-close', 'onClose');
4724
4725 // set node
4726 this.set('node', $node);
4727
4728 // create textarea
4729 var $textarea = $('<textarea id="acf-link-textarea" style="display:none;"></textarea>');
4730 $('body').append($textarea);
4731
4732 // vars
4733 var val = this.getNodeValue();
4734
4735 // open popup
4736 wpLink.open('acf-link-textarea', val.url, val.title, null);
4737 },
4738 onOpen: function () {
4739 // always show title (WP will hide title if empty)
4740 $('#wp-link-wrap').addClass('has-text-field');
4741
4742 // set inputs
4743 var val = this.getNodeValue();
4744 this.setInputValue(val);
4745
4746 // Update button text.
4747 if (val.url && wpLinkL10n) {
4748 $('#wp-link-submit').val(wpLinkL10n.update);
4749 }
4750 },
4751 close: function () {
4752 wpLink.close();
4753 },
4754 onClose: function () {
4755 // Bail early if no node.
4756 // Needed due to WP triggering this event twice.
4757 if (!this.has('node')) {
4758 return false;
4759 }
4760
4761 // Determine context.
4762 var $submit = $('#wp-link-submit');
4763 var isSubmit = $submit.is(':hover') || $submit.is(':focus');
4764
4765 // Set value
4766 if (isSubmit) {
4767 var val = this.getInputValue();
4768 this.setNodeValue(val);
4769 }
4770
4771 // Cleanup.
4772 this.off('wplink-open');
4773 this.off('wplink-close');
4774 $('#acf-link-textarea').remove();
4775 this.set('node', null);
4776 }
4777 });
4778 })(jQuery);
4779
4780 /***/ }),
4781
4782 /***/ "./assets/src/js/_acf-field-oembed.js":
4783 /*!********************************************!*\
4784 !*** ./assets/src/js/_acf-field-oembed.js ***!
4785 \********************************************/
4786 /***/ (() => {
4787
4788 (function ($, undefined) {
4789 var Field = acf.Field.extend({
4790 type: 'oembed',
4791 events: {
4792 'click [data-name="clear-button"]': 'onClickClear',
4793 'keypress .input-search': 'onKeypressSearch',
4794 'keyup .input-search': 'onKeyupSearch',
4795 'change .input-search': 'onChangeSearch'
4796 },
4797 $control: function () {
4798 return this.$('.acf-oembed');
4799 },
4800 $input: function () {
4801 return this.$('.input-value');
4802 },
4803 $search: function () {
4804 return this.$('.input-search');
4805 },
4806 getValue: function () {
4807 return this.$input().val();
4808 },
4809 getSearchVal: function () {
4810 return this.$search().val();
4811 },
4812 setValue: function (val) {
4813 // class
4814 if (val) {
4815 this.$control().addClass('has-value');
4816 } else {
4817 this.$control().removeClass('has-value');
4818 }
4819 acf.val(this.$input(), val);
4820 this.$search().val(val || '');
4821 if (val) {
4822 this.maybeSearch();
4823 } else {
4824 this.$('.canvas-media').html('');
4825 }
4826 },
4827 showLoading: function (show) {
4828 acf.showLoading(this.$('.canvas'));
4829 },
4830 hideLoading: function () {
4831 acf.hideLoading(this.$('.canvas'));
4832 },
4833 maybeSearch: function () {
4834 // vars
4835 var prevUrl = this.val();
4836 var url = this.getSearchVal();
4837
4838 // no value
4839 if (!url) {
4840 return this.clear();
4841 }
4842
4843 // fix missing 'http://' - causes the oembed code to error and fail
4844 if (url.substr(0, 4) != 'http') {
4845 url = 'http://' + url;
4846 }
4847
4848 // bail early if no change
4849 if (url === prevUrl) return;
4850
4851 // clear existing timeout
4852 var timeout = this.get('timeout');
4853 if (timeout) {
4854 clearTimeout(timeout);
4855 }
4856
4857 // set new timeout
4858 var callback = $.proxy(this.search, this, url);
4859 this.set('timeout', setTimeout(callback, 300));
4860 },
4861 search: function (url) {
4862 const ajaxData = {
4863 action: 'acf/fields/oembed/search',
4864 s: url,
4865 field_key: this.get('key'),
4866 nonce: this.get('nonce')
4867 };
4868
4869 // clear existing timeout
4870 let xhr = this.get('xhr');
4871 if (xhr) {
4872 xhr.abort();
4873 }
4874
4875 // loading
4876 this.showLoading();
4877
4878 // query
4879 xhr = $.ajax({
4880 url: acf.get('ajaxurl'),
4881 data: acf.prepareForAjax(ajaxData),
4882 type: 'post',
4883 dataType: 'json',
4884 context: this,
4885 success: function (json) {
4886 // error
4887 if (!json || !json.html) {
4888 json = {
4889 url: false,
4890 html: ''
4891 };
4892 }
4893
4894 // update vars
4895 this.val(json.url);
4896 this.$('.canvas-media').html(json.html);
4897 },
4898 complete: function () {
4899 this.hideLoading();
4900 }
4901 });
4902 this.set('xhr', xhr);
4903 },
4904 clear: function () {
4905 this.val('');
4906 this.$search().val('');
4907 this.$('.canvas-media').html('');
4908 },
4909 onClickClear: function (e, $el) {
4910 this.clear();
4911 },
4912 onKeypressSearch: function (e, $el) {
4913 if (e.which == 13) {
4914 e.preventDefault();
4915 this.maybeSearch();
4916 }
4917 },
4918 onKeyupSearch: function (e, $el) {
4919 if ($el.val()) {
4920 this.maybeSearch();
4921 }
4922 },
4923 onChangeSearch: function (e, $el) {
4924 this.maybeSearch();
4925 }
4926 });
4927 acf.registerFieldType(Field);
4928 })(jQuery);
4929
4930 /***/ }),
4931
4932 /***/ "./assets/src/js/_acf-field-page-link.js":
4933 /*!***********************************************!*\
4934 !*** ./assets/src/js/_acf-field-page-link.js ***!
4935 \***********************************************/
4936 /***/ (() => {
4937
4938 (function ($, undefined) {
4939 var Field = acf.models.SelectField.extend({
4940 type: 'page_link'
4941 });
4942 acf.registerFieldType(Field);
4943 })(jQuery);
4944
4945 /***/ }),
4946
4947 /***/ "./assets/src/js/_acf-field-post-object.js":
4948 /*!*************************************************!*\
4949 !*** ./assets/src/js/_acf-field-post-object.js ***!
4950 \*************************************************/
4951 /***/ (() => {
4952
4953 (function ($, undefined) {
4954 var Field = acf.models.SelectField.extend({
4955 type: 'post_object'
4956 });
4957 acf.registerFieldType(Field);
4958 })(jQuery);
4959
4960 /***/ }),
4961
4962 /***/ "./assets/src/js/_acf-field-radio.js":
4963 /*!*******************************************!*\
4964 !*** ./assets/src/js/_acf-field-radio.js ***!
4965 \*******************************************/
4966 /***/ (() => {
4967
4968 (function ($, undefined) {
4969 var Field = acf.Field.extend({
4970 type: 'radio',
4971 events: {
4972 'click input[type="radio"]': 'onClick',
4973 'keydown input[type="radio"]': 'onKeyDownInput'
4974 },
4975 $control: function () {
4976 return this.$('.acf-radio-list');
4977 },
4978 $input: function () {
4979 return this.$('input:checked');
4980 },
4981 $inputText: function () {
4982 return this.$('input[type="text"]');
4983 },
4984 setValue: function (val) {
4985 this.$('.selected').removeClass('selected');
4986 this.$('input[type="radio"]').prop('checked', false);
4987 if (val !== false && val !== null && val !== '') {
4988 const $input = this.$('input[type="radio"]').filter(function () {
4989 return $(this).val() === val;
4990 });
4991 if ($input.length) {
4992 $input.prop('checked', true);
4993 $input.parent('label').addClass('selected');
4994 if (this.get('other_choice')) {
4995 if (val === 'other') {
4996 this.$inputText().prop('disabled', false);
4997 } else {
4998 this.$inputText().prop('disabled', true);
4999 }
5000 }
5001 }
5002 }
5003 },
5004 getValue: function () {
5005 var val = this.$input().val();
5006 if (val === 'other' && this.get('other_choice')) {
5007 val = this.$inputText().val();
5008 }
5009 return val;
5010 },
5011 onClick: function (e, $el) {
5012 // vars
5013 var $label = $el.parent('label');
5014 var selected = $label.hasClass('selected');
5015 var val = $el.val();
5016
5017 // remove previous selected
5018 this.$('.selected').removeClass('selected');
5019
5020 // add active class
5021 $label.addClass('selected');
5022
5023 // allow null
5024 if (this.get('allow_null') && selected) {
5025 $label.removeClass('selected');
5026 $el.prop('checked', false).trigger('change');
5027 val = false;
5028 }
5029
5030 // other
5031 if (this.get('other_choice')) {
5032 // enable
5033 if (val === 'other') {
5034 this.$inputText().prop('disabled', false);
5035
5036 // disable
5037 } else {
5038 this.$inputText().prop('disabled', true);
5039 }
5040 }
5041 },
5042 onKeyDownInput: function (event, input) {
5043 if (event.which === 13) {
5044 event.preventDefault();
5045 input.prop('checked', true).trigger('change');
5046 }
5047 }
5048 });
5049 acf.registerFieldType(Field);
5050 })(jQuery);
5051
5052 /***/ }),
5053
5054 /***/ "./assets/src/js/_acf-field-range.js":
5055 /*!*******************************************!*\
5056 !*** ./assets/src/js/_acf-field-range.js ***!
5057 \*******************************************/
5058 /***/ (() => {
5059
5060 (function ($, undefined) {
5061 var Field = acf.Field.extend({
5062 type: 'range',
5063 events: {
5064 'input input[type="range"]': 'onChange',
5065 'change input': 'onChange'
5066 },
5067 $input: function () {
5068 return this.$('input[type="range"]');
5069 },
5070 $inputAlt: function () {
5071 return this.$('input[type="number"]');
5072 },
5073 setValue: function (val) {
5074 this.busy = true;
5075
5076 // Update range input (with change).
5077 acf.val(this.$input(), val);
5078
5079 // Update alt input (without change).
5080 // Read in input value to inherit min/max validation.
5081 acf.val(this.$inputAlt(), this.$input().val(), true);
5082 this.busy = false;
5083 },
5084 onChange: function (e, $el) {
5085 if (!this.busy) {
5086 this.setValue($el.val());
5087 }
5088 }
5089 });
5090 acf.registerFieldType(Field);
5091 })(jQuery);
5092
5093 /***/ }),
5094
5095 /***/ "./assets/src/js/_acf-field-relationship.js":
5096 /*!**************************************************!*\
5097 !*** ./assets/src/js/_acf-field-relationship.js ***!
5098 \**************************************************/
5099 /***/ (() => {
5100
5101 (function ($, undefined) {
5102 var Field = acf.Field.extend({
5103 type: 'relationship',
5104 events: {
5105 'keypress [data-filter]': 'onKeypressFilter',
5106 'change [data-filter]': 'onChangeFilter',
5107 'keyup [data-filter]': 'onChangeFilter',
5108 'click .choices-list .acf-rel-item': 'onClickAdd',
5109 'keypress .choices-list .acf-rel-item': 'onKeypressFilter',
5110 'keypress .values-list .acf-rel-item': 'onKeypressFilter',
5111 'click [data-name="remove_item"]': 'onClickRemove',
5112 'touchstart .values-list .acf-rel-item': 'onTouchStartValues'
5113 },
5114 $control: function () {
5115 return this.$('.acf-relationship');
5116 },
5117 $list: function (list) {
5118 return this.$('.' + list + '-list');
5119 },
5120 $listItems: function (list) {
5121 return this.$list(list).find('.acf-rel-item');
5122 },
5123 $listItem: function (list, id) {
5124 return this.$list(list).find('.acf-rel-item').filter(function () {
5125 return String($(this).data('id')) === String(id);
5126 });
5127 },
5128 getValue: function () {
5129 var val = [];
5130 this.$listItems('values').each(function () {
5131 val.push($(this).data('id'));
5132 });
5133 return val.length ? val : false;
5134 },
5135 setValue: function (value) {
5136 if (!Array.isArray(value)) {
5137 value = value ? [value] : [];
5138 }
5139 this.$list('values').html('');
5140 this.$listItems('choices').removeClass('disabled');
5141 value.forEach(id => {
5142 const $choice = this.$listItem('choices', id);
5143 const text = $choice.length ? $choice.html() : acf.strEscape(String(id));
5144 $choice.addClass('disabled');
5145 const valueHtml = this.newValue({
5146 id,
5147 text
5148 });
5149 this.$list('values').append(valueHtml);
5150 });
5151 this.$input().trigger('change');
5152 },
5153 newChoice: function (props) {
5154 return ['<li>', '<span tabindex="0" data-id="' + acf.strEscape(String(props.id)) + '" class="acf-rel-item">' + props.text + '</span>', '</li>'].join('');
5155 },
5156 newValue: function (props) {
5157 const id = acf.strEscape(String(props.id));
5158 return ['<li>', '<input type="hidden" name="' + this.getInputName() + '[]" value="' + id + '" />', '<span tabindex="0" data-id="' + id + '" class="acf-rel-item acf-rel-item-remove">' + props.text, '<a href="#" class="acf-icon -minus small dark" data-name="remove_item"></a>', '</span>', '</li>'].join('');
5159 },
5160 initialize: function () {
5161 // Delay initialization until "interacted with" or "in view".
5162 var delayed = this.proxy(acf.once(function () {
5163 // Add sortable.
5164 this.$list('values').sortable({
5165 items: 'li',
5166 zIndex: 9999,
5167 forceHelperSize: true,
5168 forcePlaceholderSize: true,
5169 scroll: true,
5170 update: this.proxy(function () {
5171 this.$input().trigger('change');
5172 })
5173 });
5174
5175 // Avoid browser remembering old scroll position and add event.
5176 this.$list('choices').scrollTop(0).on('scroll', this.proxy(this.onScrollChoices));
5177
5178 // Fetch choices.
5179 this.fetch();
5180 }));
5181
5182 // Bind "interacted with".
5183 this.$el.one('mouseover', delayed);
5184 this.$el.one('focus', 'input', delayed);
5185
5186 // Bind "in view".
5187 acf.onceInView(this.$el, delayed);
5188 },
5189 onScrollChoices: function (e) {
5190 // bail early if no more results
5191 if (this.get('loading') || !this.get('more')) {
5192 return;
5193 }
5194
5195 // Scrolled to bottom
5196 var $list = this.$list('choices');
5197 var scrollTop = Math.ceil($list.scrollTop());
5198 var scrollHeight = Math.ceil($list[0].scrollHeight);
5199 var innerHeight = Math.ceil($list.innerHeight());
5200 var paged = this.get('paged') || 1;
5201 if (scrollTop + innerHeight >= scrollHeight) {
5202 // update paged
5203 this.set('paged', paged + 1);
5204
5205 // fetch
5206 this.fetch();
5207 }
5208 },
5209 onKeypressFilter: function (e, $el) {
5210 // Receive enter key when selecting relationship items.
5211 if ($el.hasClass('acf-rel-item-add') && e.which == 13) {
5212 this.onClickAdd(e, $el);
5213 }
5214 // Receive enter key when removing relationship items.
5215 if ($el.hasClass('acf-rel-item-remove') && e.which == 13) {
5216 this.onClickRemove(e, $el);
5217 }
5218 // don't submit form
5219 if (e.which == 13) {
5220 e.preventDefault();
5221 }
5222 },
5223 onChangeFilter: function (e, $el) {
5224 // vars
5225 var val = $el.val();
5226 var filter = $el.data('filter');
5227
5228 // Bail early if filter has not changed
5229 if (this.get(filter) === val) {
5230 return;
5231 }
5232
5233 // update attr
5234 this.set(filter, val);
5235 if (filter === 's') {
5236 // If val is numeric, limit results to include.
5237 if (parseInt(val)) {
5238 this.set('include', val);
5239 }
5240 }
5241
5242 // reset paged
5243 this.set('paged', 1);
5244
5245 // fetch
5246 if ($el.is('select')) {
5247 this.fetch();
5248
5249 // search must go through timeout
5250 } else {
5251 this.maybeFetch();
5252 }
5253 },
5254 onClickAdd: function (e, $el) {
5255 // vars
5256 var val = this.val();
5257 var max = parseInt(this.get('max'));
5258
5259 // can be added?
5260 if ($el.hasClass('disabled')) {
5261 return false;
5262 }
5263
5264 // validate
5265 if (max > 0 && val && val.length >= max) {
5266 // add notice
5267 this.showNotice({
5268 text: acf.__('Maximum values reached ( {max} values )').replace('{max}', max),
5269 type: 'warning'
5270 });
5271 return false;
5272 }
5273
5274 // disable
5275 $el.addClass('disabled');
5276
5277 // add
5278 var html = this.newValue({
5279 id: $el.data('id'),
5280 text: $el.html()
5281 });
5282 this.$list('values').append(html);
5283
5284 // trigger change
5285 this.$input().trigger('change');
5286 },
5287 onClickRemove: function (e, $el) {
5288 // Prevent default here because generic handler wont be triggered.
5289 e.preventDefault();
5290 let $span;
5291 // Behavior if triggered from tabbed event.
5292 if ($el.hasClass('acf-rel-item-remove')) {
5293 $span = $el;
5294 } else {
5295 // Behavior if triggered through click event.
5296 $span = $el.parent();
5297 }
5298
5299 // vars
5300 const $li = $span.parent();
5301 const id = $span.data('id');
5302
5303 // remove value
5304 $li.remove();
5305
5306 // show choice
5307 this.$listItem('choices', id).removeClass('disabled');
5308
5309 // trigger change
5310 this.$input().trigger('change');
5311 },
5312 onTouchStartValues: function (e, $el) {
5313 $(this.$listItems('values')).removeClass('relationship-hover');
5314 $el.addClass('relationship-hover');
5315 },
5316 maybeFetch: function () {
5317 // vars
5318 var timeout = this.get('timeout');
5319
5320 // abort timeout
5321 if (timeout) {
5322 clearTimeout(timeout);
5323 }
5324
5325 // fetch
5326 timeout = this.setTimeout(this.fetch, 300);
5327 this.set('timeout', timeout);
5328 },
5329 getAjaxData: function () {
5330 // load data based on element attributes
5331 var ajaxData = this.$control().data();
5332 for (var name in ajaxData) {
5333 ajaxData[name] = this.get(name);
5334 }
5335
5336 // extra
5337 ajaxData.action = 'acf/fields/relationship/query';
5338 ajaxData.field_key = this.get('key');
5339 ajaxData.nonce = this.get('nonce');
5340
5341 // Filter.
5342 ajaxData = acf.applyFilters('relationship_ajax_data', ajaxData, this);
5343
5344 // return
5345 return ajaxData;
5346 },
5347 fetch: function () {
5348 // abort XHR if this field is already loading AJAX data
5349 var xhr = this.get('xhr');
5350 if (xhr) {
5351 xhr.abort();
5352 }
5353
5354 // add to this.o
5355 var ajaxData = this.getAjaxData();
5356
5357 // clear html if is new query
5358 var $choiceslist = this.$list('choices');
5359 if (ajaxData.paged == 1) {
5360 $choiceslist.html('');
5361 }
5362
5363 // loading
5364 var $loading = $('<li><i class="acf-loading"></i> ' + acf.__('Loading') + '</li>');
5365 $choiceslist.append($loading);
5366 this.set('loading', true);
5367
5368 // callback
5369 var onComplete = function () {
5370 this.set('loading', false);
5371 $loading.remove();
5372 };
5373 var onSuccess = function (json) {
5374 // no results
5375 if (!json || !json.results || !json.results.length) {
5376 // prevent pagination
5377 this.set('more', false);
5378
5379 // add message
5380 if (this.get('paged') == 1) {
5381 this.$list('choices').append('<li>' + acf.__('No matches found') + '</li>');
5382 }
5383
5384 // return
5385 return;
5386 }
5387
5388 // set more (allows pagination scroll)
5389 this.set('more', json.more);
5390
5391 // get new results
5392 var html = this.walkChoices(json.results);
5393 var $html = $(html);
5394
5395 // apply .disabled to left li's
5396 var val = this.val();
5397 if (val && val.length) {
5398 val.map(function (id) {
5399 $html.find('.acf-rel-item[data-id="' + id + '"]').addClass('disabled');
5400 });
5401 }
5402
5403 // append
5404 $choiceslist.append($html);
5405
5406 // merge together groups
5407 var $prevLabel = false;
5408 var $prevList = false;
5409 $choiceslist.find('.acf-rel-label').each(function () {
5410 var $label = $(this);
5411 var $list = $label.siblings('ul');
5412 if ($prevLabel && $prevLabel.text() == $label.text()) {
5413 $prevList.append($list.children());
5414 $(this).parent().remove();
5415 return;
5416 }
5417
5418 // update vars
5419 $prevLabel = $label;
5420 $prevList = $list;
5421 });
5422 };
5423
5424 // get results
5425 var xhr = $.ajax({
5426 url: acf.get('ajaxurl'),
5427 dataType: 'json',
5428 type: 'post',
5429 data: acf.prepareForAjax(ajaxData),
5430 context: this,
5431 success: onSuccess,
5432 complete: onComplete
5433 });
5434
5435 // set
5436 this.set('xhr', xhr);
5437 },
5438 walkChoices: function (data) {
5439 // walker
5440 var walk = function (data) {
5441 // vars
5442 var html = '';
5443
5444 // is array
5445 if ($.isArray(data)) {
5446 data.map(function (item) {
5447 html += walk(item);
5448 });
5449
5450 // is item
5451 } else if ($.isPlainObject(data)) {
5452 // group
5453 if (data.children !== undefined) {
5454 html += '<li><span class="acf-rel-label">' + acf.escHtml(data.text) + '</span><ul class="acf-bl">';
5455 html += walk(data.children);
5456 html += '</ul></li>';
5457
5458 // single
5459 } else {
5460 html += '<li><span tabindex="0" class="acf-rel-item acf-rel-item-add" data-id="' + acf.escAttr(data.id) + '">' + acf.escHtml(data.text) + '</span></li>';
5461 }
5462 }
5463
5464 // return
5465 return html;
5466 };
5467 return walk(data);
5468 }
5469 });
5470 acf.registerFieldType(Field);
5471 })(jQuery);
5472
5473 /***/ }),
5474
5475 /***/ "./assets/src/js/_acf-field-select.js":
5476 /*!********************************************!*\
5477 !*** ./assets/src/js/_acf-field-select.js ***!
5478 \********************************************/
5479 /***/ (() => {
5480
5481 (function ($, undefined) {
5482 var Field = acf.Field.extend({
5483 type: 'select',
5484 select2: false,
5485 wait: 'load',
5486 events: {
5487 removeField: 'onRemove',
5488 duplicateField: 'onDuplicate'
5489 },
5490 $input: function () {
5491 return this.$('select');
5492 },
5493 setValue: function (val) {
5494 const $input = this.$input();
5495 $input.val(val);
5496 if (this.select2) {
5497 $input.trigger('change');
5498 }
5499 },
5500 initialize: function () {
5501 // vars
5502 var $select = this.$input();
5503
5504 // inherit data
5505 this.inherit($select);
5506
5507 // select2
5508 if (this.get('ui')) {
5509 // populate ajax_data (allowing custom attribute to already exist)
5510 var ajaxAction = this.get('ajax_action');
5511 if (!ajaxAction) {
5512 ajaxAction = 'acf/fields/' + this.get('type') + '/query';
5513 }
5514
5515 // select2
5516 this.select2 = acf.newSelect2($select, {
5517 field: this,
5518 ajax: this.get('ajax'),
5519 multiple: this.get('multiple'),
5520 placeholder: this.get('placeholder'),
5521 allowNull: this.get('allow_null'),
5522 tags: this.get('create_options'),
5523 ajaxAction: ajaxAction
5524 });
5525 }
5526 },
5527 onRemove: function () {
5528 if (this.select2) {
5529 this.select2.destroy();
5530 }
5531 },
5532 onDuplicate: function (e, $el, $duplicate) {
5533 if (this.select2) {
5534 $duplicate.find('.select2-container').remove();
5535 $duplicate.find('select').removeClass('select2-hidden-accessible');
5536 }
5537 }
5538 });
5539 acf.registerFieldType(Field);
5540 })(jQuery);
5541
5542 /***/ }),
5543
5544 /***/ "./assets/src/js/_acf-field-tab.js":
5545 /*!*****************************************!*\
5546 !*** ./assets/src/js/_acf-field-tab.js ***!
5547 \*****************************************/
5548 /***/ (() => {
5549
5550 (function ($, undefined) {
5551 // vars
5552 var CONTEXT = 'tab';
5553 var Field = acf.Field.extend({
5554 type: 'tab',
5555 wait: '',
5556 tabs: false,
5557 tab: false,
5558 events: {
5559 duplicateField: 'onDuplicate'
5560 },
5561 findFields: function () {
5562 let filter;
5563
5564 /**
5565 * Tabs in the admin UI that can be extended by third
5566 * parties have the child settings wrapped inside an extra div,
5567 * so we need to look for that instead of an adjacent .acf-field.
5568 */
5569 switch (this.get('key')) {
5570 case 'acf_field_settings_tabs':
5571 filter = '.acf-field-settings-main';
5572 break;
5573 case 'acf_field_group_settings_tabs':
5574 filter = '.field-group-settings-tab';
5575 break;
5576 case 'acf_browse_fields_tabs':
5577 filter = '.acf-field-types-tab';
5578 break;
5579 case 'acf_icon_picker_tabs':
5580 filter = '.acf-icon-picker-tabs';
5581 break;
5582 case 'acf_post_type_tabs':
5583 filter = '.acf-post-type-advanced-settings';
5584 break;
5585 case 'acf_taxonomy_tabs':
5586 filter = '.acf-taxonomy-advanced-settings';
5587 break;
5588 case 'acf_ui_options_page_tabs':
5589 filter = '.acf-ui-options-page-advanced-settings';
5590 break;
5591 default:
5592 filter = '.acf-field';
5593 }
5594 return this.$el.nextUntil('.acf-field-tab', filter);
5595 },
5596 getFields: function () {
5597 return acf.getFields(this.findFields());
5598 },
5599 findTabs: function () {
5600 return this.$el.prevAll('.acf-tab-wrap:first');
5601 },
5602 findTab: function () {
5603 return this.$('.acf-tab-button');
5604 },
5605 initialize: function () {
5606 // bail early if is td
5607 if (this.$el.is('td')) {
5608 this.events = {};
5609 return false;
5610 }
5611
5612 // vars
5613 var $tabs = this.findTabs();
5614 var $tab = this.findTab();
5615 var settings = acf.parseArgs($tab.data(), {
5616 endpoint: false,
5617 placement: '',
5618 before: this.$el
5619 });
5620
5621 // create wrap
5622 if (!$tabs.length || settings.endpoint) {
5623 this.tabs = new Tabs(settings);
5624 } else {
5625 this.tabs = $tabs.data('acf');
5626 }
5627
5628 // add tab
5629 this.tab = this.tabs.addTab($tab, this);
5630 },
5631 isActive: function () {
5632 return this.tab.isActive();
5633 },
5634 showFields: function () {
5635 // show fields
5636 this.getFields().map(function (field) {
5637 field.show(this.cid, CONTEXT);
5638 field.hiddenByTab = false;
5639 }, this);
5640 },
5641 hideFields: function () {
5642 // hide fields
5643 this.getFields().map(function (field) {
5644 field.hide(this.cid, CONTEXT);
5645 field.hiddenByTab = this.tab;
5646 }, this);
5647 },
5648 show: function (lockKey) {
5649 // show field and store result
5650 var visible = acf.Field.prototype.show.apply(this, arguments);
5651
5652 // check if now visible
5653 if (visible) {
5654 // show tab
5655 this.tab.show();
5656
5657 // check active tabs
5658 this.tabs.refresh();
5659 }
5660
5661 // return
5662 return visible;
5663 },
5664 hide: function (lockKey) {
5665 // hide field and store result
5666 var hidden = acf.Field.prototype.hide.apply(this, arguments);
5667
5668 // check if now hidden
5669 if (hidden) {
5670 // hide tab
5671 this.tab.hide();
5672
5673 // reset tabs if this was active
5674 if (this.isActive()) {
5675 this.tabs.reset();
5676 }
5677 }
5678
5679 // return
5680 return hidden;
5681 },
5682 enable: function (lockKey) {
5683 // enable fields
5684 this.getFields().map(function (field) {
5685 field.enable(CONTEXT);
5686 });
5687 },
5688 disable: function (lockKey) {
5689 // disable fields
5690 this.getFields().map(function (field) {
5691 field.disable(CONTEXT);
5692 });
5693 },
5694 onDuplicate: function (e, $el, $duplicate) {
5695 if (this.isActive()) {
5696 $duplicate.prevAll('.acf-tab-wrap:first').remove();
5697 }
5698 }
5699 });
5700 acf.registerFieldType(Field);
5701
5702 /**
5703 * tabs
5704 *
5705 * description
5706 *
5707 * @date 8/2/18
5708 * @since ACF 5.6.5
5709 *
5710 * @param type $var Description. Default.
5711 * @return type Description.
5712 */
5713
5714 var i = 0;
5715 var Tabs = acf.Model.extend({
5716 tabs: [],
5717 active: false,
5718 actions: {
5719 refresh: 'onRefresh',
5720 close_field_object: 'onCloseFieldObject'
5721 },
5722 data: {
5723 before: false,
5724 placement: 'top',
5725 index: 0,
5726 initialized: false
5727 },
5728 setup: function (settings) {
5729 // data
5730 $.extend(this.data, settings);
5731
5732 // define this prop to avoid scope issues
5733 this.tabs = [];
5734 this.active = false;
5735
5736 // vars
5737 var placement = this.get('placement');
5738 var $before = this.get('before');
5739 var $parent = $before.parent();
5740
5741 // add sidebar for left placement
5742 if (placement == 'left' && $parent.hasClass('acf-fields')) {
5743 $parent.addClass('-sidebar');
5744 }
5745
5746 // create wrap
5747 if ($before.is('tr')) {
5748 this.$el = $('<tr class="acf-tab-wrap"><td colspan="2"><ul class="acf-hl acf-tab-group"></ul></td></tr>');
5749 } else {
5750 let ulClass = 'acf-hl acf-tab-group';
5751 if (this.get('key') === 'acf_field_settings_tabs') {
5752 ulClass = 'acf-field-settings-tab-bar';
5753 }
5754 this.$el = $('<div class="acf-tab-wrap -' + placement + '"><ul class="' + ulClass + '"></ul></div>');
5755 }
5756
5757 // append
5758 $before.before(this.$el);
5759
5760 // set index
5761 this.set('index', i, true);
5762 i++;
5763 },
5764 initializeTabs: function () {
5765 // Bail if tabs are disabled.
5766 if ('acf_field_settings_tabs' === this.get('key') && $('#acf-field-group-fields').hasClass('hide-tabs')) {
5767 return;
5768 }
5769 var tab = false;
5770
5771 // check if we've got a saved default tab.
5772 var order = acf.getPreference('this.tabs') || false;
5773 if (order) {
5774 var groupIndex = this.get('index');
5775 var tabIndex = order[groupIndex];
5776 if (this.tabs[tabIndex] && this.tabs[tabIndex].isVisible()) {
5777 tab = this.tabs[tabIndex];
5778 }
5779 }
5780
5781 // If we've got a defaultTab provided by configuration, use that.
5782 if (!tab && this.data.defaultTab && this.data.defaultTab.isVisible()) {
5783 tab = this.data.defaultTab;
5784 }
5785
5786 // find first visible tab as our default.
5787 if (!tab) {
5788 tab = this.getVisible().shift();
5789 }
5790 if (tab) {
5791 this.selectTab(tab);
5792 } else {
5793 this.closeTabs();
5794 }
5795
5796 // set local variable used by tabsManager
5797 this.set('initialized', true);
5798 },
5799 getVisible: function () {
5800 return this.tabs.filter(function (tab) {
5801 return tab.isVisible();
5802 });
5803 },
5804 getActive: function () {
5805 return this.active;
5806 },
5807 setActive: function (tab) {
5808 return this.active = tab;
5809 },
5810 hasActive: function () {
5811 return this.active !== false;
5812 },
5813 isActive: function (tab) {
5814 var active = this.getActive();
5815 return active && active.cid === tab.cid;
5816 },
5817 closeActive: function () {
5818 if (this.hasActive()) {
5819 this.closeTab(this.getActive());
5820 }
5821 },
5822 openTab: function (tab) {
5823 // close existing tab
5824 this.closeActive();
5825
5826 // open
5827 tab.open();
5828
5829 // set active
5830 this.setActive(tab);
5831
5832 // Recalculate admin menu pinning so a previously taller tab (e.g. one
5833 // containing WYSIWYG fields) doesn't leave the menu pinned against a
5834 // shorter page, which can lock page scroll.
5835 $(document).trigger('wp-pin-menu');
5836 },
5837 closeTab: function (tab) {
5838 // close
5839 tab.close();
5840
5841 // set active
5842 this.setActive(false);
5843 },
5844 closeTabs: function () {
5845 this.tabs.map(this.closeTab, this);
5846 },
5847 selectTab: function (tab) {
5848 // close other tabs
5849 this.tabs.map(function (t) {
5850 if (tab.cid !== t.cid) {
5851 this.closeTab(t);
5852 }
5853 }, this);
5854
5855 // open
5856 this.openTab(tab);
5857 },
5858 addTab: function ($a, field) {
5859 // create <li>
5860 var $li = $('<li>' + $a.outerHTML() + '</li>');
5861
5862 // add settings type class.
5863 var settingsType = $a.data('settings-type');
5864 if (settingsType) {
5865 $li.addClass('acf-settings-type-' + settingsType);
5866 }
5867
5868 // append
5869 this.$('ul').append($li);
5870
5871 // initialize
5872 var tab = new Tab({
5873 $el: $li,
5874 field: field,
5875 group: this
5876 });
5877
5878 // store
5879 this.tabs.push(tab);
5880 if ($a.data('selected')) {
5881 this.data.defaultTab = tab;
5882 }
5883
5884 // return
5885 return tab;
5886 },
5887 reset: function () {
5888 // close existing tab
5889 this.closeActive();
5890
5891 // find and active a tab
5892 return this.refresh();
5893 },
5894 refresh: function () {
5895 // bail early if active already exists
5896 if (this.hasActive()) {
5897 return false;
5898 }
5899 // find next active tab
5900 var tab = this.getVisible().shift();
5901 // open tab
5902 if (tab) {
5903 this.openTab(tab);
5904 }
5905
5906 // return
5907 return tab;
5908 },
5909 onRefresh: function () {
5910 // only for left placements
5911 if (this.get('placement') !== 'left') {
5912 return;
5913 }
5914
5915 // vars
5916 var $parent = this.$el.parent();
5917 var $list = this.$el.children('ul');
5918 var attribute = $parent.is('td') ? 'height' : 'min-height';
5919
5920 // find height (minus 1 for border-bottom)
5921 var height = $list.position().top + $list.outerHeight(true) - 1;
5922
5923 // add css
5924 $parent.css(attribute, height);
5925 },
5926 onCloseFieldObject: function (fieldObject) {
5927 const tab = this.getVisible().find(item => {
5928 const id = item.$el.closest('div[data-id]').data('id');
5929 if (fieldObject.data.id === id) {
5930 return item;
5931 }
5932 });
5933 if (tab) {
5934 // Wait for field group drawer to close
5935 setTimeout(() => {
5936 this.openTab(tab);
5937 }, 300);
5938 }
5939 }
5940 });
5941 var Tab = acf.Model.extend({
5942 group: false,
5943 field: false,
5944 events: {
5945 'click a': 'onClick'
5946 },
5947 index: function () {
5948 return this.$el.index();
5949 },
5950 isVisible: function () {
5951 return acf.isVisible(this.$el);
5952 },
5953 isActive: function () {
5954 return this.$el.hasClass('active');
5955 },
5956 open: function () {
5957 // add class
5958 this.$el.addClass('active');
5959
5960 // show field
5961 this.field.showFields();
5962 },
5963 close: function () {
5964 // remove class
5965 this.$el.removeClass('active');
5966
5967 // hide field
5968 this.field.hideFields();
5969 },
5970 onClick: function (e, $el) {
5971 // prevent default
5972 e.preventDefault();
5973
5974 // toggle
5975 this.toggle();
5976 },
5977 toggle: function () {
5978 // bail early if already active
5979 if (this.isActive()) {
5980 return;
5981 }
5982
5983 // toggle this tab
5984 this.group.openTab(this);
5985 }
5986 });
5987 var tabsManager = new acf.Model({
5988 priority: 50,
5989 actions: {
5990 prepare: 'render',
5991 append: 'render',
5992 unload: 'onUnload',
5993 show: 'render',
5994 invalid_field: 'onInvalidField'
5995 },
5996 findTabs: function () {
5997 return $('.acf-tab-wrap');
5998 },
5999 getTabs: function () {
6000 return acf.getInstances(this.findTabs());
6001 },
6002 render: function ($el) {
6003 this.getTabs().map(function (tabs) {
6004 if (!tabs.get('initialized')) {
6005 tabs.initializeTabs();
6006 }
6007 });
6008 },
6009 onInvalidField: function (field) {
6010 // bail early if busy
6011 if (this.busy) {
6012 return;
6013 }
6014
6015 // ignore if not hidden by tab
6016 if (!field.hiddenByTab) {
6017 return;
6018 }
6019
6020 // toggle tab
6021 field.hiddenByTab.toggle();
6022
6023 // ignore other invalid fields
6024 this.busy = true;
6025 this.setTimeout(function () {
6026 this.busy = false;
6027 }, 100);
6028 },
6029 onUnload: function () {
6030 // vars
6031 var order = [];
6032
6033 // loop
6034 this.getTabs().map(function (group) {
6035 // Do not save selected tab on field settings, or an acf-advanced-settings when unloading
6036 if (group.$el.children('.acf-field-settings-tab-bar').length || group.$el.parents('#acf-advanced-settings.postbox').length) {
6037 return true;
6038 }
6039 var active = group.hasActive() ? group.getActive().index() : 0;
6040 order.push(active);
6041 });
6042
6043 // bail if no tabs
6044 if (!order.length) {
6045 return;
6046 }
6047
6048 // update
6049 acf.setPreference('this.tabs', order);
6050 }
6051 });
6052 })(jQuery);
6053
6054 /***/ }),
6055
6056 /***/ "./assets/src/js/_acf-field-taxonomy.js":
6057 /*!**********************************************!*\
6058 !*** ./assets/src/js/_acf-field-taxonomy.js ***!
6059 \**********************************************/
6060 /***/ (() => {
6061
6062 (function ($, undefined) {
6063 var Field = acf.Field.extend({
6064 type: 'taxonomy',
6065 data: {
6066 ftype: 'select'
6067 },
6068 select2: false,
6069 wait: 'load',
6070 events: {
6071 'click a[data-name="add"]': 'onClickAdd',
6072 'click input[type="radio"]': 'onClickRadio',
6073 'keydown label': 'onKeyDownLabel',
6074 removeField: 'onRemove'
6075 },
6076 $control: function () {
6077 return this.$('.acf-taxonomy-field');
6078 },
6079 $input: function () {
6080 return this.getRelatedPrototype().$input.apply(this, arguments);
6081 },
6082 getRelatedType: function () {
6083 // vars
6084 var fieldType = this.get('ftype');
6085
6086 // normalize
6087 if (fieldType == 'multi_select') {
6088 fieldType = 'select';
6089 }
6090
6091 // return
6092 return fieldType;
6093 },
6094 getRelatedPrototype: function () {
6095 return acf.getFieldType(this.getRelatedType()).prototype;
6096 },
6097 getValue: function () {
6098 return this.getRelatedPrototype().getValue.apply(this, arguments);
6099 },
6100 setValue: function () {
6101 return this.getRelatedPrototype().setValue.apply(this, arguments);
6102 },
6103 initialize: function () {
6104 this.getRelatedPrototype().initialize.apply(this, arguments);
6105 },
6106 onRemove: function () {
6107 var proto = this.getRelatedPrototype();
6108 if (proto.onRemove) {
6109 proto.onRemove.apply(this, arguments);
6110 }
6111 },
6112 onClickAdd: function (e, $el) {
6113 // vars
6114 var field = this;
6115 var popup = false;
6116 var $form = false;
6117 var $name = false;
6118 var $parent = false;
6119 var $button = false;
6120 var $message = false;
6121 var notice = false;
6122
6123 // step 1.
6124 var step1 = function () {
6125 // popup
6126 popup = acf.newPopup({
6127 title: $el.attr('title'),
6128 loading: true,
6129 width: '300px'
6130 });
6131
6132 // ajax
6133 var ajaxData = {
6134 action: 'acf/fields/taxonomy/add_term',
6135 field_key: field.get('key'),
6136 nonce: field.get('nonce')
6137 };
6138
6139 // get HTML
6140 $.ajax({
6141 url: acf.get('ajaxurl'),
6142 data: acf.prepareForAjax(ajaxData),
6143 type: 'post',
6144 dataType: 'html',
6145 success: step2
6146 });
6147 };
6148
6149 // step 2.
6150 var step2 = function (html) {
6151 // update popup
6152 popup.loading(false);
6153 popup.content(html);
6154
6155 // vars
6156 $form = popup.$('form');
6157 $name = popup.$('input[name="term_name"]');
6158 $parent = popup.$('select[name="term_parent"]');
6159 $button = popup.$('.acf-submit-button');
6160
6161 // focus
6162 $name.trigger('focus');
6163
6164 // submit form
6165 popup.on('submit', 'form', step3);
6166 };
6167
6168 // step 3.
6169 var step3 = function (e, $el) {
6170 // prevent
6171 e.preventDefault();
6172 e.stopImmediatePropagation();
6173
6174 // basic validation
6175 if ($name.val() === '') {
6176 $name.trigger('focus');
6177 return false;
6178 }
6179
6180 // disable
6181 acf.startButtonLoading($button);
6182
6183 // ajax
6184 var ajaxData = {
6185 action: 'acf/fields/taxonomy/add_term',
6186 field_key: field.get('key'),
6187 nonce: field.get('nonce'),
6188 term_name: $name.val(),
6189 term_parent: $parent.length ? $parent.val() : 0
6190 };
6191 $.ajax({
6192 url: acf.get('ajaxurl'),
6193 data: acf.prepareForAjax(ajaxData),
6194 type: 'post',
6195 dataType: 'json',
6196 success: step4
6197 });
6198 };
6199
6200 // step 4.
6201 var step4 = function (json) {
6202 // enable
6203 acf.stopButtonLoading($button);
6204
6205 // remove prev notice
6206 if (notice) {
6207 notice.remove();
6208 }
6209
6210 // success
6211 if (acf.isAjaxSuccess(json)) {
6212 // clear name
6213 $name.val('');
6214
6215 // update term lists
6216 step5(json.data);
6217
6218 // notice
6219 notice = acf.newNotice({
6220 type: 'success',
6221 text: acf.getAjaxMessage(json),
6222 target: $form,
6223 timeout: 2000,
6224 dismiss: false
6225 });
6226 } else {
6227 // notice
6228 notice = acf.newNotice({
6229 type: 'error',
6230 text: acf.getAjaxError(json),
6231 target: $form,
6232 timeout: 2000,
6233 dismiss: false
6234 });
6235 }
6236
6237 // focus
6238 $name.trigger('focus');
6239 };
6240
6241 // step 5.
6242 var step5 = function (term) {
6243 // update parent dropdown
6244 var $option = $('<option value="' + term.term_id + '">' + term.term_label + '</option>');
6245 if (term.term_parent) {
6246 $parent.children('option[value="' + term.term_parent + '"]').after($option);
6247 } else {
6248 $parent.append($option);
6249 }
6250
6251 // add this new term to all taxonomy field
6252 var fields = acf.getFields({
6253 type: 'taxonomy'
6254 });
6255 fields.map(function (otherField) {
6256 if (otherField.get('taxonomy') == field.get('taxonomy')) {
6257 otherField.appendTerm(term);
6258 }
6259 });
6260
6261 // select
6262 field.selectTerm(term.term_id);
6263 };
6264
6265 // run
6266 step1();
6267 },
6268 appendTerm: function (term) {
6269 if (this.getRelatedType() == 'select') {
6270 this.appendTermSelect(term);
6271 } else {
6272 this.appendTermCheckbox(term);
6273 }
6274 },
6275 appendTermSelect: function (term) {
6276 this.select2.addOption({
6277 id: term.term_id,
6278 text: term.term_label
6279 });
6280 },
6281 appendTermCheckbox: function (term) {
6282 // vars
6283 var name = this.$('[name]:first').attr('name');
6284 var $ul = this.$('ul:first');
6285
6286 // allow multiple selection
6287 if (this.getRelatedType() == 'checkbox') {
6288 name += '[]';
6289 }
6290
6291 // create new li
6292 var $li = $(['<li data-id="' + term.term_id + '">', '<label>', '<input type="' + this.get('ftype') + '" value="' + term.term_id + '" name="' + name + '" /> ', '<span>' + term.term_name + '</span>', '</label>', '</li>'].join(''));
6293
6294 // find parent
6295 if (term.term_parent) {
6296 // vars
6297 var $parent = $ul.find('li[data-id="' + term.term_parent + '"]');
6298
6299 // update vars
6300 $ul = $parent.children('ul');
6301
6302 // create ul
6303 if (!$ul.exists()) {
6304 $ul = $('<ul class="children acf-bl"></ul>');
6305 $parent.append($ul);
6306 }
6307 }
6308
6309 // append
6310 $ul.append($li);
6311 },
6312 selectTerm: function (id) {
6313 if (this.getRelatedType() == 'select') {
6314 this.select2.selectOption(id);
6315 } else {
6316 var $input = this.$('input[value="' + id + '"]');
6317 $input.prop('checked', true).trigger('change');
6318 }
6319 },
6320 onClickRadio: function (e, $el) {
6321 // vars
6322 var $label = $el.parent('label');
6323 var selected = $label.hasClass('selected');
6324
6325 // remove previous selected
6326 this.$('.selected').removeClass('selected');
6327
6328 // add active class
6329 $label.addClass('selected');
6330
6331 // allow null
6332 if (this.get('allow_null') && selected) {
6333 $label.removeClass('selected');
6334 $el.prop('checked', false).trigger('change');
6335 }
6336 },
6337 onKeyDownLabel: function (e, $el) {
6338 // bail early if not space or enter
6339 if (e.which !== 13) {
6340 return;
6341 }
6342 e.preventDefault();
6343 const firstInput = $el.find('input').first();
6344 if (firstInput.length) {
6345 firstInput.trigger('click').trigger('focus');
6346 }
6347 }
6348 });
6349 acf.registerFieldType(Field);
6350 })(jQuery);
6351
6352 /***/ }),
6353
6354 /***/ "./assets/src/js/_acf-field-time-picker.js":
6355 /*!*************************************************!*\
6356 !*** ./assets/src/js/_acf-field-time-picker.js ***!
6357 \*************************************************/
6358 /***/ (() => {
6359
6360 (function ($, undefined) {
6361 var Field = acf.models.DatePickerField.extend({
6362 type: 'time_picker',
6363 $control: function () {
6364 return this.$('.acf-time-picker');
6365 },
6366 setValue: function (val) {
6367 acf.val(this.$input(), val);
6368 const $inputText = this.$inputText();
6369 if (val && $inputText.length) {
6370 try {
6371 const timeFormat = this.get('time_format') || $inputText.timepicker('option', 'timeFormat');
6372 const matches = val.match(/^(\d{2}):(\d{2}):(\d{2})$/);
6373 if (matches && $.datepicker && $.datepicker.formatTime) {
6374 const timeText = $.datepicker.formatTime(timeFormat, {
6375 hour: parseInt(matches[1], 10),
6376 minute: parseInt(matches[2], 10),
6377 second: parseInt(matches[3], 10)
6378 });
6379 $inputText.val(timeText);
6380 } else {
6381 $inputText.val(val);
6382 }
6383 } catch (e) {
6384 $inputText.val(val);
6385 }
6386 } else {
6387 $inputText.val('');
6388 }
6389 },
6390 initialize: function () {
6391 // vars
6392 var $input = this.$input();
6393 var $inputText = this.$inputText();
6394
6395 // args
6396 var args = {
6397 timeFormat: this.get('time_format'),
6398 altField: $input,
6399 altFieldTimeOnly: false,
6400 altTimeFormat: 'HH:mm:ss',
6401 showButtonPanel: true,
6402 controlType: 'select',
6403 oneLine: true,
6404 closeText: acf.get('dateTimePickerL10n').selectText,
6405 timeOnly: true
6406 };
6407
6408 // add custom 'Close = Select' functionality
6409 args.onClose = function (value, dp_instance, t_instance) {
6410 // vars
6411 var $close = dp_instance.dpDiv.find('.ui-datepicker-close');
6412
6413 // if clicking close button
6414 if (!value && $close.is(':hover')) {
6415 t_instance._updateDateTime();
6416 }
6417 };
6418
6419 // filter
6420 args = acf.applyFilters('time_picker_args', args, this);
6421
6422 // add date time picker
6423 acf.newTimePicker($inputText, args);
6424
6425 // action
6426 acf.doAction('time_picker_init', $inputText, args, this);
6427 }
6428 });
6429 acf.registerFieldType(Field);
6430
6431 // add
6432 acf.newTimePicker = function ($input, args) {
6433 // bail early if no datepicker library
6434 if (typeof $.timepicker === 'undefined') {
6435 return false;
6436 }
6437
6438 // defaults
6439 args = args || {};
6440
6441 // initialize
6442 $input.timepicker(args);
6443
6444 // wrap the datepicker (only if it hasn't already been wrapped)
6445 if ($('body > #ui-datepicker-div').exists()) {
6446 $('body > #ui-datepicker-div').wrap('<div class="acf-ui-datepicker" />');
6447 }
6448 };
6449 })(jQuery);
6450
6451 /***/ }),
6452
6453 /***/ "./assets/src/js/_acf-field-true-false.js":
6454 /*!************************************************!*\
6455 !*** ./assets/src/js/_acf-field-true-false.js ***!
6456 \************************************************/
6457 /***/ (() => {
6458
6459 (function ($, undefined) {
6460 var Field = acf.Field.extend({
6461 type: 'true_false',
6462 events: {
6463 'change .acf-switch-input': 'onChange',
6464 'focus .acf-switch-input': 'onFocus',
6465 'blur .acf-switch-input': 'onBlur',
6466 'keypress .acf-switch-input': 'onKeypress'
6467 },
6468 $input: function () {
6469 return this.$('input[type="checkbox"]');
6470 },
6471 $switch: function () {
6472 return this.$('.acf-switch');
6473 },
6474 setValue: function (val) {
6475 if (val && val !== '0') {
6476 this.switchOn();
6477 } else {
6478 this.switchOff();
6479 }
6480 },
6481 getValue: function () {
6482 return this.$input().prop('checked') ? 1 : 0;
6483 },
6484 initialize: function () {
6485 this.render();
6486 },
6487 render: function () {
6488 // vars
6489 var $switch = this.$switch();
6490
6491 // bail early if no $switch
6492 if (!$switch.length) return;
6493
6494 // vars
6495 var $on = $switch.children('.acf-switch-on');
6496 var $off = $switch.children('.acf-switch-off');
6497 var width = Math.max($on.width(), $off.width());
6498
6499 // bail early if no width
6500 if (!width) return;
6501
6502 // set widths
6503 $on.css('min-width', width);
6504 $off.css('min-width', width);
6505 },
6506 switchOn: function () {
6507 this.$input().prop('checked', true);
6508 this.$switch().addClass('-on');
6509 },
6510 switchOff: function () {
6511 this.$input().prop('checked', false);
6512 this.$switch().removeClass('-on');
6513 },
6514 onChange: function (e, $el) {
6515 if ($el.prop('checked')) {
6516 this.switchOn();
6517 } else {
6518 this.switchOff();
6519 }
6520 },
6521 onFocus: function (e, $el) {
6522 this.$switch().addClass('-focus');
6523 },
6524 onBlur: function (e, $el) {
6525 this.$switch().removeClass('-focus');
6526 },
6527 onKeypress: function (e, $el) {
6528 // left
6529 if (e.keyCode === 37) {
6530 return this.switchOff();
6531 }
6532
6533 // right
6534 if (e.keyCode === 39) {
6535 return this.switchOn();
6536 }
6537 }
6538 });
6539 acf.registerFieldType(Field);
6540 })(jQuery);
6541
6542 /***/ }),
6543
6544 /***/ "./assets/src/js/_acf-field-url.js":
6545 /*!*****************************************!*\
6546 !*** ./assets/src/js/_acf-field-url.js ***!
6547 \*****************************************/
6548 /***/ (() => {
6549
6550 (function ($, undefined) {
6551 var Field = acf.Field.extend({
6552 type: 'url',
6553 events: {
6554 'keyup input[type="url"]': 'onkeyup'
6555 },
6556 $control: function () {
6557 return this.$('.acf-input-wrap');
6558 },
6559 $input: function () {
6560 return this.$('input[type="url"]');
6561 },
6562 initialize: function () {
6563 this.render();
6564 },
6565 isValid: function () {
6566 // vars
6567 var val = this.val();
6568
6569 // bail early if no val
6570 if (!val) {
6571 return false;
6572 }
6573
6574 // url
6575 if (val.indexOf('://') !== -1) {
6576 return true;
6577 }
6578
6579 // protocol relative url
6580 if (val.indexOf('//') === 0) {
6581 return true;
6582 }
6583
6584 // return
6585 return false;
6586 },
6587 render: function () {
6588 // add class
6589 if (this.isValid()) {
6590 this.$control().addClass('-valid');
6591 } else {
6592 this.$control().removeClass('-valid');
6593 }
6594 },
6595 onkeyup: function (e, $el) {
6596 this.render();
6597 }
6598 });
6599 acf.registerFieldType(Field);
6600 })(jQuery);
6601
6602 /***/ }),
6603
6604 /***/ "./assets/src/js/_acf-field-user.js":
6605 /*!******************************************!*\
6606 !*** ./assets/src/js/_acf-field-user.js ***!
6607 \******************************************/
6608 /***/ (() => {
6609
6610 (function ($, undefined) {
6611 var Field = acf.models.SelectField.extend({
6612 type: 'user'
6613 });
6614 acf.registerFieldType(Field);
6615 })(jQuery);
6616
6617 /***/ }),
6618
6619 /***/ "./assets/src/js/_acf-field-wysiwyg.js":
6620 /*!*********************************************!*\
6621 !*** ./assets/src/js/_acf-field-wysiwyg.js ***!
6622 \*********************************************/
6623 /***/ (() => {
6624
6625 (function ($, undefined) {
6626 var Field = acf.Field.extend({
6627 type: 'wysiwyg',
6628 wait: 'load',
6629 events: {
6630 'mousedown .acf-editor-wrap.delay': 'onMousedown',
6631 unmountField: 'disableEditor',
6632 remountField: 'enableEditor',
6633 removeField: 'disableEditor'
6634 },
6635 $control: function () {
6636 return this.$('.acf-editor-wrap');
6637 },
6638 $input: function () {
6639 return this.$('textarea');
6640 },
6641 setValue: function (val) {
6642 acf.val(this.$input(), val);
6643 if (this.getMode() === 'visual') {
6644 const id = this.get('id');
6645 const editor = window.tinymce && tinymce.get(id);
6646 if (editor && !editor.isHidden()) {
6647 editor.setContent(val || '');
6648 }
6649 }
6650 },
6651 getMode: function () {
6652 return this.$control().hasClass('tmce-active') ? 'visual' : 'text';
6653 },
6654 initialize: function () {
6655 // initializeEditor if no delay
6656 if (!this.$control().hasClass('delay')) {
6657 this.initializeEditor();
6658 }
6659 },
6660 initializeEditor: function () {
6661 // vars
6662 var $wrap = this.$control();
6663 var $textarea = this.$input();
6664 var args = {
6665 tinymce: true,
6666 quicktags: true,
6667 toolbar: this.get('toolbar'),
6668 mode: this.getMode(),
6669 field: this
6670 };
6671
6672 // generate new id
6673 var oldId = $textarea.attr('id');
6674 var newId = acf.uniqueId('acf-editor-');
6675
6676 // Backup textarea data.
6677 var inputData = $textarea.data();
6678 var inputVal = $textarea.val();
6679
6680 // rename
6681 acf.rename({
6682 target: $wrap,
6683 search: oldId,
6684 replace: newId,
6685 destructive: true
6686 });
6687
6688 // update id
6689 this.set('id', newId, true);
6690
6691 // apply data to new textarea (acf.rename creates a new textarea element due to destructive mode)
6692 // fixes bug where conditional logic "disabled" is lost during "screen_check"
6693 this.$input().data(inputData).val(inputVal);
6694
6695 // initialize
6696 acf.tinymce.initialize(newId, args);
6697 },
6698 onMousedown: function (e) {
6699 // prevent default
6700 e.preventDefault();
6701
6702 // remove delay class
6703 var $wrap = this.$control();
6704 $wrap.removeClass('delay');
6705 $wrap.find('.acf-editor-toolbar').remove();
6706
6707 // initialize
6708 this.initializeEditor();
6709 },
6710 enableEditor: function () {
6711 if (this.getMode() == 'visual') {
6712 acf.tinymce.enable(this.get('id'));
6713 }
6714 },
6715 disableEditor: function () {
6716 acf.tinymce.destroy(this.get('id'));
6717 }
6718 });
6719 acf.registerFieldType(Field);
6720 })(jQuery);
6721
6722 /***/ }),
6723
6724 /***/ "./assets/src/js/_acf-field.js":
6725 /*!*************************************!*\
6726 !*** ./assets/src/js/_acf-field.js ***!
6727 \*************************************/
6728 /***/ (() => {
6729
6730 (function ($, undefined) {
6731 // vars
6732 var storage = [];
6733
6734 /**
6735 * acf.Field
6736 *
6737 * description
6738 *
6739 * @date 23/3/18
6740 * @since ACF 5.6.9
6741 *
6742 * @param type $var Description. Default.
6743 * @return type Description.
6744 */
6745
6746 acf.Field = acf.Model.extend({
6747 // field type
6748 type: '',
6749 // class used to avoid nested event triggers
6750 eventScope: '.acf-field',
6751 // initialize events on 'ready'
6752 wait: 'ready',
6753 /**
6754 * setup
6755 *
6756 * Called during the constructor function to setup this field ready for initialization
6757 *
6758 * @date 8/5/18
6759 * @since ACF 5.6.9
6760 *
6761 * @param jQuery $field The field element.
6762 * @return void
6763 */
6764
6765 setup: function ($field) {
6766 // set $el
6767 this.$el = $field;
6768
6769 // inherit $field data
6770 this.inherit($field);
6771
6772 // inherit control data
6773 this.inherit(this.$control());
6774 },
6775 /**
6776 * val
6777 *
6778 * Sets or returns the field's value
6779 *
6780 * @date 8/5/18
6781 * @since ACF 5.6.9
6782 *
6783 * @param mixed val Optional. The value to set
6784 * @return mixed
6785 */
6786
6787 val: function (val) {
6788 // Set.
6789 if (val !== undefined) {
6790 return this.setValue(val);
6791
6792 // Get.
6793 } else {
6794 return this.prop('disabled') ? null : this.getValue();
6795 }
6796 },
6797 /**
6798 * getValue
6799 *
6800 * returns the field's value
6801 *
6802 * @date 8/5/18
6803 * @since ACF 5.6.9
6804 *
6805 * @param void
6806 * @return mixed
6807 */
6808
6809 getValue: function () {
6810 return this.$input().val();
6811 },
6812 /**
6813 * setValue
6814 *
6815 * sets the field's value and returns true if changed
6816 *
6817 * @date 8/5/18
6818 * @since ACF 5.6.9
6819 *
6820 * @param mixed val
6821 * @return boolean. True if changed.
6822 */
6823
6824 setValue: function (val) {
6825 return acf.val(this.$input(), val);
6826 },
6827 /**
6828 * __
6829 *
6830 * i18n helper to be removed
6831 *
6832 * @date 8/5/18
6833 * @since ACF 5.6.9
6834 *
6835 * @param type $var Description. Default.
6836 * @return type Description.
6837 */
6838
6839 __: function (string) {
6840 return acf._e(this.type, string);
6841 },
6842 /**
6843 * $control
6844 *
6845 * returns the control jQuery element used for inheriting data. Uses this.control setting.
6846 *
6847 * @date 8/5/18
6848 * @since ACF 5.6.9
6849 *
6850 * @param void
6851 * @return jQuery
6852 */
6853
6854 $control: function () {
6855 return false;
6856 },
6857 /**
6858 * $input
6859 *
6860 * returns the input jQuery element used for saving values. Uses this.input setting.
6861 *
6862 * @date 8/5/18
6863 * @since ACF 5.6.9
6864 *
6865 * @param void
6866 * @return jQuery
6867 */
6868
6869 $input: function () {
6870 return this.$('[name]:first');
6871 },
6872 /**
6873 * $inputWrap
6874 *
6875 * description
6876 *
6877 * @date 12/5/18
6878 * @since ACF 5.6.9
6879 *
6880 * @param type $var Description. Default.
6881 * @return type Description.
6882 */
6883
6884 $inputWrap: function () {
6885 return this.$('.acf-input:first');
6886 },
6887 /**
6888 * $inputWrap
6889 *
6890 * description
6891 *
6892 * @date 12/5/18
6893 * @since ACF 5.6.9
6894 *
6895 * @param type $var Description. Default.
6896 * @return type Description.
6897 */
6898
6899 $labelWrap: function () {
6900 return this.$('.acf-label:first');
6901 },
6902 /**
6903 * getInputName
6904 *
6905 * Returns the field's input name
6906 *
6907 * @date 8/5/18
6908 * @since ACF 5.6.9
6909 *
6910 * @param void
6911 * @return string
6912 */
6913
6914 getInputName: function () {
6915 return this.$input().attr('name') || '';
6916 },
6917 /**
6918 * parent
6919 *
6920 * returns the field's parent field or false on failure.
6921 *
6922 * @date 8/5/18
6923 * @since ACF 5.6.9
6924 *
6925 * @param void
6926 * @return object|false
6927 */
6928
6929 parent: function () {
6930 // vars
6931 var parents = this.parents();
6932
6933 // return
6934 return parents.length ? parents[0] : false;
6935 },
6936 /**
6937 * parents
6938 *
6939 * description
6940 *
6941 * @date 9/7/18
6942 * @since ACF 5.6.9
6943 *
6944 * @param type $var Description. Default.
6945 * @return type Description.
6946 */
6947
6948 parents: function () {
6949 // vars
6950 var $parents = this.$el.parents('.acf-field');
6951
6952 // convert
6953 var parents = acf.getFields($parents);
6954
6955 // return
6956 return parents;
6957 },
6958 show: function (lockKey, context) {
6959 // show field and store result
6960 var changed = acf.show(this.$el, lockKey);
6961
6962 // do action if visibility has changed
6963 if (changed) {
6964 this.prop('hidden', false);
6965 acf.doAction('show_field', this, context);
6966 if (context === 'conditional_logic') {
6967 this.setFieldSettingsLastVisible();
6968 }
6969 }
6970
6971 // return
6972 return changed;
6973 },
6974 hide: function (lockKey, context) {
6975 // hide field and store result
6976 var changed = acf.hide(this.$el, lockKey);
6977
6978 // do action if visibility has changed
6979 if (changed) {
6980 this.prop('hidden', true);
6981 acf.doAction('hide_field', this, context);
6982 if (context === 'conditional_logic') {
6983 this.setFieldSettingsLastVisible();
6984 }
6985 }
6986
6987 // return
6988 return changed;
6989 },
6990 setFieldSettingsLastVisible: function () {
6991 // Ensure this conditional logic trigger has happened inside a field settings tab.
6992 var $parents = this.$el.parents('.acf-field-settings-main');
6993 if (!$parents.length) return;
6994 var $fields = $parents.find('.acf-field');
6995 $fields.removeClass('acf-last-visible');
6996 $fields.not('.acf-hidden').last().addClass('acf-last-visible');
6997 },
6998 enable: function (lockKey, context) {
6999 // enable field and store result
7000 var changed = acf.enable(this.$el, lockKey);
7001
7002 // do action if disabled has changed
7003 if (changed) {
7004 this.prop('disabled', false);
7005 acf.doAction('enable_field', this, context);
7006 }
7007
7008 // return
7009 return changed;
7010 },
7011 disable: function (lockKey, context) {
7012 // disabled field and store result
7013 var changed = acf.disable(this.$el, lockKey);
7014
7015 // do action if disabled has changed
7016 if (changed) {
7017 this.prop('disabled', true);
7018 acf.doAction('disable_field', this, context);
7019 }
7020
7021 // return
7022 return changed;
7023 },
7024 showEnable: function (lockKey, context) {
7025 // enable
7026 this.enable.apply(this, arguments);
7027
7028 // show and return true if changed
7029 return this.show.apply(this, arguments);
7030 },
7031 hideDisable: function (lockKey, context) {
7032 // disable
7033 this.disable.apply(this, arguments);
7034
7035 // hide and return true if changed
7036 return this.hide.apply(this, arguments);
7037 },
7038 showNotice: function (props) {
7039 // ensure object
7040 if (typeof props !== 'object') {
7041 props = {
7042 text: props
7043 };
7044 }
7045
7046 // remove old notice
7047 if (this.notice) {
7048 this.notice.remove();
7049 }
7050
7051 // create new notice
7052 props.target = this.$inputWrap();
7053 this.notice = acf.newNotice(props);
7054 },
7055 removeNotice: function (timeout) {
7056 if (this.notice) {
7057 this.notice.away(timeout || 0);
7058 this.notice = false;
7059 }
7060 },
7061 showError: function (message, location = 'before') {
7062 // add class
7063 this.$el.addClass('acf-error');
7064
7065 // add message
7066 if (message !== undefined) {
7067 this.showNotice({
7068 text: message,
7069 type: 'error',
7070 dismiss: false,
7071 location: location
7072 });
7073 }
7074
7075 // action
7076 acf.doAction('invalid_field', this);
7077
7078 // add event
7079 this.$el.one('focus change', 'input, select, textarea', $.proxy(this.removeError, this));
7080 },
7081 removeError: function () {
7082 // remove class
7083 this.$el.removeClass('acf-error');
7084
7085 // remove notice
7086 this.removeNotice(250);
7087
7088 // action
7089 acf.doAction('valid_field', this);
7090 },
7091 trigger: function (name, args, bubbles) {
7092 // allow some events to bubble
7093 if (name == 'invalidField') {
7094 bubbles = true;
7095 }
7096
7097 // return
7098 return acf.Model.prototype.trigger.apply(this, [name, args, bubbles]);
7099 }
7100 });
7101
7102 /**
7103 * newField
7104 *
7105 * description
7106 *
7107 * @date 14/12/17
7108 * @since ACF 5.6.5
7109 *
7110 * @param type $var Description. Default.
7111 * @return type Description.
7112 */
7113
7114 acf.newField = function ($field) {
7115 // vars
7116 var type = $field.data('type');
7117 var mid = modelId(type);
7118 var model = acf.models[mid] || acf.Field;
7119
7120 // instantiate
7121 var field = new model($field);
7122
7123 // actions
7124 acf.doAction('new_field', field);
7125
7126 // return
7127 return field;
7128 };
7129
7130 /**
7131 * mid
7132 *
7133 * Calculates the model ID for a field type
7134 *
7135 * @date 15/12/17
7136 * @since ACF 5.6.5
7137 *
7138 * @param string type
7139 * @return string
7140 */
7141
7142 var modelId = function (type) {
7143 return acf.strPascalCase(type || '') + 'Field';
7144 };
7145
7146 /**
7147 * registerFieldType
7148 *
7149 * description
7150 *
7151 * @date 14/12/17
7152 * @since ACF 5.6.5
7153 *
7154 * @param type $var Description. Default.
7155 * @return type Description.
7156 */
7157
7158 acf.registerFieldType = function (model) {
7159 // vars
7160 var proto = model.prototype;
7161 var type = proto.type;
7162 var mid = modelId(type);
7163
7164 // store model
7165 acf.models[mid] = model;
7166
7167 // store reference
7168 storage.push(type);
7169 };
7170
7171 /**
7172 * acf.getFieldType
7173 *
7174 * description
7175 *
7176 * @date 1/2/18
7177 * @since ACF 5.6.5
7178 *
7179 * @param type $var Description. Default.
7180 * @return type Description.
7181 */
7182
7183 acf.getFieldType = function (type) {
7184 var mid = modelId(type);
7185 return acf.models[mid] || false;
7186 };
7187
7188 /**
7189 * acf.getFieldTypes
7190 *
7191 * description
7192 *
7193 * @date 1/2/18
7194 * @since ACF 5.6.5
7195 *
7196 * @param type $var Description. Default.
7197 * @return type Description.
7198 */
7199
7200 acf.getFieldTypes = function (args) {
7201 // defaults
7202 args = acf.parseArgs(args, {
7203 category: ''
7204 // hasValue: true
7205 });
7206
7207 // clone available types
7208 var types = [];
7209
7210 // loop
7211 storage.map(function (type) {
7212 // vars
7213 var model = acf.getFieldType(type);
7214 var proto = model.prototype;
7215
7216 // check operator
7217 if (args.category && proto.category !== args.category) {
7218 return;
7219 }
7220
7221 // append
7222 types.push(model);
7223 });
7224
7225 // return
7226 return types;
7227 };
7228 })(jQuery);
7229
7230 /***/ }),
7231
7232 /***/ "./assets/src/js/_acf-fields.js":
7233 /*!**************************************!*\
7234 !*** ./assets/src/js/_acf-fields.js ***!
7235 \**************************************/
7236 /***/ (() => {
7237
7238 (function ($, undefined) {
7239 /**
7240 * findFields
7241 *
7242 * Returns a jQuery selection object of acf fields.
7243 *
7244 * @date 14/12/17
7245 * @since ACF 5.6.5
7246 *
7247 * @param object $args {
7248 * Optional. Arguments to find fields.
7249 *
7250 * @type string key The field's key (data-attribute).
7251 * @type string name The field's name (data-attribute).
7252 * @type string type The field's type (data-attribute).
7253 * @type string is jQuery selector to compare against.
7254 * @type jQuery parent jQuery element to search within.
7255 * @type jQuery sibling jQuery element to search alongside.
7256 * @type limit int The number of fields to find.
7257 * @type suppressFilters bool Whether to allow filters to add/remove results. Default behaviour will ignore clone fields.
7258 * }
7259 * @return jQuery
7260 */
7261
7262 acf.findFields = function (args) {
7263 // vars
7264 var selector = '.acf-field';
7265 var $fields = false;
7266
7267 // args
7268 args = acf.parseArgs(args, {
7269 key: '',
7270 name: '',
7271 type: '',
7272 is: '',
7273 parent: false,
7274 sibling: false,
7275 limit: false,
7276 visible: false,
7277 suppressFilters: false,
7278 excludeSubFields: false
7279 });
7280
7281 // filter args
7282 if (!args.suppressFilters) {
7283 args = acf.applyFilters('find_fields_args', args);
7284 }
7285
7286 // key
7287 if (args.key) {
7288 selector += '[data-key="' + args.key + '"]';
7289 }
7290
7291 // type
7292 if (args.type) {
7293 selector += '[data-type="' + args.type + '"]';
7294 }
7295
7296 // name
7297 if (args.name) {
7298 selector += '[data-name="' + args.name + '"]';
7299 }
7300
7301 // is
7302 if (args.is) {
7303 selector += args.is;
7304 }
7305
7306 // visibility
7307 if (args.visible) {
7308 selector += ':visible';
7309 }
7310 if (!args.suppressFilters) {
7311 selector = acf.applyFilters('find_fields_selector', selector, args);
7312 }
7313
7314 // query
7315 if (args.parent) {
7316 $fields = args.parent.find(selector);
7317 // exclude sub fields if required (only if a parent is provided)
7318 if (args.excludeSubFields) {
7319 $fields = $fields.not(args.parent.find('.acf-is-subfields .acf-field'));
7320 }
7321 } else if (args.sibling) {
7322 $fields = args.sibling.siblings(selector);
7323 } else {
7324 $fields = $(selector);
7325 }
7326
7327 // filter
7328 if (!args.suppressFilters) {
7329 $fields = $fields.not('.acf-clone .acf-field');
7330 $fields = acf.applyFilters('find_fields', $fields);
7331 }
7332
7333 // limit
7334 if (args.limit) {
7335 $fields = $fields.slice(0, args.limit);
7336 }
7337
7338 // return
7339 return $fields;
7340 };
7341
7342 /**
7343 * findField
7344 *
7345 * Finds a specific field with jQuery
7346 *
7347 * @date 14/12/17
7348 * @since ACF 5.6.5
7349 *
7350 * @param string key The field's key.
7351 * @param jQuery $parent jQuery element to search within.
7352 * @return jQuery
7353 */
7354
7355 acf.findField = function (key, $parent) {
7356 return acf.findFields({
7357 key: key,
7358 limit: 1,
7359 parent: $parent,
7360 suppressFilters: true
7361 });
7362 };
7363
7364 /**
7365 * getField
7366 *
7367 * Returns a field instance
7368 *
7369 * @date 14/12/17
7370 * @since ACF 5.6.5
7371 *
7372 * @param jQuery|string $field jQuery element or field key.
7373 * @return object
7374 */
7375
7376 acf.getField = function ($field) {
7377 // allow jQuery
7378 if ($field instanceof jQuery) {
7379 // find fields
7380 } else {
7381 $field = acf.findField($field);
7382 }
7383
7384 // instantiate
7385 var field = $field.data('acf');
7386 if (!field) {
7387 field = acf.newField($field);
7388 }
7389
7390 // return
7391 return field;
7392 };
7393
7394 /**
7395 * getFields
7396 *
7397 * Returns multiple field instances
7398 *
7399 * @date 14/12/17
7400 * @since ACF 5.6.5
7401 *
7402 * @param jQuery|object $fields jQuery elements or query args.
7403 * @return array
7404 */
7405
7406 acf.getFields = function ($fields) {
7407 // allow jQuery
7408 if ($fields instanceof jQuery) {
7409 // find fields
7410 } else {
7411 $fields = acf.findFields($fields);
7412 }
7413
7414 // loop
7415 var fields = [];
7416 $fields.each(function () {
7417 var field = acf.getField($(this));
7418 fields.push(field);
7419 });
7420
7421 // return
7422 return fields;
7423 };
7424
7425 /**
7426 * findClosestField
7427 *
7428 * Returns the closest jQuery field element
7429 *
7430 * @date 9/4/18
7431 * @since ACF 5.6.9
7432 *
7433 * @param jQuery $el
7434 * @return jQuery
7435 */
7436
7437 acf.findClosestField = function ($el) {
7438 return $el.closest('.acf-field');
7439 };
7440
7441 /**
7442 * getClosestField
7443 *
7444 * Returns the closest field instance
7445 *
7446 * @date 22/1/18
7447 * @since ACF 5.6.5
7448 *
7449 * @param jQuery $el
7450 * @return object
7451 */
7452
7453 acf.getClosestField = function ($el) {
7454 var $field = acf.findClosestField($el);
7455 return this.getField($field);
7456 };
7457
7458 /**
7459 * addGlobalFieldAction
7460 *
7461 * Sets up callback logic for global field actions
7462 *
7463 * @date 15/6/18
7464 * @since ACF 5.6.9
7465 *
7466 * @param string action
7467 * @return void
7468 */
7469
7470 var addGlobalFieldAction = function (action) {
7471 // vars
7472 var globalAction = action;
7473 var pluralAction = action + '_fields'; // ready_fields
7474 var singleAction = action + '_field'; // ready_field
7475
7476 // global action
7477 var globalCallback = function ($el /*, arg1, arg2, etc*/) {
7478 //console.log( action, arguments );
7479
7480 // get args [$el, ...]
7481 var args = acf.arrayArgs(arguments);
7482 var extraArgs = args.slice(1);
7483
7484 // find fields
7485 var fields = acf.getFields({
7486 parent: $el
7487 });
7488
7489 // check
7490 if (fields.length) {
7491 // pluralAction
7492 var pluralArgs = [pluralAction, fields].concat(extraArgs);
7493 acf.doAction.apply(null, pluralArgs);
7494 }
7495 };
7496
7497 // plural action
7498 var pluralCallback = function (fields /*, arg1, arg2, etc*/) {
7499 //console.log( pluralAction, arguments );
7500
7501 // get args [fields, ...]
7502 var args = acf.arrayArgs(arguments);
7503 var extraArgs = args.slice(1);
7504
7505 // loop
7506 fields.map(function (field, i) {
7507 //setTimeout(function(){
7508 // singleAction
7509 var singleArgs = [singleAction, field].concat(extraArgs);
7510 acf.doAction.apply(null, singleArgs);
7511 //}, i * 100);
7512 });
7513 };
7514
7515 // add actions
7516 acf.addAction(globalAction, globalCallback);
7517 acf.addAction(pluralAction, pluralCallback);
7518
7519 // also add single action
7520 addSingleFieldAction(action);
7521 };
7522
7523 /**
7524 * addSingleFieldAction
7525 *
7526 * Sets up callback logic for single field actions
7527 *
7528 * @date 15/6/18
7529 * @since ACF 5.6.9
7530 *
7531 * @param string action
7532 * @return void
7533 */
7534
7535 var addSingleFieldAction = function (action) {
7536 // vars
7537 var singleAction = action + '_field'; // ready_field
7538 var singleEvent = action + 'Field'; // readyField
7539
7540 // single action
7541 var singleCallback = function (field /*, arg1, arg2, etc*/) {
7542 //console.log( singleAction, arguments );
7543
7544 // get args [field, ...]
7545 var args = acf.arrayArgs(arguments);
7546 var extraArgs = args.slice(1);
7547
7548 // action variations (ready_field/type=image)
7549 var variations = ['type', 'name', 'key'];
7550 variations.map(function (variation) {
7551 // vars
7552 var prefix = '/' + variation + '=' + field.get(variation);
7553
7554 // singleAction
7555 args = [singleAction + prefix, field].concat(extraArgs);
7556 acf.doAction.apply(null, args);
7557 });
7558
7559 // event
7560 if (singleFieldEvents.indexOf(action) > -1) {
7561 field.trigger(singleEvent, extraArgs);
7562 }
7563 };
7564
7565 // add actions
7566 acf.addAction(singleAction, singleCallback);
7567 };
7568
7569 // vars
7570 var globalFieldActions = ['prepare', 'ready', 'load', 'append', 'remove', 'unmount', 'remount', 'sortstart', 'sortstop', 'show', 'hide', 'unload'];
7571 var singleFieldActions = ['valid', 'invalid', 'enable', 'disable', 'new', 'duplicate'];
7572 var singleFieldEvents = ['remove', 'unmount', 'remount', 'sortstart', 'sortstop', 'show', 'hide', 'unload', 'valid', 'invalid', 'enable', 'disable', 'duplicate'];
7573
7574 // add
7575 globalFieldActions.map(addGlobalFieldAction);
7576 singleFieldActions.map(addSingleFieldAction);
7577
7578 /**
7579 * fieldsEventManager
7580 *
7581 * Manages field actions and events
7582 *
7583 * @date 15/12/17
7584 * @since ACF 5.6.5
7585 *
7586 * @param void
7587 * @param void
7588 */
7589
7590 var fieldsEventManager = new acf.Model({
7591 id: 'fieldsEventManager',
7592 events: {
7593 'click .acf-field a[href="#"]': 'onClick',
7594 'change .acf-field': 'onChange'
7595 },
7596 onClick: function (e) {
7597 // prevent default of any link with an href of #
7598 e.preventDefault();
7599 },
7600 onChange: function () {
7601 // preview hack allows post to save with no title or content
7602 $('#_acf_changed').val(1);
7603 if (acf.isGutenbergPostEditor()) {
7604 try {
7605 wp.data.dispatch('core/editor').editPost({
7606 meta: {
7607 _acf_changed: 1
7608 }
7609 });
7610 } catch (error) {
7611 console.log('ACF: Failed to update _acf_changed meta', error);
7612 }
7613 }
7614 }
7615 });
7616 var duplicateFieldsManager = new acf.Model({
7617 id: 'duplicateFieldsManager',
7618 actions: {
7619 duplicate: 'onDuplicate',
7620 duplicate_fields: 'onDuplicateFields'
7621 },
7622 onDuplicate: function ($el, $el2) {
7623 var fields = acf.getFields({
7624 parent: $el
7625 });
7626 if (fields.length) {
7627 var $fields = acf.findFields({
7628 parent: $el2
7629 });
7630 acf.doAction('duplicate_fields', fields, $fields);
7631 }
7632 },
7633 onDuplicateFields: function (fields, duplicates) {
7634 fields.map(function (field, i) {
7635 acf.doAction('duplicate_field', field, $(duplicates[i]));
7636 });
7637 }
7638 });
7639 })(jQuery);
7640
7641 /***/ }),
7642
7643 /***/ "./assets/src/js/_acf-helpers.js":
7644 /*!***************************************!*\
7645 !*** ./assets/src/js/_acf-helpers.js ***!
7646 \***************************************/
7647 /***/ (() => {
7648
7649 (function ($, undefined) {
7650 /**
7651 * refreshHelper
7652 *
7653 * description
7654 *
7655 * @date 1/7/18
7656 * @since ACF 5.6.9
7657 *
7658 * @param type $var Description. Default.
7659 * @return type Description.
7660 */
7661
7662 var refreshHelper = new acf.Model({
7663 priority: 90,
7664 actions: {
7665 new_field: 'refresh',
7666 show_field: 'refresh',
7667 hide_field: 'refresh',
7668 remove_field: 'refresh',
7669 unmount_field: 'refresh',
7670 remount_field: 'refresh'
7671 },
7672 refresh: function () {
7673 acf.refresh();
7674 }
7675 });
7676
7677 /**
7678 * mountHelper
7679 *
7680 * Adds compatibility for the 'unmount' and 'remount' actions added in 5.8.0
7681 *
7682 * @date 7/3/19
7683 * @since ACF 5.7.14
7684 *
7685 * @param void
7686 * @return void
7687 */
7688 var mountHelper = new acf.Model({
7689 priority: 1,
7690 actions: {
7691 sortstart: 'onSortstart',
7692 sortstop: 'onSortstop'
7693 },
7694 onSortstart: function ($item) {
7695 acf.doAction('unmount', $item);
7696 },
7697 onSortstop: function ($item) {
7698 acf.doAction('remount', $item);
7699 }
7700 });
7701
7702 /**
7703 * sortableHelper
7704 *
7705 * Adds compatibility for sorting a <tr> element
7706 *
7707 * @date 6/3/18
7708 * @since ACF 5.6.9
7709 *
7710 * @param void
7711 * @return void
7712 */
7713
7714 var sortableHelper = new acf.Model({
7715 actions: {
7716 sortstart: 'onSortstart'
7717 },
7718 onSortstart: function ($item, $placeholder) {
7719 // if $item is a tr, apply some css to the elements
7720 if ($item.is('tr')) {
7721 // replace $placeholder children with a single td
7722 // fixes "width calculation issues" due to conditional logic hiding some children
7723 $placeholder.html('<td style="padding:0;" colspan="' + $placeholder.children().length + '"></td>');
7724
7725 // add helper class to remove absolute positioning
7726 $item.addClass('acf-sortable-tr-helper');
7727
7728 // set fixed widths for children
7729 $item.children().each(function () {
7730 $(this).width($(this).width());
7731 });
7732
7733 // mimic height
7734 $placeholder.height($item.height() + 'px');
7735
7736 // remove class
7737 $item.removeClass('acf-sortable-tr-helper');
7738 }
7739 }
7740 });
7741
7742 /**
7743 * duplicateHelper
7744 *
7745 * Fixes browser bugs when duplicating an element
7746 *
7747 * @date 6/3/18
7748 * @since ACF 5.6.9
7749 *
7750 * @param void
7751 * @return void
7752 */
7753
7754 var duplicateHelper = new acf.Model({
7755 actions: {
7756 after_duplicate: 'onAfterDuplicate'
7757 },
7758 onAfterDuplicate: function ($el, $el2) {
7759 // get original values
7760 var vals = [];
7761 $el.find('select').each(function (i) {
7762 vals.push($(this).val());
7763 });
7764
7765 // set duplicate values
7766 $el2.find('select').each(function (i) {
7767 $(this).val(vals[i]);
7768 });
7769 }
7770 });
7771
7772 /**
7773 * tableHelper
7774 *
7775 * description
7776 *
7777 * @date 6/3/18
7778 * @since ACF 5.6.9
7779 *
7780 * @param type $var Description. Default.
7781 * @return type Description.
7782 */
7783
7784 var tableHelper = new acf.Model({
7785 id: 'tableHelper',
7786 priority: 20,
7787 actions: {
7788 refresh: 'renderTables'
7789 },
7790 renderTables: function ($el) {
7791 // loop
7792 var self = this;
7793 $('.acf-table:visible').each(function () {
7794 self.renderTable($(this));
7795 });
7796 },
7797 renderTable: function ($table) {
7798 // vars
7799 var $ths = $table.find('> thead > tr:visible > th[data-key]');
7800 var $tds = $table.find('> tbody > tr:visible > td[data-key]');
7801
7802 // bail early if no thead
7803 if (!$ths.length || !$tds.length) {
7804 return false;
7805 }
7806
7807 // visibility
7808 $ths.each(function (i) {
7809 // vars
7810 var $th = $(this);
7811 var key = $th.data('key');
7812 var $cells = $tds.filter('[data-key="' + key + '"]');
7813 var $hidden = $cells.filter('.acf-hidden');
7814
7815 // always remove empty and allow cells to be hidden
7816 $cells.removeClass('acf-empty');
7817
7818 // hide $th if all cells are hidden
7819 if ($cells.length === $hidden.length) {
7820 acf.hide($th);
7821
7822 // force all hidden cells to appear empty
7823 } else {
7824 acf.show($th);
7825 $hidden.addClass('acf-empty');
7826 }
7827 });
7828
7829 // clear width
7830 $ths.css('width', 'auto');
7831
7832 // get visible
7833 $ths = $ths.not('.acf-hidden');
7834
7835 // vars
7836 var availableWidth = 100;
7837 var colspan = $ths.length;
7838
7839 // set custom widths first
7840 var $fixedWidths = $ths.filter('[data-width]');
7841 $fixedWidths.each(function () {
7842 var width = $(this).data('width');
7843 $(this).css('width', width + '%');
7844 availableWidth -= width;
7845 });
7846
7847 // set auto widths
7848 var $auoWidths = $ths.not('[data-width]');
7849 if ($auoWidths.length) {
7850 var width = availableWidth / $auoWidths.length;
7851 $auoWidths.css('width', width + '%');
7852 availableWidth = 0;
7853 }
7854
7855 // avoid stretching issue
7856 if (availableWidth > 0) {
7857 $ths.last().css('width', 'auto');
7858 }
7859
7860 // update colspan on collapsed
7861 $tds.filter('.-collapsed-target').each(function () {
7862 // vars
7863 var $td = $(this);
7864
7865 // check if collapsed
7866 if ($td.parent().hasClass('-collapsed')) {
7867 $td.attr('colspan', $ths.length);
7868 } else {
7869 $td.removeAttr('colspan');
7870 }
7871 });
7872 }
7873 });
7874
7875 /**
7876 * fieldsHelper
7877 *
7878 * description
7879 *
7880 * @date 6/3/18
7881 * @since ACF 5.6.9
7882 *
7883 * @param type $var Description. Default.
7884 * @return type Description.
7885 */
7886
7887 var fieldsHelper = new acf.Model({
7888 id: 'fieldsHelper',
7889 priority: 30,
7890 actions: {
7891 refresh: 'renderGroups'
7892 },
7893 renderGroups: function () {
7894 // loop
7895 var self = this;
7896 $('.acf-fields:visible').each(function () {
7897 self.renderGroup($(this));
7898 });
7899 },
7900 renderGroup: function ($el) {
7901 // vars
7902 var top = 0;
7903 var height = 0;
7904 var $row = $();
7905
7906 // get fields
7907 var $fields = $el.children('.acf-field[data-width]:visible');
7908
7909 // bail early if no fields
7910 if (!$fields.length) {
7911 return false;
7912 }
7913
7914 // bail early if is .-left
7915 if ($el.hasClass('-left')) {
7916 $fields.removeAttr('data-width');
7917 $fields.css('width', 'auto');
7918 return false;
7919 }
7920
7921 // reset fields
7922 $fields.removeClass('-r0 -c0').css({
7923 'min-height': 0
7924 });
7925
7926 // loop
7927 $fields.each(function (i) {
7928 // vars
7929 var $field = $(this);
7930 var position = $field.position();
7931 var thisTop = Math.ceil(position.top);
7932 var thisLeft = Math.ceil(position.left);
7933
7934 // detect change in row
7935 if ($row.length && thisTop > top) {
7936 // set previous heights
7937 $row.css({
7938 'min-height': height + 'px'
7939 });
7940
7941 // update position due to change in row above
7942 position = $field.position();
7943 thisTop = Math.ceil(position.top);
7944 thisLeft = Math.ceil(position.left);
7945
7946 // reset vars
7947 top = 0;
7948 height = 0;
7949 $row = $();
7950 }
7951
7952 // rtl
7953 if (acf.get('rtl')) {
7954 thisLeft = Math.ceil($field.parent().width() - (position.left + $field.outerWidth()));
7955 }
7956
7957 // add classes
7958 if (thisTop == 0) {
7959 $field.addClass('-r0');
7960 } else if (thisLeft == 0) {
7961 $field.addClass('-c0');
7962 }
7963
7964 // get height after class change
7965 // - add 1 for subpixel rendering
7966 var thisHeight = Math.ceil($field.outerHeight()) + 1;
7967
7968 // set height
7969 height = Math.max(height, thisHeight);
7970
7971 // set y
7972 top = Math.max(top, thisTop);
7973
7974 // append
7975 $row = $row.add($field);
7976 });
7977
7978 // clean up
7979 if ($row.length) {
7980 $row.css({
7981 'min-height': height + 'px'
7982 });
7983 }
7984 }
7985 });
7986
7987 /**
7988 * Adds a body class when holding down the "shift" key.
7989 *
7990 * @date 06/05/2020
7991 * @since ACF 5.9.0
7992 */
7993 var bodyClassShiftHelper = new acf.Model({
7994 id: 'bodyClassShiftHelper',
7995 events: {
7996 keydown: 'onKeyDown',
7997 keyup: 'onKeyUp'
7998 },
7999 isShiftKey: function (e) {
8000 return e.keyCode === 16;
8001 },
8002 onKeyDown: function (e) {
8003 if (this.isShiftKey(e)) {
8004 $('body').addClass('acf-keydown-shift');
8005 }
8006 },
8007 onKeyUp: function (e) {
8008 if (this.isShiftKey(e)) {
8009 $('body').removeClass('acf-keydown-shift');
8010 }
8011 }
8012 });
8013 })(jQuery);
8014
8015 /***/ }),
8016
8017 /***/ "./assets/src/js/_acf-media.js":
8018 /*!*************************************!*\
8019 !*** ./assets/src/js/_acf-media.js ***!
8020 \*************************************/
8021 /***/ (() => {
8022
8023 (function ($, undefined) {
8024 /**
8025 * acf.newMediaPopup
8026 *
8027 * description
8028 *
8029 * @date 10/1/18
8030 * @since ACF 5.6.5
8031 *
8032 * @param type $var Description. Default.
8033 * @return type Description.
8034 */
8035
8036 acf.newMediaPopup = function (args) {
8037 // args
8038 var popup = null;
8039 var args = acf.parseArgs(args, {
8040 mode: 'select',
8041 // 'select', 'edit'
8042 title: '',
8043 // 'Upload Image'
8044 button: '',
8045 // 'Select Image'
8046 type: '',
8047 // 'image', ''
8048 field: false,
8049 // field instance
8050 allowedTypes: '',
8051 // '.jpg, .png, etc'
8052 library: 'all',
8053 // 'all', 'uploadedTo'
8054 multiple: false,
8055 // false, true, 'add'
8056 attachment: 0,
8057 // the attachment to edit
8058 autoOpen: true,
8059 // open the popup automatically
8060 open: function () {},
8061 // callback after close
8062 select: function () {},
8063 // callback after select
8064 close: function () {} // callback after close
8065 });
8066
8067 // initialize
8068 if (args.mode == 'edit') {
8069 popup = new acf.models.EditMediaPopup(args);
8070 } else {
8071 popup = new acf.models.SelectMediaPopup(args);
8072 }
8073
8074 // open popup (allow frame customization before opening)
8075 if (args.autoOpen) {
8076 setTimeout(function () {
8077 popup.open();
8078 }, 1);
8079 }
8080
8081 // action
8082 acf.doAction('new_media_popup', popup);
8083
8084 // return
8085 return popup;
8086 };
8087
8088 /**
8089 * getPostID
8090 *
8091 * description
8092 *
8093 * @date 10/1/18
8094 * @since ACF 5.6.5
8095 *
8096 * @param type $var Description. Default.
8097 * @return type Description.
8098 */
8099
8100 var getPostID = function () {
8101 var postID = acf.get('post_id');
8102 return acf.isNumeric(postID) ? postID : 0;
8103 };
8104
8105 /**
8106 * acf.getMimeTypes
8107 *
8108 * description
8109 *
8110 * @date 11/1/18
8111 * @since ACF 5.6.5
8112 *
8113 * @param type $var Description. Default.
8114 * @return type Description.
8115 */
8116
8117 acf.getMimeTypes = function () {
8118 return this.get('mimeTypes');
8119 };
8120 acf.getMimeType = function (name) {
8121 // vars
8122 var allTypes = acf.getMimeTypes();
8123
8124 // search
8125 if (allTypes[name] !== undefined) {
8126 return allTypes[name];
8127 }
8128
8129 // some types contain a mixed key such as "jpg|jpeg|jpe"
8130 for (var key in allTypes) {
8131 if (key.indexOf(name) !== -1) {
8132 return allTypes[key];
8133 }
8134 }
8135
8136 // return
8137 return false;
8138 };
8139
8140 /**
8141 * MediaPopup
8142 *
8143 * description
8144 *
8145 * @date 10/1/18
8146 * @since ACF 5.6.5
8147 *
8148 * @param type $var Description. Default.
8149 * @return type Description.
8150 */
8151
8152 var MediaPopup = acf.Model.extend({
8153 id: 'MediaPopup',
8154 data: {},
8155 defaults: {},
8156 frame: false,
8157 setup: function (props) {
8158 $.extend(this.data, props);
8159 },
8160 initialize: function () {
8161 // vars
8162 var options = this.getFrameOptions();
8163
8164 // add states
8165 this.addFrameStates(options);
8166
8167 // create frame
8168 var frame = wp.media(options);
8169
8170 // add args reference
8171 frame.acf = this;
8172
8173 // add events
8174 this.addFrameEvents(frame, options);
8175
8176 // store frame
8177 this.frame = frame;
8178 },
8179 open: function () {
8180 this.frame.open();
8181 },
8182 close: function () {
8183 this.frame.close();
8184 },
8185 remove: function () {
8186 this.frame.detach();
8187 this.frame.remove();
8188 },
8189 getFrameOptions: function () {
8190 // vars
8191 var options = {
8192 title: this.get('title'),
8193 multiple: this.get('multiple'),
8194 library: {},
8195 states: []
8196 };
8197
8198 // type
8199 if (this.get('type')) {
8200 options.library.type = this.get('type');
8201 }
8202
8203 // type
8204 if (this.get('library') === 'uploadedTo') {
8205 options.library.uploadedTo = getPostID();
8206 }
8207
8208 // attachment
8209 if (this.get('attachment')) {
8210 options.library.post__in = [this.get('attachment')];
8211 }
8212
8213 // button
8214 if (this.get('button')) {
8215 options.button = {
8216 text: this.get('button')
8217 };
8218 }
8219
8220 // return
8221 return options;
8222 },
8223 addFrameStates: function (options) {
8224 // create query
8225 var Query = wp.media.query(options.library);
8226
8227 // add _acfuploader
8228 // this is super wack!
8229 // if you add _acfuploader to the options.library args, new uploads will not be added to the library view.
8230 // this has been traced back to the wp.media.model.Query initialize function (which can't be overridden)
8231 // Adding any custom args will cause the Attachments to not observe the uploader queue
8232 // To bypass this security issue, we add in the args AFTER the Query has been initialized
8233 // options.library._acfuploader = settings.field;
8234 if (this.get('field') && acf.isset(Query, 'mirroring', 'args')) {
8235 Query.mirroring.args._acfuploader = this.get('field');
8236 }
8237
8238 // add states
8239 options.states.push(
8240 // main state
8241 new wp.media.controller.Library({
8242 library: Query,
8243 multiple: this.get('multiple'),
8244 title: this.get('title'),
8245 priority: 20,
8246 filterable: 'all',
8247 editable: true,
8248 allowLocalEdits: true
8249 }));
8250
8251 // edit image functionality (added in WP 3.9)
8252 if (acf.isset(wp, 'media', 'controller', 'EditImage')) {
8253 options.states.push(new wp.media.controller.EditImage());
8254 }
8255 },
8256 addFrameEvents: function (frame, options) {
8257 // log all events
8258 //frame.on('all', function( e ) {
8259 // console.log( 'frame all: %o', e );
8260 //});
8261
8262 // add class
8263 frame.on('open', function () {
8264 this.$el.closest('.media-modal').addClass('acf-media-modal -' + this.acf.get('mode'));
8265 }, frame);
8266
8267 // edit image view
8268 // source: media-views.js:2410 editImageContent()
8269 frame.on('content:render:edit-image', function () {
8270 var image = this.state().get('image');
8271 var view = new wp.media.view.EditImage({
8272 model: image,
8273 controller: this
8274 }).render();
8275 this.content.set(view);
8276
8277 // after creating the wrapper view, load the actual editor via an ajax call
8278 view.loadEditor();
8279 }, frame);
8280
8281 // update toolbar button
8282 //frame.on( 'toolbar:create:select', function( toolbar ) {
8283 // toolbar.view = new wp.media.view.Toolbar.Select({
8284 // text: frame.options._button,
8285 // controller: this
8286 // });
8287 //}, frame );
8288
8289 // on select
8290 frame.on('select', function () {
8291 // vars
8292 var selection = frame.state().get('selection');
8293
8294 // if selecting images
8295 if (selection) {
8296 // loop
8297 selection.each(function (attachment, i) {
8298 frame.acf.get('select').apply(frame.acf, [attachment, i]);
8299 });
8300 }
8301 });
8302
8303 // on close
8304 frame.on('close', function () {
8305 // callback and remove
8306 setTimeout(function () {
8307 frame.acf.get('close').apply(frame.acf);
8308 frame.acf.remove();
8309 }, 1);
8310 });
8311 }
8312 });
8313
8314 /**
8315 * acf.models.SelectMediaPopup
8316 *
8317 * description
8318 *
8319 * @date 10/1/18
8320 * @since ACF 5.6.5
8321 *
8322 * @param type $var Description. Default.
8323 * @return type Description.
8324 */
8325
8326 acf.models.SelectMediaPopup = MediaPopup.extend({
8327 id: 'SelectMediaPopup',
8328 setup: function (props) {
8329 // default button
8330 if (!props.button) {
8331 props.button = acf._x('Select', 'verb');
8332 }
8333
8334 // parent
8335 MediaPopup.prototype.setup.apply(this, arguments);
8336 },
8337 addFrameEvents: function (frame, options) {
8338 // plupload
8339 // adds _acfuploader param to validate uploads
8340 if (acf.isset(_wpPluploadSettings, 'defaults', 'multipart_params')) {
8341 // add _acfuploader so that Uploader will inherit
8342 _wpPluploadSettings.defaults.multipart_params._acfuploader = this.get('field');
8343
8344 // remove acf_field so future Uploaders won't inherit
8345 frame.on('open', function () {
8346 delete _wpPluploadSettings.defaults.multipart_params._acfuploader;
8347 });
8348 }
8349
8350 // browse
8351 frame.on('content:activate:browse', function () {
8352 // vars
8353 var toolbar = false;
8354
8355 // populate above vars making sure to allow for failure
8356 // perhaps toolbar does not exist because the frame open is Upload Files
8357 try {
8358 toolbar = frame.content.get().toolbar;
8359 } catch (e) {
8360 console.log(e);
8361 return;
8362 }
8363
8364 // callback
8365 frame.acf.customizeFilters.apply(frame.acf, [toolbar]);
8366 });
8367
8368 // parent
8369 MediaPopup.prototype.addFrameEvents.apply(this, arguments);
8370 },
8371 customizeFilters: function (toolbar) {
8372 // vars
8373 var filters = toolbar.get('filters');
8374
8375 // image
8376 if (this.get('type') == 'image') {
8377 // update all
8378 filters.filters.all.text = acf.__('All images');
8379
8380 // remove some filters
8381 delete filters.filters.audio;
8382 delete filters.filters.video;
8383 delete filters.filters.image;
8384
8385 // update all filters to show images
8386 $.each(filters.filters, function (i, filter) {
8387 filter.props.type = filter.props.type || 'image';
8388 });
8389 }
8390
8391 // specific types
8392 if (this.get('allowedTypes')) {
8393 // convert ".jpg, .png" into ["jpg", "png"]
8394 var allowedTypes = this.get('allowedTypes').split(' ').join('').split('.').join('').split(',');
8395
8396 // loop
8397 allowedTypes.map(function (name) {
8398 // get type
8399 var mimeType = acf.getMimeType(name);
8400
8401 // bail early if no type
8402 if (!mimeType) return;
8403
8404 // create new filter
8405 var newFilter = {
8406 text: mimeType,
8407 props: {
8408 status: null,
8409 type: mimeType,
8410 uploadedTo: null,
8411 orderby: 'date',
8412 order: 'DESC'
8413 },
8414 priority: 20
8415 };
8416
8417 // append
8418 filters.filters[mimeType] = newFilter;
8419 });
8420 }
8421
8422 // uploaded to post
8423 if (this.get('library') === 'uploadedTo') {
8424 // vars
8425 var uploadedTo = this.frame.options.library.uploadedTo;
8426
8427 // remove some filters
8428 delete filters.filters.unattached;
8429 delete filters.filters.uploaded;
8430
8431 // add uploadedTo to filters
8432 $.each(filters.filters, function (i, filter) {
8433 filter.text += ' (' + acf.__('Uploaded to this post') + ')';
8434 filter.props.uploadedTo = uploadedTo;
8435 });
8436 }
8437
8438 // add _acfuploader to filters
8439 var field = this.get('field');
8440 $.each(filters.filters, function (k, filter) {
8441 filter.props._acfuploader = field;
8442 });
8443
8444 // add _acfuploader to search
8445 var search = toolbar.get('search');
8446 search.model.attributes._acfuploader = field;
8447
8448 // render (custom function added to prototype)
8449 if (filters.renderFilters) {
8450 filters.renderFilters();
8451 }
8452 }
8453 });
8454
8455 /**
8456 * acf.models.EditMediaPopup
8457 *
8458 * description
8459 *
8460 * @date 10/1/18
8461 * @since ACF 5.6.5
8462 *
8463 * @param type $var Description. Default.
8464 * @return type Description.
8465 */
8466
8467 acf.models.EditMediaPopup = MediaPopup.extend({
8468 id: 'SelectMediaPopup',
8469 setup: function (props) {
8470 // default button
8471 if (!props.button) {
8472 props.button = acf._x('Update', 'verb');
8473 }
8474
8475 // parent
8476 MediaPopup.prototype.setup.apply(this, arguments);
8477 },
8478 addFrameEvents: function (frame, options) {
8479 // add class
8480 frame.on('open', function () {
8481 // add class
8482 this.$el.closest('.media-modal').addClass('acf-expanded');
8483
8484 // set to browse
8485 if (this.content.mode() != 'browse') {
8486 this.content.mode('browse');
8487 }
8488
8489 // set selection
8490 var state = this.state();
8491 var selection = state.get('selection');
8492 var attachment = wp.media.attachment(frame.acf.get('attachment'));
8493 selection.add(attachment);
8494 }, frame);
8495
8496 // parent
8497 MediaPopup.prototype.addFrameEvents.apply(this, arguments);
8498 }
8499 });
8500
8501 /**
8502 * customizePrototypes
8503 *
8504 * description
8505 *
8506 * @date 11/1/18
8507 * @since ACF 5.6.5
8508 *
8509 * @param type $var Description. Default.
8510 * @return type Description.
8511 */
8512
8513 var customizePrototypes = new acf.Model({
8514 id: 'customizePrototypes',
8515 wait: 'ready',
8516 initialize: function () {
8517 // bail early if no media views
8518 if (!acf.isset(window, 'wp', 'media', 'view')) {
8519 return;
8520 }
8521
8522 // fix bug where CPT without "editor" does not set post.id setting which then prevents uploadedTo from working
8523 var postID = getPostID();
8524 if (postID && acf.isset(wp, 'media', 'view', 'settings', 'post')) {
8525 wp.media.view.settings.post.id = postID;
8526 }
8527
8528 // customize
8529 this.customizeAttachmentsButton();
8530 this.customizeAttachmentsRouter();
8531 this.customizeAttachmentFilters();
8532 this.customizeAttachmentCompat();
8533 this.customizeAttachmentLibrary();
8534 },
8535 customizeAttachmentsButton: function () {
8536 // validate
8537 if (!acf.isset(wp, 'media', 'view', 'Button')) {
8538 return;
8539 }
8540
8541 // Extend
8542 var Button = wp.media.view.Button;
8543 wp.media.view.Button = Button.extend({
8544 // Fix bug where "Select" button appears blank after editing an image.
8545 // Do this by simplifying Button initialize function and avoid deleting this.options.
8546 initialize: function () {
8547 var options = _.defaults(this.options, this.defaults);
8548 this.model = new Backbone.Model(options);
8549 this.listenTo(this.model, 'change', this.render);
8550 }
8551 });
8552 },
8553 customizeAttachmentsRouter: function () {
8554 // validate
8555 if (!acf.isset(wp, 'media', 'view', 'Router')) {
8556 return;
8557 }
8558
8559 // vars
8560 var Parent = wp.media.view.Router;
8561
8562 // extend
8563 wp.media.view.Router = Parent.extend({
8564 addExpand: function () {
8565 // vars
8566 var $a = $(['<a href="#" class="acf-expand-details">', '<span class="is-closed"><i class="acf-icon -left -small"></i>' + acf.__('Expand Details') + '</span>', '<span class="is-open"><i class="acf-icon -right -small"></i>' + acf.__('Collapse Details') + '</span>', '</a>'].join(''));
8567
8568 // add events
8569 $a.on('click', function (e) {
8570 e.preventDefault();
8571 var $div = $(this).closest('.media-modal');
8572 if ($div.hasClass('acf-expanded')) {
8573 $div.removeClass('acf-expanded');
8574 } else {
8575 $div.addClass('acf-expanded');
8576 }
8577 });
8578
8579 // append
8580 this.$el.append($a);
8581 },
8582 initialize: function () {
8583 // initialize
8584 Parent.prototype.initialize.apply(this, arguments);
8585
8586 // add buttons
8587 this.addExpand();
8588
8589 // return
8590 return this;
8591 }
8592 });
8593 },
8594 customizeAttachmentFilters: function () {
8595 // validate
8596 if (!acf.isset(wp, 'media', 'view', 'AttachmentFilters', 'All')) {
8597 return;
8598 }
8599
8600 // vars
8601 var Parent = wp.media.view.AttachmentFilters.All;
8602
8603 // renderFilters
8604 // copied from media-views.js:6939
8605 Parent.prototype.renderFilters = function () {
8606 // Build `<option>` elements.
8607 this.$el.html(_.chain(this.filters).map(function (filter, value) {
8608 return {
8609 el: $('<option></option>').val(value).html(filter.text)[0],
8610 priority: filter.priority || 50
8611 };
8612 }, this).sortBy('priority').pluck('el').value());
8613 };
8614 },
8615 customizeAttachmentCompat: function () {
8616 // validate
8617 if (!acf.isset(wp, 'media', 'view', 'AttachmentCompat')) {
8618 return;
8619 }
8620
8621 // vars
8622 var AttachmentCompat = wp.media.view.AttachmentCompat;
8623 var timeout = false;
8624
8625 // extend
8626 wp.media.view.AttachmentCompat = AttachmentCompat.extend({
8627 render: function () {
8628 // WP bug
8629 // When multiple media frames exist on the same page (WP content, WYSIWYG, image, file ),
8630 // WP creates multiple instances of this AttachmentCompat view.
8631 // Each instance will attempt to render when a new modal is created.
8632 // Use a property to avoid this and only render once per instance.
8633 if (this.rendered) {
8634 return this;
8635 }
8636
8637 // render HTML
8638 AttachmentCompat.prototype.render.apply(this, arguments);
8639
8640 // when uploading, render is called twice.
8641 // ignore first render by checking for #acf-form-data element
8642 if (!this.$('#acf-form-data').length) {
8643 return this;
8644 }
8645
8646 // clear timeout
8647 clearTimeout(timeout);
8648
8649 // setTimeout
8650 timeout = setTimeout($.proxy(function () {
8651 this.rendered = true;
8652 acf.doAction('append', this.$el);
8653 }, this), 50);
8654
8655 // return
8656 return this;
8657 },
8658 save: function (event) {
8659 var data = {};
8660 if (event) {
8661 event.preventDefault();
8662 }
8663
8664 //_.each( this.$el.serializeArray(), function( pair ) {
8665 // data[ pair.name ] = pair.value;
8666 //});
8667
8668 // Serialize data more thoroughly to allow checkbox inputs to save.
8669 data = acf.serializeForAjax(this.$el);
8670 this.controller.trigger('attachment:compat:waiting', ['waiting']);
8671 this.model.saveCompat(data).always(_.bind(this.postSave, this));
8672 }
8673 });
8674 },
8675 customizeAttachmentLibrary: function () {
8676 // validate
8677 if (!acf.isset(wp, 'media', 'view', 'Attachment', 'Library')) {
8678 return;
8679 }
8680
8681 // vars
8682 var AttachmentLibrary = wp.media.view.Attachment.Library;
8683
8684 // extend
8685 wp.media.view.Attachment.Library = AttachmentLibrary.extend({
8686 render: function () {
8687 // vars
8688 var popup = acf.isget(this, 'controller', 'acf');
8689 var attributes = acf.isget(this, 'model', 'attributes');
8690
8691 // check vars exist to avoid errors
8692 if (popup && attributes) {
8693 // show errors
8694 if (attributes.acf_errors) {
8695 this.$el.addClass('acf-disabled');
8696 }
8697
8698 // disable selected
8699 var selected = popup.get('selected');
8700 if (selected && selected.indexOf(attributes.id) > -1) {
8701 this.$el.addClass('acf-selected');
8702 }
8703 }
8704
8705 // render
8706 return AttachmentLibrary.prototype.render.apply(this, arguments);
8707 },
8708 /*
8709 * toggleSelection
8710 *
8711 * This function is called before an attachment is selected
8712 * A good place to check for errors and prevent the 'select' function from being fired
8713 *
8714 * @type function
8715 * @date 29/09/2016
8716 * @since ACF 5.4.0
8717 *
8718 * @param options (object)
8719 * @return n/a
8720 */
8721
8722 toggleSelection: function (options) {
8723 // vars
8724 // source: wp-includes/js/media-views.js:2880
8725 var collection = this.collection,
8726 selection = this.options.selection,
8727 model = this.model,
8728 single = selection.single();
8729
8730 // vars
8731 var frame = this.controller;
8732 var errors = acf.isget(this, 'model', 'attributes', 'acf_errors');
8733 var $sidebar = frame.$el.find('.media-frame-content .media-sidebar');
8734
8735 // remove previous error
8736 $sidebar.children('.acf-selection-error').remove();
8737
8738 // show attachment details
8739 $sidebar.children().removeClass('acf-hidden');
8740
8741 // add message
8742 if (frame && errors) {
8743 // vars
8744 var filename = acf.isget(this, 'model', 'attributes', 'filename');
8745
8746 // hide attachment details
8747 // Gallery field continues to show previously selected attachment...
8748 $sidebar.children().addClass('acf-hidden');
8749
8750 // append message
8751 $sidebar.prepend(['<div class="acf-selection-error">', '<span class="selection-error-label">' + acf.__('Restricted') + '</span>', '<span class="selection-error-filename">' + filename + '</span>', '<span class="selection-error-message">' + errors + '</span>', '</div>'].join(''));
8752
8753 // reset selection (unselects all attachments)
8754 selection.reset();
8755
8756 // set single (attachment displayed in sidebar)
8757 selection.single(model);
8758
8759 // return and prevent 'select' form being fired
8760 return;
8761 }
8762
8763 // return
8764 return AttachmentLibrary.prototype.toggleSelection.apply(this, arguments);
8765 }
8766 });
8767 }
8768 });
8769 })(jQuery);
8770
8771 /***/ }),
8772
8773 /***/ "./assets/src/js/_acf-postbox.js":
8774 /*!***************************************!*\
8775 !*** ./assets/src/js/_acf-postbox.js ***!
8776 \***************************************/
8777 /***/ (() => {
8778
8779 (function ($, undefined) {
8780 /**
8781 * postboxManager
8782 *
8783 * Manages postboxes on the screen.
8784 *
8785 * @date 25/5/19
8786 * @since ACF 5.8.1
8787 *
8788 * @param void
8789 * @return void
8790 */
8791 var postboxManager = new acf.Model({
8792 wait: 'prepare',
8793 priority: 1,
8794 initialize: function () {
8795 (acf.get('postboxes') || []).map(acf.newPostbox);
8796 }
8797 });
8798
8799 /**
8800 * acf.getPostbox
8801 *
8802 * Returns a postbox instance.
8803 *
8804 * @date 23/9/18
8805 * @since ACF 5.7.7
8806 *
8807 * @param mixed $el Either a jQuery element or the postbox id.
8808 * @return object
8809 */
8810 acf.getPostbox = function ($el) {
8811 // allow string parameter
8812 if (typeof arguments[0] == 'string') {
8813 $el = $('#' + arguments[0]);
8814 }
8815
8816 // return instance
8817 return acf.getInstance($el);
8818 };
8819
8820 /**
8821 * acf.getPostboxes
8822 *
8823 * Returns an array of postbox instances.
8824 *
8825 * @date 23/9/18
8826 * @since ACF 5.7.7
8827 *
8828 * @param void
8829 * @return array
8830 */
8831 acf.getPostboxes = function () {
8832 return acf.getInstances($('.acf-postbox'));
8833 };
8834
8835 /**
8836 * acf.newPostbox
8837 *
8838 * Returns a new postbox instance for the given props.
8839 *
8840 * @date 20/9/18
8841 * @since ACF 5.7.6
8842 *
8843 * @param object props The postbox properties.
8844 * @return object
8845 */
8846 acf.newPostbox = function (props) {
8847 return new acf.models.Postbox(props);
8848 };
8849
8850 /**
8851 * acf.models.Postbox
8852 *
8853 * The postbox model.
8854 *
8855 * @date 20/9/18
8856 * @since ACF 5.7.6
8857 *
8858 * @param void
8859 * @return void
8860 */
8861 acf.models.Postbox = acf.Model.extend({
8862 data: {
8863 id: '',
8864 key: '',
8865 style: 'default',
8866 label: 'top',
8867 edit: ''
8868 },
8869 setup: function (props) {
8870 // compatibility
8871 if (props.editLink) {
8872 props.edit = props.editLink;
8873 }
8874
8875 // extend data
8876 $.extend(this.data, props);
8877
8878 // set $el
8879 this.$el = this.$postbox();
8880 },
8881 $postbox: function () {
8882 return $('#' + this.get('id'));
8883 },
8884 $hide: function () {
8885 return $('#' + this.get('id') + '-hide');
8886 },
8887 $hideLabel: function () {
8888 return this.$hide().parent();
8889 },
8890 $hndle: function () {
8891 return this.$('> .hndle');
8892 },
8893 $handleActions: function () {
8894 return this.$('> .postbox-header .handle-actions');
8895 },
8896 $inside: function () {
8897 return this.$('> .inside');
8898 },
8899 isVisible: function () {
8900 return this.$el.hasClass('acf-hidden');
8901 },
8902 isHiddenByScreenOptions: function () {
8903 return this.$el.hasClass('hide-if-js') || this.$el.css('display') == 'none';
8904 },
8905 initialize: function () {
8906 // Add default class.
8907 this.$el.addClass('acf-postbox');
8908
8909 // Add field group style class (ignore in block editor).
8910 if (acf.get('editor') !== 'block') {
8911 var style = this.get('style');
8912 if (style !== 'default') {
8913 this.$el.addClass(style);
8914 }
8915 }
8916
8917 // Add .inside class.
8918 this.$inside().addClass('acf-fields').addClass('-' + this.get('label'));
8919
8920 // Append edit link.
8921 var edit = this.get('edit');
8922 if (edit) {
8923 var html = '<a href="' + edit + '" class="dashicons dashicons-admin-generic acf-hndle-cog acf-js-tooltip" title="' + acf.__('Edit field group') + '"></a>';
8924 var $handleActions = this.$handleActions();
8925 if ($handleActions.length) {
8926 $handleActions.prepend(html);
8927 } else {
8928 this.$hndle().append(html);
8929 }
8930 }
8931
8932 // Show postbox.
8933 this.show();
8934 },
8935 show: function () {
8936 // If disabled by screen options, set checked to false and return.
8937 if (this.$el.hasClass('hide-if-js')) {
8938 this.$hide().prop('checked', false);
8939 return;
8940 }
8941
8942 // Show label.
8943 this.$hideLabel().show();
8944
8945 // toggle on checkbox
8946 this.$hide().prop('checked', true);
8947
8948 // Show postbox
8949 this.$el.show().removeClass('acf-hidden');
8950
8951 // Do action.
8952 acf.doAction('show_postbox', this);
8953 },
8954 enable: function () {
8955 acf.enable(this.$el, 'postbox');
8956 },
8957 showEnable: function () {
8958 this.enable();
8959 this.show();
8960 },
8961 hide: function () {
8962 // Hide label.
8963 this.$hideLabel().hide();
8964
8965 // Hide postbox
8966 this.$el.hide().addClass('acf-hidden');
8967
8968 // Do action.
8969 acf.doAction('hide_postbox', this);
8970 },
8971 disable: function () {
8972 acf.disable(this.$el, 'postbox');
8973 },
8974 hideDisable: function () {
8975 this.disable();
8976 this.hide();
8977 },
8978 html: function (html) {
8979 // Update HTML.
8980 this.$inside().html(html);
8981
8982 // Do action.
8983 acf.doAction('append', this.$el);
8984 }
8985 });
8986 })(jQuery);
8987
8988 /***/ }),
8989
8990 /***/ "./assets/src/js/_acf-screen.js":
8991 /*!**************************************!*\
8992 !*** ./assets/src/js/_acf-screen.js ***!
8993 \**************************************/
8994 /***/ (() => {
8995
8996 (function ($, undefined) {
8997 acf.screen = new acf.Model({
8998 active: true,
8999 xhr: false,
9000 timeout: false,
9001 wait: 'load',
9002 events: {
9003 'change #page_template': 'onChange',
9004 'change #parent_id': 'onChange',
9005 'change #post-formats-select': 'onChange',
9006 'change .categorychecklist': 'onChange',
9007 'change .tagsdiv': 'onChange',
9008 'change .acf-taxonomy-field[data-save="1"]': 'onChange',
9009 'change #product-type': 'onChange'
9010 },
9011 isPost: function () {
9012 return acf.get('screen') === 'post';
9013 },
9014 isUser: function () {
9015 return acf.get('screen') === 'user';
9016 },
9017 isTaxonomy: function () {
9018 return acf.get('screen') === 'taxonomy';
9019 },
9020 isAttachment: function () {
9021 return acf.get('screen') === 'attachment';
9022 },
9023 isNavMenu: function () {
9024 return acf.get('screen') === 'nav_menu';
9025 },
9026 isWidget: function () {
9027 return acf.get('screen') === 'widget';
9028 },
9029 isComment: function () {
9030 return acf.get('screen') === 'comment';
9031 },
9032 getPageTemplate: function () {
9033 var $el = $('#page_template');
9034 return $el.length ? $el.val() : null;
9035 },
9036 getPageParent: function (e, $el) {
9037 var $el = $('#parent_id');
9038 return $el.length ? $el.val() : null;
9039 },
9040 getPageType: function (e, $el) {
9041 return this.getPageParent() ? 'child' : 'parent';
9042 },
9043 getPostType: function () {
9044 return $('#post_type').val();
9045 },
9046 getPostFormat: function (e, $el) {
9047 var $el = $('#post-formats-select input:checked');
9048 if ($el.length) {
9049 var val = $el.val();
9050 return val == '0' ? 'standard' : val;
9051 }
9052 return null;
9053 },
9054 getPostCoreTerms: function () {
9055 // vars
9056 var terms = {};
9057
9058 // serialize WP taxonomy postboxes
9059 var data = acf.serialize($('.categorydiv, .tagsdiv'));
9060
9061 // use tax_input (tag, custom-taxonomy) when possible.
9062 // this data is already formatted in taxonomy => [terms].
9063 if (data.tax_input) {
9064 terms = data.tax_input;
9065 }
9066
9067 // append "category" which uses a different name
9068 if (data.post_category) {
9069 terms.category = data.post_category;
9070 }
9071
9072 // convert any string values (tags) into array format
9073 for (var tax in terms) {
9074 if (!acf.isArray(terms[tax])) {
9075 terms[tax] = terms[tax].split(/,[\s]?/);
9076 }
9077 }
9078
9079 // return
9080 return terms;
9081 },
9082 getPostTerms: function () {
9083 // Get core terms.
9084 var terms = this.getPostCoreTerms();
9085
9086 // loop over taxonomy fields and add their values
9087 acf.getFields({
9088 type: 'taxonomy'
9089 }).map(function (field) {
9090 // ignore fields that don't save
9091 if (!field.get('save')) {
9092 return;
9093 }
9094
9095 // vars
9096 var val = field.val();
9097 var tax = field.get('taxonomy');
9098
9099 // check val
9100 if (val) {
9101 // ensure terms exists
9102 terms[tax] = terms[tax] || [];
9103
9104 // ensure val is an array
9105 val = acf.isArray(val) ? val : [val];
9106
9107 // append
9108 terms[tax] = terms[tax].concat(val);
9109 }
9110 });
9111
9112 // add WC product type
9113 if ((productType = this.getProductType()) !== null) {
9114 terms.product_type = [productType];
9115 }
9116
9117 // remove duplicate values
9118 for (var tax in terms) {
9119 terms[tax] = acf.uniqueArray(terms[tax]);
9120 }
9121
9122 // return
9123 return terms;
9124 },
9125 getProductType: function () {
9126 var $el = $('#product-type');
9127 return $el.length ? $el.val() : null;
9128 },
9129 check: function () {
9130 // bail early if not for post
9131 if (acf.get('screen') !== 'post') {
9132 return;
9133 }
9134
9135 // abort XHR if is already loading AJAX data
9136 if (this.xhr) {
9137 this.xhr.abort();
9138 }
9139
9140 // vars
9141 var ajaxData = acf.parseArgs(this.data, {
9142 action: 'acf/ajax/check_screen',
9143 screen: acf.get('screen'),
9144 exists: []
9145 });
9146
9147 // post id
9148 if (this.isPost()) {
9149 ajaxData.post_id = acf.get('post_id');
9150 }
9151
9152 // post type
9153 if ((postType = this.getPostType()) !== null) {
9154 ajaxData.post_type = postType;
9155 }
9156
9157 // page template
9158 if ((pageTemplate = this.getPageTemplate()) !== null) {
9159 ajaxData.page_template = pageTemplate;
9160 }
9161
9162 // page parent
9163 if ((pageParent = this.getPageParent()) !== null) {
9164 ajaxData.page_parent = pageParent;
9165 }
9166
9167 // page type
9168 if ((pageType = this.getPageType()) !== null) {
9169 ajaxData.page_type = pageType;
9170 }
9171
9172 // post format
9173 if ((postFormat = this.getPostFormat()) !== null) {
9174 ajaxData.post_format = postFormat;
9175 }
9176
9177 // post terms
9178 if ((postTerms = this.getPostTerms()) !== null) {
9179 ajaxData.post_terms = postTerms;
9180 }
9181
9182 // add array of existing postboxes to increase performance and reduce JSON HTML
9183 acf.getPostboxes().map(function (postbox) {
9184 ajaxData.exists.push(postbox.get('key'));
9185 });
9186
9187 // filter
9188 ajaxData = acf.applyFilters('check_screen_args', ajaxData);
9189
9190 // success
9191 var onSuccess = function (json) {
9192 // Render post screen.
9193 if (acf.get('screen') == 'post') {
9194 this.renderPostScreen(json);
9195
9196 // Render user screen.
9197 } else if (acf.get('screen') == 'user') {
9198 this.renderUserScreen(json);
9199 }
9200
9201 // action
9202 acf.doAction('check_screen_complete', json, ajaxData);
9203 };
9204
9205 // ajax
9206 this.xhr = $.ajax({
9207 url: acf.get('ajaxurl'),
9208 data: acf.prepareForAjax(ajaxData),
9209 type: 'post',
9210 dataType: 'json',
9211 context: this,
9212 success: onSuccess
9213 });
9214 },
9215 onChange: function (e, $el) {
9216 this.setTimeout(this.check, 1);
9217 },
9218 renderPostScreen: function (data) {
9219 // Helper function to copy events
9220 var copyEvents = function ($from, $to) {
9221 var events = $._data($from[0]).events;
9222 for (var type in events) {
9223 for (var i = 0; i < events[type].length; i++) {
9224 $to.on(type, events[type][i].handler);
9225 }
9226 }
9227 };
9228
9229 // Helper function to sort metabox.
9230 var sortMetabox = function (id, ids) {
9231 // Find position of id within ids.
9232 var index = ids.indexOf(id);
9233
9234 // Bail early if index not found.
9235 if (index == -1) {
9236 return false;
9237 }
9238
9239 // Loop over metaboxes behind (in reverse order).
9240 for (var i = index - 1; i >= 0; i--) {
9241 if ($('#' + ids[i]).length) {
9242 return $('#' + ids[i]).after($('#' + id));
9243 }
9244 }
9245
9246 // Loop over metaboxes infront.
9247 for (var i = index + 1; i < ids.length; i++) {
9248 if ($('#' + ids[i]).length) {
9249 return $('#' + ids[i]).before($('#' + id));
9250 }
9251 }
9252
9253 // Return false if not sorted.
9254 return false;
9255 };
9256
9257 // Keep track of visible and hidden postboxes.
9258 data.visible = [];
9259 data.hidden = [];
9260
9261 // Show these postboxes.
9262 data.results = data.results.map(function (result, i) {
9263 // vars
9264 var postbox = acf.getPostbox(result.id);
9265
9266 // Prevent "acf_after_title" position in Block Editor.
9267 if (acf.isGutenberg() && result.position == 'acf_after_title') {
9268 result.position = 'normal';
9269 }
9270
9271 // Create postbox if doesn't exist.
9272 if (!postbox) {
9273 var postboxHeader = ['<div class="postbox-header">', '<h2 class="hndle ui-sortable-handle">', '<span>' + result.title + '</span>', '</h2>', '<div class="handle-actions hide-if-no-js">', '<button type="button" class="handlediv" aria-expanded="true">', '<span class="screen-reader-text">' + acf.__('Toggle panel') + ': ' + result.title + '</span>', '<span class="toggle-indicator" aria-hidden="true"></span>', '</button>', '</div>', '</div>'].join('');
9274
9275 // Ensure result.classes is set.
9276 if (!result.classes) result.classes = '';
9277
9278 // Create it.
9279 var $postbox = $(['<div id="' + result.id + '" class="postbox ' + result.classes + '">', postboxHeader, '<div class="inside">', result.html, '</div>', '</div>'].join(''));
9280
9281 // Create new hide toggle.
9282 if ($('#adv-settings').length) {
9283 var $prefs = $('#adv-settings .metabox-prefs');
9284 var $label = $(['<label for="' + result.id + '-hide">', '<input class="hide-postbox-tog" name="' + result.id + '-hide" type="checkbox" id="' + result.id + '-hide" value="' + result.id + '" checked="checked">', ' ' + result.title, '</label>'].join(''));
9285
9286 // Copy default WP events onto checkbox.
9287 copyEvents($prefs.find('input').first(), $label.find('input'));
9288
9289 // Append hide label
9290 $prefs.append($label);
9291 }
9292
9293 // Copy default WP events onto metabox.
9294 if ($('.postbox').length) {
9295 copyEvents($('.postbox .handlediv').first(), $postbox.children('.handlediv'));
9296 copyEvents($('.postbox .hndle').first(), $postbox.children('.hndle'));
9297 }
9298
9299 // Append metabox to the bottom of "side-sortables".
9300 if (result.position === 'side') {
9301 $('#' + result.position + '-sortables').append($postbox);
9302
9303 // Prepend metabox to the top of "normal-sortbables".
9304 } else {
9305 $('#' + result.position + '-sortables').prepend($postbox);
9306 }
9307
9308 // Position metabox amongst existing ACF metaboxes within the same location.
9309 var order = [];
9310 data.results.map(function (_result) {
9311 if (result.position === _result.position && $('#' + result.position + '-sortables #' + _result.id).length) {
9312 order.push(_result.id);
9313 }
9314 });
9315 sortMetabox(result.id, order);
9316
9317 // Check 'sorted' for user preference.
9318 if (data.sorted) {
9319 // Loop over each position (acf_after_title, side, normal).
9320 for (var position in data.sorted) {
9321 let order = data.sorted[position];
9322 if (typeof order !== 'string') {
9323 continue;
9324 }
9325
9326 // Explode string into array of ids.
9327 order = order.split(',');
9328
9329 // Position metabox relative to order.
9330 if (sortMetabox(result.id, order)) {
9331 break;
9332 }
9333 }
9334 }
9335
9336 // Initalize it (modifies HTML).
9337 postbox = acf.newPostbox(result);
9338
9339 // Trigger action.
9340 acf.doAction('append', $postbox);
9341 acf.doAction('append_postbox', postbox);
9342 }
9343
9344 // show postbox
9345 postbox.showEnable();
9346
9347 // append
9348 data.visible.push(result.id);
9349
9350 // Return result (may have changed).
9351 return result;
9352 });
9353
9354 // Hide these postboxes.
9355 acf.getPostboxes().map(function (postbox) {
9356 if (data.visible.indexOf(postbox.get('id')) === -1) {
9357 // Hide postbox.
9358 postbox.hideDisable();
9359
9360 // Append to data.
9361 data.hidden.push(postbox.get('id'));
9362 }
9363 });
9364
9365 // Update style.
9366 $('#acf-style').html(data.style);
9367
9368 // Do action.
9369 acf.doAction('refresh_post_screen', data);
9370 },
9371 renderUserScreen: function (json) {}
9372 });
9373
9374 /**
9375 * gutenScreen
9376 *
9377 * Adds compatibility with the Gutenberg edit screen.
9378 *
9379 * @date 11/12/18
9380 * @since ACF 5.8.0
9381 *
9382 * @param void
9383 * @return void
9384 */
9385 var gutenScreen = new acf.Model({
9386 // Keep a reference to the most recent post attributes.
9387 postEdits: {},
9388 // Wait until assets have been loaded.
9389 wait: 'prepare',
9390 initialize: function () {
9391 // Bail early if not Gutenberg.
9392 if (!acf.isGutenbergPostEditor()) {
9393 return;
9394 }
9395
9396 // Listen for changes (use debounced version as this can fires often).
9397 wp.data.subscribe(acf.debounce(this.onChange).bind(this));
9398
9399 // Customize "acf.screen.get" functions.
9400 acf.screen.getPageTemplate = this.getPageTemplate;
9401 acf.screen.getPageParent = this.getPageParent;
9402 acf.screen.getPostType = this.getPostType;
9403 acf.screen.getPostFormat = this.getPostFormat;
9404 acf.screen.getPostCoreTerms = this.getPostCoreTerms;
9405
9406 // Disable unload
9407 acf.unload.disable();
9408
9409 // Refresh metaboxes since WP 5.3.
9410 this.addAction('refresh_post_screen', this.onRefreshPostScreen);
9411
9412 // Trigger "refresh" after WP has moved metaboxes into place.
9413 wp.domReady(acf.refresh);
9414 },
9415 onChange: function () {
9416 // Determine attributes that can trigger a refresh.
9417 var attributes = ['template', 'parent', 'format'];
9418
9419 // Append taxonomy attribute names to this list.
9420 (wp.data.select('core').getTaxonomies() || []).map(function (taxonomy) {
9421 attributes.push(taxonomy.rest_base);
9422 });
9423
9424 // Get relevant current post edits.
9425 var _postEdits = wp.data.select('core/editor').getPostEdits();
9426 var postEdits = {};
9427 attributes.map(function (k) {
9428 if (_postEdits[k] !== undefined) {
9429 postEdits[k] = _postEdits[k];
9430 }
9431 });
9432
9433 // Detect change.
9434 if (JSON.stringify(postEdits) !== JSON.stringify(this.postEdits)) {
9435 this.postEdits = postEdits;
9436
9437 // Check screen.
9438 acf.screen.check();
9439 }
9440 },
9441 getPageTemplate: function () {
9442 return wp.data.select('core/editor').getEditedPostAttribute('template');
9443 },
9444 getPageParent: function (e, $el) {
9445 return wp.data.select('core/editor').getEditedPostAttribute('parent');
9446 },
9447 getPostType: function () {
9448 return wp.data.select('core/editor').getEditedPostAttribute('type');
9449 },
9450 getPostFormat: function (e, $el) {
9451 return wp.data.select('core/editor').getEditedPostAttribute('format');
9452 },
9453 getPostCoreTerms: function () {
9454 // vars
9455 var terms = {};
9456
9457 // Loop over taxonomies.
9458 var taxonomies = wp.data.select('core').getTaxonomies() || [];
9459 taxonomies.map(function (taxonomy) {
9460 // Append selected taxonomies to terms object.
9461 var postTerms = wp.data.select('core/editor').getEditedPostAttribute(taxonomy.rest_base);
9462 if (postTerms) {
9463 terms[taxonomy.slug] = postTerms;
9464 }
9465 });
9466
9467 // return
9468 return terms;
9469 },
9470 /**
9471 * onRefreshPostScreen
9472 *
9473 * Fires after the Post edit screen metaboxs are refreshed to update the Block Editor API state.
9474 *
9475 * @date 11/11/19
9476 * @since ACF 5.8.7
9477 *
9478 * @param object data The "check_screen" JSON response data.
9479 * @return void
9480 */
9481 onRefreshPostScreen: function (data) {
9482 // Extract vars.
9483 var select = wp.data.select('core/edit-post');
9484 var dispatch = wp.data.dispatch('core/edit-post');
9485
9486 // Load current metabox locations and data.
9487 var locations = {};
9488 select.getActiveMetaBoxLocations().map(function (location) {
9489 locations[location] = select.getMetaBoxesPerLocation(location);
9490 });
9491
9492 // Generate flat array of existing ids.
9493 var ids = [];
9494 for (var k in locations) {
9495 locations[k].map(function (m) {
9496 ids.push(m.id);
9497 });
9498 }
9499
9500 // Append new ACF metaboxes (ignore those which already exist).
9501 data.results.filter(function (r) {
9502 return ids.indexOf(r.id) === -1;
9503 }).map(function (result, i) {
9504 // Ensure location exists.
9505 var location = result.position;
9506 locations[location] = locations[location] || [];
9507
9508 // Append.
9509 locations[location].push({
9510 id: result.id,
9511 title: result.title
9512 });
9513 });
9514
9515 // Remove hidden ACF metaboxes.
9516 for (var k in locations) {
9517 locations[k] = locations[k].filter(function (m) {
9518 return data.hidden.indexOf(m.id) === -1;
9519 });
9520 }
9521
9522 // Update state.
9523 dispatch.setAvailableMetaBoxesPerLocation(locations);
9524 }
9525 });
9526 })(jQuery);
9527
9528 /***/ }),
9529
9530 /***/ "./assets/src/js/_acf-select2.js":
9531 /*!***************************************!*\
9532 !*** ./assets/src/js/_acf-select2.js ***!
9533 \***************************************/
9534 /***/ (() => {
9535
9536 (function ($, undefined) {
9537 /**
9538 * acf.newSelect2
9539 *
9540 * description
9541 *
9542 * @date 13/1/18
9543 * @since ACF 5.6.5
9544 *
9545 * @param type $var Description. Default.
9546 * @return type Description.
9547 */
9548
9549 acf.newSelect2 = function ($select, props) {
9550 // defaults
9551 props = acf.parseArgs(props, {
9552 allowNull: false,
9553 placeholder: '',
9554 multiple: false,
9555 field: false,
9556 ajax: false,
9557 tags: false,
9558 ajaxAction: '',
9559 ajaxData: function (data) {
9560 return data;
9561 },
9562 ajaxResults: function (json) {
9563 return json;
9564 },
9565 escapeMarkup: false,
9566 templateSelection: false,
9567 templateResult: false,
9568 dropdownCssClass: '',
9569 suppressFilters: false
9570 });
9571
9572 // initialize
9573 if (getVersion() == 4) {
9574 var select2 = new Select2_4($select, props);
9575 } else {
9576 var select2 = new Select2_3($select, props);
9577 }
9578
9579 // actions
9580 acf.doAction('new_select2', select2);
9581
9582 // return
9583 return select2;
9584 };
9585
9586 /**
9587 * getVersion
9588 *
9589 * description
9590 *
9591 * @date 13/1/18
9592 * @since ACF 5.6.5
9593 *
9594 * @param type $var Description. Default.
9595 * @return type Description.
9596 */
9597
9598 function getVersion() {
9599 // v4
9600 if (acf.isset(window, 'jQuery', 'fn', 'select2', 'amd')) {
9601 return 4;
9602 }
9603
9604 // v3
9605 if (acf.isset(window, 'Select2')) {
9606 return 3;
9607 }
9608
9609 // return
9610 return false;
9611 }
9612
9613 /**
9614 * Select2
9615 *
9616 * description
9617 *
9618 * @date 13/1/18
9619 * @since ACF 5.6.5
9620 *
9621 * @param type $var Description. Default.
9622 * @return type Description.
9623 */
9624
9625 var Select2 = acf.Model.extend({
9626 setup: function ($select, props) {
9627 $.extend(this.data, props);
9628 this.$el = $select;
9629 },
9630 initialize: function () {},
9631 selectOption: function (value) {
9632 var $option = this.getOption(value);
9633 if (!$option.prop('selected')) {
9634 $option.prop('selected', true).trigger('change');
9635 }
9636 },
9637 unselectOption: function (value) {
9638 var $option = this.getOption(value);
9639 if ($option.prop('selected')) {
9640 $option.prop('selected', false).trigger('change');
9641 }
9642 },
9643 getOption: function (value) {
9644 return this.$('option[value="' + value + '"]');
9645 },
9646 addOption: function (option) {
9647 // defaults
9648 option = acf.parseArgs(option, {
9649 id: '',
9650 text: '',
9651 selected: false
9652 });
9653
9654 // vars
9655 var $option = this.getOption(option.id);
9656
9657 // append
9658 if (!$option.length) {
9659 $option = $('<option></option>');
9660 $option.html(option.text);
9661 $option.attr('value', option.id);
9662 $option.prop('selected', option.selected);
9663 this.$el.append($option);
9664 }
9665
9666 // chain
9667 return $option;
9668 },
9669 getValue: function () {
9670 // vars
9671 var val = [];
9672 var $options = this.$el.find('option:selected');
9673
9674 // bail early if no selected
9675 if (!$options.exists()) {
9676 return val;
9677 }
9678
9679 // sort by attribute
9680 $options = $options.sort(function (a, b) {
9681 return +a.getAttribute('data-i') - +b.getAttribute('data-i');
9682 });
9683
9684 // loop
9685 $options.each(function () {
9686 var $el = $(this);
9687 val.push({
9688 $el: $el,
9689 id: $el.attr('value'),
9690 text: $el.text()
9691 });
9692 });
9693
9694 // return
9695 return val;
9696 },
9697 mergeOptions: function () {},
9698 getChoices: function () {
9699 // callback
9700 var crawl = function ($parent) {
9701 // vars
9702 var choices = [];
9703
9704 // loop
9705 $parent.children().each(function () {
9706 // vars
9707 var $child = $(this);
9708
9709 // optgroup
9710 if ($child.is('optgroup')) {
9711 choices.push({
9712 text: $child.attr('label'),
9713 children: crawl($child)
9714 });
9715
9716 // option
9717 } else {
9718 choices.push({
9719 id: $child.attr('value'),
9720 text: $child.text()
9721 });
9722 }
9723 });
9724
9725 // return
9726 return choices;
9727 };
9728
9729 // crawl
9730 return crawl(this.$el);
9731 },
9732 getAjaxData: function (params) {
9733 // vars
9734 var ajaxData = {
9735 action: this.get('ajaxAction'),
9736 s: params.term || '',
9737 paged: params.page || 1
9738 };
9739
9740 // field helper
9741 var field = this.get('field');
9742 if (field) {
9743 ajaxData.field_key = field.get('key');
9744 if (field.get('nonce')) {
9745 ajaxData.nonce = field.get('nonce');
9746 }
9747 }
9748
9749 // callback
9750 var callback = this.get('ajaxData');
9751 if (callback) {
9752 ajaxData = callback.apply(this, [ajaxData, params]);
9753 }
9754
9755 // filter
9756 ajaxData = acf.applyFilters('select2_ajax_data', ajaxData, this.data, this.$el, field || false, this);
9757
9758 // return
9759 return acf.prepareForAjax(ajaxData);
9760 },
9761 getAjaxResults: function (json, params) {
9762 // defaults
9763 json = acf.parseArgs(json, {
9764 results: false,
9765 more: false
9766 });
9767
9768 // callback
9769 var callback = this.get('ajaxResults');
9770 if (callback) {
9771 json = callback.apply(this, [json, params]);
9772 }
9773
9774 // filter
9775 json = acf.applyFilters('select2_ajax_results', json, params, this);
9776
9777 // return
9778 return json;
9779 },
9780 processAjaxResults: function (json, params) {
9781 // vars
9782 var json = this.getAjaxResults(json, params);
9783
9784 // change more to pagination
9785 if (json.more) {
9786 json.pagination = {
9787 more: true
9788 };
9789 }
9790
9791 // merge together groups
9792 setTimeout($.proxy(this.mergeOptions, this), 1);
9793
9794 // return
9795 return json;
9796 },
9797 destroy: function () {
9798 // destroy via api
9799 if (this.$el.data('select2')) {
9800 this.$el.select2('destroy');
9801 }
9802
9803 // destroy via HTML (duplicating HTML does not contain data)
9804 this.$el.siblings('.select2-container').remove();
9805 }
9806 });
9807
9808 /**
9809 * Select2_4
9810 *
9811 * description
9812 *
9813 * @date 13/1/18
9814 * @since ACF 5.6.5
9815 *
9816 * @param type $var Description. Default.
9817 * @return type Description.
9818 */
9819
9820 var Select2_4 = Select2.extend({
9821 initialize: function () {
9822 // vars
9823 var $select = this.$el;
9824 var options = {
9825 width: '100%',
9826 allowClear: this.get('allowNull'),
9827 placeholder: this.get('placeholder'),
9828 multiple: this.get('multiple'),
9829 escapeMarkup: this.get('escapeMarkup'),
9830 templateSelection: this.get('templateSelection'),
9831 templateResult: this.get('templateResult'),
9832 dropdownCssClass: this.get('dropdownCssClass'),
9833 suppressFilters: this.get('suppressFilters'),
9834 data: []
9835 };
9836 if (this.get('tags')) {
9837 options.tags = true;
9838 options.tokenSeparators = [','];
9839 }
9840
9841 // Clear empty templateSelections, templateResults, or dropdownCssClass.
9842 if (!options.templateSelection) {
9843 delete options.templateSelection;
9844 }
9845 if (!options.templateResult) {
9846 delete options.templateResult;
9847 }
9848 if (!options.dropdownCssClass) {
9849 delete options.dropdownCssClass;
9850 }
9851
9852 // Only use the template if SelectWoo is not loaded to work around https://github.com/woocommerce/woocommerce/pull/30473
9853 if (!acf.isset(window, 'jQuery', 'fn', 'selectWoo')) {
9854 if (!options.templateSelection) {
9855 options.templateSelection = function (selection) {
9856 var $selection = $('<span class="acf-selection"></span>');
9857 $selection.html(options.escapeMarkup(selection.text));
9858 $selection.data('element', selection.element);
9859 return $selection;
9860 };
9861 }
9862 } else {
9863 delete options.templateSelection;
9864 delete options.templateResult;
9865 }
9866
9867 // Use a default, filterable escapeMarkup if not provided.
9868 if (!options.escapeMarkup) {
9869 options.escapeMarkup = function (markup) {
9870 if (typeof markup !== 'string') {
9871 return markup;
9872 }
9873 if (this.suppressFilters) {
9874 return acf.strEscape(markup);
9875 }
9876 return acf.applyFilters('select2_escape_markup', acf.strEscape(markup), markup, $select, this.data, field || false, this);
9877 };
9878 }
9879
9880 // multiple
9881 if (options.multiple) {
9882 // reorder options
9883 this.getValue().map(function (item) {
9884 item.$el.detach().appendTo($select);
9885 });
9886 }
9887
9888 // Temporarily remove conflicting attribute.
9889 var attrAjax = $select.attr('data-ajax');
9890 if (attrAjax !== undefined) {
9891 $select.removeData('ajax');
9892 $select.removeAttr('data-ajax');
9893 }
9894
9895 // ajax
9896 if (this.get('ajax')) {
9897 options.ajax = {
9898 url: acf.get('ajaxurl'),
9899 delay: 250,
9900 dataType: 'json',
9901 type: 'post',
9902 cache: false,
9903 data: $.proxy(this.getAjaxData, this),
9904 processResults: $.proxy(this.processAjaxResults, this)
9905 };
9906 }
9907
9908 // filter for 3rd party customization
9909 if (!options.suppressFilters) {
9910 var field = this.get('field');
9911 options = acf.applyFilters('select2_args', options, $select, this.data, field || false, this);
9912 }
9913 // add select2
9914 $select.select2(options);
9915
9916 // get container (Select2 v4 does not return this from constructor)
9917 var $container = $select.next('.select2-container');
9918
9919 // multiple
9920 if (options.multiple) {
9921 // vars
9922 var $ul = $container.find('ul');
9923
9924 // sortable
9925 $ul.sortable({
9926 stop: function (e) {
9927 // loop
9928 $ul.find('.select2-selection__choice').each(function () {
9929 // Attempt to use .data if it exists (select2 version < 4.0.6) or use our template data instead.
9930 if ($(this).data('data')) {
9931 var $option = $($(this).data('data').element);
9932 } else {
9933 var $option = $($(this).find('span.acf-selection').data('element'));
9934 }
9935
9936 // detach and re-append to end
9937 $option.detach().appendTo($select);
9938 });
9939
9940 // trigger change on input (JS error if trigger on select)
9941 $select.trigger('change');
9942 }
9943 });
9944
9945 // on select, move to end
9946 $select.on('select2:select', this.proxy(function (e) {
9947 this.getOption(e.params.data.id).detach().appendTo(this.$el);
9948 }));
9949 }
9950
9951 // add handler to auto-focus searchbox (for jQuery 3.6)
9952 $select.on('select2:open', () => {
9953 $('.select2-container--open .select2-search__field').get(-1).focus();
9954 });
9955
9956 // add class
9957 $container.addClass('-acf');
9958
9959 // Add back temporarily removed attr.
9960 if (attrAjax !== undefined) {
9961 $select.attr('data-ajax', attrAjax);
9962 }
9963
9964 // action for 3rd party customization
9965 if (!options.suppressFilters) {
9966 acf.doAction('select2_init', $select, options, this.data, field || false, this);
9967 }
9968 },
9969 mergeOptions: function () {
9970 // vars
9971 var $prevOptions = false;
9972 var $prevGroup = false;
9973
9974 // loop
9975 $('.select2-results__option[role="group"]').each(function () {
9976 // vars
9977 var $options = $(this).children('ul');
9978 var $group = $(this).children('strong');
9979
9980 // compare to previous
9981 if ($prevGroup && $prevGroup.text() === $group.text()) {
9982 $prevOptions.append($options.children());
9983 $(this).remove();
9984 return;
9985 }
9986
9987 // update vars
9988 $prevOptions = $options;
9989 $prevGroup = $group;
9990 });
9991 }
9992 });
9993
9994 /**
9995 * Select2_3
9996 *
9997 * description
9998 *
9999 * @date 13/1/18
10000 * @since ACF 5.6.5
10001 *
10002 * @param type $var Description. Default.
10003 * @return type Description.
10004 */
10005
10006 var Select2_3 = Select2.extend({
10007 initialize: function () {
10008 // vars
10009 var $select = this.$el;
10010 var value = this.getValue();
10011 var multiple = this.get('multiple');
10012 var options = {
10013 width: '100%',
10014 allowClear: this.get('allowNull'),
10015 placeholder: this.get('placeholder'),
10016 separator: '||',
10017 multiple: this.get('multiple'),
10018 data: this.getChoices(),
10019 escapeMarkup: function (string) {
10020 return acf.escHtml(string);
10021 },
10022 dropdownCss: {
10023 'z-index': '999999999'
10024 },
10025 initSelection: function (element, callback) {
10026 if (multiple) {
10027 callback(value);
10028 } else {
10029 callback(value.shift());
10030 }
10031 }
10032 };
10033 // get hidden input
10034 var $input = $select.siblings('input');
10035 if (!$input.length) {
10036 $input = $('<input type="hidden" />');
10037 $select.before($input);
10038 }
10039
10040 // set input value
10041 inputValue = value.map(function (item) {
10042 return item.id;
10043 }).join('||');
10044 $input.val(inputValue);
10045
10046 // multiple
10047 if (options.multiple) {
10048 // reorder options
10049 value.map(function (item) {
10050 item.$el.detach().appendTo($select);
10051 });
10052 }
10053
10054 // remove blank option as we have a clear all button
10055 if (options.allowClear) {
10056 options.data = options.data.filter(function (item) {
10057 return item.id !== '';
10058 });
10059 }
10060
10061 // remove conflicting atts
10062 $select.removeData('ajax');
10063 $select.removeAttr('data-ajax');
10064
10065 // ajax
10066 if (this.get('ajax')) {
10067 options.ajax = {
10068 url: acf.get('ajaxurl'),
10069 quietMillis: 250,
10070 dataType: 'json',
10071 type: 'post',
10072 cache: false,
10073 data: $.proxy(this.getAjaxData, this),
10074 results: $.proxy(this.processAjaxResults, this)
10075 };
10076 }
10077
10078 // filter for 3rd party customization
10079 var field = this.get('field');
10080 options = acf.applyFilters('select2_args', options, $select, this.data, field || false, this);
10081
10082 // add select2
10083 $input.select2(options);
10084
10085 // get container
10086 var $container = $input.select2('container');
10087
10088 // helper to find this select's option
10089 var getOption = $.proxy(this.getOption, this);
10090
10091 // multiple
10092 if (options.multiple) {
10093 // vars
10094 var $ul = $container.find('ul');
10095
10096 // sortable
10097 $ul.sortable({
10098 stop: function () {
10099 // loop
10100 $ul.find('.select2-search-choice').each(function () {
10101 // vars
10102 var data = $(this).data('select2Data');
10103 var $option = getOption(data.id);
10104
10105 // detach and re-append to end
10106 $option.detach().appendTo($select);
10107 });
10108
10109 // trigger change on input (JS error if trigger on select)
10110 $select.trigger('change');
10111 }
10112 });
10113 }
10114
10115 // on select, create option and move to end
10116 $input.on('select2-selecting', function (e) {
10117 // vars
10118 var item = e.choice;
10119 var $option = getOption(item.id);
10120
10121 // create if doesn't exist
10122 if (!$option.length) {
10123 $option = $('<option value="' + item.id + '">' + item.text + '</option>');
10124 }
10125
10126 // detach and re-append to end
10127 $option.detach().appendTo($select);
10128 });
10129
10130 // add class
10131 $container.addClass('-acf');
10132
10133 // action for 3rd party customization
10134 acf.doAction('select2_init', $select, options, this.data, field || false, this);
10135
10136 // change
10137 $input.on('change', function () {
10138 var val = $input.val();
10139 if (val.indexOf('||')) {
10140 val = val.split('||');
10141 }
10142 $select.val(val).trigger('change');
10143 });
10144
10145 // hide select
10146 $select.hide();
10147 },
10148 mergeOptions: function () {
10149 // vars
10150 var $prevOptions = false;
10151 var $prevGroup = false;
10152
10153 // loop
10154 $('#select2-drop .select2-result-with-children').each(function () {
10155 // vars
10156 var $options = $(this).children('ul');
10157 var $group = $(this).children('.select2-result-label');
10158
10159 // compare to previous
10160 if ($prevGroup && $prevGroup.text() === $group.text()) {
10161 $prevGroup.append($options.children());
10162 $(this).remove();
10163 return;
10164 }
10165
10166 // update vars
10167 $prevOptions = $options;
10168 $prevGroup = $group;
10169 });
10170 },
10171 getAjaxData: function (term, page) {
10172 // create Select2 v4 params
10173 var params = {
10174 term: term,
10175 page: page
10176 };
10177
10178 // filter
10179 var field = this.get('field');
10180 params = acf.applyFilters('select2_ajax_data', params, this.data, this.$el, field || false, this);
10181 // return
10182 return Select2.prototype.getAjaxData.apply(this, [params]);
10183 }
10184 });
10185
10186 // manager
10187 var select2Manager = new acf.Model({
10188 priority: 5,
10189 wait: 'prepare',
10190 actions: {
10191 duplicate: 'onDuplicate'
10192 },
10193 initialize: function () {
10194 // vars
10195 var locale = acf.get('locale');
10196 var rtl = acf.get('rtl');
10197 var l10n = acf.get('select2L10n');
10198 var version = getVersion();
10199
10200 // bail early if no l10n
10201 if (!l10n) {
10202 return false;
10203 }
10204
10205 // bail early if 'en'
10206 if (locale.indexOf('en') === 0) {
10207 return false;
10208 }
10209
10210 // initialize
10211 if (version == 4) {
10212 this.addTranslations4();
10213 } else if (version == 3) {
10214 this.addTranslations3();
10215 }
10216 },
10217 addTranslations4: function () {
10218 // vars
10219 var l10n = acf.get('select2L10n');
10220 var locale = acf.get('locale');
10221
10222 // modify local to match html[lang] attribute (used by Select2)
10223 locale = locale.replace('_', '-');
10224
10225 // select2L10n
10226 var select2L10n = {
10227 errorLoading: function () {
10228 return l10n.load_fail;
10229 },
10230 inputTooLong: function (args) {
10231 var overChars = args.input.length - args.maximum;
10232 if (overChars > 1) {
10233 return l10n.input_too_long_n.replace('%d', overChars);
10234 }
10235 return l10n.input_too_long_1;
10236 },
10237 inputTooShort: function (args) {
10238 var remainingChars = args.minimum - args.input.length;
10239 if (remainingChars > 1) {
10240 return l10n.input_too_short_n.replace('%d', remainingChars);
10241 }
10242 return l10n.input_too_short_1;
10243 },
10244 loadingMore: function () {
10245 return l10n.load_more;
10246 },
10247 maximumSelected: function (args) {
10248 var maximum = args.maximum;
10249 if (maximum > 1) {
10250 return l10n.selection_too_long_n.replace('%d', maximum);
10251 }
10252 return l10n.selection_too_long_1;
10253 },
10254 noResults: function () {
10255 return l10n.matches_0;
10256 },
10257 searching: function () {
10258 return l10n.searching;
10259 }
10260 };
10261
10262 // append
10263 jQuery.fn.select2.amd.define('select2/i18n/' + locale, [], function () {
10264 return select2L10n;
10265 });
10266 },
10267 addTranslations3: function () {
10268 // vars
10269 var l10n = acf.get('select2L10n');
10270 var locale = acf.get('locale');
10271
10272 // modify local to match html[lang] attribute (used by Select2)
10273 locale = locale.replace('_', '-');
10274
10275 // select2L10n
10276 var select2L10n = {
10277 formatMatches: function (matches) {
10278 if (matches > 1) {
10279 return l10n.matches_n.replace('%d', matches);
10280 }
10281 return l10n.matches_1;
10282 },
10283 formatNoMatches: function () {
10284 return l10n.matches_0;
10285 },
10286 formatAjaxError: function () {
10287 return l10n.load_fail;
10288 },
10289 formatInputTooShort: function (input, min) {
10290 var remainingChars = min - input.length;
10291 if (remainingChars > 1) {
10292 return l10n.input_too_short_n.replace('%d', remainingChars);
10293 }
10294 return l10n.input_too_short_1;
10295 },
10296 formatInputTooLong: function (input, max) {
10297 var overChars = input.length - max;
10298 if (overChars > 1) {
10299 return l10n.input_too_long_n.replace('%d', overChars);
10300 }
10301 return l10n.input_too_long_1;
10302 },
10303 formatSelectionTooBig: function (maximum) {
10304 if (maximum > 1) {
10305 return l10n.selection_too_long_n.replace('%d', maximum);
10306 }
10307 return l10n.selection_too_long_1;
10308 },
10309 formatLoadMore: function () {
10310 return l10n.load_more;
10311 },
10312 formatSearching: function () {
10313 return l10n.searching;
10314 }
10315 };
10316
10317 // ensure locales exists
10318 $.fn.select2.locales = $.fn.select2.locales || {};
10319
10320 // append
10321 $.fn.select2.locales[locale] = select2L10n;
10322 $.extend($.fn.select2.defaults, select2L10n);
10323 },
10324 onDuplicate: function ($el, $el2) {
10325 $el2.find('.select2-container').remove();
10326 }
10327 });
10328 })(jQuery);
10329
10330 /***/ }),
10331
10332 /***/ "./assets/src/js/_acf-tinymce.js":
10333 /*!***************************************!*\
10334 !*** ./assets/src/js/_acf-tinymce.js ***!
10335 \***************************************/
10336 /***/ (() => {
10337
10338 (function ($, undefined) {
10339 acf.tinymce = {
10340 /*
10341 * defaults
10342 *
10343 * This function will return default mce and qt settings
10344 *
10345 * @type function
10346 * @date 18/8/17
10347 * @since ACF 5.6.0
10348 *
10349 * @param $post_id (int)
10350 * @return $post_id (int)
10351 */
10352
10353 defaults: function () {
10354 // bail early if no tinyMCEPreInit
10355 if (typeof tinyMCEPreInit === 'undefined') return false;
10356
10357 // vars
10358 var defaults = {
10359 tinymce: tinyMCEPreInit.mceInit.acf_content,
10360 quicktags: tinyMCEPreInit.qtInit.acf_content
10361 };
10362
10363 // return
10364 return defaults;
10365 },
10366 /*
10367 * initialize
10368 *
10369 * This function will initialize the tinymce and quicktags instances
10370 *
10371 * @type function
10372 * @date 18/8/17
10373 * @since ACF 5.6.0
10374 *
10375 * @param $post_id (int)
10376 * @return $post_id (int)
10377 */
10378
10379 initialize: function (id, args) {
10380 // defaults
10381 args = acf.parseArgs(args, {
10382 tinymce: true,
10383 quicktags: true,
10384 toolbar: 'full',
10385 mode: 'visual',
10386 // visual,text
10387 field: false
10388 });
10389
10390 // tinymce
10391 if (args.tinymce) {
10392 this.initializeTinymce(id, args);
10393 }
10394
10395 // quicktags
10396 if (args.quicktags) {
10397 this.initializeQuicktags(id, args);
10398 }
10399 },
10400 /*
10401 * initializeTinymce
10402 *
10403 * This function will initialize the tinymce instance
10404 *
10405 * @type function
10406 * @date 18/8/17
10407 * @since ACF 5.6.0
10408 *
10409 * @param $post_id (int)
10410 * @return $post_id (int)
10411 */
10412
10413 initializeTinymce: function (id, args) {
10414 // vars
10415 var $textarea = $('#' + id);
10416 var defaults = this.defaults();
10417 var toolbars = acf.get('toolbars');
10418 var field = args.field || false;
10419 var $field = field.$el || false;
10420
10421 // bail early
10422 if (typeof tinymce === 'undefined') return false;
10423 if (!defaults) return false;
10424
10425 // check if exists
10426 if (tinymce.get(id)) {
10427 return this.enable(id);
10428 }
10429
10430 // settings
10431 var init = $.extend({}, defaults.tinymce, args.tinymce);
10432 init.id = id;
10433 init.selector = '#' + id;
10434
10435 // toolbar
10436 var toolbar = args.toolbar;
10437 if (toolbar && toolbars && toolbars[toolbar]) {
10438 for (var i = 1; i <= 4; i++) {
10439 init['toolbar' + i] = toolbars[toolbar][i] || '';
10440 }
10441 }
10442
10443 // event
10444 init.setup = function (ed) {
10445 ed.on('change', function (e) {
10446 ed.save(); // save to textarea
10447 if (!$textarea.closest('.attachment-info').length) {
10448 $textarea.trigger('change');
10449 }
10450 });
10451 ed.on('blur', function (e) {
10452 if ($textarea.closest('.attachment-info').length) {
10453 ed.save();
10454 $textarea.trigger('change');
10455 }
10456 });
10457
10458 // Fix bug where Gutenberg does not hear "mouseup" event and tries to select multiple blocks.
10459 ed.on('mouseup', function (e) {
10460 const event = new MouseEvent('mouseup');
10461 window.dispatchEvent(event);
10462 });
10463
10464 // Temporarily comment out. May not be necessary due to wysiwyg field actions.
10465 //ed.on('unload', function(e) {
10466 // acf.tinymce.remove( id );
10467 //});
10468 };
10469
10470 // disable wp_autoresize_on (no solution yet for fixed toolbar)
10471 init.wp_autoresize_on = false;
10472
10473 // Enable wpautop allowing value to save without <p> tags.
10474 // Only if the "TinyMCE Advanced" plugin hasn't already set this functionality.
10475 if (!init.tadv_noautop) {
10476 init.wpautop = true;
10477 }
10478
10479 // hook for 3rd party customization
10480 init = acf.applyFilters('wysiwyg_tinymce_settings', init, id, field);
10481
10482 // z-index fix (caused too many conflicts)
10483 //if( acf.isset(tinymce,'ui','FloatPanel') ) {
10484 // tinymce.ui.FloatPanel.zIndex = 900000;
10485 //}
10486
10487 // store settings
10488 tinyMCEPreInit.mceInit[id] = init;
10489
10490 // visual tab is active
10491 if (args.mode == 'visual') {
10492 // init
10493 var result = tinymce.init(init);
10494
10495 // get editor
10496 var ed = tinymce.get(id);
10497
10498 // validate
10499 if (!ed) {
10500 return false;
10501 }
10502
10503 // add reference
10504 ed.acf = args.field;
10505
10506 // action
10507 acf.doAction('wysiwyg_tinymce_init', ed, ed.id, init, field);
10508 }
10509 },
10510 /*
10511 * initializeQuicktags
10512 *
10513 * This function will initialize the quicktags instance
10514 *
10515 * @type function
10516 * @date 18/8/17
10517 * @since ACF 5.6.0
10518 *
10519 * @param $post_id (int)
10520 * @return $post_id (int)
10521 */
10522
10523 initializeQuicktags: function (id, args) {
10524 // vars
10525 var defaults = this.defaults();
10526
10527 // bail early
10528 if (typeof quicktags === 'undefined') return false;
10529 if (!defaults) return false;
10530
10531 // settings
10532 var init = $.extend({}, defaults.quicktags, args.quicktags);
10533 init.id = id;
10534
10535 // filter
10536 var field = args.field || false;
10537 var $field = field.$el || false;
10538 init = acf.applyFilters('wysiwyg_quicktags_settings', init, init.id, field);
10539
10540 // store settings
10541 tinyMCEPreInit.qtInit[id] = init;
10542
10543 // init
10544 var ed = quicktags(init);
10545
10546 // validate
10547 if (!ed) {
10548 return false;
10549 }
10550
10551 // generate HTML
10552 this.buildQuicktags(ed);
10553
10554 // action for 3rd party customization
10555 acf.doAction('wysiwyg_quicktags_init', ed, ed.id, init, field);
10556 },
10557 /*
10558 * buildQuicktags
10559 *
10560 * This function will build the quicktags HTML
10561 *
10562 * @type function
10563 * @date 18/8/17
10564 * @since ACF 5.6.0
10565 *
10566 * @param $post_id (int)
10567 * @return $post_id (int)
10568 */
10569
10570 buildQuicktags: function (ed) {
10571 var canvas,
10572 name,
10573 settings,
10574 theButtons,
10575 html,
10576 ed,
10577 id,
10578 i,
10579 use,
10580 instanceId,
10581 defaults = ',strong,em,link,block,del,ins,img,ul,ol,li,code,more,close,';
10582 canvas = ed.canvas;
10583 name = ed.name;
10584 settings = ed.settings;
10585 html = '';
10586 theButtons = {};
10587 use = '';
10588 instanceId = ed.id;
10589
10590 // set buttons
10591 if (settings.buttons) {
10592 use = ',' + settings.buttons + ',';
10593 }
10594 for (i in edButtons) {
10595 if (!edButtons[i]) {
10596 continue;
10597 }
10598 id = edButtons[i].id;
10599 if (use && defaults.indexOf(',' + id + ',') !== -1 && use.indexOf(',' + id + ',') === -1) {
10600 continue;
10601 }
10602 if (!edButtons[i].instance || edButtons[i].instance === instanceId) {
10603 theButtons[id] = edButtons[i];
10604 if (edButtons[i].html) {
10605 html += edButtons[i].html(name + '_');
10606 }
10607 }
10608 }
10609 if (use && use.indexOf(',dfw,') !== -1) {
10610 theButtons.dfw = new QTags.DFWButton();
10611 html += theButtons.dfw.html(name + '_');
10612 }
10613 if ('rtl' === document.getElementsByTagName('html')[0].dir) {
10614 theButtons.textdirection = new QTags.TextDirectionButton();
10615 html += theButtons.textdirection.html(name + '_');
10616 }
10617 ed.toolbar.innerHTML = html;
10618 ed.theButtons = theButtons;
10619 if (typeof jQuery !== 'undefined') {
10620 jQuery(document).triggerHandler('quicktags-init', [ed]);
10621 }
10622 },
10623 disable: function (id) {
10624 this.destroyTinymce(id);
10625 },
10626 remove: function (id) {
10627 this.destroyTinymce(id);
10628 },
10629 destroy: function (id) {
10630 this.destroyTinymce(id);
10631 },
10632 destroyTinymce: function (id) {
10633 // bail early
10634 if (typeof tinymce === 'undefined') return false;
10635
10636 // get editor
10637 var ed = tinymce.get(id);
10638
10639 // bail early if no editor
10640 if (!ed) return false;
10641
10642 // save
10643 ed.save();
10644
10645 // destroy editor
10646 ed.destroy();
10647
10648 // return
10649 return true;
10650 },
10651 enable: function (id) {
10652 this.enableTinymce(id);
10653 },
10654 enableTinymce: function (id) {
10655 // bail early
10656 if (typeof switchEditors === 'undefined') return false;
10657
10658 // bail early if not initialized
10659 if (typeof tinyMCEPreInit.mceInit[id] === 'undefined') return false;
10660
10661 // Ensure textarea element is visible
10662 // - Fixes bug in block editor when switching between "Block" and "Document" tabs.
10663 if (!tinymce.get(id)) {
10664 $('#' + id).show();
10665 }
10666
10667 // toggle
10668 switchEditors.go(id, 'tmce');
10669
10670 // return
10671 return true;
10672 }
10673 };
10674 var editorManager = new acf.Model({
10675 // hook in before fieldsEventManager, conditions, etc
10676 priority: 5,
10677 actions: {
10678 prepare: 'onPrepare',
10679 ready: 'onReady'
10680 },
10681 onPrepare: function () {
10682 // find hidden editor which may exist within a field
10683 var $div = $('#acf-hidden-wp-editor');
10684
10685 // move to footer
10686 if ($div.exists()) {
10687 $div.appendTo('body');
10688 }
10689 },
10690 onReady: function () {
10691 // Restore wp.editor functions used by tinymce removed in WP5.
10692 if (acf.isset(window, 'wp', 'oldEditor')) {
10693 wp.editor.autop = wp.oldEditor.autop;
10694 wp.editor.removep = wp.oldEditor.removep;
10695 }
10696
10697 // bail early if no tinymce
10698 if (!acf.isset(window, 'tinymce', 'on')) return;
10699
10700 // restore default activeEditor
10701 tinymce.on('AddEditor', function (data) {
10702 // vars
10703 var editor = data.editor;
10704
10705 // bail early if not 'acf'
10706 if (editor.id.substr(0, 3) !== 'acf') return;
10707
10708 // override if 'content' exists
10709 editor = tinymce.editors.content || editor;
10710
10711 // update vars
10712 tinymce.activeEditor = editor;
10713 wpActiveEditor = editor.id;
10714 });
10715 }
10716 });
10717 })(jQuery);
10718
10719 /***/ }),
10720
10721 /***/ "./assets/src/js/_acf-unload.js":
10722 /*!**************************************!*\
10723 !*** ./assets/src/js/_acf-unload.js ***!
10724 \**************************************/
10725 /***/ (() => {
10726
10727 (function ($, undefined) {
10728 acf.unload = new acf.Model({
10729 wait: 'load',
10730 active: true,
10731 changed: false,
10732 actions: {
10733 validation_failure: 'startListening',
10734 validation_success: 'stopListening'
10735 },
10736 events: {
10737 'change form .acf-field': 'startListening',
10738 'submit form': 'stopListening'
10739 },
10740 enable: function () {
10741 this.active = true;
10742 },
10743 disable: function () {
10744 this.active = false;
10745 },
10746 reset: function () {
10747 this.stopListening();
10748 },
10749 startListening: function () {
10750 // bail early if already changed, not active
10751 if (this.changed || !this.active) {
10752 return;
10753 }
10754
10755 // update
10756 this.changed = true;
10757
10758 // add event
10759 $(window).on('beforeunload', this.onUnload);
10760 },
10761 stopListening: function () {
10762 // update
10763 this.changed = false;
10764
10765 // remove event
10766 $(window).off('beforeunload', this.onUnload);
10767 },
10768 onUnload: function () {
10769 return acf.__('The changes you made will be lost if you navigate away from this page');
10770 }
10771 });
10772 })(jQuery);
10773
10774 /***/ }),
10775
10776 /***/ "./assets/src/js/_acf-validation.js":
10777 /*!******************************************!*\
10778 !*** ./assets/src/js/_acf-validation.js ***!
10779 \******************************************/
10780 /***/ (() => {
10781
10782 (function ($, undefined) {
10783 /**
10784 * Validator
10785 *
10786 * The model for validating forms
10787 *
10788 * @date 4/9/18
10789 * @since ACF 5.7.5
10790 *
10791 * @param void
10792 * @return void
10793 */
10794 var Validator = acf.Model.extend({
10795 /** @var string The model identifier. */
10796 id: 'Validator',
10797 /** @var object The model data. */
10798 data: {
10799 /** @var array The form errors. */
10800 errors: [],
10801 /** @var object The form notice. */
10802 notice: null,
10803 /** @var string The form status. loading, invalid, valid */
10804 status: ''
10805 },
10806 /** @var object The model events. */
10807 events: {
10808 'changed:status': 'onChangeStatus'
10809 },
10810 /**
10811 * addErrors
10812 *
10813 * Adds errors to the form.
10814 *
10815 * @date 4/9/18
10816 * @since ACF 5.7.5
10817 *
10818 * @param array errors An array of errors.
10819 * @return void
10820 */
10821 addErrors: function (errors) {
10822 errors.map(this.addError, this);
10823 },
10824 /**
10825 * addError
10826 *
10827 * Adds and error to the form.
10828 *
10829 * @date 4/9/18
10830 * @since ACF 5.7.5
10831 *
10832 * @param object error An error object containing input and message.
10833 * @return void
10834 */
10835 addError: function (error) {
10836 this.data.errors.push(error);
10837 },
10838 /**
10839 * hasErrors
10840 *
10841 * Returns true if the form has errors.
10842 *
10843 * @date 4/9/18
10844 * @since ACF 5.7.5
10845 *
10846 * @param void
10847 * @return bool
10848 */
10849 hasErrors: function () {
10850 return this.data.errors.length;
10851 },
10852 /**
10853 * clearErrors
10854 *
10855 * Removes any errors.
10856 *
10857 * @date 4/9/18
10858 * @since ACF 5.7.5
10859 *
10860 * @param void
10861 * @return void
10862 */
10863 clearErrors: function () {
10864 return this.data.errors = [];
10865 },
10866 /**
10867 * getErrors
10868 *
10869 * Returns the forms errors.
10870 *
10871 * @date 4/9/18
10872 * @since ACF 5.7.5
10873 *
10874 * @param void
10875 * @return array
10876 */
10877 getErrors: function () {
10878 return this.data.errors;
10879 },
10880 /**
10881 * getFieldErrors
10882 *
10883 * Returns the forms field errors.
10884 *
10885 * @date 4/9/18
10886 * @since ACF 5.7.5
10887 *
10888 * @param void
10889 * @return array
10890 */
10891 getFieldErrors: function () {
10892 // vars
10893 var errors = [];
10894 var inputs = [];
10895
10896 // loop
10897 this.getErrors().map(function (error) {
10898 // bail early if global
10899 if (!error.input) return;
10900
10901 // update if exists
10902 var i = inputs.indexOf(error.input);
10903 if (i > -1) {
10904 errors[i] = error;
10905
10906 // update
10907 } else {
10908 errors.push(error);
10909 inputs.push(error.input);
10910 }
10911 });
10912
10913 // return
10914 return errors;
10915 },
10916 /**
10917 * getGlobalErrors
10918 *
10919 * Returns the forms global errors (errors without a specific input).
10920 *
10921 * @date 4/9/18
10922 * @since ACF 5.7.5
10923 *
10924 * @param void
10925 * @return array
10926 */
10927 getGlobalErrors: function () {
10928 // return array of errors that contain no input
10929 return this.getErrors().filter(function (error) {
10930 return !error.input;
10931 });
10932 },
10933 /**
10934 * showErrors
10935 *
10936 * Displays all errors for this form.
10937 *
10938 * @since ACF 5.7.5
10939 *
10940 * @param {string} [location=before] - The location to add the error, before or after the input. Default before. Since ACF 6.3.
10941 * @return void
10942 */
10943 showErrors: function (location = 'before') {
10944 // bail early if no errors
10945 if (!this.hasErrors()) {
10946 return;
10947 }
10948
10949 // vars
10950 var fieldErrors = this.getFieldErrors();
10951 var globalErrors = this.getGlobalErrors();
10952
10953 // vars
10954 var errorCount = 0;
10955 var $scrollTo = false;
10956
10957 // loop
10958 fieldErrors.map(function (error) {
10959 // get input
10960 var $input = this.$('[name="' + error.input + '"]').first();
10961
10962 // if $_POST value was an array, this $input may not exist
10963 if (!$input.length) {
10964 $input = this.$('[name^="' + error.input + '"]').first();
10965 }
10966
10967 // bail early if input doesn't exist
10968 if (!$input.length) {
10969 return;
10970 }
10971
10972 // increase
10973 errorCount++;
10974
10975 // get field
10976 var field = acf.getClosestField($input);
10977
10978 // make sure the postbox containing this field is not hidden by screen options
10979 ensureFieldPostBoxIsVisible(field.$el);
10980
10981 // show error
10982 field.showError(error.message, location);
10983
10984 // set $scrollTo
10985 if (!$scrollTo) {
10986 $scrollTo = field.$el;
10987 }
10988 }, this);
10989
10990 // errorMessage
10991 var errorMessage = acf.__('Validation failed');
10992 globalErrors.map(function (error) {
10993 errorMessage += '. ' + error.message;
10994 });
10995 if (errorCount == 1) {
10996 errorMessage += '. ' + acf.__('1 field requires attention');
10997 } else if (errorCount > 1) {
10998 errorMessage += '. ' + acf.__('%d fields require attention').replace('%d', errorCount);
10999 }
11000
11001 // notice
11002 if (this.has('notice')) {
11003 this.get('notice').update({
11004 type: 'error',
11005 text: errorMessage
11006 });
11007 } else {
11008 var notice = acf.newNotice({
11009 type: 'error',
11010 text: errorMessage,
11011 target: this.$el
11012 });
11013 this.set('notice', notice);
11014 }
11015
11016 // If in a modal, don't try to scroll.
11017 if (this.$el.parents('.acf-popup-box').length) {
11018 return;
11019 }
11020
11021 // if no $scrollTo, set to message
11022 if (!$scrollTo) {
11023 $scrollTo = this.get('notice').$el;
11024 }
11025
11026 // timeout
11027 setTimeout(function () {
11028 $('html, body').animate({
11029 scrollTop: $scrollTo.offset().top - $(window).height() / 2
11030 }, 500);
11031 }, 10);
11032 },
11033 /**
11034 * onChangeStatus
11035 *
11036 * Update the form class when changing the 'status' data
11037 *
11038 * @date 4/9/18
11039 * @since ACF 5.7.5
11040 *
11041 * @param object e The event object.
11042 * @param jQuery $el The form element.
11043 * @param string value The new status.
11044 * @param string prevValue The old status.
11045 * @return void
11046 */
11047 onChangeStatus: function (e, $el, value, prevValue) {
11048 this.$el.removeClass('is-' + prevValue).addClass('is-' + value);
11049 },
11050 /**
11051 * validate
11052 *
11053 * Validates the form via AJAX.
11054 *
11055 * @date 4/9/18
11056 * @since ACF 5.7.5
11057 *
11058 * @param object args A list of settings to customize the validation process.
11059 * @return bool True if the form is valid.
11060 */
11061 validate: function (args) {
11062 // default args
11063 args = acf.parseArgs(args, {
11064 // trigger event
11065 event: false,
11066 // reset the form after submit
11067 reset: false,
11068 // loading callback
11069 loading: function () {},
11070 // complete callback
11071 complete: function () {},
11072 // failure callback
11073 failure: function () {},
11074 // success callback
11075 success: function ($form) {
11076 $form.submit();
11077 }
11078 });
11079
11080 // return true if is valid - allows form submit
11081 if (this.get('status') == 'valid') {
11082 return true;
11083 }
11084
11085 // return false if is currently validating - prevents form submit
11086 if (this.get('status') == 'validating') {
11087 return false;
11088 }
11089
11090 // return true if no ACF fields exist (no need to validate)
11091 if (!this.$('.acf-field').length) {
11092 return true;
11093 }
11094
11095 // if event is provided, create a new success callback.
11096 if (args.event) {
11097 var event = $.Event(null, args.event);
11098 args.success = function () {
11099 acf.enableSubmit($(event.target)).trigger(event);
11100 };
11101 }
11102
11103 // action for 3rd party
11104 acf.doAction('validation_begin', this.$el);
11105
11106 // lock form
11107 acf.lockForm(this.$el);
11108
11109 // loading callback
11110 args.loading(this.$el, this);
11111
11112 // update status
11113 this.set('status', 'validating');
11114
11115 // success callback
11116 var onSuccess = function (json) {
11117 // validate
11118 if (!acf.isAjaxSuccess(json)) {
11119 return;
11120 }
11121
11122 // filter
11123 var data = acf.applyFilters('validation_complete', json.data, this.$el, this);
11124
11125 // add errors
11126 if (!data.valid) {
11127 this.addErrors(data.errors);
11128 }
11129 };
11130
11131 // complete
11132 var onComplete = function () {
11133 // unlock form
11134 acf.unlockForm(this.$el);
11135
11136 // failure
11137 if (this.hasErrors()) {
11138 // update status
11139 this.set('status', 'invalid');
11140
11141 // action
11142 acf.doAction('validation_failure', this.$el, this);
11143
11144 // display errors
11145 this.showErrors();
11146
11147 // failure callback
11148 args.failure(this.$el, this);
11149
11150 // success
11151 } else {
11152 // update status
11153 this.set('status', 'valid');
11154
11155 // remove previous error message
11156 if (this.has('notice')) {
11157 this.get('notice').update({
11158 type: 'success',
11159 text: acf.__('Validation successful'),
11160 timeout: 1000
11161 });
11162 }
11163
11164 // action
11165 acf.doAction('validation_success', this.$el, this);
11166 acf.doAction('submit', this.$el);
11167
11168 // success callback (submit form)
11169 args.success(this.$el, this);
11170
11171 // lock form
11172 acf.lockForm(this.$el);
11173
11174 // reset
11175 if (args.reset) {
11176 this.reset();
11177 }
11178 }
11179
11180 // complete callback
11181 args.complete(this.$el, this);
11182
11183 // clear errors
11184 this.clearErrors();
11185 };
11186
11187 // serialize form data
11188 var data = acf.serialize(this.$el);
11189 data.action = 'acf/validate_save_post';
11190
11191 // ajax
11192 $.ajax({
11193 url: acf.get('ajaxurl'),
11194 data: acf.prepareForAjax(data, true),
11195 type: 'post',
11196 dataType: 'json',
11197 context: this,
11198 success: onSuccess,
11199 complete: onComplete
11200 });
11201
11202 // return false to fail validation and allow AJAX
11203 return false;
11204 },
11205 /**
11206 * setup
11207 *
11208 * Called during the constructor function to setup this instance
11209 *
11210 * @date 4/9/18
11211 * @since ACF 5.7.5
11212 *
11213 * @param jQuery $form The form element.
11214 * @return void
11215 */
11216 setup: function ($form) {
11217 // set $el
11218 this.$el = $form;
11219 },
11220 /**
11221 * reset
11222 *
11223 * Rests the validation to be used again.
11224 *
11225 * @date 6/9/18
11226 * @since ACF 5.7.5
11227 *
11228 * @param void
11229 * @return void
11230 */
11231 reset: function () {
11232 // reset data
11233 this.set('errors', []);
11234 this.set('notice', null);
11235 this.set('status', '');
11236
11237 // unlock form
11238 acf.unlockForm(this.$el);
11239 }
11240 });
11241
11242 /**
11243 * getValidator
11244 *
11245 * Returns the instance for a given form element.
11246 *
11247 * @date 4/9/18
11248 * @since ACF 5.7.5
11249 *
11250 * @param jQuery $el The form element.
11251 * @return object
11252 */
11253 var getValidator = function ($el) {
11254 // instantiate
11255 var validator = $el.data('acf');
11256 if (!validator) {
11257 validator = new Validator($el);
11258 }
11259
11260 // return
11261 return validator;
11262 };
11263
11264 /**
11265 * A helper function to generate a Validator for a block form, so .addErrors can be run via block logic.
11266 *
11267 * @since ACF 6.3
11268 *
11269 * @param $el The jQuery block form wrapper element.
11270 * @return bool
11271 */
11272 acf.getBlockFormValidator = function ($el) {
11273 return getValidator($el);
11274 };
11275
11276 /**
11277 * A helper function for the Validator.validate() function.
11278 * Returns true if form is valid, or fetches a validation request and returns false.
11279 *
11280 * @since ACF 5.6.9
11281 *
11282 * @param object args A list of settings to customize the validation process.
11283 * @return bool
11284 */
11285 acf.validateForm = function (args) {
11286 return getValidator(args.form).validate(args);
11287 };
11288
11289 /**
11290 * acf.enableSubmit
11291 *
11292 * Enables a submit button and returns the element.
11293 *
11294 * @date 30/8/18
11295 * @since ACF 5.7.4
11296 *
11297 * @param jQuery $submit The submit button.
11298 * @return jQuery
11299 */
11300 acf.enableSubmit = function ($submit) {
11301 return $submit.removeClass('disabled').removeAttr('disabled');
11302 };
11303
11304 /**
11305 * acf.disableSubmit
11306 *
11307 * Disables a submit button and returns the element.
11308 *
11309 * @date 30/8/18
11310 * @since ACF 5.7.4
11311 *
11312 * @param jQuery $submit The submit button.
11313 * @return jQuery
11314 */
11315 acf.disableSubmit = function ($submit) {
11316 return $submit.addClass('disabled').attr('disabled', true);
11317 };
11318
11319 /**
11320 * acf.showSpinner
11321 *
11322 * Shows the spinner element.
11323 *
11324 * @date 4/9/18
11325 * @since ACF 5.7.5
11326 *
11327 * @param jQuery $spinner The spinner element.
11328 * @return jQuery
11329 */
11330 acf.showSpinner = function ($spinner) {
11331 $spinner.addClass('is-active'); // add class (WP > 4.2)
11332 $spinner.css('display', 'inline-block'); // css (WP < 4.2)
11333 return $spinner;
11334 };
11335
11336 /**
11337 * acf.hideSpinner
11338 *
11339 * Hides the spinner element.
11340 *
11341 * @date 4/9/18
11342 * @since ACF 5.7.5
11343 *
11344 * @param jQuery $spinner The spinner element.
11345 * @return jQuery
11346 */
11347 acf.hideSpinner = function ($spinner) {
11348 $spinner.removeClass('is-active'); // add class (WP > 4.2)
11349 $spinner.css('display', 'none'); // css (WP < 4.2)
11350 return $spinner;
11351 };
11352
11353 /**
11354 * acf.lockForm
11355 *
11356 * Locks a form by disabling its primary inputs and showing a spinner.
11357 *
11358 * @date 4/9/18
11359 * @since ACF 5.7.5
11360 *
11361 * @param jQuery $form The form element.
11362 * @return jQuery
11363 */
11364 acf.lockForm = function ($form) {
11365 // vars
11366 var $wrap = findSubmitWrap($form);
11367 var $submit = $wrap.find('.button, [type="submit"]').not('.acf-nav, .acf-repeater-add-row');
11368 var $spinner = $wrap.find('.spinner, .acf-spinner');
11369
11370 // hide all spinners (hides the preview spinner)
11371 acf.hideSpinner($spinner);
11372
11373 // lock
11374 acf.disableSubmit($submit);
11375 acf.showSpinner($spinner.last());
11376 return $form;
11377 };
11378
11379 /**
11380 * acf.unlockForm
11381 *
11382 * Unlocks a form by enabling its primary inputs and hiding all spinners.
11383 *
11384 * @date 4/9/18
11385 * @since ACF 5.7.5
11386 *
11387 * @param jQuery $form The form element.
11388 * @return jQuery
11389 */
11390 acf.unlockForm = function ($form) {
11391 // vars
11392 var $wrap = findSubmitWrap($form);
11393 var $submit = $wrap.find('.button, [type="submit"]').not('.acf-nav, .acf-repeater-add-row');
11394 var $spinner = $wrap.find('.spinner, .acf-spinner');
11395
11396 // unlock
11397 acf.enableSubmit($submit);
11398 acf.hideSpinner($spinner);
11399 return $form;
11400 };
11401
11402 /**
11403 * findSubmitWrap
11404 *
11405 * An internal function to find the 'primary' form submit wrapping element.
11406 *
11407 * @date 4/9/18
11408 * @since ACF 5.7.5
11409 *
11410 * @param jQuery $form The form element.
11411 * @return jQuery
11412 */
11413 var findSubmitWrap = function ($form) {
11414 // default post submit div
11415 var $wrap = $form.find('#submitdiv');
11416 if ($wrap.length) {
11417 return $wrap;
11418 }
11419
11420 // 3rd party publish box
11421 var $wrap = $form.find('#submitpost');
11422 if ($wrap.length) {
11423 return $wrap;
11424 }
11425
11426 // term, user
11427 var $wrap = $form.find('p.submit').last();
11428 if ($wrap.length) {
11429 return $wrap;
11430 }
11431
11432 // front end form
11433 var $wrap = $form.find('.acf-form-submit');
11434 if ($wrap.length) {
11435 return $wrap;
11436 }
11437
11438 // ACF 6.2 options page modal
11439 var $wrap = $('#acf-create-options-page-form .acf-actions');
11440 if ($wrap.length) {
11441 return $wrap;
11442 }
11443
11444 // ACF 6.0+ headerbar submit
11445 var $wrap = $('.acf-headerbar-actions');
11446 if ($wrap.length) {
11447 return $wrap;
11448 }
11449
11450 // default
11451 return $form;
11452 };
11453
11454 /**
11455 * A debounced function to trigger a form submission.
11456 *
11457 * @date 15/07/2020
11458 * @since ACF 5.9.0
11459 *
11460 * @param type Var Description.
11461 * @return type Description.
11462 */
11463 var submitFormDebounced = acf.debounce(function ($form) {
11464 $form.submit();
11465 });
11466
11467 /**
11468 * Ensure field is visible for validation errors
11469 *
11470 * @date 20/10/2021
11471 * @since ACF 5.11.0
11472 */
11473 var ensureFieldPostBoxIsVisible = function ($el) {
11474 // Find the postbox element containing this field.
11475 var $postbox = $el.parents('.acf-postbox');
11476 if ($postbox.length) {
11477 var acf_postbox = acf.getPostbox($postbox);
11478 if (acf_postbox && acf_postbox.isHiddenByScreenOptions()) {
11479 // Rather than using .show() here, we don't want the field to appear next reload.
11480 // So just temporarily show the field group so validation can complete.
11481 acf_postbox.$el.removeClass('hide-if-js');
11482 acf_postbox.$el.css('display', '');
11483 }
11484 }
11485 };
11486
11487 /**
11488 * Ensure metaboxes which contain browser validation failures are visible.
11489 *
11490 * @date 20/10/2021
11491 * @since ACF 5.11.0
11492 *
11493 * @param {jQuery} [$form] - Optional form element to scope the input search to. If omitted, searches the entire document.
11494 */
11495 const ensureInvalidFieldVisibility = function ($form) {
11496 // Load each ACF input field and check its browser validation state.
11497 // Scope to the given form if provided, otherwise search the entire document.
11498 const $inputs = $form ? $form.find('.acf-field input') : $('.acf-field input');
11499 $inputs.each(function () {
11500 // Use validity.valid (a property) instead of checkValidity() (a method) to avoid
11501 // dispatching the native 'invalid' event, which can trigger ACF validation prematurely.
11502 if (!this.validity.valid) {
11503 // Field is invalid, so we need to make sure its metabox is visible.
11504 ensureFieldPostBoxIsVisible($(this));
11505 }
11506 });
11507 };
11508
11509 /**
11510 * acf.validation
11511 *
11512 * Global validation logic
11513 *
11514 * @date 4/4/18
11515 * @since ACF 5.6.9
11516 *
11517 * @param void
11518 * @return void
11519 */
11520
11521 acf.validation = new acf.Model({
11522 /** @var string The model identifier. */
11523 id: 'validation',
11524 /** @var bool The active state. Set to false before 'prepare' to prevent validation. */
11525 active: true,
11526 /** @var string The model initialize time. */
11527 wait: 'prepare',
11528 /** @var object The model actions. */
11529 actions: {
11530 ready: 'addInputEvents',
11531 append: 'addInputEvents'
11532 },
11533 /** @var object The model events. */
11534 events: {
11535 'click input[type="submit"]': 'onClickSubmit',
11536 'click button[type="submit"]': 'onClickSubmit',
11537 'click #save-post': 'onClickSave',
11538 'submit form#post': 'onSubmitPost',
11539 'submit form': 'onSubmit'
11540 },
11541 /**
11542 * initialize
11543 *
11544 * Called when initializing the model.
11545 *
11546 * @date 4/9/18
11547 * @since ACF 5.7.5
11548 *
11549 * @param void
11550 * @return void
11551 */
11552 initialize: function () {
11553 // check 'validation' setting
11554 if (!acf.get('validation')) {
11555 this.active = false;
11556 this.actions = {};
11557 this.events = {};
11558 }
11559 },
11560 /**
11561 * enable
11562 *
11563 * Enables validation.
11564 *
11565 * @date 4/9/18
11566 * @since ACF 5.7.5
11567 *
11568 * @param void
11569 * @return void
11570 */
11571 enable: function () {
11572 this.active = true;
11573 },
11574 /**
11575 * disable
11576 *
11577 * Disables validation.
11578 *
11579 * @date 4/9/18
11580 * @since ACF 5.7.5
11581 *
11582 * @param void
11583 * @return void
11584 */
11585 disable: function () {
11586 this.active = false;
11587 },
11588 /**
11589 * reset
11590 *
11591 * Rests the form validation to be used again
11592 *
11593 * @date 6/9/18
11594 * @since ACF 5.7.5
11595 *
11596 * @param jQuery $form The form element.
11597 * @return void
11598 */
11599 reset: function ($form) {
11600 getValidator($form).reset();
11601 },
11602 /**
11603 * addInputEvents
11604 *
11605 * Adds 'invalid' event listeners to HTML inputs.
11606 *
11607 * @date 4/9/18
11608 * @since ACF 5.7.5
11609 *
11610 * @param jQuery $el The element being added / readied.
11611 * @return void
11612 */
11613 addInputEvents: function ($el) {
11614 // Bug exists in Safari where custom "invalid" handling prevents draft from saving.
11615 if (acf.get('browser') === 'safari') return;
11616
11617 // vars
11618 var $inputs = $('.acf-field [name]', $el);
11619
11620 // check
11621 if ($inputs.length) {
11622 this.on($inputs, 'invalid', 'onInvalid');
11623 }
11624 },
11625 /**
11626 * onInvalid
11627 *
11628 * Callback for the 'invalid' event.
11629 *
11630 * @date 4/9/18
11631 * @since ACF 5.7.5
11632 *
11633 * @param object e The event object.
11634 * @param jQuery $el The input element.
11635 * @return void
11636 */
11637 onInvalid: function (e, $el) {
11638 // prevent default
11639 // - prevents browser error message
11640 // - also fixes chrome bug where 'hidden-by-tab' field throws focus error
11641 e.preventDefault();
11642
11643 // vars
11644 var $form = $el.closest('form');
11645
11646 // check form exists
11647 if ($form.length) {
11648 // add error to validator
11649 getValidator($form).addError({
11650 input: $el.attr('name'),
11651 message: acf.strEscape(e.target.validationMessage)
11652 });
11653
11654 // trigger submit on $form
11655 // - allows for "save", "preview" and "publish" to work
11656 submitFormDebounced($form);
11657 }
11658 },
11659 /**
11660 * onClickSubmit
11661 *
11662 * Callback when clicking submit.
11663 *
11664 * Only acts on submit buttons that are associated with a form containing ACF fields.
11665 * This prevents submit buttons in unrelated UI (e.g. the WP link inserter modal) from
11666 * triggering premature validation of ACF fields on the page behind the modal.
11667 *
11668 * Uses the native HTMLButtonElement.form property to resolve the associated form,
11669 * which correctly handles both DOM-ancestor forms and the HTML form="id" attribute.
11670 *
11671 * @date 4/9/18
11672 * @since ACF 5.7.5
11673 *
11674 * @param object e The event object.
11675 * @param jQuery $el The submit button element.
11676 * @return void
11677 */
11678 onClickSubmit: function (e, $el) {
11679 const form = $el.length ? $el[0].form : null;
11680 if (!form) {
11681 return;
11682 }
11683 const $form = $(form);
11684 if (!$form.find('.acf-field').length) {
11685 return;
11686 }
11687
11688 // Some browsers (safari) force their browser validation before our AJAX validation,
11689 // so we need to make sure fields are visible earlier than showErrors().
11690 ensureInvalidFieldVisibility($form);
11691 this.set('originalEvent', e);
11692 },
11693 /**
11694 * onClickSave
11695 *
11696 * Set ignore to true when saving a draft.
11697 *
11698 * @date 4/9/18
11699 * @since ACF 5.7.5
11700 *
11701 * @param object e The event object.
11702 * @param jQuery $el The input element.
11703 * @return void
11704 */
11705 onClickSave: function (e, $el) {
11706 this.set('ignore', true);
11707 },
11708 /**
11709 * onSubmitPost
11710 *
11711 * Callback when the 'post' form is submit.
11712 *
11713 * @date 5/3/19
11714 * @since ACF 5.7.13
11715 *
11716 * @param object e The event object.
11717 * @param jQuery $el The input element.
11718 * @return void
11719 */
11720 onSubmitPost: function (e, $el) {
11721 // Check if is preview.
11722 if ($('input#wp-preview').val() === 'dopreview') {
11723 // Ignore validation.
11724 this.set('ignore', true);
11725
11726 // Unlock form to fix conflict with core "submit.edit-post" event causing all submit buttons to be disabled.
11727 acf.unlockForm($el);
11728 }
11729 },
11730 /**
11731 * onSubmit
11732 *
11733 * Callback when the form is submit.
11734 *
11735 * @date 4/9/18
11736 * @since ACF 5.7.5
11737 *
11738 * @param object e The event object.
11739 * @param jQuery $el The input element.
11740 * @return void
11741 */
11742 onSubmit: function (e, $el) {
11743 // Allow form to submit if...
11744 if (
11745 // Validation has been disabled.
11746 !this.active ||
11747 // Or this event is to be ignored.
11748 this.get('ignore') ||
11749 // Or this event has already been prevented.
11750 e.isDefaultPrevented()) {
11751 // Return early and call reset function.
11752 return this.allowSubmit();
11753 }
11754
11755 // Validate form.
11756 var valid = acf.validateForm({
11757 form: $el,
11758 event: this.get('originalEvent')
11759 });
11760
11761 // If not valid, stop event to prevent form submit.
11762 if (!valid) {
11763 e.preventDefault();
11764 }
11765 },
11766 /**
11767 * allowSubmit
11768 *
11769 * Resets data during onSubmit when the form is allowed to submit.
11770 *
11771 * @date 5/3/19
11772 * @since ACF 5.7.13
11773 *
11774 * @param void
11775 * @return void
11776 */
11777 allowSubmit: function () {
11778 // Reset "ignore" state.
11779 this.set('ignore', false);
11780
11781 // Reset "originalEvent" object.
11782 this.set('originalEvent', false);
11783
11784 // Return true
11785 return true;
11786 }
11787 });
11788 var gutenbergValidation = new acf.Model({
11789 wait: 'prepare',
11790 initialize: function () {
11791 // Bail early if not Gutenberg.
11792 if (!acf.isGutenberg()) {
11793 return;
11794 }
11795
11796 // Customize the editor.
11797 this.customizeEditor();
11798 },
11799 customizeEditor: function () {
11800 // Extract vars.
11801 var editor = wp.data.dispatch('core/editor');
11802 var editorSelect = wp.data.select('core/editor');
11803 var notices = wp.data.dispatch('core/notices');
11804
11805 // Backup original method.
11806 var savePost = editor.savePost;
11807
11808 // Listen for changes to post status and perform actions:
11809 // a) Enable validation for "publish" action.
11810 // b) Remember last non "publish" status used for restoring after validation fail.
11811 var useValidation = false;
11812 var lastPostStatus = '';
11813 wp.data.subscribe(function () {
11814 var postStatus = editorSelect.getEditedPostAttribute('status');
11815 useValidation = postStatus === 'publish' || postStatus === 'future';
11816 lastPostStatus = postStatus !== 'publish' ? postStatus : lastPostStatus;
11817 });
11818
11819 // Create validation version.
11820 editor.savePost = function (options) {
11821 options = options || {};
11822
11823 // Backup vars.
11824 var _this = this;
11825 var _args = arguments;
11826 // Perform validation within a Promise.
11827 return new Promise(function (resolve, reject) {
11828 if (typeof acf.gutenbergEditPost === 'function') {
11829 acf.gutenbergEditPost();
11830 }
11831
11832 // Bail early if is autosave or preview.
11833 if (options.isAutosave || options.isPreview) {
11834 return resolve('Validation ignored (autosave).');
11835 }
11836
11837 // Bail early if validation is not needed.
11838 if (!useValidation) {
11839 return resolve('Validation ignored (draft).');
11840 }
11841
11842 // Check if we've currently got an ACF block selected which is failing validation, but might not be presented yet.
11843 if ('undefined' !== typeof acf.blockInstances) {
11844 const selectedBlockId = wp.data.select('core/block-editor').getSelectedBlockClientId();
11845 if (selectedBlockId && selectedBlockId in acf.blockInstances) {
11846 const acfBlockState = acf.blockInstances[selectedBlockId];
11847 if (acfBlockState.validation_errors) {
11848 // Deselect the block to show the error and lock the save.
11849 acf.debug('Rejecting save because the block editor has a invalid ACF block selected.');
11850 notices.createErrorNotice(acf.__('An ACF Block on this page requires attention before you can save.'), {
11851 id: 'acf-validation',
11852 isDismissible: true
11853 });
11854 wp.data.dispatch('core/editor').lockPostSaving('acf/block/' + selectedBlockId);
11855 wp.data.dispatch('core/block-editor').selectBlock(false);
11856 return reject('ACF Validation failed for selected block.');
11857 }
11858 }
11859 }
11860
11861 // Recursive function to check all blocks (including nested innerBlocks) for ACF validation errors
11862 function checkBlocksForErrors(blocks) {
11863 const errors = [];
11864 return new Promise(function (resolve) {
11865 // Iterate through each block
11866 blocks.forEach(block => {
11867 // If this block has nested blocks, recursively check them
11868 if (block.innerBlocks.length > 0) {
11869 checkBlocksForErrors(block.innerBlocks).then(hasError => {
11870 if (hasError) {
11871 return resolve(true);
11872 }
11873 });
11874 }
11875
11876 // Check if this block has an ACF error attribute
11877 if (block.attributes.hasAcfError) {
11878 // Check if the publish panel is open and close it if so
11879 const publishPanel = document.getElementsByClassName('editor-post-publish-panel')[0];
11880 if (publishPanel) {
11881 // See https://github.com/WordPress/secure-custom-fields/pull/272
11882 // `togglePublishSidebar` was only introduced in WP 6.6, it should be optional
11883 wp.data.dispatch('core/editor').togglePublishSidebar?.();
11884 }
11885
11886 // Add block to errors array
11887 errors.push(block);
11888
11889 // Dispatch a custom event to notify about the block with validation error
11890 document.dispatchEvent(new CustomEvent('acf/block/has-error', {
11891 detail: {
11892 acfBlocksWithValidationErrors: block.clientId
11893 }
11894 }));
11895
11896 // Log debug message
11897 acf.debug('Rejecting save because the block editor has a invalid ACF block selected.');
11898
11899 // Resolve with true (error found)
11900 return resolve(true);
11901 }
11902 });
11903
11904 // If errors were found, select the first one
11905 if (errors.length > 0) {
11906 const blockClientId = errors[0].clientId;
11907 wp.data.dispatch('core/block-editor').selectBlock(blockClientId);
11908 }
11909
11910 // No errors found, resolve with false
11911 return resolve(false);
11912 });
11913 }
11914
11915 // Call the function with all blocks from the editor
11916 checkBlocksForErrors(wp.data.select('core/block-editor').getBlocks()).then(hasError => {
11917 // If errors were found
11918 if (hasError) {
11919 // Display an error notice
11920 notices.createErrorNotice(acf.__('An ACF Block on this page requires attention before you can save.'), {
11921 id: 'acf-blocks-validation',
11922 isDismissible: true
11923 });
11924
11925 // Reject the save operation
11926 return reject('ACF Block Validation failed');
11927 }
11928 });
11929
11930 // Validate the editor form.
11931 var valid = acf.validateForm({
11932 form: $('#wpbody-content > .block-editor'),
11933 reset: true,
11934 complete: function ($form, validator) {
11935 // Always unlock the form after AJAX.
11936 editor.unlockPostSaving('acf');
11937 },
11938 failure: function ($form, validator) {
11939 // Get validation error and append to Gutenberg notices.
11940 var notice = validator.get('notice');
11941 var action = validator.get('action');
11942 if (action && 'object' === typeof action && action.label && action.url) {
11943 notices.createErrorNotice(notice.get('text', {
11944 id: 'acf-validation',
11945 isDismissible: true,
11946 actions: [{
11947 label: action.label,
11948 url: action.url
11949 }]
11950 }));
11951 } else {
11952 notices.createErrorNotice(notice.get('text'), {
11953 id: 'acf-validation',
11954 isDismissible: true
11955 });
11956 }
11957 notice.remove();
11958 // Restore last non "publish" status.
11959 if (lastPostStatus) {
11960 editor.editPost({
11961 status: lastPostStatus
11962 });
11963 }
11964
11965 // Reject promise and prevent savePost().
11966 reject('Validation failed.');
11967 },
11968 success: function () {
11969 notices.removeNotice('acf-validation');
11970
11971 // Resolve promise and allow savePost().
11972 resolve('Validation success.');
11973 }
11974 });
11975
11976 // Resolve promise and allow savePost() if no validation is needed.
11977 if (valid) {
11978 resolve('Validation bypassed.');
11979
11980 // Otherwise, lock the form and wait for AJAX response.
11981 } else {
11982 editor.lockPostSaving('acf');
11983 }
11984 }).then(function () {
11985 return savePost.apply(_this, _args);
11986 }, err => {
11987 // Nothing to do here, user is alerted of validation issues.
11988 });
11989 };
11990 }
11991 });
11992 })(jQuery);
11993
11994 /***/ })
11995
11996 /******/ });
11997 /************************************************************************/
11998 /******/ // The module cache
11999 /******/ var __webpack_module_cache__ = {};
12000 /******/
12001 /******/ // The require function
12002 /******/ function __webpack_require__(moduleId) {
12003 /******/ // Check if module is in cache
12004 /******/ var cachedModule = __webpack_module_cache__[moduleId];
12005 /******/ if (cachedModule !== undefined) {
12006 /******/ return cachedModule.exports;
12007 /******/ }
12008 /******/ // Create a new module (and put it into the cache)
12009 /******/ var module = __webpack_module_cache__[moduleId] = {
12010 /******/ // no module.id needed
12011 /******/ // no module.loaded needed
12012 /******/ exports: {}
12013 /******/ };
12014 /******/
12015 /******/ // Execute the module function
12016 /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
12017 /******/
12018 /******/ // Return the exports of the module
12019 /******/ return module.exports;
12020 /******/ }
12021 /******/
12022 /************************************************************************/
12023 /******/ /* webpack/runtime/compat get default export */
12024 /******/ (() => {
12025 /******/ // getDefaultExport function for compatibility with non-harmony modules
12026 /******/ __webpack_require__.n = (module) => {
12027 /******/ var getter = module && module.__esModule ?
12028 /******/ () => (module['default']) :
12029 /******/ () => (module);
12030 /******/ __webpack_require__.d(getter, { a: getter });
12031 /******/ return getter;
12032 /******/ };
12033 /******/ })();
12034 /******/
12035 /******/ /* webpack/runtime/define property getters */
12036 /******/ (() => {
12037 /******/ // define getter functions for harmony exports
12038 /******/ __webpack_require__.d = (exports, definition) => {
12039 /******/ for(var key in definition) {
12040 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
12041 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
12042 /******/ }
12043 /******/ }
12044 /******/ };
12045 /******/ })();
12046 /******/
12047 /******/ /* webpack/runtime/hasOwnProperty shorthand */
12048 /******/ (() => {
12049 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
12050 /******/ })();
12051 /******/
12052 /******/ /* webpack/runtime/make namespace object */
12053 /******/ (() => {
12054 /******/ // define __esModule on exports
12055 /******/ __webpack_require__.r = (exports) => {
12056 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
12057 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
12058 /******/ }
12059 /******/ Object.defineProperty(exports, '__esModule', { value: true });
12060 /******/ };
12061 /******/ })();
12062 /******/
12063 /************************************************************************/
12064 var __webpack_exports__ = {};
12065 // This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
12066 (() => {
12067 "use strict";
12068 /*!************************************!*\
12069 !*** ./assets/src/js/acf-input.js ***!
12070 \************************************/
12071 __webpack_require__.r(__webpack_exports__);
12072 /* harmony import */ var _acf_field_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_acf-field.js */ "./assets/src/js/_acf-field.js");
12073 /* harmony import */ var _acf_field_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_acf_field_js__WEBPACK_IMPORTED_MODULE_0__);
12074 /* harmony import */ var _acf_fields_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_acf-fields.js */ "./assets/src/js/_acf-fields.js");
12075 /* harmony import */ var _acf_fields_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_acf_fields_js__WEBPACK_IMPORTED_MODULE_1__);
12076 /* harmony import */ var _acf_field_accordion_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_acf-field-accordion.js */ "./assets/src/js/_acf-field-accordion.js");
12077 /* harmony import */ var _acf_field_accordion_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_acf_field_accordion_js__WEBPACK_IMPORTED_MODULE_2__);
12078 /* harmony import */ var _acf_field_button_group_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./_acf-field-button-group.js */ "./assets/src/js/_acf-field-button-group.js");
12079 /* harmony import */ var _acf_field_checkbox_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./_acf-field-checkbox.js */ "./assets/src/js/_acf-field-checkbox.js");
12080 /* harmony import */ var _acf_field_checkbox_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_acf_field_checkbox_js__WEBPACK_IMPORTED_MODULE_4__);
12081 /* harmony import */ var _acf_field_color_picker_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./_acf-field-color-picker.js */ "./assets/src/js/_acf-field-color-picker.js");
12082 /* harmony import */ var _acf_field_color_picker_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_acf_field_color_picker_js__WEBPACK_IMPORTED_MODULE_5__);
12083 /* harmony import */ var _acf_field_date_picker_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./_acf-field-date-picker.js */ "./assets/src/js/_acf-field-date-picker.js");
12084 /* harmony import */ var _acf_field_date_picker_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_acf_field_date_picker_js__WEBPACK_IMPORTED_MODULE_6__);
12085 /* harmony import */ var _acf_field_date_time_picker_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./_acf-field-date-time-picker.js */ "./assets/src/js/_acf-field-date-time-picker.js");
12086 /* harmony import */ var _acf_field_date_time_picker_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(_acf_field_date_time_picker_js__WEBPACK_IMPORTED_MODULE_7__);
12087 /* harmony import */ var _acf_field_google_map_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./_acf-field-google-map.js */ "./assets/src/js/_acf-field-google-map.js");
12088 /* harmony import */ var _acf_field_google_map_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(_acf_field_google_map_js__WEBPACK_IMPORTED_MODULE_8__);
12089 /* harmony import */ var _acf_field_icon_picker_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./_acf-field-icon-picker.js */ "./assets/src/js/_acf-field-icon-picker.js");
12090 /* harmony import */ var _acf_field_icon_picker_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(_acf_field_icon_picker_js__WEBPACK_IMPORTED_MODULE_9__);
12091 /* harmony import */ var _acf_field_image_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./_acf-field-image.js */ "./assets/src/js/_acf-field-image.js");
12092 /* harmony import */ var _acf_field_image_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(_acf_field_image_js__WEBPACK_IMPORTED_MODULE_10__);
12093 /* harmony import */ var _acf_field_file_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./_acf-field-file.js */ "./assets/src/js/_acf-field-file.js");
12094 /* harmony import */ var _acf_field_file_js__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(_acf_field_file_js__WEBPACK_IMPORTED_MODULE_11__);
12095 /* harmony import */ var _acf_field_link_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./_acf-field-link.js */ "./assets/src/js/_acf-field-link.js");
12096 /* harmony import */ var _acf_field_link_js__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(_acf_field_link_js__WEBPACK_IMPORTED_MODULE_12__);
12097 /* harmony import */ var _acf_field_oembed_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./_acf-field-oembed.js */ "./assets/src/js/_acf-field-oembed.js");
12098 /* harmony import */ var _acf_field_oembed_js__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(_acf_field_oembed_js__WEBPACK_IMPORTED_MODULE_13__);
12099 /* harmony import */ var _acf_field_radio_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./_acf-field-radio.js */ "./assets/src/js/_acf-field-radio.js");
12100 /* harmony import */ var _acf_field_radio_js__WEBPACK_IMPORTED_MODULE_14___default = /*#__PURE__*/__webpack_require__.n(_acf_field_radio_js__WEBPACK_IMPORTED_MODULE_14__);
12101 /* harmony import */ var _acf_field_range_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./_acf-field-range.js */ "./assets/src/js/_acf-field-range.js");
12102 /* harmony import */ var _acf_field_range_js__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(_acf_field_range_js__WEBPACK_IMPORTED_MODULE_15__);
12103 /* harmony import */ var _acf_field_relationship_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./_acf-field-relationship.js */ "./assets/src/js/_acf-field-relationship.js");
12104 /* harmony import */ var _acf_field_relationship_js__WEBPACK_IMPORTED_MODULE_16___default = /*#__PURE__*/__webpack_require__.n(_acf_field_relationship_js__WEBPACK_IMPORTED_MODULE_16__);
12105 /* harmony import */ var _acf_field_select_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./_acf-field-select.js */ "./assets/src/js/_acf-field-select.js");
12106 /* harmony import */ var _acf_field_select_js__WEBPACK_IMPORTED_MODULE_17___default = /*#__PURE__*/__webpack_require__.n(_acf_field_select_js__WEBPACK_IMPORTED_MODULE_17__);
12107 /* harmony import */ var _acf_field_tab_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./_acf-field-tab.js */ "./assets/src/js/_acf-field-tab.js");
12108 /* harmony import */ var _acf_field_tab_js__WEBPACK_IMPORTED_MODULE_18___default = /*#__PURE__*/__webpack_require__.n(_acf_field_tab_js__WEBPACK_IMPORTED_MODULE_18__);
12109 /* harmony import */ var _acf_field_post_object_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./_acf-field-post-object.js */ "./assets/src/js/_acf-field-post-object.js");
12110 /* harmony import */ var _acf_field_post_object_js__WEBPACK_IMPORTED_MODULE_19___default = /*#__PURE__*/__webpack_require__.n(_acf_field_post_object_js__WEBPACK_IMPORTED_MODULE_19__);
12111 /* harmony import */ var _acf_field_page_link_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./_acf-field-page-link.js */ "./assets/src/js/_acf-field-page-link.js");
12112 /* harmony import */ var _acf_field_page_link_js__WEBPACK_IMPORTED_MODULE_20___default = /*#__PURE__*/__webpack_require__.n(_acf_field_page_link_js__WEBPACK_IMPORTED_MODULE_20__);
12113 /* harmony import */ var _acf_field_user_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./_acf-field-user.js */ "./assets/src/js/_acf-field-user.js");
12114 /* harmony import */ var _acf_field_user_js__WEBPACK_IMPORTED_MODULE_21___default = /*#__PURE__*/__webpack_require__.n(_acf_field_user_js__WEBPACK_IMPORTED_MODULE_21__);
12115 /* harmony import */ var _acf_field_taxonomy_js__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./_acf-field-taxonomy.js */ "./assets/src/js/_acf-field-taxonomy.js");
12116 /* harmony import */ var _acf_field_taxonomy_js__WEBPACK_IMPORTED_MODULE_22___default = /*#__PURE__*/__webpack_require__.n(_acf_field_taxonomy_js__WEBPACK_IMPORTED_MODULE_22__);
12117 /* harmony import */ var _acf_field_time_picker_js__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./_acf-field-time-picker.js */ "./assets/src/js/_acf-field-time-picker.js");
12118 /* harmony import */ var _acf_field_time_picker_js__WEBPACK_IMPORTED_MODULE_23___default = /*#__PURE__*/__webpack_require__.n(_acf_field_time_picker_js__WEBPACK_IMPORTED_MODULE_23__);
12119 /* harmony import */ var _acf_field_true_false_js__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./_acf-field-true-false.js */ "./assets/src/js/_acf-field-true-false.js");
12120 /* harmony import */ var _acf_field_true_false_js__WEBPACK_IMPORTED_MODULE_24___default = /*#__PURE__*/__webpack_require__.n(_acf_field_true_false_js__WEBPACK_IMPORTED_MODULE_24__);
12121 /* harmony import */ var _acf_field_url_js__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./_acf-field-url.js */ "./assets/src/js/_acf-field-url.js");
12122 /* harmony import */ var _acf_field_url_js__WEBPACK_IMPORTED_MODULE_25___default = /*#__PURE__*/__webpack_require__.n(_acf_field_url_js__WEBPACK_IMPORTED_MODULE_25__);
12123 /* harmony import */ var _acf_field_wysiwyg_js__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./_acf-field-wysiwyg.js */ "./assets/src/js/_acf-field-wysiwyg.js");
12124 /* harmony import */ var _acf_field_wysiwyg_js__WEBPACK_IMPORTED_MODULE_26___default = /*#__PURE__*/__webpack_require__.n(_acf_field_wysiwyg_js__WEBPACK_IMPORTED_MODULE_26__);
12125 /* harmony import */ var _acf_condition_js__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./_acf-condition.js */ "./assets/src/js/_acf-condition.js");
12126 /* harmony import */ var _acf_condition_js__WEBPACK_IMPORTED_MODULE_27___default = /*#__PURE__*/__webpack_require__.n(_acf_condition_js__WEBPACK_IMPORTED_MODULE_27__);
12127 /* harmony import */ var _acf_conditions_js__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./_acf-conditions.js */ "./assets/src/js/_acf-conditions.js");
12128 /* harmony import */ var _acf_conditions_js__WEBPACK_IMPORTED_MODULE_28___default = /*#__PURE__*/__webpack_require__.n(_acf_conditions_js__WEBPACK_IMPORTED_MODULE_28__);
12129 /* harmony import */ var _acf_condition_types_js__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./_acf-condition-types.js */ "./assets/src/js/_acf-condition-types.js");
12130 /* harmony import */ var _acf_condition_types_js__WEBPACK_IMPORTED_MODULE_29___default = /*#__PURE__*/__webpack_require__.n(_acf_condition_types_js__WEBPACK_IMPORTED_MODULE_29__);
12131 /* harmony import */ var _acf_unload_js__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./_acf-unload.js */ "./assets/src/js/_acf-unload.js");
12132 /* harmony import */ var _acf_unload_js__WEBPACK_IMPORTED_MODULE_30___default = /*#__PURE__*/__webpack_require__.n(_acf_unload_js__WEBPACK_IMPORTED_MODULE_30__);
12133 /* harmony import */ var _acf_postbox_js__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./_acf-postbox.js */ "./assets/src/js/_acf-postbox.js");
12134 /* harmony import */ var _acf_postbox_js__WEBPACK_IMPORTED_MODULE_31___default = /*#__PURE__*/__webpack_require__.n(_acf_postbox_js__WEBPACK_IMPORTED_MODULE_31__);
12135 /* harmony import */ var _acf_media_js__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ./_acf-media.js */ "./assets/src/js/_acf-media.js");
12136 /* harmony import */ var _acf_media_js__WEBPACK_IMPORTED_MODULE_32___default = /*#__PURE__*/__webpack_require__.n(_acf_media_js__WEBPACK_IMPORTED_MODULE_32__);
12137 /* harmony import */ var _acf_screen_js__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ./_acf-screen.js */ "./assets/src/js/_acf-screen.js");
12138 /* harmony import */ var _acf_screen_js__WEBPACK_IMPORTED_MODULE_33___default = /*#__PURE__*/__webpack_require__.n(_acf_screen_js__WEBPACK_IMPORTED_MODULE_33__);
12139 /* harmony import */ var _acf_select2_js__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ./_acf-select2.js */ "./assets/src/js/_acf-select2.js");
12140 /* harmony import */ var _acf_select2_js__WEBPACK_IMPORTED_MODULE_34___default = /*#__PURE__*/__webpack_require__.n(_acf_select2_js__WEBPACK_IMPORTED_MODULE_34__);
12141 /* harmony import */ var _acf_tinymce_js__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./_acf-tinymce.js */ "./assets/src/js/_acf-tinymce.js");
12142 /* harmony import */ var _acf_tinymce_js__WEBPACK_IMPORTED_MODULE_35___default = /*#__PURE__*/__webpack_require__.n(_acf_tinymce_js__WEBPACK_IMPORTED_MODULE_35__);
12143 /* harmony import */ var _acf_validation_js__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ./_acf-validation.js */ "./assets/src/js/_acf-validation.js");
12144 /* harmony import */ var _acf_validation_js__WEBPACK_IMPORTED_MODULE_36___default = /*#__PURE__*/__webpack_require__.n(_acf_validation_js__WEBPACK_IMPORTED_MODULE_36__);
12145 /* harmony import */ var _acf_helpers_js__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./_acf-helpers.js */ "./assets/src/js/_acf-helpers.js");
12146 /* harmony import */ var _acf_helpers_js__WEBPACK_IMPORTED_MODULE_37___default = /*#__PURE__*/__webpack_require__.n(_acf_helpers_js__WEBPACK_IMPORTED_MODULE_37__);
12147 /* harmony import */ var _acf_compatibility_js__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ./_acf-compatibility.js */ "./assets/src/js/_acf-compatibility.js");
12148 /* harmony import */ var _acf_compatibility_js__WEBPACK_IMPORTED_MODULE_38___default = /*#__PURE__*/__webpack_require__.n(_acf_compatibility_js__WEBPACK_IMPORTED_MODULE_38__);
12149
12150
12151
12152
12153
12154
12155
12156
12157
12158
12159
12160
12161
12162
12163
12164
12165
12166
12167
12168
12169
12170
12171
12172
12173
12174
12175
12176
12177
12178
12179
12180
12181
12182
12183
12184
12185
12186
12187
12188 })();
12189
12190 /******/ })()
12191 ;
12192 //# sourceMappingURL=acf-input.js.map