PluginProbe ʕ •ᴥ•ʔ
Secure Custom Fields / 6.4.2
Secure Custom Fields v6.4.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
pro 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.js 1 year ago acf-field-group.js 1 year ago acf-field-group.js.map 1 year ago acf-field-group.min.js 1 year ago acf-input.js 1 year ago acf-input.js.map 1 year ago acf-input.min.js 1 year ago acf-internal-post-type.js 1 year ago acf-internal-post-type.js.map 1 year ago acf-internal-post-type.min.js 1 year ago acf.js 1 year ago acf.js.map 1 year ago acf.min.js 1 year ago index.php 1 year ago
acf-input.js
11575 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 compatibilty 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 // compability
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 scafold 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 var __ = acf.__;
713 var parseString = function (val) {
714 return val ? '' + val : '';
715 };
716 var 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 var 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 var isGreaterThan = function (v1, v2) {
734 return parseFloat(v1) > parseFloat(v2);
735 };
736 var isLessThan = function (v1, v2) {
737 return parseFloat(v1) < parseFloat(v2);
738 };
739 var 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 var containsString = function (haystack, needle) {
747 return parseString(haystack).indexOf(parseString(needle)) > -1;
748 };
749 var matchesPattern = function (v1, pattern) {
750 var 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.escHtml(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.escHtml(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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var 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 var choices = [];
1683 var 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 var 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 var 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 var 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 var LessThan = GreaterThan.extend({
1770 type: 'lessThan',
1771 operator: '<',
1772 label: __('Value is less than'),
1773 match: function (rule, field) {
1774 var 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 var 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 var 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 avaibale 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 // clonse 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 // enpoint
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
2458 // classes
2459 // - remove 'inside' which is a #poststuff WP class
2460 var $parent = $field.parent();
2461 $wrap.addClass($parent.hasClass('-left') ? '-left' : '');
2462 $wrap.addClass($parent.hasClass('-clear') ? '-clear' : '');
2463
2464 // append
2465 $wrap.append($field.nextUntil('.acf-field-accordion', '.acf-field'));
2466
2467 // clean up
2468 $wrap.removeAttr('data-open data-multi_expand data-endpoint');
2469 }
2470 });
2471 acf.registerFieldType(Field);
2472
2473 /**
2474 * accordionManager
2475 *
2476 * Events manager for the acf accordion
2477 *
2478 * @date 14/2/18
2479 * @since ACF 5.6.9
2480 *
2481 * @param void
2482 * @return void
2483 */
2484
2485 var accordionManager = new acf.Model({
2486 actions: {
2487 unload: 'onUnload'
2488 },
2489 events: {
2490 'click .acf-accordion-title': 'onClick',
2491 'invalidField .acf-accordion': 'onInvalidField'
2492 },
2493 isOpen: function ($el) {
2494 return $el.hasClass('-open');
2495 },
2496 toggle: function ($el) {
2497 if (this.isOpen($el)) {
2498 this.close($el);
2499 } else {
2500 this.open($el);
2501 }
2502 },
2503 iconHtml: function (props) {
2504 // Use SVG inside Gutenberg editor.
2505 if (acf.isGutenberg()) {
2506 if (props.open) {
2507 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>';
2508 } else {
2509 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>';
2510 }
2511 } else {
2512 if (props.open) {
2513 return '<i class="acf-accordion-icon dashicons dashicons-arrow-down"></i>';
2514 } else {
2515 return '<i class="acf-accordion-icon dashicons dashicons-arrow-right"></i>';
2516 }
2517 }
2518 },
2519 open: function ($el) {
2520 var duration = acf.isGutenberg() ? 0 : 300;
2521
2522 // open
2523 $el.find('.acf-accordion-content:first').slideDown(duration).css('display', 'block');
2524 $el.find('.acf-accordion-icon:first').replaceWith(this.iconHtml({
2525 open: true
2526 }));
2527 $el.addClass('-open');
2528
2529 // action
2530 acf.doAction('show', $el);
2531
2532 // close siblings
2533 if (!$el.attr('multi-expand')) {
2534 $el.siblings('.acf-accordion.-open').each(function () {
2535 accordionManager.close($(this));
2536 });
2537 }
2538 },
2539 close: function ($el) {
2540 var duration = acf.isGutenberg() ? 0 : 300;
2541
2542 // close
2543 $el.find('.acf-accordion-content:first').slideUp(duration);
2544 $el.find('.acf-accordion-icon:first').replaceWith(this.iconHtml({
2545 open: false
2546 }));
2547 $el.removeClass('-open');
2548
2549 // action
2550 acf.doAction('hide', $el);
2551 },
2552 onClick: function (e, $el) {
2553 // prevent Defailt
2554 e.preventDefault();
2555
2556 // open close
2557 this.toggle($el.parent());
2558 },
2559 onInvalidField: function (e, $el) {
2560 // bail early if already focused
2561 if (this.busy) {
2562 return;
2563 }
2564
2565 // disable functionality for 1sec (allow next validation to work)
2566 this.busy = true;
2567 this.setTimeout(function () {
2568 this.busy = false;
2569 }, 1000);
2570
2571 // open accordion
2572 this.open($el);
2573 },
2574 onUnload: function (e) {
2575 // vars
2576 var order = [];
2577
2578 // loop
2579 $('.acf-accordion').each(function () {
2580 var open = $(this).hasClass('-open') ? 1 : 0;
2581 order.push(open);
2582 });
2583
2584 // set
2585 if (order.length) {
2586 acf.setPreference('this.accordions', order);
2587 }
2588 }
2589 });
2590 })(jQuery);
2591
2592 /***/ }),
2593
2594 /***/ "./assets/src/js/_acf-field-button-group.js":
2595 /*!**************************************************!*\
2596 !*** ./assets/src/js/_acf-field-button-group.js ***!
2597 \**************************************************/
2598 /***/ (() => {
2599
2600 (function ($, undefined) {
2601 var Field = acf.Field.extend({
2602 type: 'button_group',
2603 events: {
2604 'click input[type="radio"]': 'onClick'
2605 },
2606 $control: function () {
2607 return this.$('.acf-button-group');
2608 },
2609 $input: function () {
2610 return this.$('input:checked');
2611 },
2612 setValue: function (val) {
2613 this.$('input[value="' + val + '"]').prop('checked', true).trigger('change');
2614 },
2615 onClick: function (e, $el) {
2616 // vars
2617 var $label = $el.parent('label');
2618 var selected = $label.hasClass('selected');
2619
2620 // remove previous selected
2621 this.$('.selected').removeClass('selected');
2622
2623 // add active class
2624 $label.addClass('selected');
2625
2626 // allow null
2627 if (this.get('allow_null') && selected) {
2628 $label.removeClass('selected');
2629 $el.prop('checked', false).trigger('change');
2630 }
2631 }
2632 });
2633 acf.registerFieldType(Field);
2634 })(jQuery);
2635
2636 /***/ }),
2637
2638 /***/ "./assets/src/js/_acf-field-checkbox.js":
2639 /*!**********************************************!*\
2640 !*** ./assets/src/js/_acf-field-checkbox.js ***!
2641 \**********************************************/
2642 /***/ (() => {
2643
2644 (function ($, undefined) {
2645 var Field = acf.Field.extend({
2646 type: 'checkbox',
2647 events: {
2648 'change input': 'onChange',
2649 'click .acf-add-checkbox': 'onClickAdd',
2650 'click .acf-checkbox-toggle': 'onClickToggle',
2651 'click .acf-checkbox-custom': 'onClickCustom'
2652 },
2653 $control: function () {
2654 return this.$('.acf-checkbox-list');
2655 },
2656 $toggle: function () {
2657 return this.$('.acf-checkbox-toggle');
2658 },
2659 $input: function () {
2660 return this.$('input[type="hidden"]');
2661 },
2662 $inputs: function () {
2663 return this.$('input[type="checkbox"]').not('.acf-checkbox-toggle');
2664 },
2665 getValue: function () {
2666 var val = [];
2667 this.$(':checked').each(function () {
2668 val.push($(this).val());
2669 });
2670 return val.length ? val : false;
2671 },
2672 onChange: function (e, $el) {
2673 // Vars.
2674 var checked = $el.prop('checked');
2675 var $label = $el.parent('label');
2676 var $toggle = this.$toggle();
2677
2678 // Add or remove "selected" class.
2679 if (checked) {
2680 $label.addClass('selected');
2681 } else {
2682 $label.removeClass('selected');
2683 }
2684
2685 // Update toggle state if all inputs are checked.
2686 if ($toggle.length) {
2687 var $inputs = this.$inputs();
2688
2689 // all checked
2690 if ($inputs.not(':checked').length == 0) {
2691 $toggle.prop('checked', true);
2692 } else {
2693 $toggle.prop('checked', false);
2694 }
2695 }
2696 },
2697 onClickAdd: function (e, $el) {
2698 var html = '<li><input class="acf-checkbox-custom" type="checkbox" checked="checked" /><input type="text" name="' + this.getInputName() + '[]" /></li>';
2699 $el.parent('li').before(html);
2700 $el.parent('li').parent().find('input[type="text"]').last().focus();
2701 },
2702 onClickToggle: function (e, $el) {
2703 // Vars.
2704 var checked = $el.prop('checked');
2705 var $inputs = this.$('input[type="checkbox"]');
2706 var $labels = this.$('label');
2707
2708 // Update "checked" state.
2709 $inputs.prop('checked', checked);
2710
2711 // Add or remove "selected" class.
2712 if (checked) {
2713 $labels.addClass('selected');
2714 } else {
2715 $labels.removeClass('selected');
2716 }
2717 },
2718 onClickCustom: function (e, $el) {
2719 var checked = $el.prop('checked');
2720 var $text = $el.next('input[type="text"]');
2721
2722 // checked
2723 if (checked) {
2724 $text.prop('disabled', false);
2725
2726 // not checked
2727 } else {
2728 $text.prop('disabled', true);
2729
2730 // remove
2731 if ($text.val() == '') {
2732 $el.parent('li').remove();
2733 }
2734 }
2735 }
2736 });
2737 acf.registerFieldType(Field);
2738 })(jQuery);
2739
2740 /***/ }),
2741
2742 /***/ "./assets/src/js/_acf-field-color-picker.js":
2743 /*!**************************************************!*\
2744 !*** ./assets/src/js/_acf-field-color-picker.js ***!
2745 \**************************************************/
2746 /***/ (() => {
2747
2748 (function ($, undefined) {
2749 var Field = acf.Field.extend({
2750 type: 'color_picker',
2751 wait: 'load',
2752 events: {
2753 duplicateField: 'onDuplicate'
2754 },
2755 $control: function () {
2756 return this.$('.acf-color-picker');
2757 },
2758 $input: function () {
2759 return this.$('input[type="hidden"]');
2760 },
2761 $inputText: function () {
2762 return this.$('input[type="text"]');
2763 },
2764 setValue: function (val) {
2765 // update input (with change)
2766 acf.val(this.$input(), val);
2767
2768 // update iris
2769 this.$inputText().iris('color', val);
2770 },
2771 initialize: function () {
2772 // vars
2773 var $input = this.$input();
2774 var $inputText = this.$inputText();
2775
2776 // event
2777 var onChange = function (e) {
2778 // timeout is required to ensure the $input val is correct
2779 setTimeout(function () {
2780 acf.val($input, $inputText.val());
2781 }, 1);
2782 };
2783
2784 // args
2785 var args = {
2786 defaultColor: false,
2787 palettes: true,
2788 hide: true,
2789 change: onChange,
2790 clear: onChange
2791 };
2792
2793 // filter
2794 var args = acf.applyFilters('color_picker_args', args, this);
2795
2796 // initialize
2797 $inputText.wpColorPicker(args);
2798 },
2799 onDuplicate: function (e, $el, $duplicate) {
2800 // The wpColorPicker library does not provide a destroy method.
2801 // Manually reset DOM by replacing elements back to their original state.
2802 $colorPicker = $duplicate.find('.wp-picker-container');
2803 $inputText = $duplicate.find('input[type="text"]');
2804 $colorPicker.replaceWith($inputText);
2805 }
2806 });
2807 acf.registerFieldType(Field);
2808 })(jQuery);
2809
2810 /***/ }),
2811
2812 /***/ "./assets/src/js/_acf-field-date-picker.js":
2813 /*!*************************************************!*\
2814 !*** ./assets/src/js/_acf-field-date-picker.js ***!
2815 \*************************************************/
2816 /***/ (() => {
2817
2818 (function ($, undefined) {
2819 var Field = acf.Field.extend({
2820 type: 'date_picker',
2821 events: {
2822 'blur input[type="text"]': 'onBlur',
2823 duplicateField: 'onDuplicate'
2824 },
2825 $control: function () {
2826 return this.$('.acf-date-picker');
2827 },
2828 $input: function () {
2829 return this.$('input[type="hidden"]');
2830 },
2831 $inputText: function () {
2832 return this.$('input[type="text"]');
2833 },
2834 initialize: function () {
2835 // save_format: compatibility with ACF < 5.0.0
2836 if (this.has('save_format')) {
2837 return this.initializeCompatibility();
2838 }
2839
2840 // vars
2841 var $input = this.$input();
2842 var $inputText = this.$inputText();
2843
2844 // args
2845 var args = {
2846 dateFormat: this.get('date_format'),
2847 altField: $input,
2848 altFormat: 'yymmdd',
2849 changeYear: true,
2850 yearRange: '-100:+100',
2851 changeMonth: true,
2852 showButtonPanel: true,
2853 firstDay: this.get('first_day')
2854 };
2855
2856 // filter
2857 args = acf.applyFilters('date_picker_args', args, this);
2858
2859 // add date picker
2860 acf.newDatePicker($inputText, args);
2861
2862 // action
2863 acf.doAction('date_picker_init', $inputText, args, this);
2864 },
2865 initializeCompatibility: function () {
2866 // vars
2867 var $input = this.$input();
2868 var $inputText = this.$inputText();
2869
2870 // get and set value from alt field
2871 $inputText.val($input.val());
2872
2873 // args
2874 var args = {
2875 dateFormat: this.get('date_format'),
2876 altField: $input,
2877 altFormat: this.get('save_format'),
2878 changeYear: true,
2879 yearRange: '-100:+100',
2880 changeMonth: true,
2881 showButtonPanel: true,
2882 firstDay: this.get('first_day')
2883 };
2884
2885 // filter for 3rd party customization
2886 args = acf.applyFilters('date_picker_args', args, this);
2887
2888 // backup
2889 var dateFormat = args.dateFormat;
2890
2891 // change args.dateFormat
2892 args.dateFormat = this.get('save_format');
2893
2894 // add date picker
2895 acf.newDatePicker($inputText, args);
2896
2897 // now change the format back to how it should be.
2898 $inputText.datepicker('option', 'dateFormat', dateFormat);
2899
2900 // action for 3rd party customization
2901 acf.doAction('date_picker_init', $inputText, args, this);
2902 },
2903 onBlur: function () {
2904 if (!this.$inputText().val()) {
2905 acf.val(this.$input(), '');
2906 }
2907 },
2908 onDuplicate: function (e, $el, $duplicate) {
2909 $duplicate.find('input[type="text"]').removeClass('hasDatepicker').removeAttr('id');
2910 }
2911 });
2912 acf.registerFieldType(Field);
2913
2914 // manager
2915 var datePickerManager = new acf.Model({
2916 priority: 5,
2917 wait: 'ready',
2918 initialize: function () {
2919 // vars
2920 var locale = acf.get('locale');
2921 var rtl = acf.get('rtl');
2922 var l10n = acf.get('datePickerL10n');
2923
2924 // bail early if no l10n
2925 if (!l10n) {
2926 return false;
2927 }
2928
2929 // bail early if no datepicker library
2930 if (typeof $.datepicker === 'undefined') {
2931 return false;
2932 }
2933
2934 // rtl
2935 l10n.isRTL = rtl;
2936
2937 // append
2938 $.datepicker.regional[locale] = l10n;
2939 $.datepicker.setDefaults(l10n);
2940 }
2941 });
2942
2943 // add
2944 acf.newDatePicker = function ($input, args) {
2945 // bail early if no datepicker library
2946 if (typeof $.datepicker === 'undefined') {
2947 return false;
2948 }
2949
2950 // defaults
2951 args = args || {};
2952
2953 // initialize
2954 $input.datepicker(args);
2955
2956 // wrap the datepicker (only if it hasn't already been wrapped)
2957 if ($('body > #ui-datepicker-div').exists()) {
2958 $('body > #ui-datepicker-div').wrap('<div class="acf-ui-datepicker" />');
2959 }
2960 };
2961 })(jQuery);
2962
2963 /***/ }),
2964
2965 /***/ "./assets/src/js/_acf-field-date-time-picker.js":
2966 /*!******************************************************!*\
2967 !*** ./assets/src/js/_acf-field-date-time-picker.js ***!
2968 \******************************************************/
2969 /***/ (() => {
2970
2971 (function ($, undefined) {
2972 var Field = acf.models.DatePickerField.extend({
2973 type: 'date_time_picker',
2974 $control: function () {
2975 return this.$('.acf-date-time-picker');
2976 },
2977 initialize: function () {
2978 // vars
2979 var $input = this.$input();
2980 var $inputText = this.$inputText();
2981
2982 // args
2983 var args = {
2984 dateFormat: this.get('date_format'),
2985 timeFormat: this.get('time_format'),
2986 altField: $input,
2987 altFieldTimeOnly: false,
2988 altFormat: 'yy-mm-dd',
2989 altTimeFormat: 'HH:mm:ss',
2990 changeYear: true,
2991 yearRange: '-100:+100',
2992 changeMonth: true,
2993 showButtonPanel: true,
2994 firstDay: this.get('first_day'),
2995 controlType: 'select',
2996 oneLine: true
2997 };
2998
2999 // filter
3000 args = acf.applyFilters('date_time_picker_args', args, this);
3001
3002 // add date time picker
3003 acf.newDateTimePicker($inputText, args);
3004
3005 // action
3006 acf.doAction('date_time_picker_init', $inputText, args, this);
3007 }
3008 });
3009 acf.registerFieldType(Field);
3010
3011 // manager
3012 var dateTimePickerManager = new acf.Model({
3013 priority: 5,
3014 wait: 'ready',
3015 initialize: function () {
3016 // vars
3017 var locale = acf.get('locale');
3018 var rtl = acf.get('rtl');
3019 var l10n = acf.get('dateTimePickerL10n');
3020
3021 // bail early if no l10n
3022 if (!l10n) {
3023 return false;
3024 }
3025
3026 // bail early if no datepicker library
3027 if (typeof $.timepicker === 'undefined') {
3028 return false;
3029 }
3030
3031 // rtl
3032 l10n.isRTL = rtl;
3033
3034 // append
3035 $.timepicker.regional[locale] = l10n;
3036 $.timepicker.setDefaults(l10n);
3037 }
3038 });
3039
3040 // add
3041 acf.newDateTimePicker = function ($input, args) {
3042 // bail early if no datepicker library
3043 if (typeof $.timepicker === 'undefined') {
3044 return false;
3045 }
3046
3047 // defaults
3048 args = args || {};
3049
3050 // initialize
3051 $input.datetimepicker(args);
3052
3053 // wrap the datepicker (only if it hasn't already been wrapped)
3054 if ($('body > #ui-datepicker-div').exists()) {
3055 $('body > #ui-datepicker-div').wrap('<div class="acf-ui-datepicker" />');
3056 }
3057 };
3058 })(jQuery);
3059
3060 /***/ }),
3061
3062 /***/ "./assets/src/js/_acf-field-file.js":
3063 /*!******************************************!*\
3064 !*** ./assets/src/js/_acf-field-file.js ***!
3065 \******************************************/
3066 /***/ (() => {
3067
3068 (function ($, undefined) {
3069 var Field = acf.models.ImageField.extend({
3070 type: 'file',
3071 $control: function () {
3072 return this.$('.acf-file-uploader');
3073 },
3074 $input: function () {
3075 return this.$('input[type="hidden"]:first');
3076 },
3077 validateAttachment: function (attachment) {
3078 // defaults
3079 attachment = attachment || {};
3080
3081 // WP attachment
3082 if (attachment.id !== undefined) {
3083 attachment = attachment.attributes;
3084 }
3085
3086 // args
3087 attachment = acf.parseArgs(attachment, {
3088 url: '',
3089 alt: '',
3090 title: '',
3091 filename: '',
3092 filesizeHumanReadable: '',
3093 icon: '/wp-includes/images/media/default.png'
3094 });
3095
3096 // return
3097 return attachment;
3098 },
3099 render: function (attachment) {
3100 // vars
3101 attachment = this.validateAttachment(attachment);
3102
3103 // update image
3104 this.$('img').attr({
3105 src: attachment.icon,
3106 alt: attachment.alt,
3107 title: attachment.title
3108 });
3109
3110 // update elements
3111 this.$('[data-name="title"]').text(attachment.title);
3112 this.$('[data-name="filename"]').text(attachment.filename).attr('href', attachment.url);
3113 this.$('[data-name="filesize"]').text(attachment.filesizeHumanReadable);
3114
3115 // vars
3116 var val = attachment.id || '';
3117
3118 // update val
3119 acf.val(this.$input(), val);
3120
3121 // update class
3122 if (val) {
3123 this.$control().addClass('has-value');
3124 } else {
3125 this.$control().removeClass('has-value');
3126 }
3127 },
3128 selectAttachment: function () {
3129 // vars
3130 var parent = this.parent();
3131 var multiple = parent && parent.get('type') === 'repeater';
3132
3133 // new frame
3134 var frame = acf.newMediaPopup({
3135 mode: 'select',
3136 title: acf.__('Select File'),
3137 field: this.get('key'),
3138 multiple: multiple,
3139 library: this.get('library'),
3140 allowedTypes: this.get('mime_types'),
3141 select: $.proxy(function (attachment, i) {
3142 if (i > 0) {
3143 this.append(attachment, parent);
3144 } else {
3145 this.render(attachment);
3146 }
3147 }, this)
3148 });
3149 },
3150 editAttachment: function () {
3151 // vars
3152 var val = this.val();
3153
3154 // bail early if no val
3155 if (!val) {
3156 return false;
3157 }
3158
3159 // popup
3160 var frame = acf.newMediaPopup({
3161 mode: 'edit',
3162 title: acf.__('Edit File'),
3163 button: acf.__('Update File'),
3164 attachment: val,
3165 field: this.get('key'),
3166 select: $.proxy(function (attachment, i) {
3167 this.render(attachment);
3168 }, this)
3169 });
3170 }
3171 });
3172 acf.registerFieldType(Field);
3173 })(jQuery);
3174
3175 /***/ }),
3176
3177 /***/ "./assets/src/js/_acf-field-google-map.js":
3178 /*!************************************************!*\
3179 !*** ./assets/src/js/_acf-field-google-map.js ***!
3180 \************************************************/
3181 /***/ (() => {
3182
3183 (function ($, undefined) {
3184 var Field = acf.Field.extend({
3185 type: 'google_map',
3186 map: false,
3187 wait: 'load',
3188 events: {
3189 'click a[data-name="clear"]': 'onClickClear',
3190 'click a[data-name="locate"]': 'onClickLocate',
3191 'click a[data-name="search"]': 'onClickSearch',
3192 'keydown .search': 'onKeydownSearch',
3193 'keyup .search': 'onKeyupSearch',
3194 'focus .search': 'onFocusSearch',
3195 'blur .search': 'onBlurSearch',
3196 showField: 'onShow'
3197 },
3198 $control: function () {
3199 return this.$('.acf-google-map');
3200 },
3201 $search: function () {
3202 return this.$('.search');
3203 },
3204 $canvas: function () {
3205 return this.$('.canvas');
3206 },
3207 setState: function (state) {
3208 // Remove previous state classes.
3209 this.$control().removeClass('-value -loading -searching');
3210
3211 // Determine auto state based of current value.
3212 if (state === 'default') {
3213 state = this.val() ? 'value' : '';
3214 }
3215
3216 // Update state class.
3217 if (state) {
3218 this.$control().addClass('-' + state);
3219 }
3220 },
3221 getValue: function () {
3222 var val = this.$input().val();
3223 if (val) {
3224 return JSON.parse(val);
3225 } else {
3226 return false;
3227 }
3228 },
3229 setValue: function (val, silent) {
3230 // Convert input value.
3231 var valAttr = '';
3232 if (val) {
3233 valAttr = JSON.stringify(val);
3234 }
3235
3236 // Update input (with change).
3237 acf.val(this.$input(), valAttr);
3238
3239 // Bail early if silent update.
3240 if (silent) {
3241 return;
3242 }
3243
3244 // Render.
3245 this.renderVal(val);
3246
3247 /**
3248 * Fires immediately after the value has changed.
3249 *
3250 * @date 12/02/2014
3251 * @since ACF 5.0.0
3252 *
3253 * @param object|string val The new value.
3254 * @param object map The Google Map isntance.
3255 * @param object field The field instance.
3256 */
3257 acf.doAction('google_map_change', val, this.map, this);
3258 },
3259 renderVal: function (val) {
3260 // Value.
3261 if (val) {
3262 this.setState('value');
3263 this.$search().val(val.address);
3264 this.setPosition(val.lat, val.lng);
3265
3266 // No value.
3267 } else {
3268 this.setState('');
3269 this.$search().val('');
3270 this.map.marker.setVisible(false);
3271 }
3272 },
3273 newLatLng: function (lat, lng) {
3274 return new google.maps.LatLng(parseFloat(lat), parseFloat(lng));
3275 },
3276 setPosition: function (lat, lng) {
3277 // Update marker position.
3278 this.map.marker.setPosition({
3279 lat: parseFloat(lat),
3280 lng: parseFloat(lng)
3281 });
3282
3283 // Show marker.
3284 this.map.marker.setVisible(true);
3285
3286 // Center map.
3287 this.center();
3288 },
3289 center: function () {
3290 // Find marker position.
3291 var position = this.map.marker.getPosition();
3292 if (position) {
3293 var lat = position.lat();
3294 var lng = position.lng();
3295
3296 // Or find default settings.
3297 } else {
3298 var lat = this.get('lat');
3299 var lng = this.get('lng');
3300 }
3301
3302 // Center map.
3303 this.map.setCenter({
3304 lat: parseFloat(lat),
3305 lng: parseFloat(lng)
3306 });
3307 },
3308 initialize: function () {
3309 // Ensure Google API is loaded and then initialize map.
3310 withAPI(this.initializeMap.bind(this));
3311 },
3312 initializeMap: function () {
3313 // Get value ignoring conditional logic status.
3314 var val = this.getValue();
3315
3316 // Construct default args.
3317 var args = acf.parseArgs(val, {
3318 zoom: this.get('zoom'),
3319 lat: this.get('lat'),
3320 lng: this.get('lng')
3321 });
3322
3323 // Create Map.
3324 var mapArgs = {
3325 scrollwheel: false,
3326 zoom: parseInt(args.zoom),
3327 center: {
3328 lat: parseFloat(args.lat),
3329 lng: parseFloat(args.lng)
3330 },
3331 mapTypeId: google.maps.MapTypeId.ROADMAP,
3332 marker: {
3333 draggable: true,
3334 raiseOnDrag: true
3335 },
3336 autocomplete: {}
3337 };
3338 mapArgs = acf.applyFilters('google_map_args', mapArgs, this);
3339 var map = new google.maps.Map(this.$canvas()[0], mapArgs);
3340
3341 // Create Marker.
3342 var markerArgs = acf.parseArgs(mapArgs.marker, {
3343 draggable: true,
3344 raiseOnDrag: true,
3345 map: map
3346 });
3347 markerArgs = acf.applyFilters('google_map_marker_args', markerArgs, this);
3348 var marker = new google.maps.Marker(markerArgs);
3349
3350 // Maybe Create Autocomplete.
3351 var autocomplete = false;
3352 if (acf.isset(google, 'maps', 'places', 'Autocomplete')) {
3353 var autocompleteArgs = mapArgs.autocomplete || {};
3354 autocompleteArgs = acf.applyFilters('google_map_autocomplete_args', autocompleteArgs, this);
3355 autocomplete = new google.maps.places.Autocomplete(this.$search()[0], autocompleteArgs);
3356 autocomplete.bindTo('bounds', map);
3357 }
3358
3359 // Add map events.
3360 this.addMapEvents(this, map, marker, autocomplete);
3361
3362 // Append references.
3363 map.acf = this;
3364 map.marker = marker;
3365 map.autocomplete = autocomplete;
3366 this.map = map;
3367
3368 // Set position.
3369 if (val) {
3370 this.setPosition(val.lat, val.lng);
3371 }
3372
3373 /**
3374 * Fires immediately after the Google Map has been initialized.
3375 *
3376 * @date 12/02/2014
3377 * @since ACF 5.0.0
3378 *
3379 * @param object map The Google Map isntance.
3380 * @param object marker The Google Map marker isntance.
3381 * @param object field The field instance.
3382 */
3383 acf.doAction('google_map_init', map, marker, this);
3384 },
3385 addMapEvents: function (field, map, marker, autocomplete) {
3386 // Click map.
3387 google.maps.event.addListener(map, 'click', function (e) {
3388 var lat = e.latLng.lat();
3389 var lng = e.latLng.lng();
3390 field.searchPosition(lat, lng);
3391 });
3392
3393 // Drag marker.
3394 google.maps.event.addListener(marker, 'dragend', function () {
3395 var lat = this.getPosition().lat();
3396 var lng = this.getPosition().lng();
3397 field.searchPosition(lat, lng);
3398 });
3399
3400 // Autocomplete search.
3401 if (autocomplete) {
3402 google.maps.event.addListener(autocomplete, 'place_changed', function () {
3403 var place = this.getPlace();
3404 field.searchPlace(place);
3405 });
3406 }
3407
3408 // Detect zoom change.
3409 google.maps.event.addListener(map, 'zoom_changed', function () {
3410 var val = field.val();
3411 if (val) {
3412 val.zoom = map.getZoom();
3413 field.setValue(val, true);
3414 }
3415 });
3416 },
3417 searchPosition: function (lat, lng) {
3418 //console.log('searchPosition', lat, lng );
3419
3420 // Start Loading.
3421 this.setState('loading');
3422
3423 // Query Geocoder.
3424 var latLng = {
3425 lat: lat,
3426 lng: lng
3427 };
3428 geocoder.geocode({
3429 location: latLng
3430 }, function (results, status) {
3431 //console.log('searchPosition', arguments );
3432
3433 // End Loading.
3434 this.setState('');
3435
3436 // Status failure.
3437 if (status !== 'OK') {
3438 this.showNotice({
3439 text: acf.__('Location not found: %s').replace('%s', status),
3440 type: 'warning'
3441 });
3442
3443 // Success.
3444 } else {
3445 var val = this.parseResult(results[0]);
3446
3447 // Override lat/lng to match user defined marker location.
3448 // Avoids issue where marker "snaps" to nearest result.
3449 val.lat = lat;
3450 val.lng = lng;
3451 this.val(val);
3452 }
3453 }.bind(this));
3454 },
3455 searchPlace: function (place) {
3456 //console.log('searchPlace', place );
3457
3458 // Bail early if no place.
3459 if (!place) {
3460 return;
3461 }
3462
3463 // Selecting from the autocomplete dropdown will return a rich PlaceResult object.
3464 // Be sure to over-write the "formatted_address" value with the one displayed to the user for best UX.
3465 if (place.geometry) {
3466 place.formatted_address = this.$search().val();
3467 var val = this.parseResult(place);
3468 this.val(val);
3469
3470 // Searching a custom address will return an empty PlaceResult object.
3471 } else if (place.name) {
3472 this.searchAddress(place.name);
3473 }
3474 },
3475 searchAddress: function (address) {
3476 //console.log('searchAddress', address );
3477
3478 // Bail early if no address.
3479 if (!address) {
3480 return;
3481 }
3482
3483 // Allow "lat,lng" search.
3484 var latLng = address.split(',');
3485 if (latLng.length == 2) {
3486 var lat = parseFloat(latLng[0]);
3487 var lng = parseFloat(latLng[1]);
3488 if (lat && lng) {
3489 return this.searchPosition(lat, lng);
3490 }
3491 }
3492
3493 // Start Loading.
3494 this.setState('loading');
3495
3496 // Query Geocoder.
3497 geocoder.geocode({
3498 address: address
3499 }, function (results, status) {
3500 //console.log('searchPosition', arguments );
3501
3502 // End Loading.
3503 this.setState('');
3504
3505 // Status failure.
3506 if (status !== 'OK') {
3507 this.showNotice({
3508 text: acf.__('Location not found: %s').replace('%s', status),
3509 type: 'warning'
3510 });
3511
3512 // Success.
3513 } else {
3514 var val = this.parseResult(results[0]);
3515
3516 // Override address data with parameter allowing custom address to be defined in search.
3517 val.address = address;
3518
3519 // Update value.
3520 this.val(val);
3521 }
3522 }.bind(this));
3523 },
3524 searchLocation: function () {
3525 //console.log('searchLocation' );
3526
3527 // Check HTML5 geolocation.
3528 if (!navigator.geolocation) {
3529 return alert(acf.__('Sorry, this browser does not support geolocation'));
3530 }
3531
3532 // Start Loading.
3533 this.setState('loading');
3534
3535 // Query Geolocation.
3536 navigator.geolocation.getCurrentPosition(
3537 // Success.
3538 function (results) {
3539 // End Loading.
3540 this.setState('');
3541
3542 // Search position.
3543 var lat = results.coords.latitude;
3544 var lng = results.coords.longitude;
3545 this.searchPosition(lat, lng);
3546 }.bind(this),
3547 // Failure.
3548 function (error) {
3549 this.setState('');
3550 }.bind(this));
3551 },
3552 /**
3553 * parseResult
3554 *
3555 * Returns location data for the given GeocoderResult object.
3556 *
3557 * @date 15/10/19
3558 * @since ACF 5.8.6
3559 *
3560 * @param object obj A GeocoderResult object.
3561 * @return object
3562 */
3563 parseResult: function (obj) {
3564 // Construct basic data.
3565 var result = {
3566 address: obj.formatted_address,
3567 lat: obj.geometry.location.lat(),
3568 lng: obj.geometry.location.lng()
3569 };
3570
3571 // Add zoom level.
3572 result.zoom = this.map.getZoom();
3573
3574 // Add place ID.
3575 if (obj.place_id) {
3576 result.place_id = obj.place_id;
3577 }
3578
3579 // Add place name.
3580 if (obj.name) {
3581 result.name = obj.name;
3582 }
3583
3584 // Create search map for address component data.
3585 var map = {
3586 street_number: ['street_number'],
3587 street_name: ['street_address', 'route'],
3588 city: ['locality', 'postal_town'],
3589 state: ['administrative_area_level_1', 'administrative_area_level_2', 'administrative_area_level_3', 'administrative_area_level_4', 'administrative_area_level_5'],
3590 post_code: ['postal_code'],
3591 country: ['country']
3592 };
3593
3594 // Loop over map.
3595 for (var k in map) {
3596 var keywords = map[k];
3597
3598 // Loop over address components.
3599 for (var i = 0; i < obj.address_components.length; i++) {
3600 var component = obj.address_components[i];
3601 var component_type = component.types[0];
3602
3603 // Look for matching component type.
3604 if (keywords.indexOf(component_type) !== -1) {
3605 // Append to result.
3606 result[k] = component.long_name;
3607
3608 // Append short version.
3609 if (component.long_name !== component.short_name) {
3610 result[k + '_short'] = component.short_name;
3611 }
3612 }
3613 }
3614 }
3615
3616 /**
3617 * Filters the parsed result.
3618 *
3619 * @date 18/10/19
3620 * @since ACF 5.8.6
3621 *
3622 * @param object result The parsed result value.
3623 * @param object obj The GeocoderResult object.
3624 */
3625 return acf.applyFilters('google_map_result', result, obj, this.map, this);
3626 },
3627 onClickClear: function () {
3628 this.val(false);
3629 },
3630 onClickLocate: function () {
3631 this.searchLocation();
3632 },
3633 onClickSearch: function () {
3634 this.searchAddress(this.$search().val());
3635 },
3636 onFocusSearch: function (e, $el) {
3637 this.setState('searching');
3638 },
3639 onBlurSearch: function (e, $el) {
3640 // Get saved address value.
3641 var val = this.val();
3642 var address = val ? val.address : '';
3643
3644 // Remove 'is-searching' if value has not changed.
3645 if ($el.val() === address) {
3646 this.setState('default');
3647 }
3648 },
3649 onKeyupSearch: function (e, $el) {
3650 // Clear empty value.
3651 if (!$el.val()) {
3652 this.val(false);
3653 }
3654 },
3655 // Prevent form from submitting.
3656 onKeydownSearch: function (e, $el) {
3657 if (e.which == 13) {
3658 e.preventDefault();
3659 $el.blur();
3660 }
3661 },
3662 // Center map once made visible.
3663 onShow: function () {
3664 if (this.map) {
3665 this.setTimeout(this.center);
3666 }
3667 }
3668 });
3669 acf.registerFieldType(Field);
3670
3671 // Vars.
3672 var loading = false;
3673 var geocoder = false;
3674
3675 /**
3676 * withAPI
3677 *
3678 * Loads the Google Maps API library and troggers callback.
3679 *
3680 * @date 28/3/19
3681 * @since ACF 5.7.14
3682 *
3683 * @param function callback The callback to excecute.
3684 * @return void
3685 */
3686
3687 function withAPI(callback) {
3688 // Check if geocoder exists.
3689 if (geocoder) {
3690 return callback();
3691 }
3692
3693 // Check if geocoder API exists.
3694 if (acf.isset(window, 'google', 'maps', 'Geocoder')) {
3695 geocoder = new google.maps.Geocoder();
3696 return callback();
3697 }
3698
3699 // Geocoder will need to be loaded. Hook callback to action.
3700 acf.addAction('google_map_api_loaded', callback);
3701
3702 // Bail early if already loading API.
3703 if (loading) {
3704 return;
3705 }
3706
3707 // load api
3708 var url = acf.get('google_map_api');
3709 if (url) {
3710 // Set loading status.
3711 loading = true;
3712
3713 // Load API
3714 $.ajax({
3715 url: url,
3716 dataType: 'script',
3717 cache: true,
3718 success: function () {
3719 geocoder = new google.maps.Geocoder();
3720 acf.doAction('google_map_api_loaded');
3721 }
3722 });
3723 }
3724 }
3725 })(jQuery);
3726
3727 /***/ }),
3728
3729 /***/ "./assets/src/js/_acf-field-icon-picker.js":
3730 /*!*************************************************!*\
3731 !*** ./assets/src/js/_acf-field-icon-picker.js ***!
3732 \*************************************************/
3733 /***/ (() => {
3734
3735 (function ($, undefined) {
3736 const Field = acf.Field.extend({
3737 type: 'icon_picker',
3738 wait: 'load',
3739 events: {
3740 showField: 'scrollToSelectedDashicon',
3741 'input .acf-icon_url': 'onUrlChange',
3742 'click .acf-icon-picker-dashicon': 'onDashiconClick',
3743 'focus .acf-icon-picker-dashicon-radio': 'onDashiconRadioFocus',
3744 'blur .acf-icon-picker-dashicon-radio': 'onDashiconRadioBlur',
3745 'keydown .acf-icon-picker-dashicon-radio': 'onDashiconKeyDown',
3746 'input .acf-dashicons-search-input': 'onDashiconSearch',
3747 'keydown .acf-dashicons-search-input': 'onDashiconSearchKeyDown',
3748 'click .acf-icon-picker-media-library-button': 'onMediaLibraryButtonClick',
3749 'click .acf-icon-picker-media-library-preview': 'onMediaLibraryButtonClick'
3750 },
3751 $typeInput() {
3752 return this.$('input[type="hidden"][data-hidden-type="type"]:first');
3753 },
3754 $valueInput() {
3755 return this.$('input[type="hidden"][data-hidden-type="value"]:first');
3756 },
3757 $tabButton() {
3758 return this.$('.acf-tab-button');
3759 },
3760 $selectedIcon() {
3761 return this.$('.acf-icon-picker-dashicon.active');
3762 },
3763 $selectedRadio() {
3764 return this.$('.acf-icon-picker-dashicon.active input');
3765 },
3766 $dashiconsList() {
3767 return this.$('.acf-dashicons-list');
3768 },
3769 $mediaLibraryButton() {
3770 return this.$('.acf-icon-picker-media-library-button');
3771 },
3772 initialize() {
3773 // Set up actions hook callbacks.
3774 this.addActions();
3775
3776 // Initialize the state of the icon picker.
3777 let typeAndValue = {
3778 type: this.$typeInput().val(),
3779 value: this.$valueInput().val()
3780 };
3781
3782 // Store the type and value object.
3783 this.set('typeAndValue', typeAndValue);
3784
3785 // Any time any acf tab is clicked, we will re-scroll to the selected dashicon.
3786 $('.acf-tab-button').on('click', () => {
3787 this.initializeDashiconsTab(this.get('typeAndValue'));
3788 });
3789
3790 // Fire the action which lets people know the state has been updated.
3791 acf.doAction(this.get('name') + '/type_and_value_change', typeAndValue);
3792 this.initializeDashiconsTab(typeAndValue);
3793 this.alignMediaLibraryTabToCurrentValue(typeAndValue);
3794 },
3795 addActions() {
3796 // Set up an action listener for when the type and value changes.
3797 acf.addAction(this.get('name') + '/type_and_value_change', newTypeAndValue => {
3798 // Align the visual state of each tab to the current value.
3799 this.alignDashiconsTabToCurrentValue(newTypeAndValue);
3800 this.alignMediaLibraryTabToCurrentValue(newTypeAndValue);
3801 this.alignUrlTabToCurrentValue(newTypeAndValue);
3802 });
3803 },
3804 updateTypeAndValue(type, value) {
3805 const typeAndValue = {
3806 type,
3807 value
3808 };
3809
3810 // Update the values in the hidden fields, which are what will actually be saved.
3811 acf.val(this.$typeInput(), type);
3812 acf.val(this.$valueInput(), value);
3813
3814 // Fire an action to let each tab set itself according to the typeAndValue state.
3815 acf.doAction(this.get('name') + '/type_and_value_change', typeAndValue);
3816
3817 // Set the state.
3818 this.set('typeAndValue', typeAndValue);
3819 },
3820 scrollToSelectedDashicon() {
3821 const innerElement = this.$selectedIcon();
3822
3823 // If no icon is selected, do nothing.
3824 if (innerElement.length === 0) {
3825 return;
3826 }
3827 const scrollingDiv = this.$dashiconsList();
3828 scrollingDiv.scrollTop(0);
3829 const distance = innerElement.position().top - 50;
3830 if (distance === 0) {
3831 return;
3832 }
3833 scrollingDiv.scrollTop(distance);
3834 },
3835 initializeDashiconsTab(typeAndValue) {
3836 const dashicons = this.getDashiconsList() || [];
3837 this.set('dashicons', dashicons);
3838 this.renderDashiconList();
3839 this.initializeSelectedDashicon(typeAndValue);
3840 },
3841 initializeSelectedDashicon(typeAndValue) {
3842 if (typeAndValue.type !== 'dashicons') {
3843 return;
3844 }
3845 // Select the correct dashicon.
3846 this.selectDashicon(typeAndValue.value, false).then(() => {
3847 // Scroll to the selected dashicon.
3848 this.scrollToSelectedDashicon();
3849 });
3850 },
3851 alignDashiconsTabToCurrentValue(typeAndValue) {
3852 if (typeAndValue.type !== 'dashicons') {
3853 this.unselectDashicon();
3854 }
3855 },
3856 renderDashiconHTML(dashicon) {
3857 const id = `${this.get('name')}-${dashicon.key}`;
3858 return `<div class="dashicons ${acf.strEscape(dashicon.key)} acf-icon-picker-dashicon" data-icon="${acf.strEscape(dashicon.key)}">
3859 <label for="${acf.strEscape(id)}">${acf.strEscape(dashicon.label)}</label>
3860 <input id="${acf.strEscape(id)}" type="radio" class="acf-icon-picker-dashicon-radio" name="acf-icon-picker-dashicon-radio" value="${acf.strEscape(dashicon.key)}">
3861 </div>`;
3862 },
3863 renderDashiconList() {
3864 const dashicons = this.get('dashicons');
3865 this.$dashiconsList().empty();
3866 dashicons.forEach(dashicon => {
3867 this.$dashiconsList().append(this.renderDashiconHTML(dashicon));
3868 });
3869 },
3870 getDashiconsList() {
3871 const iconPickeri10n = acf.get('iconPickeri10n') || [];
3872 const dashicons = Object.entries(iconPickeri10n).map(([key, value]) => {
3873 return {
3874 key,
3875 label: value
3876 };
3877 });
3878 return dashicons;
3879 },
3880 getDashiconsBySearch(searchTerm) {
3881 const lowercaseSearchTerm = searchTerm.toLowerCase();
3882 const dashicons = this.getDashiconsList();
3883 const filteredDashicons = dashicons.filter(function (icon) {
3884 const lowercaseIconLabel = icon.label.toLowerCase();
3885 return lowercaseIconLabel.indexOf(lowercaseSearchTerm) > -1;
3886 });
3887 return filteredDashicons;
3888 },
3889 selectDashicon(dashicon, setFocus = true) {
3890 this.set('selectedDashicon', dashicon);
3891
3892 // Select the new one.
3893 const $newIcon = this.$dashiconsList().find('.acf-icon-picker-dashicon[data-icon="' + dashicon + '"]');
3894 $newIcon.addClass('active');
3895 const $input = $newIcon.find('input');
3896 const thePromise = $input.prop('checked', true).promise();
3897 if (setFocus) {
3898 $input.trigger('focus');
3899 }
3900 this.updateTypeAndValue('dashicons', dashicon);
3901 return thePromise;
3902 },
3903 unselectDashicon() {
3904 // Remove the currently active dashicon, if any.
3905 this.$dashiconsList().find('.acf-icon-picker-dashicon').removeClass('active');
3906 this.set('selectedDashicon', false);
3907 },
3908 onDashiconRadioFocus(e) {
3909 const dashicon = e.target.value;
3910 const $newIcon = this.$dashiconsList().find('.acf-icon-picker-dashicon[data-icon="' + dashicon + '"]');
3911 $newIcon.addClass('focus');
3912
3913 // If this is a different icon than previously selected, select it.
3914 if (this.get('selectedDashicon') !== dashicon) {
3915 this.unselectDashicon();
3916 this.selectDashicon(dashicon);
3917 }
3918 },
3919 onDashiconRadioBlur(e) {
3920 const icon = this.$(e.target);
3921 const iconParent = icon.parent();
3922 iconParent.removeClass('focus');
3923 },
3924 onDashiconClick(e) {
3925 e.preventDefault();
3926 const icon = this.$(e.target);
3927 const dashicon = icon.find('input').val();
3928 const $newIcon = this.$dashiconsList().find('.acf-icon-picker-dashicon[data-icon="' + dashicon + '"]');
3929
3930 // By forcing focus on the input, we fire onDashiconRadioFocus.
3931 $newIcon.find('input').prop('checked', true).trigger('focus');
3932 },
3933 onDashiconSearch(e) {
3934 const searchTerm = e.target.value;
3935 const filteredDashicons = this.getDashiconsBySearch(searchTerm);
3936 if (filteredDashicons.length > 0 || !searchTerm) {
3937 this.set('dashicons', filteredDashicons);
3938 this.$('.acf-dashicons-list-empty').hide();
3939 this.$('.acf-dashicons-list ').show();
3940 this.renderDashiconList();
3941
3942 // Announce change of data to screen readers.
3943 wp.a11y.speak(acf.get('iconPickerA11yStrings').newResultsFoundForSearchTerm, 'polite');
3944 } else {
3945 // Truncate the search term if it's too long.
3946 const visualSearchTerm = searchTerm.length > 30 ? searchTerm.substring(0, 30) + '&hellip;' : searchTerm;
3947 this.$('.acf-dashicons-list ').hide();
3948 this.$('.acf-dashicons-list-empty').find('.acf-invalid-dashicon-search-term').text(visualSearchTerm);
3949 this.$('.acf-dashicons-list-empty').css('display', 'flex');
3950 this.$('.acf-dashicons-list-empty').show();
3951
3952 // Announce change of data to screen readers.
3953 wp.a11y.speak(acf.get('iconPickerA11yStrings').noResultsForSearchTerm, 'polite');
3954 }
3955 },
3956 onDashiconSearchKeyDown(e) {
3957 // Check if the pressed key is Enter (key code 13)
3958 if (e.which === 13) {
3959 // Prevent submitting the entire form if someone presses enter after searching.
3960 e.preventDefault();
3961 }
3962 },
3963 onDashiconKeyDown(e) {
3964 if (e.which === 13) {
3965 // If someone presses enter while an icon is focused, prevent the form from submitting.
3966 e.preventDefault();
3967 }
3968 },
3969 alignMediaLibraryTabToCurrentValue(typeAndValue) {
3970 const type = typeAndValue.type;
3971 const value = typeAndValue.value;
3972 if (type !== 'media_library' && type !== 'dashicons') {
3973 // Hide the preview container on the media library tab.
3974 this.$('.acf-icon-picker-media-library-preview').hide();
3975 }
3976 if (type === 'media_library') {
3977 const previewUrl = this.get('mediaLibraryPreviewUrl');
3978 // Set the image file preview src.
3979 this.$('.acf-icon-picker-media-library-preview-img img').attr('src', previewUrl);
3980
3981 // Hide the dashicon preview.
3982 this.$('.acf-icon-picker-media-library-preview-dashicon').hide();
3983
3984 // Show the image file preview.
3985 this.$('.acf-icon-picker-media-library-preview-img').show();
3986
3987 // Show the preview container (it may have been hidden if nothing was ever selected yet).
3988 this.$('.acf-icon-picker-media-library-preview').show();
3989 }
3990 if (type === 'dashicons') {
3991 // Set the dashicon preview class.
3992 this.$('.acf-icon-picker-media-library-preview-dashicon .dashicons').attr('class', 'dashicons ' + value);
3993
3994 // Hide the image file preview.
3995 this.$('.acf-icon-picker-media-library-preview-img').hide();
3996
3997 // Show the dashicon preview.
3998 this.$('.acf-icon-picker-media-library-preview-dashicon').show();
3999
4000 // Show the preview container (it may have been hidden if nothing was ever selected yet).
4001 this.$('.acf-icon-picker-media-library-preview').show();
4002 }
4003 },
4004 async onMediaLibraryButtonClick(e) {
4005 e.preventDefault();
4006 await this.selectAndReturnAttachment().then(attachment => {
4007 // When an attachment is selected, update the preview and the hidden fields.
4008 this.set('mediaLibraryPreviewUrl', attachment.attributes.url);
4009 this.updateTypeAndValue('media_library', attachment.id);
4010 });
4011 },
4012 selectAndReturnAttachment() {
4013 return new Promise(resolve => {
4014 acf.newMediaPopup({
4015 mode: 'select',
4016 type: 'image',
4017 title: acf.__('Select Image'),
4018 field: this.get('key'),
4019 multiple: false,
4020 library: 'all',
4021 allowedTypes: 'image',
4022 select: resolve
4023 });
4024 });
4025 },
4026 alignUrlTabToCurrentValue(typeAndValue) {
4027 if (typeAndValue.type !== 'url') {
4028 this.$('.acf-icon_url').val('');
4029 }
4030 },
4031 onUrlChange(event) {
4032 const currentValue = event.target.value;
4033 this.updateTypeAndValue('url', currentValue);
4034 }
4035 });
4036 acf.registerFieldType(Field);
4037 })(jQuery);
4038
4039 /***/ }),
4040
4041 /***/ "./assets/src/js/_acf-field-image.js":
4042 /*!*******************************************!*\
4043 !*** ./assets/src/js/_acf-field-image.js ***!
4044 \*******************************************/
4045 /***/ (() => {
4046
4047 (function ($, undefined) {
4048 var Field = acf.Field.extend({
4049 type: 'image',
4050 $control: function () {
4051 return this.$('.acf-image-uploader');
4052 },
4053 $input: function () {
4054 return this.$('input[type="hidden"]:first');
4055 },
4056 events: {
4057 'click a[data-name="add"]': 'onClickAdd',
4058 'click a[data-name="edit"]': 'onClickEdit',
4059 'click a[data-name="remove"]': 'onClickRemove',
4060 'change input[type="file"]': 'onChange'
4061 },
4062 initialize: function () {
4063 // add attribute to form
4064 if (this.get('uploader') === 'basic') {
4065 this.$el.closest('form').attr('enctype', 'multipart/form-data');
4066 }
4067 },
4068 validateAttachment: function (attachment) {
4069 // Use WP attachment attributes when available.
4070 if (attachment && attachment.attributes) {
4071 attachment = attachment.attributes;
4072 }
4073
4074 // Apply defaults.
4075 attachment = acf.parseArgs(attachment, {
4076 id: 0,
4077 url: '',
4078 alt: '',
4079 title: '',
4080 caption: '',
4081 description: '',
4082 width: 0,
4083 height: 0
4084 });
4085
4086 // Override with "preview size".
4087 var size = acf.isget(attachment, 'sizes', this.get('preview_size'));
4088 if (size) {
4089 attachment.url = size.url;
4090 attachment.width = size.width;
4091 attachment.height = size.height;
4092 }
4093
4094 // Return.
4095 return attachment;
4096 },
4097 render: function (attachment) {
4098 attachment = this.validateAttachment(attachment);
4099
4100 // Update DOM.
4101 this.$('img').attr({
4102 src: attachment.url,
4103 alt: attachment.alt
4104 });
4105 if (attachment.id) {
4106 this.val(attachment.id);
4107 this.$control().addClass('has-value');
4108 } else {
4109 this.val('');
4110 this.$control().removeClass('has-value');
4111 }
4112 },
4113 // create a new repeater row and render value
4114 append: function (attachment, parent) {
4115 // create function to find next available field within parent
4116 var getNext = function (field, parent) {
4117 // find existing file fields within parent
4118 var fields = acf.getFields({
4119 key: field.get('key'),
4120 parent: parent.$el
4121 });
4122
4123 // find the first field with no value
4124 for (var i = 0; i < fields.length; i++) {
4125 if (!fields[i].val()) {
4126 return fields[i];
4127 }
4128 }
4129
4130 // return
4131 return false;
4132 };
4133
4134 // find existing file fields within parent
4135 var field = getNext(this, parent);
4136
4137 // add new row if no available field
4138 if (!field) {
4139 parent.$('.acf-button:last').trigger('click');
4140 field = getNext(this, parent);
4141 }
4142
4143 // render
4144 if (field) {
4145 field.render(attachment);
4146 }
4147 },
4148 selectAttachment: function () {
4149 // vars
4150 var parent = this.parent();
4151 var multiple = parent && parent.get('type') === 'repeater';
4152
4153 // new frame
4154 var frame = acf.newMediaPopup({
4155 mode: 'select',
4156 type: 'image',
4157 title: acf.__('Select Image'),
4158 field: this.get('key'),
4159 multiple: multiple,
4160 library: this.get('library'),
4161 allowedTypes: this.get('mime_types'),
4162 select: $.proxy(function (attachment, i) {
4163 if (i > 0) {
4164 this.append(attachment, parent);
4165 } else {
4166 this.render(attachment);
4167 }
4168 }, this)
4169 });
4170 },
4171 editAttachment: function () {
4172 // vars
4173 var val = this.val();
4174
4175 // bail early if no val
4176 if (!val) return;
4177
4178 // popup
4179 var frame = acf.newMediaPopup({
4180 mode: 'edit',
4181 title: acf.__('Edit Image'),
4182 button: acf.__('Update Image'),
4183 attachment: val,
4184 field: this.get('key'),
4185 select: $.proxy(function (attachment, i) {
4186 this.render(attachment);
4187 }, this)
4188 });
4189 },
4190 removeAttachment: function () {
4191 this.render(false);
4192 },
4193 onClickAdd: function (e, $el) {
4194 this.selectAttachment();
4195 },
4196 onClickEdit: function (e, $el) {
4197 this.editAttachment();
4198 },
4199 onClickRemove: function (e, $el) {
4200 this.removeAttachment();
4201 },
4202 onChange: function (e, $el) {
4203 var $hiddenInput = this.$input();
4204 if (!$el.val()) {
4205 $hiddenInput.val('');
4206 }
4207 acf.getFileInputData($el, function (data) {
4208 $hiddenInput.val($.param(data));
4209 });
4210 }
4211 });
4212 acf.registerFieldType(Field);
4213 })(jQuery);
4214
4215 /***/ }),
4216
4217 /***/ "./assets/src/js/_acf-field-link.js":
4218 /*!******************************************!*\
4219 !*** ./assets/src/js/_acf-field-link.js ***!
4220 \******************************************/
4221 /***/ (() => {
4222
4223 (function ($, undefined) {
4224 var Field = acf.Field.extend({
4225 type: 'link',
4226 events: {
4227 'click a[data-name="add"]': 'onClickEdit',
4228 'click a[data-name="edit"]': 'onClickEdit',
4229 'click a[data-name="remove"]': 'onClickRemove',
4230 'change .link-node': 'onChange'
4231 },
4232 $control: function () {
4233 return this.$('.acf-link');
4234 },
4235 $node: function () {
4236 return this.$('.link-node');
4237 },
4238 getValue: function () {
4239 // vars
4240 var $node = this.$node();
4241
4242 // return false if empty
4243 if (!$node.attr('href')) {
4244 return false;
4245 }
4246
4247 // return
4248 return {
4249 title: $node.html(),
4250 url: $node.attr('href'),
4251 target: $node.attr('target')
4252 };
4253 },
4254 setValue: function (val) {
4255 // default
4256 val = acf.parseArgs(val, {
4257 title: '',
4258 url: '',
4259 target: ''
4260 });
4261
4262 // vars
4263 var $div = this.$control();
4264 var $node = this.$node();
4265
4266 // remove class
4267 $div.removeClass('-value -external');
4268
4269 // add class
4270 if (val.url) $div.addClass('-value');
4271 if (val.target === '_blank') $div.addClass('-external');
4272
4273 // update text
4274 this.$('.link-title').html(val.title);
4275 this.$('.link-url').attr('href', val.url).text(val.url);
4276
4277 // update node
4278 $node.html(val.title);
4279 $node.attr('href', val.url);
4280 $node.attr('target', val.target);
4281
4282 // update inputs
4283 this.$('.input-title').val(val.title);
4284 this.$('.input-target').val(val.target);
4285 this.$('.input-url').val(val.url).trigger('change');
4286 },
4287 onClickEdit: function (e, $el) {
4288 acf.wpLink.open(this.$node());
4289 },
4290 onClickRemove: function (e, $el) {
4291 this.setValue(false);
4292 },
4293 onChange: function (e, $el) {
4294 // get the changed value
4295 var val = this.getValue();
4296
4297 // update inputs
4298 this.setValue(val);
4299 }
4300 });
4301 acf.registerFieldType(Field);
4302
4303 // manager
4304 acf.wpLink = new acf.Model({
4305 getNodeValue: function () {
4306 var $node = this.get('node');
4307 return {
4308 title: acf.decode($node.html()),
4309 url: $node.attr('href'),
4310 target: $node.attr('target')
4311 };
4312 },
4313 setNodeValue: function (val) {
4314 var $node = this.get('node');
4315 $node.text(val.title);
4316 $node.attr('href', val.url);
4317 $node.attr('target', val.target);
4318 $node.trigger('change');
4319 },
4320 getInputValue: function () {
4321 return {
4322 title: $('#wp-link-text').val(),
4323 url: $('#wp-link-url').val(),
4324 target: $('#wp-link-target').prop('checked') ? '_blank' : ''
4325 };
4326 },
4327 setInputValue: function (val) {
4328 $('#wp-link-text').val(val.title);
4329 $('#wp-link-url').val(val.url);
4330 $('#wp-link-target').prop('checked', val.target === '_blank');
4331 },
4332 open: function ($node) {
4333 // add events
4334 this.on('wplink-open', 'onOpen');
4335 this.on('wplink-close', 'onClose');
4336
4337 // set node
4338 this.set('node', $node);
4339
4340 // create textarea
4341 var $textarea = $('<textarea id="acf-link-textarea" style="display:none;"></textarea>');
4342 $('body').append($textarea);
4343
4344 // vars
4345 var val = this.getNodeValue();
4346
4347 // open popup
4348 wpLink.open('acf-link-textarea', val.url, val.title, null);
4349 },
4350 onOpen: function () {
4351 // always show title (WP will hide title if empty)
4352 $('#wp-link-wrap').addClass('has-text-field');
4353
4354 // set inputs
4355 var val = this.getNodeValue();
4356 this.setInputValue(val);
4357
4358 // Update button text.
4359 if (val.url && wpLinkL10n) {
4360 $('#wp-link-submit').val(wpLinkL10n.update);
4361 }
4362 },
4363 close: function () {
4364 wpLink.close();
4365 },
4366 onClose: function () {
4367 // Bail early if no node.
4368 // Needed due to WP triggering this event twice.
4369 if (!this.has('node')) {
4370 return false;
4371 }
4372
4373 // Determine context.
4374 var $submit = $('#wp-link-submit');
4375 var isSubmit = $submit.is(':hover') || $submit.is(':focus');
4376
4377 // Set value
4378 if (isSubmit) {
4379 var val = this.getInputValue();
4380 this.setNodeValue(val);
4381 }
4382
4383 // Cleanup.
4384 this.off('wplink-open');
4385 this.off('wplink-close');
4386 $('#acf-link-textarea').remove();
4387 this.set('node', null);
4388 }
4389 });
4390 })(jQuery);
4391
4392 /***/ }),
4393
4394 /***/ "./assets/src/js/_acf-field-oembed.js":
4395 /*!********************************************!*\
4396 !*** ./assets/src/js/_acf-field-oembed.js ***!
4397 \********************************************/
4398 /***/ (() => {
4399
4400 (function ($, undefined) {
4401 var Field = acf.Field.extend({
4402 type: 'oembed',
4403 events: {
4404 'click [data-name="clear-button"]': 'onClickClear',
4405 'keypress .input-search': 'onKeypressSearch',
4406 'keyup .input-search': 'onKeyupSearch',
4407 'change .input-search': 'onChangeSearch'
4408 },
4409 $control: function () {
4410 return this.$('.acf-oembed');
4411 },
4412 $input: function () {
4413 return this.$('.input-value');
4414 },
4415 $search: function () {
4416 return this.$('.input-search');
4417 },
4418 getValue: function () {
4419 return this.$input().val();
4420 },
4421 getSearchVal: function () {
4422 return this.$search().val();
4423 },
4424 setValue: function (val) {
4425 // class
4426 if (val) {
4427 this.$control().addClass('has-value');
4428 } else {
4429 this.$control().removeClass('has-value');
4430 }
4431 acf.val(this.$input(), val);
4432 },
4433 showLoading: function (show) {
4434 acf.showLoading(this.$('.canvas'));
4435 },
4436 hideLoading: function () {
4437 acf.hideLoading(this.$('.canvas'));
4438 },
4439 maybeSearch: function () {
4440 // vars
4441 var prevUrl = this.val();
4442 var url = this.getSearchVal();
4443
4444 // no value
4445 if (!url) {
4446 return this.clear();
4447 }
4448
4449 // fix missing 'http://' - causes the oembed code to error and fail
4450 if (url.substr(0, 4) != 'http') {
4451 url = 'http://' + url;
4452 }
4453
4454 // bail early if no change
4455 if (url === prevUrl) return;
4456
4457 // clear existing timeout
4458 var timeout = this.get('timeout');
4459 if (timeout) {
4460 clearTimeout(timeout);
4461 }
4462
4463 // set new timeout
4464 var callback = $.proxy(this.search, this, url);
4465 this.set('timeout', setTimeout(callback, 300));
4466 },
4467 search: function (url) {
4468 const ajaxData = {
4469 action: 'acf/fields/oembed/search',
4470 s: url,
4471 field_key: this.get('key'),
4472 nonce: this.get('nonce')
4473 };
4474
4475 // clear existing timeout
4476 let xhr = this.get('xhr');
4477 if (xhr) {
4478 xhr.abort();
4479 }
4480
4481 // loading
4482 this.showLoading();
4483
4484 // query
4485 xhr = $.ajax({
4486 url: acf.get('ajaxurl'),
4487 data: acf.prepareForAjax(ajaxData),
4488 type: 'post',
4489 dataType: 'json',
4490 context: this,
4491 success: function (json) {
4492 // error
4493 if (!json || !json.html) {
4494 json = {
4495 url: false,
4496 html: ''
4497 };
4498 }
4499
4500 // update vars
4501 this.val(json.url);
4502 this.$('.canvas-media').html(json.html);
4503 },
4504 complete: function () {
4505 this.hideLoading();
4506 }
4507 });
4508 this.set('xhr', xhr);
4509 },
4510 clear: function () {
4511 this.val('');
4512 this.$search().val('');
4513 this.$('.canvas-media').html('');
4514 },
4515 onClickClear: function (e, $el) {
4516 this.clear();
4517 },
4518 onKeypressSearch: function (e, $el) {
4519 if (e.which == 13) {
4520 e.preventDefault();
4521 this.maybeSearch();
4522 }
4523 },
4524 onKeyupSearch: function (e, $el) {
4525 if ($el.val()) {
4526 this.maybeSearch();
4527 }
4528 },
4529 onChangeSearch: function (e, $el) {
4530 this.maybeSearch();
4531 }
4532 });
4533 acf.registerFieldType(Field);
4534 })(jQuery);
4535
4536 /***/ }),
4537
4538 /***/ "./assets/src/js/_acf-field-page-link.js":
4539 /*!***********************************************!*\
4540 !*** ./assets/src/js/_acf-field-page-link.js ***!
4541 \***********************************************/
4542 /***/ (() => {
4543
4544 (function ($, undefined) {
4545 var Field = acf.models.SelectField.extend({
4546 type: 'page_link'
4547 });
4548 acf.registerFieldType(Field);
4549 })(jQuery);
4550
4551 /***/ }),
4552
4553 /***/ "./assets/src/js/_acf-field-post-object.js":
4554 /*!*************************************************!*\
4555 !*** ./assets/src/js/_acf-field-post-object.js ***!
4556 \*************************************************/
4557 /***/ (() => {
4558
4559 (function ($, undefined) {
4560 var Field = acf.models.SelectField.extend({
4561 type: 'post_object'
4562 });
4563 acf.registerFieldType(Field);
4564 })(jQuery);
4565
4566 /***/ }),
4567
4568 /***/ "./assets/src/js/_acf-field-radio.js":
4569 /*!*******************************************!*\
4570 !*** ./assets/src/js/_acf-field-radio.js ***!
4571 \*******************************************/
4572 /***/ (() => {
4573
4574 (function ($, undefined) {
4575 var Field = acf.Field.extend({
4576 type: 'radio',
4577 events: {
4578 'click input[type="radio"]': 'onClick'
4579 },
4580 $control: function () {
4581 return this.$('.acf-radio-list');
4582 },
4583 $input: function () {
4584 return this.$('input:checked');
4585 },
4586 $inputText: function () {
4587 return this.$('input[type="text"]');
4588 },
4589 getValue: function () {
4590 var val = this.$input().val();
4591 if (val === 'other' && this.get('other_choice')) {
4592 val = this.$inputText().val();
4593 }
4594 return val;
4595 },
4596 onClick: function (e, $el) {
4597 // vars
4598 var $label = $el.parent('label');
4599 var selected = $label.hasClass('selected');
4600 var val = $el.val();
4601
4602 // remove previous selected
4603 this.$('.selected').removeClass('selected');
4604
4605 // add active class
4606 $label.addClass('selected');
4607
4608 // allow null
4609 if (this.get('allow_null') && selected) {
4610 $label.removeClass('selected');
4611 $el.prop('checked', false).trigger('change');
4612 val = false;
4613 }
4614
4615 // other
4616 if (this.get('other_choice')) {
4617 // enable
4618 if (val === 'other') {
4619 this.$inputText().prop('disabled', false);
4620
4621 // disable
4622 } else {
4623 this.$inputText().prop('disabled', true);
4624 }
4625 }
4626 }
4627 });
4628 acf.registerFieldType(Field);
4629 })(jQuery);
4630
4631 /***/ }),
4632
4633 /***/ "./assets/src/js/_acf-field-range.js":
4634 /*!*******************************************!*\
4635 !*** ./assets/src/js/_acf-field-range.js ***!
4636 \*******************************************/
4637 /***/ (() => {
4638
4639 (function ($, undefined) {
4640 var Field = acf.Field.extend({
4641 type: 'range',
4642 events: {
4643 'input input[type="range"]': 'onChange',
4644 'change input': 'onChange'
4645 },
4646 $input: function () {
4647 return this.$('input[type="range"]');
4648 },
4649 $inputAlt: function () {
4650 return this.$('input[type="number"]');
4651 },
4652 setValue: function (val) {
4653 this.busy = true;
4654
4655 // Update range input (with change).
4656 acf.val(this.$input(), val);
4657
4658 // Update alt input (without change).
4659 // Read in input value to inherit min/max validation.
4660 acf.val(this.$inputAlt(), this.$input().val(), true);
4661 this.busy = false;
4662 },
4663 onChange: function (e, $el) {
4664 if (!this.busy) {
4665 this.setValue($el.val());
4666 }
4667 }
4668 });
4669 acf.registerFieldType(Field);
4670 })(jQuery);
4671
4672 /***/ }),
4673
4674 /***/ "./assets/src/js/_acf-field-relationship.js":
4675 /*!**************************************************!*\
4676 !*** ./assets/src/js/_acf-field-relationship.js ***!
4677 \**************************************************/
4678 /***/ (() => {
4679
4680 (function ($, undefined) {
4681 var Field = acf.Field.extend({
4682 type: 'relationship',
4683 events: {
4684 'keypress [data-filter]': 'onKeypressFilter',
4685 'change [data-filter]': 'onChangeFilter',
4686 'keyup [data-filter]': 'onChangeFilter',
4687 'click .choices-list .acf-rel-item': 'onClickAdd',
4688 'keypress .choices-list .acf-rel-item': 'onKeypressFilter',
4689 'keypress .values-list .acf-rel-item': 'onKeypressFilter',
4690 'click [data-name="remove_item"]': 'onClickRemove',
4691 'touchstart .values-list .acf-rel-item': 'onTouchStartValues'
4692 },
4693 $control: function () {
4694 return this.$('.acf-relationship');
4695 },
4696 $list: function (list) {
4697 return this.$('.' + list + '-list');
4698 },
4699 $listItems: function (list) {
4700 return this.$list(list).find('.acf-rel-item');
4701 },
4702 $listItem: function (list, id) {
4703 return this.$list(list).find('.acf-rel-item[data-id="' + id + '"]');
4704 },
4705 getValue: function () {
4706 var val = [];
4707 this.$listItems('values').each(function () {
4708 val.push($(this).data('id'));
4709 });
4710 return val.length ? val : false;
4711 },
4712 newChoice: function (props) {
4713 return ['<li>', '<span tabindex="0" data-id="' + props.id + '" class="acf-rel-item">' + props.text + '</span>', '</li>'].join('');
4714 },
4715 newValue: function (props) {
4716 return ['<li>', '<input type="hidden" name="' + this.getInputName() + '[]" value="' + props.id + '" />', '<span tabindex="0" data-id="' + props.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('');
4717 },
4718 initialize: function () {
4719 // Delay initialization until "interacted with" or "in view".
4720 var delayed = this.proxy(acf.once(function () {
4721 // Add sortable.
4722 this.$list('values').sortable({
4723 items: 'li',
4724 forceHelperSize: true,
4725 forcePlaceholderSize: true,
4726 scroll: true,
4727 update: this.proxy(function () {
4728 this.$input().trigger('change');
4729 })
4730 });
4731
4732 // Avoid browser remembering old scroll position and add event.
4733 this.$list('choices').scrollTop(0).on('scroll', this.proxy(this.onScrollChoices));
4734
4735 // Fetch choices.
4736 this.fetch();
4737 }));
4738
4739 // Bind "interacted with".
4740 this.$el.one('mouseover', delayed);
4741 this.$el.one('focus', 'input', delayed);
4742
4743 // Bind "in view".
4744 acf.onceInView(this.$el, delayed);
4745 },
4746 onScrollChoices: function (e) {
4747 // bail early if no more results
4748 if (this.get('loading') || !this.get('more')) {
4749 return;
4750 }
4751
4752 // Scrolled to bottom
4753 var $list = this.$list('choices');
4754 var scrollTop = Math.ceil($list.scrollTop());
4755 var scrollHeight = Math.ceil($list[0].scrollHeight);
4756 var innerHeight = Math.ceil($list.innerHeight());
4757 var paged = this.get('paged') || 1;
4758 if (scrollTop + innerHeight >= scrollHeight) {
4759 // update paged
4760 this.set('paged', paged + 1);
4761
4762 // fetch
4763 this.fetch();
4764 }
4765 },
4766 onKeypressFilter: function (e, $el) {
4767 // Receive enter key when selecting relationship items.
4768 if ($el.hasClass('acf-rel-item-add') && e.which == 13) {
4769 this.onClickAdd(e, $el);
4770 }
4771 // Receive enter key when removing relationship items.
4772 if ($el.hasClass('acf-rel-item-remove') && e.which == 13) {
4773 this.onClickRemove(e, $el);
4774 }
4775 // don't submit form
4776 if (e.which == 13) {
4777 e.preventDefault();
4778 }
4779 },
4780 onChangeFilter: function (e, $el) {
4781 // vars
4782 var val = $el.val();
4783 var filter = $el.data('filter');
4784
4785 // Bail early if filter has not changed
4786 if (this.get(filter) === val) {
4787 return;
4788 }
4789
4790 // update attr
4791 this.set(filter, val);
4792 if (filter === 's') {
4793 // If val is numeric, limit results to include.
4794 if (parseInt(val)) {
4795 this.set('include', val);
4796 }
4797 }
4798
4799 // reset paged
4800 this.set('paged', 1);
4801
4802 // fetch
4803 if ($el.is('select')) {
4804 this.fetch();
4805
4806 // search must go through timeout
4807 } else {
4808 this.maybeFetch();
4809 }
4810 },
4811 onClickAdd: function (e, $el) {
4812 // vars
4813 var val = this.val();
4814 var max = parseInt(this.get('max'));
4815
4816 // can be added?
4817 if ($el.hasClass('disabled')) {
4818 return false;
4819 }
4820
4821 // validate
4822 if (max > 0 && val && val.length >= max) {
4823 // add notice
4824 this.showNotice({
4825 text: acf.__('Maximum values reached ( {max} values )').replace('{max}', max),
4826 type: 'warning'
4827 });
4828 return false;
4829 }
4830
4831 // disable
4832 $el.addClass('disabled');
4833
4834 // add
4835 var html = this.newValue({
4836 id: $el.data('id'),
4837 text: $el.html()
4838 });
4839 this.$list('values').append(html);
4840
4841 // trigger change
4842 this.$input().trigger('change');
4843 },
4844 onClickRemove: function (e, $el) {
4845 // Prevent default here because generic handler wont be triggered.
4846 e.preventDefault();
4847 let $span;
4848 // Behavior if triggered from tabbed event.
4849 if ($el.hasClass('acf-rel-item-remove')) {
4850 $span = $el;
4851 } else {
4852 // Behavior if triggered through click event.
4853 $span = $el.parent();
4854 }
4855
4856 // vars
4857 const $li = $span.parent();
4858 const id = $span.data('id');
4859
4860 // remove value
4861 $li.remove();
4862
4863 // show choice
4864 this.$listItem('choices', id).removeClass('disabled');
4865
4866 // trigger change
4867 this.$input().trigger('change');
4868 },
4869 onTouchStartValues: function (e, $el) {
4870 $(this.$listItems('values')).removeClass('relationship-hover');
4871 $el.addClass('relationship-hover');
4872 },
4873 maybeFetch: function () {
4874 // vars
4875 var timeout = this.get('timeout');
4876
4877 // abort timeout
4878 if (timeout) {
4879 clearTimeout(timeout);
4880 }
4881
4882 // fetch
4883 timeout = this.setTimeout(this.fetch, 300);
4884 this.set('timeout', timeout);
4885 },
4886 getAjaxData: function () {
4887 // load data based on element attributes
4888 var ajaxData = this.$control().data();
4889 for (var name in ajaxData) {
4890 ajaxData[name] = this.get(name);
4891 }
4892
4893 // extra
4894 ajaxData.action = 'acf/fields/relationship/query';
4895 ajaxData.field_key = this.get('key');
4896 ajaxData.nonce = this.get('nonce');
4897
4898 // Filter.
4899 ajaxData = acf.applyFilters('relationship_ajax_data', ajaxData, this);
4900
4901 // return
4902 return ajaxData;
4903 },
4904 fetch: function () {
4905 // abort XHR if this field is already loading AJAX data
4906 var xhr = this.get('xhr');
4907 if (xhr) {
4908 xhr.abort();
4909 }
4910
4911 // add to this.o
4912 var ajaxData = this.getAjaxData();
4913
4914 // clear html if is new query
4915 var $choiceslist = this.$list('choices');
4916 if (ajaxData.paged == 1) {
4917 $choiceslist.html('');
4918 }
4919
4920 // loading
4921 var $loading = $('<li><i class="acf-loading"></i> ' + acf.__('Loading') + '</li>');
4922 $choiceslist.append($loading);
4923 this.set('loading', true);
4924
4925 // callback
4926 var onComplete = function () {
4927 this.set('loading', false);
4928 $loading.remove();
4929 };
4930 var onSuccess = function (json) {
4931 // no results
4932 if (!json || !json.results || !json.results.length) {
4933 // prevent pagination
4934 this.set('more', false);
4935
4936 // add message
4937 if (this.get('paged') == 1) {
4938 this.$list('choices').append('<li>' + acf.__('No matches found') + '</li>');
4939 }
4940
4941 // return
4942 return;
4943 }
4944
4945 // set more (allows pagination scroll)
4946 this.set('more', json.more);
4947
4948 // get new results
4949 var html = this.walkChoices(json.results);
4950 var $html = $(html);
4951
4952 // apply .disabled to left li's
4953 var val = this.val();
4954 if (val && val.length) {
4955 val.map(function (id) {
4956 $html.find('.acf-rel-item[data-id="' + id + '"]').addClass('disabled');
4957 });
4958 }
4959
4960 // append
4961 $choiceslist.append($html);
4962
4963 // merge together groups
4964 var $prevLabel = false;
4965 var $prevList = false;
4966 $choiceslist.find('.acf-rel-label').each(function () {
4967 var $label = $(this);
4968 var $list = $label.siblings('ul');
4969 if ($prevLabel && $prevLabel.text() == $label.text()) {
4970 $prevList.append($list.children());
4971 $(this).parent().remove();
4972 return;
4973 }
4974
4975 // update vars
4976 $prevLabel = $label;
4977 $prevList = $list;
4978 });
4979 };
4980
4981 // get results
4982 var xhr = $.ajax({
4983 url: acf.get('ajaxurl'),
4984 dataType: 'json',
4985 type: 'post',
4986 data: acf.prepareForAjax(ajaxData),
4987 context: this,
4988 success: onSuccess,
4989 complete: onComplete
4990 });
4991
4992 // set
4993 this.set('xhr', xhr);
4994 },
4995 walkChoices: function (data) {
4996 // walker
4997 var walk = function (data) {
4998 // vars
4999 var html = '';
5000
5001 // is array
5002 if ($.isArray(data)) {
5003 data.map(function (item) {
5004 html += walk(item);
5005 });
5006
5007 // is item
5008 } else if ($.isPlainObject(data)) {
5009 // group
5010 if (data.children !== undefined) {
5011 html += '<li><span class="acf-rel-label">' + acf.escHtml(data.text) + '</span><ul class="acf-bl">';
5012 html += walk(data.children);
5013 html += '</ul></li>';
5014
5015 // single
5016 } else {
5017 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>';
5018 }
5019 }
5020
5021 // return
5022 return html;
5023 };
5024 return walk(data);
5025 }
5026 });
5027 acf.registerFieldType(Field);
5028 })(jQuery);
5029
5030 /***/ }),
5031
5032 /***/ "./assets/src/js/_acf-field-select.js":
5033 /*!********************************************!*\
5034 !*** ./assets/src/js/_acf-field-select.js ***!
5035 \********************************************/
5036 /***/ (() => {
5037
5038 (function ($, undefined) {
5039 var Field = acf.Field.extend({
5040 type: 'select',
5041 select2: false,
5042 wait: 'load',
5043 events: {
5044 removeField: 'onRemove',
5045 duplicateField: 'onDuplicate'
5046 },
5047 $input: function () {
5048 return this.$('select');
5049 },
5050 initialize: function () {
5051 // vars
5052 var $select = this.$input();
5053
5054 // inherit data
5055 this.inherit($select);
5056
5057 // select2
5058 if (this.get('ui')) {
5059 // populate ajax_data (allowing custom attribute to already exist)
5060 var ajaxAction = this.get('ajax_action');
5061 if (!ajaxAction) {
5062 ajaxAction = 'acf/fields/' + this.get('type') + '/query';
5063 }
5064
5065 // select2
5066 this.select2 = acf.newSelect2($select, {
5067 field: this,
5068 ajax: this.get('ajax'),
5069 multiple: this.get('multiple'),
5070 placeholder: this.get('placeholder'),
5071 allowNull: this.get('allow_null'),
5072 ajaxAction: ajaxAction
5073 });
5074 }
5075 },
5076 onRemove: function () {
5077 if (this.select2) {
5078 this.select2.destroy();
5079 }
5080 },
5081 onDuplicate: function (e, $el, $duplicate) {
5082 if (this.select2) {
5083 $duplicate.find('.select2-container').remove();
5084 $duplicate.find('select').removeClass('select2-hidden-accessible');
5085 }
5086 }
5087 });
5088 acf.registerFieldType(Field);
5089 })(jQuery);
5090
5091 /***/ }),
5092
5093 /***/ "./assets/src/js/_acf-field-tab.js":
5094 /*!*****************************************!*\
5095 !*** ./assets/src/js/_acf-field-tab.js ***!
5096 \*****************************************/
5097 /***/ (() => {
5098
5099 (function ($, undefined) {
5100 // vars
5101 var CONTEXT = 'tab';
5102 var Field = acf.Field.extend({
5103 type: 'tab',
5104 wait: '',
5105 tabs: false,
5106 tab: false,
5107 events: {
5108 duplicateField: 'onDuplicate'
5109 },
5110 findFields: function () {
5111 let filter;
5112
5113 /**
5114 * Tabs in the admin UI that can be extended by third
5115 * parties have the child settings wrapped inside an extra div,
5116 * so we need to look for that instead of an adjacent .acf-field.
5117 */
5118 switch (this.get('key')) {
5119 case 'acf_field_settings_tabs':
5120 filter = '.acf-field-settings-main';
5121 break;
5122 case 'acf_field_group_settings_tabs':
5123 filter = '.field-group-settings-tab';
5124 break;
5125 case 'acf_browse_fields_tabs':
5126 filter = '.acf-field-types-tab';
5127 break;
5128 case 'acf_icon_picker_tabs':
5129 filter = '.acf-icon-picker-tabs';
5130 break;
5131 case 'acf_post_type_tabs':
5132 filter = '.acf-post-type-advanced-settings';
5133 break;
5134 case 'acf_taxonomy_tabs':
5135 filter = '.acf-taxonomy-advanced-settings';
5136 break;
5137 case 'acf_ui_options_page_tabs':
5138 filter = '.acf-ui-options-page-advanced-settings';
5139 break;
5140 default:
5141 filter = '.acf-field';
5142 }
5143 return this.$el.nextUntil('.acf-field-tab', filter);
5144 },
5145 getFields: function () {
5146 return acf.getFields(this.findFields());
5147 },
5148 findTabs: function () {
5149 return this.$el.prevAll('.acf-tab-wrap:first');
5150 },
5151 findTab: function () {
5152 return this.$('.acf-tab-button');
5153 },
5154 initialize: function () {
5155 // bail early if is td
5156 if (this.$el.is('td')) {
5157 this.events = {};
5158 return false;
5159 }
5160
5161 // vars
5162 var $tabs = this.findTabs();
5163 var $tab = this.findTab();
5164 var settings = acf.parseArgs($tab.data(), {
5165 endpoint: false,
5166 placement: '',
5167 before: this.$el
5168 });
5169
5170 // create wrap
5171 if (!$tabs.length || settings.endpoint) {
5172 this.tabs = new Tabs(settings);
5173 } else {
5174 this.tabs = $tabs.data('acf');
5175 }
5176
5177 // add tab
5178 this.tab = this.tabs.addTab($tab, this);
5179 },
5180 isActive: function () {
5181 return this.tab.isActive();
5182 },
5183 showFields: function () {
5184 // show fields
5185 this.getFields().map(function (field) {
5186 field.show(this.cid, CONTEXT);
5187 field.hiddenByTab = false;
5188 }, this);
5189 },
5190 hideFields: function () {
5191 // hide fields
5192 this.getFields().map(function (field) {
5193 field.hide(this.cid, CONTEXT);
5194 field.hiddenByTab = this.tab;
5195 }, this);
5196 },
5197 show: function (lockKey) {
5198 // show field and store result
5199 var visible = acf.Field.prototype.show.apply(this, arguments);
5200
5201 // check if now visible
5202 if (visible) {
5203 // show tab
5204 this.tab.show();
5205
5206 // check active tabs
5207 this.tabs.refresh();
5208 }
5209
5210 // return
5211 return visible;
5212 },
5213 hide: function (lockKey) {
5214 // hide field and store result
5215 var hidden = acf.Field.prototype.hide.apply(this, arguments);
5216
5217 // check if now hidden
5218 if (hidden) {
5219 // hide tab
5220 this.tab.hide();
5221
5222 // reset tabs if this was active
5223 if (this.isActive()) {
5224 this.tabs.reset();
5225 }
5226 }
5227
5228 // return
5229 return hidden;
5230 },
5231 enable: function (lockKey) {
5232 // enable fields
5233 this.getFields().map(function (field) {
5234 field.enable(CONTEXT);
5235 });
5236 },
5237 disable: function (lockKey) {
5238 // disable fields
5239 this.getFields().map(function (field) {
5240 field.disable(CONTEXT);
5241 });
5242 },
5243 onDuplicate: function (e, $el, $duplicate) {
5244 if (this.isActive()) {
5245 $duplicate.prevAll('.acf-tab-wrap:first').remove();
5246 }
5247 }
5248 });
5249 acf.registerFieldType(Field);
5250
5251 /**
5252 * tabs
5253 *
5254 * description
5255 *
5256 * @date 8/2/18
5257 * @since ACF 5.6.5
5258 *
5259 * @param type $var Description. Default.
5260 * @return type Description.
5261 */
5262
5263 var i = 0;
5264 var Tabs = acf.Model.extend({
5265 tabs: [],
5266 active: false,
5267 actions: {
5268 refresh: 'onRefresh',
5269 close_field_object: 'onCloseFieldObject'
5270 },
5271 data: {
5272 before: false,
5273 placement: 'top',
5274 index: 0,
5275 initialized: false
5276 },
5277 setup: function (settings) {
5278 // data
5279 $.extend(this.data, settings);
5280
5281 // define this prop to avoid scope issues
5282 this.tabs = [];
5283 this.active = false;
5284
5285 // vars
5286 var placement = this.get('placement');
5287 var $before = this.get('before');
5288 var $parent = $before.parent();
5289
5290 // add sidebar for left placement
5291 if (placement == 'left' && $parent.hasClass('acf-fields')) {
5292 $parent.addClass('-sidebar');
5293 }
5294
5295 // create wrap
5296 if ($before.is('tr')) {
5297 this.$el = $('<tr class="acf-tab-wrap"><td colspan="2"><ul class="acf-hl acf-tab-group"></ul></td></tr>');
5298 } else {
5299 let ulClass = 'acf-hl acf-tab-group';
5300 if (this.get('key') === 'acf_field_settings_tabs') {
5301 ulClass = 'acf-field-settings-tab-bar';
5302 }
5303 this.$el = $('<div class="acf-tab-wrap -' + placement + '"><ul class="' + ulClass + '"></ul></div>');
5304 }
5305
5306 // append
5307 $before.before(this.$el);
5308
5309 // set index
5310 this.set('index', i, true);
5311 i++;
5312 },
5313 initializeTabs: function () {
5314 // Bail if tabs are disabled.
5315 if ('acf_field_settings_tabs' === this.get('key') && $('#acf-field-group-fields').hasClass('hide-tabs')) {
5316 return;
5317 }
5318 var tab = false;
5319
5320 // check if we've got a saved default tab.
5321 var order = acf.getPreference('this.tabs') || false;
5322 if (order) {
5323 var groupIndex = this.get('index');
5324 var tabIndex = order[groupIndex];
5325 if (this.tabs[tabIndex] && this.tabs[tabIndex].isVisible()) {
5326 tab = this.tabs[tabIndex];
5327 }
5328 }
5329
5330 // If we've got a defaultTab provided by configuration, use that.
5331 if (!tab && this.data.defaultTab && this.data.defaultTab.isVisible()) {
5332 tab = this.data.defaultTab;
5333 }
5334
5335 // find first visible tab as our default.
5336 if (!tab) {
5337 tab = this.getVisible().shift();
5338 }
5339 if (tab) {
5340 this.selectTab(tab);
5341 } else {
5342 this.closeTabs();
5343 }
5344
5345 // set local variable used by tabsManager
5346 this.set('initialized', true);
5347 },
5348 getVisible: function () {
5349 return this.tabs.filter(function (tab) {
5350 return tab.isVisible();
5351 });
5352 },
5353 getActive: function () {
5354 return this.active;
5355 },
5356 setActive: function (tab) {
5357 return this.active = tab;
5358 },
5359 hasActive: function () {
5360 return this.active !== false;
5361 },
5362 isActive: function (tab) {
5363 var active = this.getActive();
5364 return active && active.cid === tab.cid;
5365 },
5366 closeActive: function () {
5367 if (this.hasActive()) {
5368 this.closeTab(this.getActive());
5369 }
5370 },
5371 openTab: function (tab) {
5372 // close existing tab
5373 this.closeActive();
5374
5375 // open
5376 tab.open();
5377
5378 // set active
5379 this.setActive(tab);
5380 },
5381 closeTab: function (tab) {
5382 // close
5383 tab.close();
5384
5385 // set active
5386 this.setActive(false);
5387 },
5388 closeTabs: function () {
5389 this.tabs.map(this.closeTab, this);
5390 },
5391 selectTab: function (tab) {
5392 // close other tabs
5393 this.tabs.map(function (t) {
5394 if (tab.cid !== t.cid) {
5395 this.closeTab(t);
5396 }
5397 }, this);
5398
5399 // open
5400 this.openTab(tab);
5401 },
5402 addTab: function ($a, field) {
5403 // create <li>
5404 var $li = $('<li>' + $a.outerHTML() + '</li>');
5405
5406 // add settings type class.
5407 var settingsType = $a.data('settings-type');
5408 if (settingsType) {
5409 $li.addClass('acf-settings-type-' + settingsType);
5410 }
5411
5412 // append
5413 this.$('ul').append($li);
5414
5415 // initialize
5416 var tab = new Tab({
5417 $el: $li,
5418 field: field,
5419 group: this
5420 });
5421
5422 // store
5423 this.tabs.push(tab);
5424 if ($a.data('selected')) {
5425 this.data.defaultTab = tab;
5426 }
5427
5428 // return
5429 return tab;
5430 },
5431 reset: function () {
5432 // close existing tab
5433 this.closeActive();
5434
5435 // find and active a tab
5436 return this.refresh();
5437 },
5438 refresh: function () {
5439 // bail early if active already exists
5440 if (this.hasActive()) {
5441 return false;
5442 }
5443 // find next active tab
5444 var tab = this.getVisible().shift();
5445 // open tab
5446 if (tab) {
5447 this.openTab(tab);
5448 }
5449
5450 // return
5451 return tab;
5452 },
5453 onRefresh: function () {
5454 // only for left placements
5455 if (this.get('placement') !== 'left') {
5456 return;
5457 }
5458
5459 // vars
5460 var $parent = this.$el.parent();
5461 var $list = this.$el.children('ul');
5462 var attribute = $parent.is('td') ? 'height' : 'min-height';
5463
5464 // find height (minus 1 for border-bottom)
5465 var height = $list.position().top + $list.outerHeight(true) - 1;
5466
5467 // add css
5468 $parent.css(attribute, height);
5469 },
5470 onCloseFieldObject: function (fieldObject) {
5471 const tab = this.getVisible().find(item => {
5472 const id = item.$el.closest('div[data-id]').data('id');
5473 if (fieldObject.data.id === id) {
5474 return item;
5475 }
5476 });
5477 if (tab) {
5478 // Wait for field group drawer to close
5479 setTimeout(() => {
5480 this.openTab(tab);
5481 }, 300);
5482 }
5483 }
5484 });
5485 var Tab = acf.Model.extend({
5486 group: false,
5487 field: false,
5488 events: {
5489 'click a': 'onClick'
5490 },
5491 index: function () {
5492 return this.$el.index();
5493 },
5494 isVisible: function () {
5495 return acf.isVisible(this.$el);
5496 },
5497 isActive: function () {
5498 return this.$el.hasClass('active');
5499 },
5500 open: function () {
5501 // add class
5502 this.$el.addClass('active');
5503
5504 // show field
5505 this.field.showFields();
5506 },
5507 close: function () {
5508 // remove class
5509 this.$el.removeClass('active');
5510
5511 // hide field
5512 this.field.hideFields();
5513 },
5514 onClick: function (e, $el) {
5515 // prevent default
5516 e.preventDefault();
5517
5518 // toggle
5519 this.toggle();
5520 },
5521 toggle: function () {
5522 // bail early if already active
5523 if (this.isActive()) {
5524 return;
5525 }
5526
5527 // toggle this tab
5528 this.group.openTab(this);
5529 }
5530 });
5531 var tabsManager = new acf.Model({
5532 priority: 50,
5533 actions: {
5534 prepare: 'render',
5535 append: 'render',
5536 unload: 'onUnload',
5537 show: 'render',
5538 invalid_field: 'onInvalidField'
5539 },
5540 findTabs: function () {
5541 return $('.acf-tab-wrap');
5542 },
5543 getTabs: function () {
5544 return acf.getInstances(this.findTabs());
5545 },
5546 render: function ($el) {
5547 this.getTabs().map(function (tabs) {
5548 if (!tabs.get('initialized')) {
5549 tabs.initializeTabs();
5550 }
5551 });
5552 },
5553 onInvalidField: function (field) {
5554 // bail early if busy
5555 if (this.busy) {
5556 return;
5557 }
5558
5559 // ignore if not hidden by tab
5560 if (!field.hiddenByTab) {
5561 return;
5562 }
5563
5564 // toggle tab
5565 field.hiddenByTab.toggle();
5566
5567 // ignore other invalid fields
5568 this.busy = true;
5569 this.setTimeout(function () {
5570 this.busy = false;
5571 }, 100);
5572 },
5573 onUnload: function () {
5574 // vars
5575 var order = [];
5576
5577 // loop
5578 this.getTabs().map(function (group) {
5579 // Do not save selected tab on field settings, or an acf-advanced-settings when unloading
5580 if (group.$el.children('.acf-field-settings-tab-bar').length || group.$el.parents('#acf-advanced-settings.postbox').length) {
5581 return true;
5582 }
5583 var active = group.hasActive() ? group.getActive().index() : 0;
5584 order.push(active);
5585 });
5586
5587 // bail if no tabs
5588 if (!order.length) {
5589 return;
5590 }
5591
5592 // update
5593 acf.setPreference('this.tabs', order);
5594 }
5595 });
5596 })(jQuery);
5597
5598 /***/ }),
5599
5600 /***/ "./assets/src/js/_acf-field-taxonomy.js":
5601 /*!**********************************************!*\
5602 !*** ./assets/src/js/_acf-field-taxonomy.js ***!
5603 \**********************************************/
5604 /***/ (() => {
5605
5606 (function ($, undefined) {
5607 var Field = acf.Field.extend({
5608 type: 'taxonomy',
5609 data: {
5610 ftype: 'select'
5611 },
5612 select2: false,
5613 wait: 'load',
5614 events: {
5615 'click a[data-name="add"]': 'onClickAdd',
5616 'click input[type="radio"]': 'onClickRadio',
5617 removeField: 'onRemove'
5618 },
5619 $control: function () {
5620 return this.$('.acf-taxonomy-field');
5621 },
5622 $input: function () {
5623 return this.getRelatedPrototype().$input.apply(this, arguments);
5624 },
5625 getRelatedType: function () {
5626 // vars
5627 var fieldType = this.get('ftype');
5628
5629 // normalize
5630 if (fieldType == 'multi_select') {
5631 fieldType = 'select';
5632 }
5633
5634 // return
5635 return fieldType;
5636 },
5637 getRelatedPrototype: function () {
5638 return acf.getFieldType(this.getRelatedType()).prototype;
5639 },
5640 getValue: function () {
5641 return this.getRelatedPrototype().getValue.apply(this, arguments);
5642 },
5643 setValue: function () {
5644 return this.getRelatedPrototype().setValue.apply(this, arguments);
5645 },
5646 initialize: function () {
5647 this.getRelatedPrototype().initialize.apply(this, arguments);
5648 },
5649 onRemove: function () {
5650 var proto = this.getRelatedPrototype();
5651 if (proto.onRemove) {
5652 proto.onRemove.apply(this, arguments);
5653 }
5654 },
5655 onClickAdd: function (e, $el) {
5656 // vars
5657 var field = this;
5658 var popup = false;
5659 var $form = false;
5660 var $name = false;
5661 var $parent = false;
5662 var $button = false;
5663 var $message = false;
5664 var notice = false;
5665
5666 // step 1.
5667 var step1 = function () {
5668 // popup
5669 popup = acf.newPopup({
5670 title: $el.attr('title'),
5671 loading: true,
5672 width: '300px'
5673 });
5674
5675 // ajax
5676 var ajaxData = {
5677 action: 'acf/fields/taxonomy/add_term',
5678 field_key: field.get('key'),
5679 nonce: field.get('nonce')
5680 };
5681
5682 // get HTML
5683 $.ajax({
5684 url: acf.get('ajaxurl'),
5685 data: acf.prepareForAjax(ajaxData),
5686 type: 'post',
5687 dataType: 'html',
5688 success: step2
5689 });
5690 };
5691
5692 // step 2.
5693 var step2 = function (html) {
5694 // update popup
5695 popup.loading(false);
5696 popup.content(html);
5697
5698 // vars
5699 $form = popup.$('form');
5700 $name = popup.$('input[name="term_name"]');
5701 $parent = popup.$('select[name="term_parent"]');
5702 $button = popup.$('.acf-submit-button');
5703
5704 // focus
5705 $name.trigger('focus');
5706
5707 // submit form
5708 popup.on('submit', 'form', step3);
5709 };
5710
5711 // step 3.
5712 var step3 = function (e, $el) {
5713 // prevent
5714 e.preventDefault();
5715 e.stopImmediatePropagation();
5716
5717 // basic validation
5718 if ($name.val() === '') {
5719 $name.trigger('focus');
5720 return false;
5721 }
5722
5723 // disable
5724 acf.startButtonLoading($button);
5725
5726 // ajax
5727 var ajaxData = {
5728 action: 'acf/fields/taxonomy/add_term',
5729 field_key: field.get('key'),
5730 nonce: field.get('nonce'),
5731 term_name: $name.val(),
5732 term_parent: $parent.length ? $parent.val() : 0
5733 };
5734 $.ajax({
5735 url: acf.get('ajaxurl'),
5736 data: acf.prepareForAjax(ajaxData),
5737 type: 'post',
5738 dataType: 'json',
5739 success: step4
5740 });
5741 };
5742
5743 // step 4.
5744 var step4 = function (json) {
5745 // enable
5746 acf.stopButtonLoading($button);
5747
5748 // remove prev notice
5749 if (notice) {
5750 notice.remove();
5751 }
5752
5753 // success
5754 if (acf.isAjaxSuccess(json)) {
5755 // clear name
5756 $name.val('');
5757
5758 // update term lists
5759 step5(json.data);
5760
5761 // notice
5762 notice = acf.newNotice({
5763 type: 'success',
5764 text: acf.getAjaxMessage(json),
5765 target: $form,
5766 timeout: 2000,
5767 dismiss: false
5768 });
5769 } else {
5770 // notice
5771 notice = acf.newNotice({
5772 type: 'error',
5773 text: acf.getAjaxError(json),
5774 target: $form,
5775 timeout: 2000,
5776 dismiss: false
5777 });
5778 }
5779
5780 // focus
5781 $name.trigger('focus');
5782 };
5783
5784 // step 5.
5785 var step5 = function (term) {
5786 // update parent dropdown
5787 var $option = $('<option value="' + term.term_id + '">' + term.term_label + '</option>');
5788 if (term.term_parent) {
5789 $parent.children('option[value="' + term.term_parent + '"]').after($option);
5790 } else {
5791 $parent.append($option);
5792 }
5793
5794 // add this new term to all taxonomy field
5795 var fields = acf.getFields({
5796 type: 'taxonomy'
5797 });
5798 fields.map(function (otherField) {
5799 if (otherField.get('taxonomy') == field.get('taxonomy')) {
5800 otherField.appendTerm(term);
5801 }
5802 });
5803
5804 // select
5805 field.selectTerm(term.term_id);
5806 };
5807
5808 // run
5809 step1();
5810 },
5811 appendTerm: function (term) {
5812 if (this.getRelatedType() == 'select') {
5813 this.appendTermSelect(term);
5814 } else {
5815 this.appendTermCheckbox(term);
5816 }
5817 },
5818 appendTermSelect: function (term) {
5819 this.select2.addOption({
5820 id: term.term_id,
5821 text: term.term_label
5822 });
5823 },
5824 appendTermCheckbox: function (term) {
5825 // vars
5826 var name = this.$('[name]:first').attr('name');
5827 var $ul = this.$('ul:first');
5828
5829 // allow multiple selection
5830 if (this.getRelatedType() == 'checkbox') {
5831 name += '[]';
5832 }
5833
5834 // create new li
5835 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(''));
5836
5837 // find parent
5838 if (term.term_parent) {
5839 // vars
5840 var $parent = $ul.find('li[data-id="' + term.term_parent + '"]');
5841
5842 // update vars
5843 $ul = $parent.children('ul');
5844
5845 // create ul
5846 if (!$ul.exists()) {
5847 $ul = $('<ul class="children acf-bl"></ul>');
5848 $parent.append($ul);
5849 }
5850 }
5851
5852 // append
5853 $ul.append($li);
5854 },
5855 selectTerm: function (id) {
5856 if (this.getRelatedType() == 'select') {
5857 this.select2.selectOption(id);
5858 } else {
5859 var $input = this.$('input[value="' + id + '"]');
5860 $input.prop('checked', true).trigger('change');
5861 }
5862 },
5863 onClickRadio: function (e, $el) {
5864 // vars
5865 var $label = $el.parent('label');
5866 var selected = $label.hasClass('selected');
5867
5868 // remove previous selected
5869 this.$('.selected').removeClass('selected');
5870
5871 // add active class
5872 $label.addClass('selected');
5873
5874 // allow null
5875 if (this.get('allow_null') && selected) {
5876 $label.removeClass('selected');
5877 $el.prop('checked', false).trigger('change');
5878 }
5879 }
5880 });
5881 acf.registerFieldType(Field);
5882 })(jQuery);
5883
5884 /***/ }),
5885
5886 /***/ "./assets/src/js/_acf-field-time-picker.js":
5887 /*!*************************************************!*\
5888 !*** ./assets/src/js/_acf-field-time-picker.js ***!
5889 \*************************************************/
5890 /***/ (() => {
5891
5892 (function ($, undefined) {
5893 var Field = acf.models.DatePickerField.extend({
5894 type: 'time_picker',
5895 $control: function () {
5896 return this.$('.acf-time-picker');
5897 },
5898 initialize: function () {
5899 // vars
5900 var $input = this.$input();
5901 var $inputText = this.$inputText();
5902
5903 // args
5904 var args = {
5905 timeFormat: this.get('time_format'),
5906 altField: $input,
5907 altFieldTimeOnly: false,
5908 altTimeFormat: 'HH:mm:ss',
5909 showButtonPanel: true,
5910 controlType: 'select',
5911 oneLine: true,
5912 closeText: acf.get('dateTimePickerL10n').selectText,
5913 timeOnly: true
5914 };
5915
5916 // add custom 'Close = Select' functionality
5917 args.onClose = function (value, dp_instance, t_instance) {
5918 // vars
5919 var $close = dp_instance.dpDiv.find('.ui-datepicker-close');
5920
5921 // if clicking close button
5922 if (!value && $close.is(':hover')) {
5923 t_instance._updateDateTime();
5924 }
5925 };
5926
5927 // filter
5928 args = acf.applyFilters('time_picker_args', args, this);
5929
5930 // add date time picker
5931 acf.newTimePicker($inputText, args);
5932
5933 // action
5934 acf.doAction('time_picker_init', $inputText, args, this);
5935 }
5936 });
5937 acf.registerFieldType(Field);
5938
5939 // add
5940 acf.newTimePicker = function ($input, args) {
5941 // bail early if no datepicker library
5942 if (typeof $.timepicker === 'undefined') {
5943 return false;
5944 }
5945
5946 // defaults
5947 args = args || {};
5948
5949 // initialize
5950 $input.timepicker(args);
5951
5952 // wrap the datepicker (only if it hasn't already been wrapped)
5953 if ($('body > #ui-datepicker-div').exists()) {
5954 $('body > #ui-datepicker-div').wrap('<div class="acf-ui-datepicker" />');
5955 }
5956 };
5957 })(jQuery);
5958
5959 /***/ }),
5960
5961 /***/ "./assets/src/js/_acf-field-true-false.js":
5962 /*!************************************************!*\
5963 !*** ./assets/src/js/_acf-field-true-false.js ***!
5964 \************************************************/
5965 /***/ (() => {
5966
5967 (function ($, undefined) {
5968 var Field = acf.Field.extend({
5969 type: 'true_false',
5970 events: {
5971 'change .acf-switch-input': 'onChange',
5972 'focus .acf-switch-input': 'onFocus',
5973 'blur .acf-switch-input': 'onBlur',
5974 'keypress .acf-switch-input': 'onKeypress'
5975 },
5976 $input: function () {
5977 return this.$('input[type="checkbox"]');
5978 },
5979 $switch: function () {
5980 return this.$('.acf-switch');
5981 },
5982 getValue: function () {
5983 return this.$input().prop('checked') ? 1 : 0;
5984 },
5985 initialize: function () {
5986 this.render();
5987 },
5988 render: function () {
5989 // vars
5990 var $switch = this.$switch();
5991
5992 // bail early if no $switch
5993 if (!$switch.length) return;
5994
5995 // vars
5996 var $on = $switch.children('.acf-switch-on');
5997 var $off = $switch.children('.acf-switch-off');
5998 var width = Math.max($on.width(), $off.width());
5999
6000 // bail early if no width
6001 if (!width) return;
6002
6003 // set widths
6004 $on.css('min-width', width);
6005 $off.css('min-width', width);
6006 },
6007 switchOn: function () {
6008 this.$input().prop('checked', true);
6009 this.$switch().addClass('-on');
6010 },
6011 switchOff: function () {
6012 this.$input().prop('checked', false);
6013 this.$switch().removeClass('-on');
6014 },
6015 onChange: function (e, $el) {
6016 if ($el.prop('checked')) {
6017 this.switchOn();
6018 } else {
6019 this.switchOff();
6020 }
6021 },
6022 onFocus: function (e, $el) {
6023 this.$switch().addClass('-focus');
6024 },
6025 onBlur: function (e, $el) {
6026 this.$switch().removeClass('-focus');
6027 },
6028 onKeypress: function (e, $el) {
6029 // left
6030 if (e.keyCode === 37) {
6031 return this.switchOff();
6032 }
6033
6034 // right
6035 if (e.keyCode === 39) {
6036 return this.switchOn();
6037 }
6038 }
6039 });
6040 acf.registerFieldType(Field);
6041 })(jQuery);
6042
6043 /***/ }),
6044
6045 /***/ "./assets/src/js/_acf-field-url.js":
6046 /*!*****************************************!*\
6047 !*** ./assets/src/js/_acf-field-url.js ***!
6048 \*****************************************/
6049 /***/ (() => {
6050
6051 (function ($, undefined) {
6052 var Field = acf.Field.extend({
6053 type: 'url',
6054 events: {
6055 'keyup input[type="url"]': 'onkeyup'
6056 },
6057 $control: function () {
6058 return this.$('.acf-input-wrap');
6059 },
6060 $input: function () {
6061 return this.$('input[type="url"]');
6062 },
6063 initialize: function () {
6064 this.render();
6065 },
6066 isValid: function () {
6067 // vars
6068 var val = this.val();
6069
6070 // bail early if no val
6071 if (!val) {
6072 return false;
6073 }
6074
6075 // url
6076 if (val.indexOf('://') !== -1) {
6077 return true;
6078 }
6079
6080 // protocol relative url
6081 if (val.indexOf('//') === 0) {
6082 return true;
6083 }
6084
6085 // return
6086 return false;
6087 },
6088 render: function () {
6089 // add class
6090 if (this.isValid()) {
6091 this.$control().addClass('-valid');
6092 } else {
6093 this.$control().removeClass('-valid');
6094 }
6095 },
6096 onkeyup: function (e, $el) {
6097 this.render();
6098 }
6099 });
6100 acf.registerFieldType(Field);
6101 })(jQuery);
6102
6103 /***/ }),
6104
6105 /***/ "./assets/src/js/_acf-field-user.js":
6106 /*!******************************************!*\
6107 !*** ./assets/src/js/_acf-field-user.js ***!
6108 \******************************************/
6109 /***/ (() => {
6110
6111 (function ($, undefined) {
6112 var Field = acf.models.SelectField.extend({
6113 type: 'user'
6114 });
6115 acf.registerFieldType(Field);
6116 })(jQuery);
6117
6118 /***/ }),
6119
6120 /***/ "./assets/src/js/_acf-field-wysiwyg.js":
6121 /*!*********************************************!*\
6122 !*** ./assets/src/js/_acf-field-wysiwyg.js ***!
6123 \*********************************************/
6124 /***/ (() => {
6125
6126 (function ($, undefined) {
6127 var Field = acf.Field.extend({
6128 type: 'wysiwyg',
6129 wait: 'load',
6130 events: {
6131 'mousedown .acf-editor-wrap.delay': 'onMousedown',
6132 unmountField: 'disableEditor',
6133 remountField: 'enableEditor',
6134 removeField: 'disableEditor'
6135 },
6136 $control: function () {
6137 return this.$('.acf-editor-wrap');
6138 },
6139 $input: function () {
6140 return this.$('textarea');
6141 },
6142 getMode: function () {
6143 return this.$control().hasClass('tmce-active') ? 'visual' : 'text';
6144 },
6145 initialize: function () {
6146 // initializeEditor if no delay
6147 if (!this.$control().hasClass('delay')) {
6148 this.initializeEditor();
6149 }
6150 },
6151 initializeEditor: function () {
6152 // vars
6153 var $wrap = this.$control();
6154 var $textarea = this.$input();
6155 var args = {
6156 tinymce: true,
6157 quicktags: true,
6158 toolbar: this.get('toolbar'),
6159 mode: this.getMode(),
6160 field: this
6161 };
6162
6163 // generate new id
6164 var oldId = $textarea.attr('id');
6165 var newId = acf.uniqueId('acf-editor-');
6166
6167 // Backup textarea data.
6168 var inputData = $textarea.data();
6169 var inputVal = $textarea.val();
6170
6171 // rename
6172 acf.rename({
6173 target: $wrap,
6174 search: oldId,
6175 replace: newId,
6176 destructive: true
6177 });
6178
6179 // update id
6180 this.set('id', newId, true);
6181
6182 // apply data to new textarea (acf.rename creates a new textarea element due to destructive mode)
6183 // fixes bug where conditional logic "disabled" is lost during "screen_check"
6184 this.$input().data(inputData).val(inputVal);
6185
6186 // initialize
6187 acf.tinymce.initialize(newId, args);
6188 },
6189 onMousedown: function (e) {
6190 // prevent default
6191 e.preventDefault();
6192
6193 // remove delay class
6194 var $wrap = this.$control();
6195 $wrap.removeClass('delay');
6196 $wrap.find('.acf-editor-toolbar').remove();
6197
6198 // initialize
6199 this.initializeEditor();
6200 },
6201 enableEditor: function () {
6202 if (this.getMode() == 'visual') {
6203 acf.tinymce.enable(this.get('id'));
6204 }
6205 },
6206 disableEditor: function () {
6207 acf.tinymce.destroy(this.get('id'));
6208 }
6209 });
6210 acf.registerFieldType(Field);
6211 })(jQuery);
6212
6213 /***/ }),
6214
6215 /***/ "./assets/src/js/_acf-field.js":
6216 /*!*************************************!*\
6217 !*** ./assets/src/js/_acf-field.js ***!
6218 \*************************************/
6219 /***/ (() => {
6220
6221 (function ($, undefined) {
6222 // vars
6223 var storage = [];
6224
6225 /**
6226 * acf.Field
6227 *
6228 * description
6229 *
6230 * @date 23/3/18
6231 * @since ACF 5.6.9
6232 *
6233 * @param type $var Description. Default.
6234 * @return type Description.
6235 */
6236
6237 acf.Field = acf.Model.extend({
6238 // field type
6239 type: '',
6240 // class used to avoid nested event triggers
6241 eventScope: '.acf-field',
6242 // initialize events on 'ready'
6243 wait: 'ready',
6244 /**
6245 * setup
6246 *
6247 * Called during the constructor function to setup this field ready for initialization
6248 *
6249 * @date 8/5/18
6250 * @since ACF 5.6.9
6251 *
6252 * @param jQuery $field The field element.
6253 * @return void
6254 */
6255
6256 setup: function ($field) {
6257 // set $el
6258 this.$el = $field;
6259
6260 // inherit $field data
6261 this.inherit($field);
6262
6263 // inherit controll data
6264 this.inherit(this.$control());
6265 },
6266 /**
6267 * val
6268 *
6269 * Sets or returns the field's value
6270 *
6271 * @date 8/5/18
6272 * @since ACF 5.6.9
6273 *
6274 * @param mixed val Optional. The value to set
6275 * @return mixed
6276 */
6277
6278 val: function (val) {
6279 // Set.
6280 if (val !== undefined) {
6281 return this.setValue(val);
6282
6283 // Get.
6284 } else {
6285 return this.prop('disabled') ? null : this.getValue();
6286 }
6287 },
6288 /**
6289 * getValue
6290 *
6291 * returns the field's value
6292 *
6293 * @date 8/5/18
6294 * @since ACF 5.6.9
6295 *
6296 * @param void
6297 * @return mixed
6298 */
6299
6300 getValue: function () {
6301 return this.$input().val();
6302 },
6303 /**
6304 * setValue
6305 *
6306 * sets the field's value and returns true if changed
6307 *
6308 * @date 8/5/18
6309 * @since ACF 5.6.9
6310 *
6311 * @param mixed val
6312 * @return boolean. True if changed.
6313 */
6314
6315 setValue: function (val) {
6316 return acf.val(this.$input(), val);
6317 },
6318 /**
6319 * __
6320 *
6321 * i18n helper to be removed
6322 *
6323 * @date 8/5/18
6324 * @since ACF 5.6.9
6325 *
6326 * @param type $var Description. Default.
6327 * @return type Description.
6328 */
6329
6330 __: function (string) {
6331 return acf._e(this.type, string);
6332 },
6333 /**
6334 * $control
6335 *
6336 * returns the control jQuery element used for inheriting data. Uses this.control setting.
6337 *
6338 * @date 8/5/18
6339 * @since ACF 5.6.9
6340 *
6341 * @param void
6342 * @return jQuery
6343 */
6344
6345 $control: function () {
6346 return false;
6347 },
6348 /**
6349 * $input
6350 *
6351 * returns the input jQuery element used for saving values. Uses this.input setting.
6352 *
6353 * @date 8/5/18
6354 * @since ACF 5.6.9
6355 *
6356 * @param void
6357 * @return jQuery
6358 */
6359
6360 $input: function () {
6361 return this.$('[name]:first');
6362 },
6363 /**
6364 * $inputWrap
6365 *
6366 * description
6367 *
6368 * @date 12/5/18
6369 * @since ACF 5.6.9
6370 *
6371 * @param type $var Description. Default.
6372 * @return type Description.
6373 */
6374
6375 $inputWrap: function () {
6376 return this.$('.acf-input:first');
6377 },
6378 /**
6379 * $inputWrap
6380 *
6381 * description
6382 *
6383 * @date 12/5/18
6384 * @since ACF 5.6.9
6385 *
6386 * @param type $var Description. Default.
6387 * @return type Description.
6388 */
6389
6390 $labelWrap: function () {
6391 return this.$('.acf-label:first');
6392 },
6393 /**
6394 * getInputName
6395 *
6396 * Returns the field's input name
6397 *
6398 * @date 8/5/18
6399 * @since ACF 5.6.9
6400 *
6401 * @param void
6402 * @return string
6403 */
6404
6405 getInputName: function () {
6406 return this.$input().attr('name') || '';
6407 },
6408 /**
6409 * parent
6410 *
6411 * returns the field's parent field or false on failure.
6412 *
6413 * @date 8/5/18
6414 * @since ACF 5.6.9
6415 *
6416 * @param void
6417 * @return object|false
6418 */
6419
6420 parent: function () {
6421 // vars
6422 var parents = this.parents();
6423
6424 // return
6425 return parents.length ? parents[0] : false;
6426 },
6427 /**
6428 * parents
6429 *
6430 * description
6431 *
6432 * @date 9/7/18
6433 * @since ACF 5.6.9
6434 *
6435 * @param type $var Description. Default.
6436 * @return type Description.
6437 */
6438
6439 parents: function () {
6440 // vars
6441 var $parents = this.$el.parents('.acf-field');
6442
6443 // convert
6444 var parents = acf.getFields($parents);
6445
6446 // return
6447 return parents;
6448 },
6449 show: function (lockKey, context) {
6450 // show field and store result
6451 var changed = acf.show(this.$el, lockKey);
6452
6453 // do action if visibility has changed
6454 if (changed) {
6455 this.prop('hidden', false);
6456 acf.doAction('show_field', this, context);
6457 if (context === 'conditional_logic') {
6458 this.setFieldSettingsLastVisible();
6459 }
6460 }
6461
6462 // return
6463 return changed;
6464 },
6465 hide: function (lockKey, context) {
6466 // hide field and store result
6467 var changed = acf.hide(this.$el, lockKey);
6468
6469 // do action if visibility has changed
6470 if (changed) {
6471 this.prop('hidden', true);
6472 acf.doAction('hide_field', this, context);
6473 if (context === 'conditional_logic') {
6474 this.setFieldSettingsLastVisible();
6475 }
6476 }
6477
6478 // return
6479 return changed;
6480 },
6481 setFieldSettingsLastVisible: function () {
6482 // Ensure this conditional logic trigger has happened inside a field settings tab.
6483 var $parents = this.$el.parents('.acf-field-settings-main');
6484 if (!$parents.length) return;
6485 var $fields = $parents.find('.acf-field');
6486 $fields.removeClass('acf-last-visible');
6487 $fields.not('.acf-hidden').last().addClass('acf-last-visible');
6488 },
6489 enable: function (lockKey, context) {
6490 // enable field and store result
6491 var changed = acf.enable(this.$el, lockKey);
6492
6493 // do action if disabled has changed
6494 if (changed) {
6495 this.prop('disabled', false);
6496 acf.doAction('enable_field', this, context);
6497 }
6498
6499 // return
6500 return changed;
6501 },
6502 disable: function (lockKey, context) {
6503 // disabled field and store result
6504 var changed = acf.disable(this.$el, lockKey);
6505
6506 // do action if disabled has changed
6507 if (changed) {
6508 this.prop('disabled', true);
6509 acf.doAction('disable_field', this, context);
6510 }
6511
6512 // return
6513 return changed;
6514 },
6515 showEnable: function (lockKey, context) {
6516 // enable
6517 this.enable.apply(this, arguments);
6518
6519 // show and return true if changed
6520 return this.show.apply(this, arguments);
6521 },
6522 hideDisable: function (lockKey, context) {
6523 // disable
6524 this.disable.apply(this, arguments);
6525
6526 // hide and return true if changed
6527 return this.hide.apply(this, arguments);
6528 },
6529 showNotice: function (props) {
6530 // ensure object
6531 if (typeof props !== 'object') {
6532 props = {
6533 text: props
6534 };
6535 }
6536
6537 // remove old notice
6538 if (this.notice) {
6539 this.notice.remove();
6540 }
6541
6542 // create new notice
6543 props.target = this.$inputWrap();
6544 this.notice = acf.newNotice(props);
6545 },
6546 removeNotice: function (timeout) {
6547 if (this.notice) {
6548 this.notice.away(timeout || 0);
6549 this.notice = false;
6550 }
6551 },
6552 showError: function (message, location = 'before') {
6553 // add class
6554 this.$el.addClass('acf-error');
6555
6556 // add message
6557 if (message !== undefined) {
6558 this.showNotice({
6559 text: message,
6560 type: 'error',
6561 dismiss: false,
6562 location: location
6563 });
6564 }
6565
6566 // action
6567 acf.doAction('invalid_field', this);
6568
6569 // add event
6570 this.$el.one('focus change', 'input, select, textarea', $.proxy(this.removeError, this));
6571 },
6572 removeError: function () {
6573 // remove class
6574 this.$el.removeClass('acf-error');
6575
6576 // remove notice
6577 this.removeNotice(250);
6578
6579 // action
6580 acf.doAction('valid_field', this);
6581 },
6582 trigger: function (name, args, bubbles) {
6583 // allow some events to bubble
6584 if (name == 'invalidField') {
6585 bubbles = true;
6586 }
6587
6588 // return
6589 return acf.Model.prototype.trigger.apply(this, [name, args, bubbles]);
6590 }
6591 });
6592
6593 /**
6594 * newField
6595 *
6596 * description
6597 *
6598 * @date 14/12/17
6599 * @since ACF 5.6.5
6600 *
6601 * @param type $var Description. Default.
6602 * @return type Description.
6603 */
6604
6605 acf.newField = function ($field) {
6606 // vars
6607 var type = $field.data('type');
6608 var mid = modelId(type);
6609 var model = acf.models[mid] || acf.Field;
6610
6611 // instantiate
6612 var field = new model($field);
6613
6614 // actions
6615 acf.doAction('new_field', field);
6616
6617 // return
6618 return field;
6619 };
6620
6621 /**
6622 * mid
6623 *
6624 * Calculates the model ID for a field type
6625 *
6626 * @date 15/12/17
6627 * @since ACF 5.6.5
6628 *
6629 * @param string type
6630 * @return string
6631 */
6632
6633 var modelId = function (type) {
6634 return acf.strPascalCase(type || '') + 'Field';
6635 };
6636
6637 /**
6638 * registerFieldType
6639 *
6640 * description
6641 *
6642 * @date 14/12/17
6643 * @since ACF 5.6.5
6644 *
6645 * @param type $var Description. Default.
6646 * @return type Description.
6647 */
6648
6649 acf.registerFieldType = function (model) {
6650 // vars
6651 var proto = model.prototype;
6652 var type = proto.type;
6653 var mid = modelId(type);
6654
6655 // store model
6656 acf.models[mid] = model;
6657
6658 // store reference
6659 storage.push(type);
6660 };
6661
6662 /**
6663 * acf.getFieldType
6664 *
6665 * description
6666 *
6667 * @date 1/2/18
6668 * @since ACF 5.6.5
6669 *
6670 * @param type $var Description. Default.
6671 * @return type Description.
6672 */
6673
6674 acf.getFieldType = function (type) {
6675 var mid = modelId(type);
6676 return acf.models[mid] || false;
6677 };
6678
6679 /**
6680 * acf.getFieldTypes
6681 *
6682 * description
6683 *
6684 * @date 1/2/18
6685 * @since ACF 5.6.5
6686 *
6687 * @param type $var Description. Default.
6688 * @return type Description.
6689 */
6690
6691 acf.getFieldTypes = function (args) {
6692 // defaults
6693 args = acf.parseArgs(args, {
6694 category: ''
6695 // hasValue: true
6696 });
6697
6698 // clonse available types
6699 var types = [];
6700
6701 // loop
6702 storage.map(function (type) {
6703 // vars
6704 var model = acf.getFieldType(type);
6705 var proto = model.prototype;
6706
6707 // check operator
6708 if (args.category && proto.category !== args.category) {
6709 return;
6710 }
6711
6712 // append
6713 types.push(model);
6714 });
6715
6716 // return
6717 return types;
6718 };
6719 })(jQuery);
6720
6721 /***/ }),
6722
6723 /***/ "./assets/src/js/_acf-fields.js":
6724 /*!**************************************!*\
6725 !*** ./assets/src/js/_acf-fields.js ***!
6726 \**************************************/
6727 /***/ (() => {
6728
6729 (function ($, undefined) {
6730 /**
6731 * findFields
6732 *
6733 * Returns a jQuery selection object of acf fields.
6734 *
6735 * @date 14/12/17
6736 * @since ACF 5.6.5
6737 *
6738 * @param object $args {
6739 * Optional. Arguments to find fields.
6740 *
6741 * @type string key The field's key (data-attribute).
6742 * @type string name The field's name (data-attribute).
6743 * @type string type The field's type (data-attribute).
6744 * @type string is jQuery selector to compare against.
6745 * @type jQuery parent jQuery element to search within.
6746 * @type jQuery sibling jQuery element to search alongside.
6747 * @type limit int The number of fields to find.
6748 * @type suppressFilters bool Whether to allow filters to add/remove results. Default behaviour will ignore clone fields.
6749 * }
6750 * @return jQuery
6751 */
6752
6753 acf.findFields = function (args) {
6754 // vars
6755 var selector = '.acf-field';
6756 var $fields = false;
6757
6758 // args
6759 args = acf.parseArgs(args, {
6760 key: '',
6761 name: '',
6762 type: '',
6763 is: '',
6764 parent: false,
6765 sibling: false,
6766 limit: false,
6767 visible: false,
6768 suppressFilters: false,
6769 excludeSubFields: false
6770 });
6771
6772 // filter args
6773 if (!args.suppressFilters) {
6774 args = acf.applyFilters('find_fields_args', args);
6775 }
6776
6777 // key
6778 if (args.key) {
6779 selector += '[data-key="' + args.key + '"]';
6780 }
6781
6782 // type
6783 if (args.type) {
6784 selector += '[data-type="' + args.type + '"]';
6785 }
6786
6787 // name
6788 if (args.name) {
6789 selector += '[data-name="' + args.name + '"]';
6790 }
6791
6792 // is
6793 if (args.is) {
6794 selector += args.is;
6795 }
6796
6797 // visibility
6798 if (args.visible) {
6799 selector += ':visible';
6800 }
6801 if (!args.suppressFilters) {
6802 selector = acf.applyFilters('find_fields_selector', selector, args);
6803 }
6804
6805 // query
6806 if (args.parent) {
6807 $fields = args.parent.find(selector);
6808 // exclude sub fields if required (only if a parent is provided)
6809 if (args.excludeSubFields) {
6810 $fields = $fields.not(args.parent.find('.acf-is-subfields .acf-field'));
6811 }
6812 } else if (args.sibling) {
6813 $fields = args.sibling.siblings(selector);
6814 } else {
6815 $fields = $(selector);
6816 }
6817
6818 // filter
6819 if (!args.suppressFilters) {
6820 $fields = $fields.not('.acf-clone .acf-field');
6821 $fields = acf.applyFilters('find_fields', $fields);
6822 }
6823
6824 // limit
6825 if (args.limit) {
6826 $fields = $fields.slice(0, args.limit);
6827 }
6828
6829 // return
6830 return $fields;
6831 };
6832
6833 /**
6834 * findField
6835 *
6836 * Finds a specific field with jQuery
6837 *
6838 * @date 14/12/17
6839 * @since ACF 5.6.5
6840 *
6841 * @param string key The field's key.
6842 * @param jQuery $parent jQuery element to search within.
6843 * @return jQuery
6844 */
6845
6846 acf.findField = function (key, $parent) {
6847 return acf.findFields({
6848 key: key,
6849 limit: 1,
6850 parent: $parent,
6851 suppressFilters: true
6852 });
6853 };
6854
6855 /**
6856 * getField
6857 *
6858 * Returns a field instance
6859 *
6860 * @date 14/12/17
6861 * @since ACF 5.6.5
6862 *
6863 * @param jQuery|string $field jQuery element or field key.
6864 * @return object
6865 */
6866
6867 acf.getField = function ($field) {
6868 // allow jQuery
6869 if ($field instanceof jQuery) {
6870 // find fields
6871 } else {
6872 $field = acf.findField($field);
6873 }
6874
6875 // instantiate
6876 var field = $field.data('acf');
6877 if (!field) {
6878 field = acf.newField($field);
6879 }
6880
6881 // return
6882 return field;
6883 };
6884
6885 /**
6886 * getFields
6887 *
6888 * Returns multiple field instances
6889 *
6890 * @date 14/12/17
6891 * @since ACF 5.6.5
6892 *
6893 * @param jQuery|object $fields jQuery elements or query args.
6894 * @return array
6895 */
6896
6897 acf.getFields = function ($fields) {
6898 // allow jQuery
6899 if ($fields instanceof jQuery) {
6900 // find fields
6901 } else {
6902 $fields = acf.findFields($fields);
6903 }
6904
6905 // loop
6906 var fields = [];
6907 $fields.each(function () {
6908 var field = acf.getField($(this));
6909 fields.push(field);
6910 });
6911
6912 // return
6913 return fields;
6914 };
6915
6916 /**
6917 * findClosestField
6918 *
6919 * Returns the closest jQuery field element
6920 *
6921 * @date 9/4/18
6922 * @since ACF 5.6.9
6923 *
6924 * @param jQuery $el
6925 * @return jQuery
6926 */
6927
6928 acf.findClosestField = function ($el) {
6929 return $el.closest('.acf-field');
6930 };
6931
6932 /**
6933 * getClosestField
6934 *
6935 * Returns the closest field instance
6936 *
6937 * @date 22/1/18
6938 * @since ACF 5.6.5
6939 *
6940 * @param jQuery $el
6941 * @return object
6942 */
6943
6944 acf.getClosestField = function ($el) {
6945 var $field = acf.findClosestField($el);
6946 return this.getField($field);
6947 };
6948
6949 /**
6950 * addGlobalFieldAction
6951 *
6952 * Sets up callback logic for global field actions
6953 *
6954 * @date 15/6/18
6955 * @since ACF 5.6.9
6956 *
6957 * @param string action
6958 * @return void
6959 */
6960
6961 var addGlobalFieldAction = function (action) {
6962 // vars
6963 var globalAction = action;
6964 var pluralAction = action + '_fields'; // ready_fields
6965 var singleAction = action + '_field'; // ready_field
6966
6967 // global action
6968 var globalCallback = function ($el /*, arg1, arg2, etc*/) {
6969 //console.log( action, arguments );
6970
6971 // get args [$el, ...]
6972 var args = acf.arrayArgs(arguments);
6973 var extraArgs = args.slice(1);
6974
6975 // find fields
6976 var fields = acf.getFields({
6977 parent: $el
6978 });
6979
6980 // check
6981 if (fields.length) {
6982 // pluralAction
6983 var pluralArgs = [pluralAction, fields].concat(extraArgs);
6984 acf.doAction.apply(null, pluralArgs);
6985 }
6986 };
6987
6988 // plural action
6989 var pluralCallback = function (fields /*, arg1, arg2, etc*/) {
6990 //console.log( pluralAction, arguments );
6991
6992 // get args [fields, ...]
6993 var args = acf.arrayArgs(arguments);
6994 var extraArgs = args.slice(1);
6995
6996 // loop
6997 fields.map(function (field, i) {
6998 //setTimeout(function(){
6999 // singleAction
7000 var singleArgs = [singleAction, field].concat(extraArgs);
7001 acf.doAction.apply(null, singleArgs);
7002 //}, i * 100);
7003 });
7004 };
7005
7006 // add actions
7007 acf.addAction(globalAction, globalCallback);
7008 acf.addAction(pluralAction, pluralCallback);
7009
7010 // also add single action
7011 addSingleFieldAction(action);
7012 };
7013
7014 /**
7015 * addSingleFieldAction
7016 *
7017 * Sets up callback logic for single field actions
7018 *
7019 * @date 15/6/18
7020 * @since ACF 5.6.9
7021 *
7022 * @param string action
7023 * @return void
7024 */
7025
7026 var addSingleFieldAction = function (action) {
7027 // vars
7028 var singleAction = action + '_field'; // ready_field
7029 var singleEvent = action + 'Field'; // readyField
7030
7031 // single action
7032 var singleCallback = function (field /*, arg1, arg2, etc*/) {
7033 //console.log( singleAction, arguments );
7034
7035 // get args [field, ...]
7036 var args = acf.arrayArgs(arguments);
7037 var extraArgs = args.slice(1);
7038
7039 // action variations (ready_field/type=image)
7040 var variations = ['type', 'name', 'key'];
7041 variations.map(function (variation) {
7042 // vars
7043 var prefix = '/' + variation + '=' + field.get(variation);
7044
7045 // singleAction
7046 args = [singleAction + prefix, field].concat(extraArgs);
7047 acf.doAction.apply(null, args);
7048 });
7049
7050 // event
7051 if (singleFieldEvents.indexOf(action) > -1) {
7052 field.trigger(singleEvent, extraArgs);
7053 }
7054 };
7055
7056 // add actions
7057 acf.addAction(singleAction, singleCallback);
7058 };
7059
7060 // vars
7061 var globalFieldActions = ['prepare', 'ready', 'load', 'append', 'remove', 'unmount', 'remount', 'sortstart', 'sortstop', 'show', 'hide', 'unload'];
7062 var singleFieldActions = ['valid', 'invalid', 'enable', 'disable', 'new', 'duplicate'];
7063 var singleFieldEvents = ['remove', 'unmount', 'remount', 'sortstart', 'sortstop', 'show', 'hide', 'unload', 'valid', 'invalid', 'enable', 'disable', 'duplicate'];
7064
7065 // add
7066 globalFieldActions.map(addGlobalFieldAction);
7067 singleFieldActions.map(addSingleFieldAction);
7068
7069 /**
7070 * fieldsEventManager
7071 *
7072 * Manages field actions and events
7073 *
7074 * @date 15/12/17
7075 * @since ACF 5.6.5
7076 *
7077 * @param void
7078 * @param void
7079 */
7080
7081 var fieldsEventManager = new acf.Model({
7082 id: 'fieldsEventManager',
7083 events: {
7084 'click .acf-field a[href="#"]': 'onClick',
7085 'change .acf-field': 'onChange'
7086 },
7087 onClick: function (e) {
7088 // prevent default of any link with an href of #
7089 e.preventDefault();
7090 },
7091 onChange: function () {
7092 // preview hack allows post to save with no title or content
7093 $('#_acf_changed').val(1);
7094 if (acf.isGutenbergPostEditor()) {
7095 try {
7096 wp.data.dispatch('core/editor').editPost({
7097 meta: {
7098 _acf_changed: 1
7099 }
7100 });
7101 } catch (error) {
7102 console.log('ACF: Failed to update _acf_changed meta', error);
7103 }
7104 }
7105 }
7106 });
7107 var duplicateFieldsManager = new acf.Model({
7108 id: 'duplicateFieldsManager',
7109 actions: {
7110 duplicate: 'onDuplicate',
7111 duplicate_fields: 'onDuplicateFields'
7112 },
7113 onDuplicate: function ($el, $el2) {
7114 var fields = acf.getFields({
7115 parent: $el
7116 });
7117 if (fields.length) {
7118 var $fields = acf.findFields({
7119 parent: $el2
7120 });
7121 acf.doAction('duplicate_fields', fields, $fields);
7122 }
7123 },
7124 onDuplicateFields: function (fields, duplicates) {
7125 fields.map(function (field, i) {
7126 acf.doAction('duplicate_field', field, $(duplicates[i]));
7127 });
7128 }
7129 });
7130 })(jQuery);
7131
7132 /***/ }),
7133
7134 /***/ "./assets/src/js/_acf-helpers.js":
7135 /*!***************************************!*\
7136 !*** ./assets/src/js/_acf-helpers.js ***!
7137 \***************************************/
7138 /***/ (() => {
7139
7140 (function ($, undefined) {
7141 /**
7142 * refreshHelper
7143 *
7144 * description
7145 *
7146 * @date 1/7/18
7147 * @since ACF 5.6.9
7148 *
7149 * @param type $var Description. Default.
7150 * @return type Description.
7151 */
7152
7153 var refreshHelper = new acf.Model({
7154 priority: 90,
7155 actions: {
7156 new_field: 'refresh',
7157 show_field: 'refresh',
7158 hide_field: 'refresh',
7159 remove_field: 'refresh',
7160 unmount_field: 'refresh',
7161 remount_field: 'refresh'
7162 },
7163 refresh: function () {
7164 acf.refresh();
7165 }
7166 });
7167
7168 /**
7169 * mountHelper
7170 *
7171 * Adds compatiblity for the 'unmount' and 'remount' actions added in 5.8.0
7172 *
7173 * @date 7/3/19
7174 * @since ACF 5.7.14
7175 *
7176 * @param void
7177 * @return void
7178 */
7179 var mountHelper = new acf.Model({
7180 priority: 1,
7181 actions: {
7182 sortstart: 'onSortstart',
7183 sortstop: 'onSortstop'
7184 },
7185 onSortstart: function ($item) {
7186 acf.doAction('unmount', $item);
7187 },
7188 onSortstop: function ($item) {
7189 acf.doAction('remount', $item);
7190 }
7191 });
7192
7193 /**
7194 * sortableHelper
7195 *
7196 * Adds compatibility for sorting a <tr> element
7197 *
7198 * @date 6/3/18
7199 * @since ACF 5.6.9
7200 *
7201 * @param void
7202 * @return void
7203 */
7204
7205 var sortableHelper = new acf.Model({
7206 actions: {
7207 sortstart: 'onSortstart'
7208 },
7209 onSortstart: function ($item, $placeholder) {
7210 // if $item is a tr, apply some css to the elements
7211 if ($item.is('tr')) {
7212 // replace $placeholder children with a single td
7213 // fixes "width calculation issues" due to conditional logic hiding some children
7214 $placeholder.html('<td style="padding:0;" colspan="' + $placeholder.children().length + '"></td>');
7215
7216 // add helper class to remove absolute positioning
7217 $item.addClass('acf-sortable-tr-helper');
7218
7219 // set fixed widths for children
7220 $item.children().each(function () {
7221 $(this).width($(this).width());
7222 });
7223
7224 // mimic height
7225 $placeholder.height($item.height() + 'px');
7226
7227 // remove class
7228 $item.removeClass('acf-sortable-tr-helper');
7229 }
7230 }
7231 });
7232
7233 /**
7234 * duplicateHelper
7235 *
7236 * Fixes browser bugs when duplicating an element
7237 *
7238 * @date 6/3/18
7239 * @since ACF 5.6.9
7240 *
7241 * @param void
7242 * @return void
7243 */
7244
7245 var duplicateHelper = new acf.Model({
7246 actions: {
7247 after_duplicate: 'onAfterDuplicate'
7248 },
7249 onAfterDuplicate: function ($el, $el2) {
7250 // get original values
7251 var vals = [];
7252 $el.find('select').each(function (i) {
7253 vals.push($(this).val());
7254 });
7255
7256 // set duplicate values
7257 $el2.find('select').each(function (i) {
7258 $(this).val(vals[i]);
7259 });
7260 }
7261 });
7262
7263 /**
7264 * tableHelper
7265 *
7266 * description
7267 *
7268 * @date 6/3/18
7269 * @since ACF 5.6.9
7270 *
7271 * @param type $var Description. Default.
7272 * @return type Description.
7273 */
7274
7275 var tableHelper = new acf.Model({
7276 id: 'tableHelper',
7277 priority: 20,
7278 actions: {
7279 refresh: 'renderTables'
7280 },
7281 renderTables: function ($el) {
7282 // loop
7283 var self = this;
7284 $('.acf-table:visible').each(function () {
7285 self.renderTable($(this));
7286 });
7287 },
7288 renderTable: function ($table) {
7289 // vars
7290 var $ths = $table.find('> thead > tr:visible > th[data-key]');
7291 var $tds = $table.find('> tbody > tr:visible > td[data-key]');
7292
7293 // bail early if no thead
7294 if (!$ths.length || !$tds.length) {
7295 return false;
7296 }
7297
7298 // visiblity
7299 $ths.each(function (i) {
7300 // vars
7301 var $th = $(this);
7302 var key = $th.data('key');
7303 var $cells = $tds.filter('[data-key="' + key + '"]');
7304 var $hidden = $cells.filter('.acf-hidden');
7305
7306 // always remove empty and allow cells to be hidden
7307 $cells.removeClass('acf-empty');
7308
7309 // hide $th if all cells are hidden
7310 if ($cells.length === $hidden.length) {
7311 acf.hide($th);
7312
7313 // force all hidden cells to appear empty
7314 } else {
7315 acf.show($th);
7316 $hidden.addClass('acf-empty');
7317 }
7318 });
7319
7320 // clear width
7321 $ths.css('width', 'auto');
7322
7323 // get visible
7324 $ths = $ths.not('.acf-hidden');
7325
7326 // vars
7327 var availableWidth = 100;
7328 var colspan = $ths.length;
7329
7330 // set custom widths first
7331 var $fixedWidths = $ths.filter('[data-width]');
7332 $fixedWidths.each(function () {
7333 var width = $(this).data('width');
7334 $(this).css('width', width + '%');
7335 availableWidth -= width;
7336 });
7337
7338 // set auto widths
7339 var $auoWidths = $ths.not('[data-width]');
7340 if ($auoWidths.length) {
7341 var width = availableWidth / $auoWidths.length;
7342 $auoWidths.css('width', width + '%');
7343 availableWidth = 0;
7344 }
7345
7346 // avoid stretching issue
7347 if (availableWidth > 0) {
7348 $ths.last().css('width', 'auto');
7349 }
7350
7351 // update colspan on collapsed
7352 $tds.filter('.-collapsed-target').each(function () {
7353 // vars
7354 var $td = $(this);
7355
7356 // check if collapsed
7357 if ($td.parent().hasClass('-collapsed')) {
7358 $td.attr('colspan', $ths.length);
7359 } else {
7360 $td.removeAttr('colspan');
7361 }
7362 });
7363 }
7364 });
7365
7366 /**
7367 * fieldsHelper
7368 *
7369 * description
7370 *
7371 * @date 6/3/18
7372 * @since ACF 5.6.9
7373 *
7374 * @param type $var Description. Default.
7375 * @return type Description.
7376 */
7377
7378 var fieldsHelper = new acf.Model({
7379 id: 'fieldsHelper',
7380 priority: 30,
7381 actions: {
7382 refresh: 'renderGroups'
7383 },
7384 renderGroups: function () {
7385 // loop
7386 var self = this;
7387 $('.acf-fields:visible').each(function () {
7388 self.renderGroup($(this));
7389 });
7390 },
7391 renderGroup: function ($el) {
7392 // vars
7393 var top = 0;
7394 var height = 0;
7395 var $row = $();
7396
7397 // get fields
7398 var $fields = $el.children('.acf-field[data-width]:visible');
7399
7400 // bail early if no fields
7401 if (!$fields.length) {
7402 return false;
7403 }
7404
7405 // bail early if is .-left
7406 if ($el.hasClass('-left')) {
7407 $fields.removeAttr('data-width');
7408 $fields.css('width', 'auto');
7409 return false;
7410 }
7411
7412 // reset fields
7413 $fields.removeClass('-r0 -c0').css({
7414 'min-height': 0
7415 });
7416
7417 // loop
7418 $fields.each(function (i) {
7419 // vars
7420 var $field = $(this);
7421 var position = $field.position();
7422 var thisTop = Math.ceil(position.top);
7423 var thisLeft = Math.ceil(position.left);
7424
7425 // detect change in row
7426 if ($row.length && thisTop > top) {
7427 // set previous heights
7428 $row.css({
7429 'min-height': height + 'px'
7430 });
7431
7432 // update position due to change in row above
7433 position = $field.position();
7434 thisTop = Math.ceil(position.top);
7435 thisLeft = Math.ceil(position.left);
7436
7437 // reset vars
7438 top = 0;
7439 height = 0;
7440 $row = $();
7441 }
7442
7443 // rtl
7444 if (acf.get('rtl')) {
7445 thisLeft = Math.ceil($field.parent().width() - (position.left + $field.outerWidth()));
7446 }
7447
7448 // add classes
7449 if (thisTop == 0) {
7450 $field.addClass('-r0');
7451 } else if (thisLeft == 0) {
7452 $field.addClass('-c0');
7453 }
7454
7455 // get height after class change
7456 // - add 1 for subpixel rendering
7457 var thisHeight = Math.ceil($field.outerHeight()) + 1;
7458
7459 // set height
7460 height = Math.max(height, thisHeight);
7461
7462 // set y
7463 top = Math.max(top, thisTop);
7464
7465 // append
7466 $row = $row.add($field);
7467 });
7468
7469 // clean up
7470 if ($row.length) {
7471 $row.css({
7472 'min-height': height + 'px'
7473 });
7474 }
7475 }
7476 });
7477
7478 /**
7479 * Adds a body class when holding down the "shift" key.
7480 *
7481 * @date 06/05/2020
7482 * @since ACF 5.9.0
7483 */
7484 var bodyClassShiftHelper = new acf.Model({
7485 id: 'bodyClassShiftHelper',
7486 events: {
7487 keydown: 'onKeyDown',
7488 keyup: 'onKeyUp'
7489 },
7490 isShiftKey: function (e) {
7491 return e.keyCode === 16;
7492 },
7493 onKeyDown: function (e) {
7494 if (this.isShiftKey(e)) {
7495 $('body').addClass('acf-keydown-shift');
7496 }
7497 },
7498 onKeyUp: function (e) {
7499 if (this.isShiftKey(e)) {
7500 $('body').removeClass('acf-keydown-shift');
7501 }
7502 }
7503 });
7504 })(jQuery);
7505
7506 /***/ }),
7507
7508 /***/ "./assets/src/js/_acf-media.js":
7509 /*!*************************************!*\
7510 !*** ./assets/src/js/_acf-media.js ***!
7511 \*************************************/
7512 /***/ (() => {
7513
7514 (function ($, undefined) {
7515 /**
7516 * acf.newMediaPopup
7517 *
7518 * description
7519 *
7520 * @date 10/1/18
7521 * @since ACF 5.6.5
7522 *
7523 * @param type $var Description. Default.
7524 * @return type Description.
7525 */
7526
7527 acf.newMediaPopup = function (args) {
7528 // args
7529 var popup = null;
7530 var args = acf.parseArgs(args, {
7531 mode: 'select',
7532 // 'select', 'edit'
7533 title: '',
7534 // 'Upload Image'
7535 button: '',
7536 // 'Select Image'
7537 type: '',
7538 // 'image', ''
7539 field: false,
7540 // field instance
7541 allowedTypes: '',
7542 // '.jpg, .png, etc'
7543 library: 'all',
7544 // 'all', 'uploadedTo'
7545 multiple: false,
7546 // false, true, 'add'
7547 attachment: 0,
7548 // the attachment to edit
7549 autoOpen: true,
7550 // open the popup automatically
7551 open: function () {},
7552 // callback after close
7553 select: function () {},
7554 // callback after select
7555 close: function () {} // callback after close
7556 });
7557
7558 // initialize
7559 if (args.mode == 'edit') {
7560 popup = new acf.models.EditMediaPopup(args);
7561 } else {
7562 popup = new acf.models.SelectMediaPopup(args);
7563 }
7564
7565 // open popup (allow frame customization before opening)
7566 if (args.autoOpen) {
7567 setTimeout(function () {
7568 popup.open();
7569 }, 1);
7570 }
7571
7572 // action
7573 acf.doAction('new_media_popup', popup);
7574
7575 // return
7576 return popup;
7577 };
7578
7579 /**
7580 * getPostID
7581 *
7582 * description
7583 *
7584 * @date 10/1/18
7585 * @since ACF 5.6.5
7586 *
7587 * @param type $var Description. Default.
7588 * @return type Description.
7589 */
7590
7591 var getPostID = function () {
7592 var postID = acf.get('post_id');
7593 return acf.isNumeric(postID) ? postID : 0;
7594 };
7595
7596 /**
7597 * acf.getMimeTypes
7598 *
7599 * description
7600 *
7601 * @date 11/1/18
7602 * @since ACF 5.6.5
7603 *
7604 * @param type $var Description. Default.
7605 * @return type Description.
7606 */
7607
7608 acf.getMimeTypes = function () {
7609 return this.get('mimeTypes');
7610 };
7611 acf.getMimeType = function (name) {
7612 // vars
7613 var allTypes = acf.getMimeTypes();
7614
7615 // search
7616 if (allTypes[name] !== undefined) {
7617 return allTypes[name];
7618 }
7619
7620 // some types contain a mixed key such as "jpg|jpeg|jpe"
7621 for (var key in allTypes) {
7622 if (key.indexOf(name) !== -1) {
7623 return allTypes[key];
7624 }
7625 }
7626
7627 // return
7628 return false;
7629 };
7630
7631 /**
7632 * MediaPopup
7633 *
7634 * description
7635 *
7636 * @date 10/1/18
7637 * @since ACF 5.6.5
7638 *
7639 * @param type $var Description. Default.
7640 * @return type Description.
7641 */
7642
7643 var MediaPopup = acf.Model.extend({
7644 id: 'MediaPopup',
7645 data: {},
7646 defaults: {},
7647 frame: false,
7648 setup: function (props) {
7649 $.extend(this.data, props);
7650 },
7651 initialize: function () {
7652 // vars
7653 var options = this.getFrameOptions();
7654
7655 // add states
7656 this.addFrameStates(options);
7657
7658 // create frame
7659 var frame = wp.media(options);
7660
7661 // add args reference
7662 frame.acf = this;
7663
7664 // add events
7665 this.addFrameEvents(frame, options);
7666
7667 // strore frame
7668 this.frame = frame;
7669 },
7670 open: function () {
7671 this.frame.open();
7672 },
7673 close: function () {
7674 this.frame.close();
7675 },
7676 remove: function () {
7677 this.frame.detach();
7678 this.frame.remove();
7679 },
7680 getFrameOptions: function () {
7681 // vars
7682 var options = {
7683 title: this.get('title'),
7684 multiple: this.get('multiple'),
7685 library: {},
7686 states: []
7687 };
7688
7689 // type
7690 if (this.get('type')) {
7691 options.library.type = this.get('type');
7692 }
7693
7694 // type
7695 if (this.get('library') === 'uploadedTo') {
7696 options.library.uploadedTo = getPostID();
7697 }
7698
7699 // attachment
7700 if (this.get('attachment')) {
7701 options.library.post__in = [this.get('attachment')];
7702 }
7703
7704 // button
7705 if (this.get('button')) {
7706 options.button = {
7707 text: this.get('button')
7708 };
7709 }
7710
7711 // return
7712 return options;
7713 },
7714 addFrameStates: function (options) {
7715 // create query
7716 var Query = wp.media.query(options.library);
7717
7718 // add _acfuploader
7719 // this is super wack!
7720 // if you add _acfuploader to the options.library args, new uploads will not be added to the library view.
7721 // this has been traced back to the wp.media.model.Query initialize function (which can't be overriden)
7722 // Adding any custom args will cause the Attahcments to not observe the uploader queue
7723 // To bypass this security issue, we add in the args AFTER the Query has been initialized
7724 // options.library._acfuploader = settings.field;
7725 if (this.get('field') && acf.isset(Query, 'mirroring', 'args')) {
7726 Query.mirroring.args._acfuploader = this.get('field');
7727 }
7728
7729 // add states
7730 options.states.push(
7731 // main state
7732 new wp.media.controller.Library({
7733 library: Query,
7734 multiple: this.get('multiple'),
7735 title: this.get('title'),
7736 priority: 20,
7737 filterable: 'all',
7738 editable: true,
7739 allowLocalEdits: true
7740 }));
7741
7742 // edit image functionality (added in WP 3.9)
7743 if (acf.isset(wp, 'media', 'controller', 'EditImage')) {
7744 options.states.push(new wp.media.controller.EditImage());
7745 }
7746 },
7747 addFrameEvents: function (frame, options) {
7748 // log all events
7749 //frame.on('all', function( e ) {
7750 // console.log( 'frame all: %o', e );
7751 //});
7752
7753 // add class
7754 frame.on('open', function () {
7755 this.$el.closest('.media-modal').addClass('acf-media-modal -' + this.acf.get('mode'));
7756 }, frame);
7757
7758 // edit image view
7759 // source: media-views.js:2410 editImageContent()
7760 frame.on('content:render:edit-image', function () {
7761 var image = this.state().get('image');
7762 var view = new wp.media.view.EditImage({
7763 model: image,
7764 controller: this
7765 }).render();
7766 this.content.set(view);
7767
7768 // after creating the wrapper view, load the actual editor via an ajax call
7769 view.loadEditor();
7770 }, frame);
7771
7772 // update toolbar button
7773 //frame.on( 'toolbar:create:select', function( toolbar ) {
7774 // toolbar.view = new wp.media.view.Toolbar.Select({
7775 // text: frame.options._button,
7776 // controller: this
7777 // });
7778 //}, frame );
7779
7780 // on select
7781 frame.on('select', function () {
7782 // vars
7783 var selection = frame.state().get('selection');
7784
7785 // if selecting images
7786 if (selection) {
7787 // loop
7788 selection.each(function (attachment, i) {
7789 frame.acf.get('select').apply(frame.acf, [attachment, i]);
7790 });
7791 }
7792 });
7793
7794 // on close
7795 frame.on('close', function () {
7796 // callback and remove
7797 setTimeout(function () {
7798 frame.acf.get('close').apply(frame.acf);
7799 frame.acf.remove();
7800 }, 1);
7801 });
7802 }
7803 });
7804
7805 /**
7806 * acf.models.SelectMediaPopup
7807 *
7808 * description
7809 *
7810 * @date 10/1/18
7811 * @since ACF 5.6.5
7812 *
7813 * @param type $var Description. Default.
7814 * @return type Description.
7815 */
7816
7817 acf.models.SelectMediaPopup = MediaPopup.extend({
7818 id: 'SelectMediaPopup',
7819 setup: function (props) {
7820 // default button
7821 if (!props.button) {
7822 props.button = acf._x('Select', 'verb');
7823 }
7824
7825 // parent
7826 MediaPopup.prototype.setup.apply(this, arguments);
7827 },
7828 addFrameEvents: function (frame, options) {
7829 // plupload
7830 // adds _acfuploader param to validate uploads
7831 if (acf.isset(_wpPluploadSettings, 'defaults', 'multipart_params')) {
7832 // add _acfuploader so that Uploader will inherit
7833 _wpPluploadSettings.defaults.multipart_params._acfuploader = this.get('field');
7834
7835 // remove acf_field so future Uploaders won't inherit
7836 frame.on('open', function () {
7837 delete _wpPluploadSettings.defaults.multipart_params._acfuploader;
7838 });
7839 }
7840
7841 // browse
7842 frame.on('content:activate:browse', function () {
7843 // vars
7844 var toolbar = false;
7845
7846 // populate above vars making sure to allow for failure
7847 // perhaps toolbar does not exist because the frame open is Upload Files
7848 try {
7849 toolbar = frame.content.get().toolbar;
7850 } catch (e) {
7851 console.log(e);
7852 return;
7853 }
7854
7855 // callback
7856 frame.acf.customizeFilters.apply(frame.acf, [toolbar]);
7857 });
7858
7859 // parent
7860 MediaPopup.prototype.addFrameEvents.apply(this, arguments);
7861 },
7862 customizeFilters: function (toolbar) {
7863 // vars
7864 var filters = toolbar.get('filters');
7865
7866 // image
7867 if (this.get('type') == 'image') {
7868 // update all
7869 filters.filters.all.text = acf.__('All images');
7870
7871 // remove some filters
7872 delete filters.filters.audio;
7873 delete filters.filters.video;
7874 delete filters.filters.image;
7875
7876 // update all filters to show images
7877 $.each(filters.filters, function (i, filter) {
7878 filter.props.type = filter.props.type || 'image';
7879 });
7880 }
7881
7882 // specific types
7883 if (this.get('allowedTypes')) {
7884 // convert ".jpg, .png" into ["jpg", "png"]
7885 var allowedTypes = this.get('allowedTypes').split(' ').join('').split('.').join('').split(',');
7886
7887 // loop
7888 allowedTypes.map(function (name) {
7889 // get type
7890 var mimeType = acf.getMimeType(name);
7891
7892 // bail early if no type
7893 if (!mimeType) return;
7894
7895 // create new filter
7896 var newFilter = {
7897 text: mimeType,
7898 props: {
7899 status: null,
7900 type: mimeType,
7901 uploadedTo: null,
7902 orderby: 'date',
7903 order: 'DESC'
7904 },
7905 priority: 20
7906 };
7907
7908 // append
7909 filters.filters[mimeType] = newFilter;
7910 });
7911 }
7912
7913 // uploaded to post
7914 if (this.get('library') === 'uploadedTo') {
7915 // vars
7916 var uploadedTo = this.frame.options.library.uploadedTo;
7917
7918 // remove some filters
7919 delete filters.filters.unattached;
7920 delete filters.filters.uploaded;
7921
7922 // add uploadedTo to filters
7923 $.each(filters.filters, function (i, filter) {
7924 filter.text += ' (' + acf.__('Uploaded to this post') + ')';
7925 filter.props.uploadedTo = uploadedTo;
7926 });
7927 }
7928
7929 // add _acfuploader to filters
7930 var field = this.get('field');
7931 $.each(filters.filters, function (k, filter) {
7932 filter.props._acfuploader = field;
7933 });
7934
7935 // add _acfuplaoder to search
7936 var search = toolbar.get('search');
7937 search.model.attributes._acfuploader = field;
7938
7939 // render (custom function added to prototype)
7940 if (filters.renderFilters) {
7941 filters.renderFilters();
7942 }
7943 }
7944 });
7945
7946 /**
7947 * acf.models.EditMediaPopup
7948 *
7949 * description
7950 *
7951 * @date 10/1/18
7952 * @since ACF 5.6.5
7953 *
7954 * @param type $var Description. Default.
7955 * @return type Description.
7956 */
7957
7958 acf.models.EditMediaPopup = MediaPopup.extend({
7959 id: 'SelectMediaPopup',
7960 setup: function (props) {
7961 // default button
7962 if (!props.button) {
7963 props.button = acf._x('Update', 'verb');
7964 }
7965
7966 // parent
7967 MediaPopup.prototype.setup.apply(this, arguments);
7968 },
7969 addFrameEvents: function (frame, options) {
7970 // add class
7971 frame.on('open', function () {
7972 // add class
7973 this.$el.closest('.media-modal').addClass('acf-expanded');
7974
7975 // set to browse
7976 if (this.content.mode() != 'browse') {
7977 this.content.mode('browse');
7978 }
7979
7980 // set selection
7981 var state = this.state();
7982 var selection = state.get('selection');
7983 var attachment = wp.media.attachment(frame.acf.get('attachment'));
7984 selection.add(attachment);
7985 }, frame);
7986
7987 // parent
7988 MediaPopup.prototype.addFrameEvents.apply(this, arguments);
7989 }
7990 });
7991
7992 /**
7993 * customizePrototypes
7994 *
7995 * description
7996 *
7997 * @date 11/1/18
7998 * @since ACF 5.6.5
7999 *
8000 * @param type $var Description. Default.
8001 * @return type Description.
8002 */
8003
8004 var customizePrototypes = new acf.Model({
8005 id: 'customizePrototypes',
8006 wait: 'ready',
8007 initialize: function () {
8008 // bail early if no media views
8009 if (!acf.isset(window, 'wp', 'media', 'view')) {
8010 return;
8011 }
8012
8013 // fix bug where CPT without "editor" does not set post.id setting which then prevents uploadedTo from working
8014 var postID = getPostID();
8015 if (postID && acf.isset(wp, 'media', 'view', 'settings', 'post')) {
8016 wp.media.view.settings.post.id = postID;
8017 }
8018
8019 // customize
8020 this.customizeAttachmentsButton();
8021 this.customizeAttachmentsRouter();
8022 this.customizeAttachmentFilters();
8023 this.customizeAttachmentCompat();
8024 this.customizeAttachmentLibrary();
8025 },
8026 customizeAttachmentsButton: function () {
8027 // validate
8028 if (!acf.isset(wp, 'media', 'view', 'Button')) {
8029 return;
8030 }
8031
8032 // Extend
8033 var Button = wp.media.view.Button;
8034 wp.media.view.Button = Button.extend({
8035 // Fix bug where "Select" button appears blank after editing an image.
8036 // Do this by simplifying Button initialize function and avoid deleting this.options.
8037 initialize: function () {
8038 var options = _.defaults(this.options, this.defaults);
8039 this.model = new Backbone.Model(options);
8040 this.listenTo(this.model, 'change', this.render);
8041 }
8042 });
8043 },
8044 customizeAttachmentsRouter: function () {
8045 // validate
8046 if (!acf.isset(wp, 'media', 'view', 'Router')) {
8047 return;
8048 }
8049
8050 // vars
8051 var Parent = wp.media.view.Router;
8052
8053 // extend
8054 wp.media.view.Router = Parent.extend({
8055 addExpand: function () {
8056 // vars
8057 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(''));
8058
8059 // add events
8060 $a.on('click', function (e) {
8061 e.preventDefault();
8062 var $div = $(this).closest('.media-modal');
8063 if ($div.hasClass('acf-expanded')) {
8064 $div.removeClass('acf-expanded');
8065 } else {
8066 $div.addClass('acf-expanded');
8067 }
8068 });
8069
8070 // append
8071 this.$el.append($a);
8072 },
8073 initialize: function () {
8074 // initialize
8075 Parent.prototype.initialize.apply(this, arguments);
8076
8077 // add buttons
8078 this.addExpand();
8079
8080 // return
8081 return this;
8082 }
8083 });
8084 },
8085 customizeAttachmentFilters: function () {
8086 // validate
8087 if (!acf.isset(wp, 'media', 'view', 'AttachmentFilters', 'All')) {
8088 return;
8089 }
8090
8091 // vars
8092 var Parent = wp.media.view.AttachmentFilters.All;
8093
8094 // renderFilters
8095 // copied from media-views.js:6939
8096 Parent.prototype.renderFilters = function () {
8097 // Build `<option>` elements.
8098 this.$el.html(_.chain(this.filters).map(function (filter, value) {
8099 return {
8100 el: $('<option></option>').val(value).html(filter.text)[0],
8101 priority: filter.priority || 50
8102 };
8103 }, this).sortBy('priority').pluck('el').value());
8104 };
8105 },
8106 customizeAttachmentCompat: function () {
8107 // validate
8108 if (!acf.isset(wp, 'media', 'view', 'AttachmentCompat')) {
8109 return;
8110 }
8111
8112 // vars
8113 var AttachmentCompat = wp.media.view.AttachmentCompat;
8114 var timeout = false;
8115
8116 // extend
8117 wp.media.view.AttachmentCompat = AttachmentCompat.extend({
8118 render: function () {
8119 // WP bug
8120 // When multiple media frames exist on the same page (WP content, WYSIWYG, image, file ),
8121 // WP creates multiple instances of this AttachmentCompat view.
8122 // Each instance will attempt to render when a new modal is created.
8123 // Use a property to avoid this and only render once per instance.
8124 if (this.rendered) {
8125 return this;
8126 }
8127
8128 // render HTML
8129 AttachmentCompat.prototype.render.apply(this, arguments);
8130
8131 // when uploading, render is called twice.
8132 // ignore first render by checking for #acf-form-data element
8133 if (!this.$('#acf-form-data').length) {
8134 return this;
8135 }
8136
8137 // clear timeout
8138 clearTimeout(timeout);
8139
8140 // setTimeout
8141 timeout = setTimeout($.proxy(function () {
8142 this.rendered = true;
8143 acf.doAction('append', this.$el);
8144 }, this), 50);
8145
8146 // return
8147 return this;
8148 },
8149 save: function (event) {
8150 var data = {};
8151 if (event) {
8152 event.preventDefault();
8153 }
8154
8155 //_.each( this.$el.serializeArray(), function( pair ) {
8156 // data[ pair.name ] = pair.value;
8157 //});
8158
8159 // Serialize data more thoroughly to allow chckbox inputs to save.
8160 data = acf.serializeForAjax(this.$el);
8161 this.controller.trigger('attachment:compat:waiting', ['waiting']);
8162 this.model.saveCompat(data).always(_.bind(this.postSave, this));
8163 }
8164 });
8165 },
8166 customizeAttachmentLibrary: function () {
8167 // validate
8168 if (!acf.isset(wp, 'media', 'view', 'Attachment', 'Library')) {
8169 return;
8170 }
8171
8172 // vars
8173 var AttachmentLibrary = wp.media.view.Attachment.Library;
8174
8175 // extend
8176 wp.media.view.Attachment.Library = AttachmentLibrary.extend({
8177 render: function () {
8178 // vars
8179 var popup = acf.isget(this, 'controller', 'acf');
8180 var attributes = acf.isget(this, 'model', 'attributes');
8181
8182 // check vars exist to avoid errors
8183 if (popup && attributes) {
8184 // show errors
8185 if (attributes.acf_errors) {
8186 this.$el.addClass('acf-disabled');
8187 }
8188
8189 // disable selected
8190 var selected = popup.get('selected');
8191 if (selected && selected.indexOf(attributes.id) > -1) {
8192 this.$el.addClass('acf-selected');
8193 }
8194 }
8195
8196 // render
8197 return AttachmentLibrary.prototype.render.apply(this, arguments);
8198 },
8199 /*
8200 * toggleSelection
8201 *
8202 * This function is called before an attachment is selected
8203 * A good place to check for errors and prevent the 'select' function from being fired
8204 *
8205 * @type function
8206 * @date 29/09/2016
8207 * @since ACF 5.4.0
8208 *
8209 * @param options (object)
8210 * @return n/a
8211 */
8212
8213 toggleSelection: function (options) {
8214 // vars
8215 // source: wp-includes/js/media-views.js:2880
8216 var collection = this.collection,
8217 selection = this.options.selection,
8218 model = this.model,
8219 single = selection.single();
8220
8221 // vars
8222 var frame = this.controller;
8223 var errors = acf.isget(this, 'model', 'attributes', 'acf_errors');
8224 var $sidebar = frame.$el.find('.media-frame-content .media-sidebar');
8225
8226 // remove previous error
8227 $sidebar.children('.acf-selection-error').remove();
8228
8229 // show attachment details
8230 $sidebar.children().removeClass('acf-hidden');
8231
8232 // add message
8233 if (frame && errors) {
8234 // vars
8235 var filename = acf.isget(this, 'model', 'attributes', 'filename');
8236
8237 // hide attachment details
8238 // Gallery field continues to show previously selected attachment...
8239 $sidebar.children().addClass('acf-hidden');
8240
8241 // append message
8242 $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(''));
8243
8244 // reset selection (unselects all attachments)
8245 selection.reset();
8246
8247 // set single (attachment displayed in sidebar)
8248 selection.single(model);
8249
8250 // return and prevent 'select' form being fired
8251 return;
8252 }
8253
8254 // return
8255 return AttachmentLibrary.prototype.toggleSelection.apply(this, arguments);
8256 }
8257 });
8258 }
8259 });
8260 })(jQuery);
8261
8262 /***/ }),
8263
8264 /***/ "./assets/src/js/_acf-postbox.js":
8265 /*!***************************************!*\
8266 !*** ./assets/src/js/_acf-postbox.js ***!
8267 \***************************************/
8268 /***/ (() => {
8269
8270 (function ($, undefined) {
8271 /**
8272 * postboxManager
8273 *
8274 * Manages postboxes on the screen.
8275 *
8276 * @date 25/5/19
8277 * @since ACF 5.8.1
8278 *
8279 * @param void
8280 * @return void
8281 */
8282 var postboxManager = new acf.Model({
8283 wait: 'prepare',
8284 priority: 1,
8285 initialize: function () {
8286 (acf.get('postboxes') || []).map(acf.newPostbox);
8287 }
8288 });
8289
8290 /**
8291 * acf.getPostbox
8292 *
8293 * Returns a postbox instance.
8294 *
8295 * @date 23/9/18
8296 * @since ACF 5.7.7
8297 *
8298 * @param mixed $el Either a jQuery element or the postbox id.
8299 * @return object
8300 */
8301 acf.getPostbox = function ($el) {
8302 // allow string parameter
8303 if (typeof arguments[0] == 'string') {
8304 $el = $('#' + arguments[0]);
8305 }
8306
8307 // return instance
8308 return acf.getInstance($el);
8309 };
8310
8311 /**
8312 * acf.getPostboxes
8313 *
8314 * Returns an array of postbox instances.
8315 *
8316 * @date 23/9/18
8317 * @since ACF 5.7.7
8318 *
8319 * @param void
8320 * @return array
8321 */
8322 acf.getPostboxes = function () {
8323 return acf.getInstances($('.acf-postbox'));
8324 };
8325
8326 /**
8327 * acf.newPostbox
8328 *
8329 * Returns a new postbox instance for the given props.
8330 *
8331 * @date 20/9/18
8332 * @since ACF 5.7.6
8333 *
8334 * @param object props The postbox properties.
8335 * @return object
8336 */
8337 acf.newPostbox = function (props) {
8338 return new acf.models.Postbox(props);
8339 };
8340
8341 /**
8342 * acf.models.Postbox
8343 *
8344 * The postbox model.
8345 *
8346 * @date 20/9/18
8347 * @since ACF 5.7.6
8348 *
8349 * @param void
8350 * @return void
8351 */
8352 acf.models.Postbox = acf.Model.extend({
8353 data: {
8354 id: '',
8355 key: '',
8356 style: 'default',
8357 label: 'top',
8358 edit: ''
8359 },
8360 setup: function (props) {
8361 // compatibilty
8362 if (props.editLink) {
8363 props.edit = props.editLink;
8364 }
8365
8366 // extend data
8367 $.extend(this.data, props);
8368
8369 // set $el
8370 this.$el = this.$postbox();
8371 },
8372 $postbox: function () {
8373 return $('#' + this.get('id'));
8374 },
8375 $hide: function () {
8376 return $('#' + this.get('id') + '-hide');
8377 },
8378 $hideLabel: function () {
8379 return this.$hide().parent();
8380 },
8381 $hndle: function () {
8382 return this.$('> .hndle');
8383 },
8384 $handleActions: function () {
8385 return this.$('> .postbox-header .handle-actions');
8386 },
8387 $inside: function () {
8388 return this.$('> .inside');
8389 },
8390 isVisible: function () {
8391 return this.$el.hasClass('acf-hidden');
8392 },
8393 isHiddenByScreenOptions: function () {
8394 return this.$el.hasClass('hide-if-js') || this.$el.css('display') == 'none';
8395 },
8396 initialize: function () {
8397 // Add default class.
8398 this.$el.addClass('acf-postbox');
8399
8400 // Add field group style class (ignore in block editor).
8401 if (acf.get('editor') !== 'block') {
8402 var style = this.get('style');
8403 if (style !== 'default') {
8404 this.$el.addClass(style);
8405 }
8406 }
8407
8408 // Add .inside class.
8409 this.$inside().addClass('acf-fields').addClass('-' + this.get('label'));
8410
8411 // Append edit link.
8412 var edit = this.get('edit');
8413 if (edit) {
8414 var html = '<a href="' + edit + '" class="dashicons dashicons-admin-generic acf-hndle-cog acf-js-tooltip" title="' + acf.__('Edit field group') + '"></a>';
8415 var $handleActions = this.$handleActions();
8416 if ($handleActions.length) {
8417 $handleActions.prepend(html);
8418 } else {
8419 this.$hndle().append(html);
8420 }
8421 }
8422
8423 // Show postbox.
8424 this.show();
8425 },
8426 show: function () {
8427 // If disabled by screen options, set checked to false and return.
8428 if (this.$el.hasClass('hide-if-js')) {
8429 this.$hide().prop('checked', false);
8430 return;
8431 }
8432
8433 // Show label.
8434 this.$hideLabel().show();
8435
8436 // toggle on checkbox
8437 this.$hide().prop('checked', true);
8438
8439 // Show postbox
8440 this.$el.show().removeClass('acf-hidden');
8441
8442 // Do action.
8443 acf.doAction('show_postbox', this);
8444 },
8445 enable: function () {
8446 acf.enable(this.$el, 'postbox');
8447 },
8448 showEnable: function () {
8449 this.enable();
8450 this.show();
8451 },
8452 hide: function () {
8453 // Hide label.
8454 this.$hideLabel().hide();
8455
8456 // Hide postbox
8457 this.$el.hide().addClass('acf-hidden');
8458
8459 // Do action.
8460 acf.doAction('hide_postbox', this);
8461 },
8462 disable: function () {
8463 acf.disable(this.$el, 'postbox');
8464 },
8465 hideDisable: function () {
8466 this.disable();
8467 this.hide();
8468 },
8469 html: function (html) {
8470 // Update HTML.
8471 this.$inside().html(html);
8472
8473 // Do action.
8474 acf.doAction('append', this.$el);
8475 }
8476 });
8477 })(jQuery);
8478
8479 /***/ }),
8480
8481 /***/ "./assets/src/js/_acf-screen.js":
8482 /*!**************************************!*\
8483 !*** ./assets/src/js/_acf-screen.js ***!
8484 \**************************************/
8485 /***/ (() => {
8486
8487 (function ($, undefined) {
8488 acf.screen = new acf.Model({
8489 active: true,
8490 xhr: false,
8491 timeout: false,
8492 wait: 'load',
8493 events: {
8494 'change #page_template': 'onChange',
8495 'change #parent_id': 'onChange',
8496 'change #post-formats-select': 'onChange',
8497 'change .categorychecklist': 'onChange',
8498 'change .tagsdiv': 'onChange',
8499 'change .acf-taxonomy-field[data-save="1"]': 'onChange',
8500 'change #product-type': 'onChange'
8501 },
8502 isPost: function () {
8503 return acf.get('screen') === 'post';
8504 },
8505 isUser: function () {
8506 return acf.get('screen') === 'user';
8507 },
8508 isTaxonomy: function () {
8509 return acf.get('screen') === 'taxonomy';
8510 },
8511 isAttachment: function () {
8512 return acf.get('screen') === 'attachment';
8513 },
8514 isNavMenu: function () {
8515 return acf.get('screen') === 'nav_menu';
8516 },
8517 isWidget: function () {
8518 return acf.get('screen') === 'widget';
8519 },
8520 isComment: function () {
8521 return acf.get('screen') === 'comment';
8522 },
8523 getPageTemplate: function () {
8524 var $el = $('#page_template');
8525 return $el.length ? $el.val() : null;
8526 },
8527 getPageParent: function (e, $el) {
8528 var $el = $('#parent_id');
8529 return $el.length ? $el.val() : null;
8530 },
8531 getPageType: function (e, $el) {
8532 return this.getPageParent() ? 'child' : 'parent';
8533 },
8534 getPostType: function () {
8535 return $('#post_type').val();
8536 },
8537 getPostFormat: function (e, $el) {
8538 var $el = $('#post-formats-select input:checked');
8539 if ($el.length) {
8540 var val = $el.val();
8541 return val == '0' ? 'standard' : val;
8542 }
8543 return null;
8544 },
8545 getPostCoreTerms: function () {
8546 // vars
8547 var terms = {};
8548
8549 // serialize WP taxonomy postboxes
8550 var data = acf.serialize($('.categorydiv, .tagsdiv'));
8551
8552 // use tax_input (tag, custom-taxonomy) when possible.
8553 // this data is already formatted in taxonomy => [terms].
8554 if (data.tax_input) {
8555 terms = data.tax_input;
8556 }
8557
8558 // append "category" which uses a different name
8559 if (data.post_category) {
8560 terms.category = data.post_category;
8561 }
8562
8563 // convert any string values (tags) into array format
8564 for (var tax in terms) {
8565 if (!acf.isArray(terms[tax])) {
8566 terms[tax] = terms[tax].split(/,[\s]?/);
8567 }
8568 }
8569
8570 // return
8571 return terms;
8572 },
8573 getPostTerms: function () {
8574 // Get core terms.
8575 var terms = this.getPostCoreTerms();
8576
8577 // loop over taxonomy fields and add their values
8578 acf.getFields({
8579 type: 'taxonomy'
8580 }).map(function (field) {
8581 // ignore fields that don't save
8582 if (!field.get('save')) {
8583 return;
8584 }
8585
8586 // vars
8587 var val = field.val();
8588 var tax = field.get('taxonomy');
8589
8590 // check val
8591 if (val) {
8592 // ensure terms exists
8593 terms[tax] = terms[tax] || [];
8594
8595 // ensure val is an array
8596 val = acf.isArray(val) ? val : [val];
8597
8598 // append
8599 terms[tax] = terms[tax].concat(val);
8600 }
8601 });
8602
8603 // add WC product type
8604 if ((productType = this.getProductType()) !== null) {
8605 terms.product_type = [productType];
8606 }
8607
8608 // remove duplicate values
8609 for (var tax in terms) {
8610 terms[tax] = acf.uniqueArray(terms[tax]);
8611 }
8612
8613 // return
8614 return terms;
8615 },
8616 getProductType: function () {
8617 var $el = $('#product-type');
8618 return $el.length ? $el.val() : null;
8619 },
8620 check: function () {
8621 // bail early if not for post
8622 if (acf.get('screen') !== 'post') {
8623 return;
8624 }
8625
8626 // abort XHR if is already loading AJAX data
8627 if (this.xhr) {
8628 this.xhr.abort();
8629 }
8630
8631 // vars
8632 var ajaxData = acf.parseArgs(this.data, {
8633 action: 'acf/ajax/check_screen',
8634 screen: acf.get('screen'),
8635 exists: []
8636 });
8637
8638 // post id
8639 if (this.isPost()) {
8640 ajaxData.post_id = acf.get('post_id');
8641 }
8642
8643 // post type
8644 if ((postType = this.getPostType()) !== null) {
8645 ajaxData.post_type = postType;
8646 }
8647
8648 // page template
8649 if ((pageTemplate = this.getPageTemplate()) !== null) {
8650 ajaxData.page_template = pageTemplate;
8651 }
8652
8653 // page parent
8654 if ((pageParent = this.getPageParent()) !== null) {
8655 ajaxData.page_parent = pageParent;
8656 }
8657
8658 // page type
8659 if ((pageType = this.getPageType()) !== null) {
8660 ajaxData.page_type = pageType;
8661 }
8662
8663 // post format
8664 if ((postFormat = this.getPostFormat()) !== null) {
8665 ajaxData.post_format = postFormat;
8666 }
8667
8668 // post terms
8669 if ((postTerms = this.getPostTerms()) !== null) {
8670 ajaxData.post_terms = postTerms;
8671 }
8672
8673 // add array of existing postboxes to increase performance and reduce JSON HTML
8674 acf.getPostboxes().map(function (postbox) {
8675 ajaxData.exists.push(postbox.get('key'));
8676 });
8677
8678 // filter
8679 ajaxData = acf.applyFilters('check_screen_args', ajaxData);
8680
8681 // success
8682 var onSuccess = function (json) {
8683 // Render post screen.
8684 if (acf.get('screen') == 'post') {
8685 this.renderPostScreen(json);
8686
8687 // Render user screen.
8688 } else if (acf.get('screen') == 'user') {
8689 this.renderUserScreen(json);
8690 }
8691
8692 // action
8693 acf.doAction('check_screen_complete', json, ajaxData);
8694 };
8695
8696 // ajax
8697 this.xhr = $.ajax({
8698 url: acf.get('ajaxurl'),
8699 data: acf.prepareForAjax(ajaxData),
8700 type: 'post',
8701 dataType: 'json',
8702 context: this,
8703 success: onSuccess
8704 });
8705 },
8706 onChange: function (e, $el) {
8707 this.setTimeout(this.check, 1);
8708 },
8709 renderPostScreen: function (data) {
8710 // Helper function to copy events
8711 var copyEvents = function ($from, $to) {
8712 var events = $._data($from[0]).events;
8713 for (var type in events) {
8714 for (var i = 0; i < events[type].length; i++) {
8715 $to.on(type, events[type][i].handler);
8716 }
8717 }
8718 };
8719
8720 // Helper function to sort metabox.
8721 var sortMetabox = function (id, ids) {
8722 // Find position of id within ids.
8723 var index = ids.indexOf(id);
8724
8725 // Bail early if index not found.
8726 if (index == -1) {
8727 return false;
8728 }
8729
8730 // Loop over metaboxes behind (in reverse order).
8731 for (var i = index - 1; i >= 0; i--) {
8732 if ($('#' + ids[i]).length) {
8733 return $('#' + ids[i]).after($('#' + id));
8734 }
8735 }
8736
8737 // Loop over metaboxes infront.
8738 for (var i = index + 1; i < ids.length; i++) {
8739 if ($('#' + ids[i]).length) {
8740 return $('#' + ids[i]).before($('#' + id));
8741 }
8742 }
8743
8744 // Return false if not sorted.
8745 return false;
8746 };
8747
8748 // Keep track of visible and hidden postboxes.
8749 data.visible = [];
8750 data.hidden = [];
8751
8752 // Show these postboxes.
8753 data.results = data.results.map(function (result, i) {
8754 // vars
8755 var postbox = acf.getPostbox(result.id);
8756
8757 // Prevent "acf_after_title" position in Block Editor.
8758 if (acf.isGutenberg() && result.position == 'acf_after_title') {
8759 result.position = 'normal';
8760 }
8761
8762 // Create postbox if doesn't exist.
8763 if (!postbox) {
8764 var wpMinorVersion = parseFloat(acf.get('wp_version'));
8765 if (wpMinorVersion >= 5.5) {
8766 var postboxHeader = ['<div class="postbox-header">', '<h2 class="hndle ui-sortable-handle">', '<span>' + acf.escHtml(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">Toggle panel: ' + acf.escHtml(result.title) + '</span>', '<span class="toggle-indicator" aria-hidden="true"></span>', '</button>', '</div>', '</div>'].join('');
8767 } else {
8768 var postboxHeader = ['<button type="button" class="handlediv" aria-expanded="true">', '<span class="screen-reader-text">Toggle panel: ' + acf.escHtml(result.title) + '</span>', '<span class="toggle-indicator" aria-hidden="true"></span>', '</button>', '<h2 class="hndle ui-sortable-handle">', '<span>' + acf.escHtml(result.title) + '</span>', '</h2>'].join('');
8769 }
8770
8771 // Ensure result.classes is set.
8772 if (!result.classes) result.classes = '';
8773
8774 // Create it.
8775 var $postbox = $(['<div id="' + result.id + '" class="postbox ' + result.classes + '">', postboxHeader, '<div class="inside">', result.html, '</div>', '</div>'].join(''));
8776
8777 // Create new hide toggle.
8778 if ($('#adv-settings').length) {
8779 var $prefs = $('#adv-settings .metabox-prefs');
8780 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(''));
8781
8782 // Copy default WP events onto checkbox.
8783 copyEvents($prefs.find('input').first(), $label.find('input'));
8784
8785 // Append hide label
8786 $prefs.append($label);
8787 }
8788
8789 // Copy default WP events onto metabox.
8790 if ($('.postbox').length) {
8791 copyEvents($('.postbox .handlediv').first(), $postbox.children('.handlediv'));
8792 copyEvents($('.postbox .hndle').first(), $postbox.children('.hndle'));
8793 }
8794
8795 // Append metabox to the bottom of "side-sortables".
8796 if (result.position === 'side') {
8797 $('#' + result.position + '-sortables').append($postbox);
8798
8799 // Prepend metabox to the top of "normal-sortbables".
8800 } else {
8801 $('#' + result.position + '-sortables').prepend($postbox);
8802 }
8803
8804 // Position metabox amongst existing ACF metaboxes within the same location.
8805 var order = [];
8806 data.results.map(function (_result) {
8807 if (result.position === _result.position && $('#' + result.position + '-sortables #' + _result.id).length) {
8808 order.push(_result.id);
8809 }
8810 });
8811 sortMetabox(result.id, order);
8812
8813 // Check 'sorted' for user preference.
8814 if (data.sorted) {
8815 // Loop over each position (acf_after_title, side, normal).
8816 for (var position in data.sorted) {
8817 let order = data.sorted[position];
8818 if (typeof order !== 'string') {
8819 continue;
8820 }
8821
8822 // Explode string into array of ids.
8823 order = order.split(',');
8824
8825 // Position metabox relative to order.
8826 if (sortMetabox(result.id, order)) {
8827 break;
8828 }
8829 }
8830 }
8831
8832 // Initalize it (modifies HTML).
8833 postbox = acf.newPostbox(result);
8834
8835 // Trigger action.
8836 acf.doAction('append', $postbox);
8837 acf.doAction('append_postbox', postbox);
8838 }
8839
8840 // show postbox
8841 postbox.showEnable();
8842
8843 // append
8844 data.visible.push(result.id);
8845
8846 // Return result (may have changed).
8847 return result;
8848 });
8849
8850 // Hide these postboxes.
8851 acf.getPostboxes().map(function (postbox) {
8852 if (data.visible.indexOf(postbox.get('id')) === -1) {
8853 // Hide postbox.
8854 postbox.hideDisable();
8855
8856 // Append to data.
8857 data.hidden.push(postbox.get('id'));
8858 }
8859 });
8860
8861 // Update style.
8862 $('#acf-style').html(data.style);
8863
8864 // Do action.
8865 acf.doAction('refresh_post_screen', data);
8866 },
8867 renderUserScreen: function (json) {}
8868 });
8869
8870 /**
8871 * gutenScreen
8872 *
8873 * Adds compatibility with the Gutenberg edit screen.
8874 *
8875 * @date 11/12/18
8876 * @since ACF 5.8.0
8877 *
8878 * @param void
8879 * @return void
8880 */
8881 var gutenScreen = new acf.Model({
8882 // Keep a reference to the most recent post attributes.
8883 postEdits: {},
8884 // Wait until assets have been loaded.
8885 wait: 'prepare',
8886 initialize: function () {
8887 // Bail early if not Gutenberg.
8888 if (!acf.isGutenbergPostEditor()) {
8889 return;
8890 }
8891
8892 // Listen for changes (use debounced version as this can fires often).
8893 wp.data.subscribe(acf.debounce(this.onChange).bind(this));
8894
8895 // Customize "acf.screen.get" functions.
8896 acf.screen.getPageTemplate = this.getPageTemplate;
8897 acf.screen.getPageParent = this.getPageParent;
8898 acf.screen.getPostType = this.getPostType;
8899 acf.screen.getPostFormat = this.getPostFormat;
8900 acf.screen.getPostCoreTerms = this.getPostCoreTerms;
8901
8902 // Disable unload
8903 acf.unload.disable();
8904
8905 // Refresh metaboxes since WP 5.3.
8906 var wpMinorVersion = parseFloat(acf.get('wp_version'));
8907 if (wpMinorVersion >= 5.3) {
8908 this.addAction('refresh_post_screen', this.onRefreshPostScreen);
8909 }
8910
8911 // Trigger "refresh" after WP has moved metaboxes into place.
8912 wp.domReady(acf.refresh);
8913 },
8914 onChange: function () {
8915 // Determine attributes that can trigger a refresh.
8916 var attributes = ['template', 'parent', 'format'];
8917
8918 // Append taxonomy attribute names to this list.
8919 (wp.data.select('core').getTaxonomies() || []).map(function (taxonomy) {
8920 attributes.push(taxonomy.rest_base);
8921 });
8922
8923 // Get relevant current post edits.
8924 var _postEdits = wp.data.select('core/editor').getPostEdits();
8925 var postEdits = {};
8926 attributes.map(function (k) {
8927 if (_postEdits[k] !== undefined) {
8928 postEdits[k] = _postEdits[k];
8929 }
8930 });
8931
8932 // Detect change.
8933 if (JSON.stringify(postEdits) !== JSON.stringify(this.postEdits)) {
8934 this.postEdits = postEdits;
8935
8936 // Check screen.
8937 acf.screen.check();
8938 }
8939 },
8940 getPageTemplate: function () {
8941 return wp.data.select('core/editor').getEditedPostAttribute('template');
8942 },
8943 getPageParent: function (e, $el) {
8944 return wp.data.select('core/editor').getEditedPostAttribute('parent');
8945 },
8946 getPostType: function () {
8947 return wp.data.select('core/editor').getEditedPostAttribute('type');
8948 },
8949 getPostFormat: function (e, $el) {
8950 return wp.data.select('core/editor').getEditedPostAttribute('format');
8951 },
8952 getPostCoreTerms: function () {
8953 // vars
8954 var terms = {};
8955
8956 // Loop over taxonomies.
8957 var taxonomies = wp.data.select('core').getTaxonomies() || [];
8958 taxonomies.map(function (taxonomy) {
8959 // Append selected taxonomies to terms object.
8960 var postTerms = wp.data.select('core/editor').getEditedPostAttribute(taxonomy.rest_base);
8961 if (postTerms) {
8962 terms[taxonomy.slug] = postTerms;
8963 }
8964 });
8965
8966 // return
8967 return terms;
8968 },
8969 /**
8970 * onRefreshPostScreen
8971 *
8972 * Fires after the Post edit screen metaboxs are refreshed to update the Block Editor API state.
8973 *
8974 * @date 11/11/19
8975 * @since ACF 5.8.7
8976 *
8977 * @param object data The "check_screen" JSON response data.
8978 * @return void
8979 */
8980 onRefreshPostScreen: function (data) {
8981 // Extract vars.
8982 var select = wp.data.select('core/edit-post');
8983 var dispatch = wp.data.dispatch('core/edit-post');
8984
8985 // Load current metabox locations and data.
8986 var locations = {};
8987 select.getActiveMetaBoxLocations().map(function (location) {
8988 locations[location] = select.getMetaBoxesPerLocation(location);
8989 });
8990
8991 // Generate flat array of existing ids.
8992 var ids = [];
8993 for (var k in locations) {
8994 locations[k].map(function (m) {
8995 ids.push(m.id);
8996 });
8997 }
8998
8999 // Append new ACF metaboxes (ignore those which already exist).
9000 data.results.filter(function (r) {
9001 return ids.indexOf(r.id) === -1;
9002 }).map(function (result, i) {
9003 // Ensure location exists.
9004 var location = result.position;
9005 locations[location] = locations[location] || [];
9006
9007 // Append.
9008 locations[location].push({
9009 id: result.id,
9010 title: result.title
9011 });
9012 });
9013
9014 // Remove hidden ACF metaboxes.
9015 for (var k in locations) {
9016 locations[k] = locations[k].filter(function (m) {
9017 return data.hidden.indexOf(m.id) === -1;
9018 });
9019 }
9020
9021 // Update state.
9022 dispatch.setAvailableMetaBoxesPerLocation(locations);
9023 }
9024 });
9025 })(jQuery);
9026
9027 /***/ }),
9028
9029 /***/ "./assets/src/js/_acf-select2.js":
9030 /*!***************************************!*\
9031 !*** ./assets/src/js/_acf-select2.js ***!
9032 \***************************************/
9033 /***/ (() => {
9034
9035 (function ($, undefined) {
9036 /**
9037 * acf.newSelect2
9038 *
9039 * description
9040 *
9041 * @date 13/1/18
9042 * @since ACF 5.6.5
9043 *
9044 * @param type $var Description. Default.
9045 * @return type Description.
9046 */
9047
9048 acf.newSelect2 = function ($select, props) {
9049 // defaults
9050 props = acf.parseArgs(props, {
9051 allowNull: false,
9052 placeholder: '',
9053 multiple: false,
9054 field: false,
9055 ajax: false,
9056 ajaxAction: '',
9057 ajaxData: function (data) {
9058 return data;
9059 },
9060 ajaxResults: function (json) {
9061 return json;
9062 },
9063 escapeMarkup: false,
9064 templateSelection: false,
9065 templateResult: false,
9066 dropdownCssClass: '',
9067 suppressFilters: false
9068 });
9069
9070 // initialize
9071 if (getVersion() == 4) {
9072 var select2 = new Select2_4($select, props);
9073 } else {
9074 var select2 = new Select2_3($select, props);
9075 }
9076
9077 // actions
9078 acf.doAction('new_select2', select2);
9079
9080 // return
9081 return select2;
9082 };
9083
9084 /**
9085 * getVersion
9086 *
9087 * description
9088 *
9089 * @date 13/1/18
9090 * @since ACF 5.6.5
9091 *
9092 * @param type $var Description. Default.
9093 * @return type Description.
9094 */
9095
9096 function getVersion() {
9097 // v4
9098 if (acf.isset(window, 'jQuery', 'fn', 'select2', 'amd')) {
9099 return 4;
9100 }
9101
9102 // v3
9103 if (acf.isset(window, 'Select2')) {
9104 return 3;
9105 }
9106
9107 // return
9108 return false;
9109 }
9110
9111 /**
9112 * Select2
9113 *
9114 * description
9115 *
9116 * @date 13/1/18
9117 * @since ACF 5.6.5
9118 *
9119 * @param type $var Description. Default.
9120 * @return type Description.
9121 */
9122
9123 var Select2 = acf.Model.extend({
9124 setup: function ($select, props) {
9125 $.extend(this.data, props);
9126 this.$el = $select;
9127 },
9128 initialize: function () {},
9129 selectOption: function (value) {
9130 var $option = this.getOption(value);
9131 if (!$option.prop('selected')) {
9132 $option.prop('selected', true).trigger('change');
9133 }
9134 },
9135 unselectOption: function (value) {
9136 var $option = this.getOption(value);
9137 if ($option.prop('selected')) {
9138 $option.prop('selected', false).trigger('change');
9139 }
9140 },
9141 getOption: function (value) {
9142 return this.$('option[value="' + value + '"]');
9143 },
9144 addOption: function (option) {
9145 // defaults
9146 option = acf.parseArgs(option, {
9147 id: '',
9148 text: '',
9149 selected: false
9150 });
9151
9152 // vars
9153 var $option = this.getOption(option.id);
9154
9155 // append
9156 if (!$option.length) {
9157 $option = $('<option></option>');
9158 $option.html(option.text);
9159 $option.attr('value', option.id);
9160 $option.prop('selected', option.selected);
9161 this.$el.append($option);
9162 }
9163
9164 // chain
9165 return $option;
9166 },
9167 getValue: function () {
9168 // vars
9169 var val = [];
9170 var $options = this.$el.find('option:selected');
9171
9172 // bail early if no selected
9173 if (!$options.exists()) {
9174 return val;
9175 }
9176
9177 // sort by attribute
9178 $options = $options.sort(function (a, b) {
9179 return +a.getAttribute('data-i') - +b.getAttribute('data-i');
9180 });
9181
9182 // loop
9183 $options.each(function () {
9184 var $el = $(this);
9185 val.push({
9186 $el: $el,
9187 id: $el.attr('value'),
9188 text: $el.text()
9189 });
9190 });
9191
9192 // return
9193 return val;
9194 },
9195 mergeOptions: function () {},
9196 getChoices: function () {
9197 // callback
9198 var crawl = function ($parent) {
9199 // vars
9200 var choices = [];
9201
9202 // loop
9203 $parent.children().each(function () {
9204 // vars
9205 var $child = $(this);
9206
9207 // optgroup
9208 if ($child.is('optgroup')) {
9209 choices.push({
9210 text: $child.attr('label'),
9211 children: crawl($child)
9212 });
9213
9214 // option
9215 } else {
9216 choices.push({
9217 id: $child.attr('value'),
9218 text: $child.text()
9219 });
9220 }
9221 });
9222
9223 // return
9224 return choices;
9225 };
9226
9227 // crawl
9228 return crawl(this.$el);
9229 },
9230 getAjaxData: function (params) {
9231 // vars
9232 var ajaxData = {
9233 action: this.get('ajaxAction'),
9234 s: params.term || '',
9235 paged: params.page || 1
9236 };
9237
9238 // field helper
9239 var field = this.get('field');
9240 if (field) {
9241 ajaxData.field_key = field.get('key');
9242 if (field.get('nonce')) {
9243 ajaxData.nonce = field.get('nonce');
9244 }
9245 }
9246
9247 // callback
9248 var callback = this.get('ajaxData');
9249 if (callback) {
9250 ajaxData = callback.apply(this, [ajaxData, params]);
9251 }
9252
9253 // filter
9254 ajaxData = acf.applyFilters('select2_ajax_data', ajaxData, this.data, this.$el, field || false, this);
9255
9256 // return
9257 return acf.prepareForAjax(ajaxData);
9258 },
9259 getAjaxResults: function (json, params) {
9260 // defaults
9261 json = acf.parseArgs(json, {
9262 results: false,
9263 more: false
9264 });
9265
9266 // callback
9267 var callback = this.get('ajaxResults');
9268 if (callback) {
9269 json = callback.apply(this, [json, params]);
9270 }
9271
9272 // filter
9273 json = acf.applyFilters('select2_ajax_results', json, params, this);
9274
9275 // return
9276 return json;
9277 },
9278 processAjaxResults: function (json, params) {
9279 // vars
9280 var json = this.getAjaxResults(json, params);
9281
9282 // change more to pagination
9283 if (json.more) {
9284 json.pagination = {
9285 more: true
9286 };
9287 }
9288
9289 // merge together groups
9290 setTimeout($.proxy(this.mergeOptions, this), 1);
9291
9292 // return
9293 return json;
9294 },
9295 destroy: function () {
9296 // destroy via api
9297 if (this.$el.data('select2')) {
9298 this.$el.select2('destroy');
9299 }
9300
9301 // destory via HTML (duplicating HTML does not contain data)
9302 this.$el.siblings('.select2-container').remove();
9303 }
9304 });
9305
9306 /**
9307 * Select2_4
9308 *
9309 * description
9310 *
9311 * @date 13/1/18
9312 * @since ACF 5.6.5
9313 *
9314 * @param type $var Description. Default.
9315 * @return type Description.
9316 */
9317
9318 var Select2_4 = Select2.extend({
9319 initialize: function () {
9320 // vars
9321 var $select = this.$el;
9322 var options = {
9323 width: '100%',
9324 allowClear: this.get('allowNull'),
9325 placeholder: this.get('placeholder'),
9326 multiple: this.get('multiple'),
9327 escapeMarkup: this.get('escapeMarkup'),
9328 templateSelection: this.get('templateSelection'),
9329 templateResult: this.get('templateResult'),
9330 dropdownCssClass: this.get('dropdownCssClass'),
9331 suppressFilters: this.get('suppressFilters'),
9332 data: []
9333 };
9334
9335 // Clear empty templateSelections, templateResults, or dropdownCssClass.
9336 if (!options.templateSelection) {
9337 delete options.templateSelection;
9338 }
9339 if (!options.templateResult) {
9340 delete options.templateResult;
9341 }
9342 if (!options.dropdownCssClass) {
9343 delete options.dropdownCssClass;
9344 }
9345
9346 // Only use the template if SelectWoo is not loaded to work around https://github.com/woocommerce/woocommerce/pull/30473
9347 if (!acf.isset(window, 'jQuery', 'fn', 'selectWoo')) {
9348 if (!options.templateSelection) {
9349 options.templateSelection = function (selection) {
9350 var $selection = $('<span class="acf-selection"></span>');
9351 $selection.html(options.escapeMarkup(selection.text));
9352 $selection.data('element', selection.element);
9353 return $selection;
9354 };
9355 }
9356 } else {
9357 delete options.templateSelection;
9358 delete options.templateResult;
9359 }
9360
9361 // Use a default, filterable escapeMarkup if not provided.
9362 if (!options.escapeMarkup) {
9363 options.escapeMarkup = function (markup) {
9364 if (typeof markup !== 'string') {
9365 return markup;
9366 }
9367 if (this.suppressFilters) {
9368 return acf.strEscape(markup);
9369 }
9370 return acf.applyFilters('select2_escape_markup', acf.strEscape(markup), markup, $select, this.data, field || false, this);
9371 };
9372 }
9373
9374 // multiple
9375 if (options.multiple) {
9376 // reorder options
9377 this.getValue().map(function (item) {
9378 item.$el.detach().appendTo($select);
9379 });
9380 }
9381
9382 // Temporarily remove conflicting attribute.
9383 var attrAjax = $select.attr('data-ajax');
9384 if (attrAjax !== undefined) {
9385 $select.removeData('ajax');
9386 $select.removeAttr('data-ajax');
9387 }
9388
9389 // ajax
9390 if (this.get('ajax')) {
9391 options.ajax = {
9392 url: acf.get('ajaxurl'),
9393 delay: 250,
9394 dataType: 'json',
9395 type: 'post',
9396 cache: false,
9397 data: $.proxy(this.getAjaxData, this),
9398 processResults: $.proxy(this.processAjaxResults, this)
9399 };
9400 }
9401
9402 // filter for 3rd party customization
9403 if (!options.suppressFilters) {
9404 var field = this.get('field');
9405 options = acf.applyFilters('select2_args', options, $select, this.data, field || false, this);
9406 }
9407 // add select2
9408 $select.select2(options);
9409
9410 // get container (Select2 v4 does not return this from constructor)
9411 var $container = $select.next('.select2-container');
9412
9413 // multiple
9414 if (options.multiple) {
9415 // vars
9416 var $ul = $container.find('ul');
9417
9418 // sortable
9419 $ul.sortable({
9420 stop: function (e) {
9421 // loop
9422 $ul.find('.select2-selection__choice').each(function () {
9423 // Attempt to use .data if it exists (select2 version < 4.0.6) or use our template data instead.
9424 if ($(this).data('data')) {
9425 var $option = $($(this).data('data').element);
9426 } else {
9427 var $option = $($(this).find('span.acf-selection').data('element'));
9428 }
9429
9430 // detach and re-append to end
9431 $option.detach().appendTo($select);
9432 });
9433
9434 // trigger change on input (JS error if trigger on select)
9435 $select.trigger('change');
9436 }
9437 });
9438
9439 // on select, move to end
9440 $select.on('select2:select', this.proxy(function (e) {
9441 this.getOption(e.params.data.id).detach().appendTo(this.$el);
9442 }));
9443 }
9444
9445 // add handler to auto-focus searchbox (for jQuery 3.6)
9446 $select.on('select2:open', () => {
9447 $('.select2-container--open .select2-search__field').get(-1).focus();
9448 });
9449
9450 // add class
9451 $container.addClass('-acf');
9452
9453 // Add back temporarily removed attr.
9454 if (attrAjax !== undefined) {
9455 $select.attr('data-ajax', attrAjax);
9456 }
9457
9458 // action for 3rd party customization
9459 if (!options.suppressFilters) {
9460 acf.doAction('select2_init', $select, options, this.data, field || false, this);
9461 }
9462 },
9463 mergeOptions: function () {
9464 // vars
9465 var $prevOptions = false;
9466 var $prevGroup = false;
9467
9468 // loop
9469 $('.select2-results__option[role="group"]').each(function () {
9470 // vars
9471 var $options = $(this).children('ul');
9472 var $group = $(this).children('strong');
9473
9474 // compare to previous
9475 if ($prevGroup && $prevGroup.text() === $group.text()) {
9476 $prevOptions.append($options.children());
9477 $(this).remove();
9478 return;
9479 }
9480
9481 // update vars
9482 $prevOptions = $options;
9483 $prevGroup = $group;
9484 });
9485 }
9486 });
9487
9488 /**
9489 * Select2_3
9490 *
9491 * description
9492 *
9493 * @date 13/1/18
9494 * @since ACF 5.6.5
9495 *
9496 * @param type $var Description. Default.
9497 * @return type Description.
9498 */
9499
9500 var Select2_3 = Select2.extend({
9501 initialize: function () {
9502 // vars
9503 var $select = this.$el;
9504 var value = this.getValue();
9505 var multiple = this.get('multiple');
9506 var options = {
9507 width: '100%',
9508 allowClear: this.get('allowNull'),
9509 placeholder: this.get('placeholder'),
9510 separator: '||',
9511 multiple: this.get('multiple'),
9512 data: this.getChoices(),
9513 escapeMarkup: function (string) {
9514 return acf.escHtml(string);
9515 },
9516 dropdownCss: {
9517 'z-index': '999999999'
9518 },
9519 initSelection: function (element, callback) {
9520 if (multiple) {
9521 callback(value);
9522 } else {
9523 callback(value.shift());
9524 }
9525 }
9526 };
9527 // get hidden input
9528 var $input = $select.siblings('input');
9529 if (!$input.length) {
9530 $input = $('<input type="hidden" />');
9531 $select.before($input);
9532 }
9533
9534 // set input value
9535 inputValue = value.map(function (item) {
9536 return item.id;
9537 }).join('||');
9538 $input.val(inputValue);
9539
9540 // multiple
9541 if (options.multiple) {
9542 // reorder options
9543 value.map(function (item) {
9544 item.$el.detach().appendTo($select);
9545 });
9546 }
9547
9548 // remove blank option as we have a clear all button
9549 if (options.allowClear) {
9550 options.data = options.data.filter(function (item) {
9551 return item.id !== '';
9552 });
9553 }
9554
9555 // remove conflicting atts
9556 $select.removeData('ajax');
9557 $select.removeAttr('data-ajax');
9558
9559 // ajax
9560 if (this.get('ajax')) {
9561 options.ajax = {
9562 url: acf.get('ajaxurl'),
9563 quietMillis: 250,
9564 dataType: 'json',
9565 type: 'post',
9566 cache: false,
9567 data: $.proxy(this.getAjaxData, this),
9568 results: $.proxy(this.processAjaxResults, this)
9569 };
9570 }
9571
9572 // filter for 3rd party customization
9573 var field = this.get('field');
9574 options = acf.applyFilters('select2_args', options, $select, this.data, field || false, this);
9575
9576 // add select2
9577 $input.select2(options);
9578
9579 // get container
9580 var $container = $input.select2('container');
9581
9582 // helper to find this select's option
9583 var getOption = $.proxy(this.getOption, this);
9584
9585 // multiple
9586 if (options.multiple) {
9587 // vars
9588 var $ul = $container.find('ul');
9589
9590 // sortable
9591 $ul.sortable({
9592 stop: function () {
9593 // loop
9594 $ul.find('.select2-search-choice').each(function () {
9595 // vars
9596 var data = $(this).data('select2Data');
9597 var $option = getOption(data.id);
9598
9599 // detach and re-append to end
9600 $option.detach().appendTo($select);
9601 });
9602
9603 // trigger change on input (JS error if trigger on select)
9604 $select.trigger('change');
9605 }
9606 });
9607 }
9608
9609 // on select, create option and move to end
9610 $input.on('select2-selecting', function (e) {
9611 // vars
9612 var item = e.choice;
9613 var $option = getOption(item.id);
9614
9615 // create if doesn't exist
9616 if (!$option.length) {
9617 $option = $('<option value="' + item.id + '">' + item.text + '</option>');
9618 }
9619
9620 // detach and re-append to end
9621 $option.detach().appendTo($select);
9622 });
9623
9624 // add class
9625 $container.addClass('-acf');
9626
9627 // action for 3rd party customization
9628 acf.doAction('select2_init', $select, options, this.data, field || false, this);
9629
9630 // change
9631 $input.on('change', function () {
9632 var val = $input.val();
9633 if (val.indexOf('||')) {
9634 val = val.split('||');
9635 }
9636 $select.val(val).trigger('change');
9637 });
9638
9639 // hide select
9640 $select.hide();
9641 },
9642 mergeOptions: function () {
9643 // vars
9644 var $prevOptions = false;
9645 var $prevGroup = false;
9646
9647 // loop
9648 $('#select2-drop .select2-result-with-children').each(function () {
9649 // vars
9650 var $options = $(this).children('ul');
9651 var $group = $(this).children('.select2-result-label');
9652
9653 // compare to previous
9654 if ($prevGroup && $prevGroup.text() === $group.text()) {
9655 $prevGroup.append($options.children());
9656 $(this).remove();
9657 return;
9658 }
9659
9660 // update vars
9661 $prevOptions = $options;
9662 $prevGroup = $group;
9663 });
9664 },
9665 getAjaxData: function (term, page) {
9666 // create Select2 v4 params
9667 var params = {
9668 term: term,
9669 page: page
9670 };
9671
9672 // filter
9673 var field = this.get('field');
9674 params = acf.applyFilters('select2_ajax_data', params, this.data, this.$el, field || false, this);
9675 // return
9676 return Select2.prototype.getAjaxData.apply(this, [params]);
9677 }
9678 });
9679
9680 // manager
9681 var select2Manager = new acf.Model({
9682 priority: 5,
9683 wait: 'prepare',
9684 actions: {
9685 duplicate: 'onDuplicate'
9686 },
9687 initialize: function () {
9688 // vars
9689 var locale = acf.get('locale');
9690 var rtl = acf.get('rtl');
9691 var l10n = acf.get('select2L10n');
9692 var version = getVersion();
9693
9694 // bail early if no l10n
9695 if (!l10n) {
9696 return false;
9697 }
9698
9699 // bail early if 'en'
9700 if (locale.indexOf('en') === 0) {
9701 return false;
9702 }
9703
9704 // initialize
9705 if (version == 4) {
9706 this.addTranslations4();
9707 } else if (version == 3) {
9708 this.addTranslations3();
9709 }
9710 },
9711 addTranslations4: function () {
9712 // vars
9713 var l10n = acf.get('select2L10n');
9714 var locale = acf.get('locale');
9715
9716 // modify local to match html[lang] attribute (used by Select2)
9717 locale = locale.replace('_', '-');
9718
9719 // select2L10n
9720 var select2L10n = {
9721 errorLoading: function () {
9722 return l10n.load_fail;
9723 },
9724 inputTooLong: function (args) {
9725 var overChars = args.input.length - args.maximum;
9726 if (overChars > 1) {
9727 return l10n.input_too_long_n.replace('%d', overChars);
9728 }
9729 return l10n.input_too_long_1;
9730 },
9731 inputTooShort: function (args) {
9732 var remainingChars = args.minimum - args.input.length;
9733 if (remainingChars > 1) {
9734 return l10n.input_too_short_n.replace('%d', remainingChars);
9735 }
9736 return l10n.input_too_short_1;
9737 },
9738 loadingMore: function () {
9739 return l10n.load_more;
9740 },
9741 maximumSelected: function (args) {
9742 var maximum = args.maximum;
9743 if (maximum > 1) {
9744 return l10n.selection_too_long_n.replace('%d', maximum);
9745 }
9746 return l10n.selection_too_long_1;
9747 },
9748 noResults: function () {
9749 return l10n.matches_0;
9750 },
9751 searching: function () {
9752 return l10n.searching;
9753 }
9754 };
9755
9756 // append
9757 jQuery.fn.select2.amd.define('select2/i18n/' + locale, [], function () {
9758 return select2L10n;
9759 });
9760 },
9761 addTranslations3: function () {
9762 // vars
9763 var l10n = acf.get('select2L10n');
9764 var locale = acf.get('locale');
9765
9766 // modify local to match html[lang] attribute (used by Select2)
9767 locale = locale.replace('_', '-');
9768
9769 // select2L10n
9770 var select2L10n = {
9771 formatMatches: function (matches) {
9772 if (matches > 1) {
9773 return l10n.matches_n.replace('%d', matches);
9774 }
9775 return l10n.matches_1;
9776 },
9777 formatNoMatches: function () {
9778 return l10n.matches_0;
9779 },
9780 formatAjaxError: function () {
9781 return l10n.load_fail;
9782 },
9783 formatInputTooShort: function (input, min) {
9784 var remainingChars = min - input.length;
9785 if (remainingChars > 1) {
9786 return l10n.input_too_short_n.replace('%d', remainingChars);
9787 }
9788 return l10n.input_too_short_1;
9789 },
9790 formatInputTooLong: function (input, max) {
9791 var overChars = input.length - max;
9792 if (overChars > 1) {
9793 return l10n.input_too_long_n.replace('%d', overChars);
9794 }
9795 return l10n.input_too_long_1;
9796 },
9797 formatSelectionTooBig: function (maximum) {
9798 if (maximum > 1) {
9799 return l10n.selection_too_long_n.replace('%d', maximum);
9800 }
9801 return l10n.selection_too_long_1;
9802 },
9803 formatLoadMore: function () {
9804 return l10n.load_more;
9805 },
9806 formatSearching: function () {
9807 return l10n.searching;
9808 }
9809 };
9810
9811 // ensure locales exists
9812 $.fn.select2.locales = $.fn.select2.locales || {};
9813
9814 // append
9815 $.fn.select2.locales[locale] = select2L10n;
9816 $.extend($.fn.select2.defaults, select2L10n);
9817 },
9818 onDuplicate: function ($el, $el2) {
9819 $el2.find('.select2-container').remove();
9820 }
9821 });
9822 })(jQuery);
9823
9824 /***/ }),
9825
9826 /***/ "./assets/src/js/_acf-tinymce.js":
9827 /*!***************************************!*\
9828 !*** ./assets/src/js/_acf-tinymce.js ***!
9829 \***************************************/
9830 /***/ (() => {
9831
9832 (function ($, undefined) {
9833 acf.tinymce = {
9834 /*
9835 * defaults
9836 *
9837 * This function will return default mce and qt settings
9838 *
9839 * @type function
9840 * @date 18/8/17
9841 * @since ACF 5.6.0
9842 *
9843 * @param $post_id (int)
9844 * @return $post_id (int)
9845 */
9846
9847 defaults: function () {
9848 // bail early if no tinyMCEPreInit
9849 if (typeof tinyMCEPreInit === 'undefined') return false;
9850
9851 // vars
9852 var defaults = {
9853 tinymce: tinyMCEPreInit.mceInit.acf_content,
9854 quicktags: tinyMCEPreInit.qtInit.acf_content
9855 };
9856
9857 // return
9858 return defaults;
9859 },
9860 /*
9861 * initialize
9862 *
9863 * This function will initialize the tinymce and quicktags instances
9864 *
9865 * @type function
9866 * @date 18/8/17
9867 * @since ACF 5.6.0
9868 *
9869 * @param $post_id (int)
9870 * @return $post_id (int)
9871 */
9872
9873 initialize: function (id, args) {
9874 // defaults
9875 args = acf.parseArgs(args, {
9876 tinymce: true,
9877 quicktags: true,
9878 toolbar: 'full',
9879 mode: 'visual',
9880 // visual,text
9881 field: false
9882 });
9883
9884 // tinymce
9885 if (args.tinymce) {
9886 this.initializeTinymce(id, args);
9887 }
9888
9889 // quicktags
9890 if (args.quicktags) {
9891 this.initializeQuicktags(id, args);
9892 }
9893 },
9894 /*
9895 * initializeTinymce
9896 *
9897 * This function will initialize the tinymce instance
9898 *
9899 * @type function
9900 * @date 18/8/17
9901 * @since ACF 5.6.0
9902 *
9903 * @param $post_id (int)
9904 * @return $post_id (int)
9905 */
9906
9907 initializeTinymce: function (id, args) {
9908 // vars
9909 var $textarea = $('#' + id);
9910 var defaults = this.defaults();
9911 var toolbars = acf.get('toolbars');
9912 var field = args.field || false;
9913 var $field = field.$el || false;
9914
9915 // bail early
9916 if (typeof tinymce === 'undefined') return false;
9917 if (!defaults) return false;
9918
9919 // check if exists
9920 if (tinymce.get(id)) {
9921 return this.enable(id);
9922 }
9923
9924 // settings
9925 var init = $.extend({}, defaults.tinymce, args.tinymce);
9926 init.id = id;
9927 init.selector = '#' + id;
9928
9929 // toolbar
9930 var toolbar = args.toolbar;
9931 if (toolbar && toolbars && toolbars[toolbar]) {
9932 for (var i = 1; i <= 4; i++) {
9933 init['toolbar' + i] = toolbars[toolbar][i] || '';
9934 }
9935 }
9936
9937 // event
9938 init.setup = function (ed) {
9939 ed.on('change', function (e) {
9940 ed.save(); // save to textarea
9941 $textarea.trigger('change');
9942 });
9943
9944 // Fix bug where Gutenberg does not hear "mouseup" event and tries to select multiple blocks.
9945 ed.on('mouseup', function (e) {
9946 var event = new MouseEvent('mouseup');
9947 window.dispatchEvent(event);
9948 });
9949
9950 // Temporarily comment out. May not be necessary due to wysiwyg field actions.
9951 //ed.on('unload', function(e) {
9952 // acf.tinymce.remove( id );
9953 //});
9954 };
9955
9956 // disable wp_autoresize_on (no solution yet for fixed toolbar)
9957 init.wp_autoresize_on = false;
9958
9959 // Enable wpautop allowing value to save without <p> tags.
9960 // Only if the "TinyMCE Advanced" plugin hasn't already set this functionality.
9961 if (!init.tadv_noautop) {
9962 init.wpautop = true;
9963 }
9964
9965 // hook for 3rd party customization
9966 init = acf.applyFilters('wysiwyg_tinymce_settings', init, id, field);
9967
9968 // z-index fix (caused too many conflicts)
9969 //if( acf.isset(tinymce,'ui','FloatPanel') ) {
9970 // tinymce.ui.FloatPanel.zIndex = 900000;
9971 //}
9972
9973 // store settings
9974 tinyMCEPreInit.mceInit[id] = init;
9975
9976 // visual tab is active
9977 if (args.mode == 'visual') {
9978 // init
9979 var result = tinymce.init(init);
9980
9981 // get editor
9982 var ed = tinymce.get(id);
9983
9984 // validate
9985 if (!ed) {
9986 return false;
9987 }
9988
9989 // add reference
9990 ed.acf = args.field;
9991
9992 // action
9993 acf.doAction('wysiwyg_tinymce_init', ed, ed.id, init, field);
9994 }
9995 },
9996 /*
9997 * initializeQuicktags
9998 *
9999 * This function will initialize the quicktags instance
10000 *
10001 * @type function
10002 * @date 18/8/17
10003 * @since ACF 5.6.0
10004 *
10005 * @param $post_id (int)
10006 * @return $post_id (int)
10007 */
10008
10009 initializeQuicktags: function (id, args) {
10010 // vars
10011 var defaults = this.defaults();
10012
10013 // bail early
10014 if (typeof quicktags === 'undefined') return false;
10015 if (!defaults) return false;
10016
10017 // settings
10018 var init = $.extend({}, defaults.quicktags, args.quicktags);
10019 init.id = id;
10020
10021 // filter
10022 var field = args.field || false;
10023 var $field = field.$el || false;
10024 init = acf.applyFilters('wysiwyg_quicktags_settings', init, init.id, field);
10025
10026 // store settings
10027 tinyMCEPreInit.qtInit[id] = init;
10028
10029 // init
10030 var ed = quicktags(init);
10031
10032 // validate
10033 if (!ed) {
10034 return false;
10035 }
10036
10037 // generate HTML
10038 this.buildQuicktags(ed);
10039
10040 // action for 3rd party customization
10041 acf.doAction('wysiwyg_quicktags_init', ed, ed.id, init, field);
10042 },
10043 /*
10044 * buildQuicktags
10045 *
10046 * This function will build the quicktags HTML
10047 *
10048 * @type function
10049 * @date 18/8/17
10050 * @since ACF 5.6.0
10051 *
10052 * @param $post_id (int)
10053 * @return $post_id (int)
10054 */
10055
10056 buildQuicktags: function (ed) {
10057 var canvas,
10058 name,
10059 settings,
10060 theButtons,
10061 html,
10062 ed,
10063 id,
10064 i,
10065 use,
10066 instanceId,
10067 defaults = ',strong,em,link,block,del,ins,img,ul,ol,li,code,more,close,';
10068 canvas = ed.canvas;
10069 name = ed.name;
10070 settings = ed.settings;
10071 html = '';
10072 theButtons = {};
10073 use = '';
10074 instanceId = ed.id;
10075
10076 // set buttons
10077 if (settings.buttons) {
10078 use = ',' + settings.buttons + ',';
10079 }
10080 for (i in edButtons) {
10081 if (!edButtons[i]) {
10082 continue;
10083 }
10084 id = edButtons[i].id;
10085 if (use && defaults.indexOf(',' + id + ',') !== -1 && use.indexOf(',' + id + ',') === -1) {
10086 continue;
10087 }
10088 if (!edButtons[i].instance || edButtons[i].instance === instanceId) {
10089 theButtons[id] = edButtons[i];
10090 if (edButtons[i].html) {
10091 html += edButtons[i].html(name + '_');
10092 }
10093 }
10094 }
10095 if (use && use.indexOf(',dfw,') !== -1) {
10096 theButtons.dfw = new QTags.DFWButton();
10097 html += theButtons.dfw.html(name + '_');
10098 }
10099 if ('rtl' === document.getElementsByTagName('html')[0].dir) {
10100 theButtons.textdirection = new QTags.TextDirectionButton();
10101 html += theButtons.textdirection.html(name + '_');
10102 }
10103 ed.toolbar.innerHTML = html;
10104 ed.theButtons = theButtons;
10105 if (typeof jQuery !== 'undefined') {
10106 jQuery(document).triggerHandler('quicktags-init', [ed]);
10107 }
10108 },
10109 disable: function (id) {
10110 this.destroyTinymce(id);
10111 },
10112 remove: function (id) {
10113 this.destroyTinymce(id);
10114 },
10115 destroy: function (id) {
10116 this.destroyTinymce(id);
10117 },
10118 destroyTinymce: function (id) {
10119 // bail early
10120 if (typeof tinymce === 'undefined') return false;
10121
10122 // get editor
10123 var ed = tinymce.get(id);
10124
10125 // bail early if no editor
10126 if (!ed) return false;
10127
10128 // save
10129 ed.save();
10130
10131 // destroy editor
10132 ed.destroy();
10133
10134 // return
10135 return true;
10136 },
10137 enable: function (id) {
10138 this.enableTinymce(id);
10139 },
10140 enableTinymce: function (id) {
10141 // bail early
10142 if (typeof switchEditors === 'undefined') return false;
10143
10144 // bail early if not initialized
10145 if (typeof tinyMCEPreInit.mceInit[id] === 'undefined') return false;
10146
10147 // Ensure textarea element is visible
10148 // - Fixes bug in block editor when switching between "Block" and "Document" tabs.
10149 $('#' + id).show();
10150
10151 // toggle
10152 switchEditors.go(id, 'tmce');
10153
10154 // return
10155 return true;
10156 }
10157 };
10158 var editorManager = new acf.Model({
10159 // hook in before fieldsEventManager, conditions, etc
10160 priority: 5,
10161 actions: {
10162 prepare: 'onPrepare',
10163 ready: 'onReady'
10164 },
10165 onPrepare: function () {
10166 // find hidden editor which may exist within a field
10167 var $div = $('#acf-hidden-wp-editor');
10168
10169 // move to footer
10170 if ($div.exists()) {
10171 $div.appendTo('body');
10172 }
10173 },
10174 onReady: function () {
10175 // Restore wp.editor functions used by tinymce removed in WP5.
10176 if (acf.isset(window, 'wp', 'oldEditor')) {
10177 wp.editor.autop = wp.oldEditor.autop;
10178 wp.editor.removep = wp.oldEditor.removep;
10179 }
10180
10181 // bail early if no tinymce
10182 if (!acf.isset(window, 'tinymce', 'on')) return;
10183
10184 // restore default activeEditor
10185 tinymce.on('AddEditor', function (data) {
10186 // vars
10187 var editor = data.editor;
10188
10189 // bail early if not 'acf'
10190 if (editor.id.substr(0, 3) !== 'acf') return;
10191
10192 // override if 'content' exists
10193 editor = tinymce.editors.content || editor;
10194
10195 // update vars
10196 tinymce.activeEditor = editor;
10197 wpActiveEditor = editor.id;
10198 });
10199 }
10200 });
10201 })(jQuery);
10202
10203 /***/ }),
10204
10205 /***/ "./assets/src/js/_acf-unload.js":
10206 /*!**************************************!*\
10207 !*** ./assets/src/js/_acf-unload.js ***!
10208 \**************************************/
10209 /***/ (() => {
10210
10211 (function ($, undefined) {
10212 acf.unload = new acf.Model({
10213 wait: 'load',
10214 active: true,
10215 changed: false,
10216 actions: {
10217 validation_failure: 'startListening',
10218 validation_success: 'stopListening'
10219 },
10220 events: {
10221 'change form .acf-field': 'startListening',
10222 'submit form': 'stopListening'
10223 },
10224 enable: function () {
10225 this.active = true;
10226 },
10227 disable: function () {
10228 this.active = false;
10229 },
10230 reset: function () {
10231 this.stopListening();
10232 },
10233 startListening: function () {
10234 // bail early if already changed, not active
10235 if (this.changed || !this.active) {
10236 return;
10237 }
10238
10239 // update
10240 this.changed = true;
10241
10242 // add event
10243 $(window).on('beforeunload', this.onUnload);
10244 },
10245 stopListening: function () {
10246 // update
10247 this.changed = false;
10248
10249 // remove event
10250 $(window).off('beforeunload', this.onUnload);
10251 },
10252 onUnload: function () {
10253 return acf.__('The changes you made will be lost if you navigate away from this page');
10254 }
10255 });
10256 })(jQuery);
10257
10258 /***/ }),
10259
10260 /***/ "./assets/src/js/_acf-validation.js":
10261 /*!******************************************!*\
10262 !*** ./assets/src/js/_acf-validation.js ***!
10263 \******************************************/
10264 /***/ (() => {
10265
10266 (function ($, undefined) {
10267 /**
10268 * Validator
10269 *
10270 * The model for validating forms
10271 *
10272 * @date 4/9/18
10273 * @since ACF 5.7.5
10274 *
10275 * @param void
10276 * @return void
10277 */
10278 var Validator = acf.Model.extend({
10279 /** @var string The model identifier. */
10280 id: 'Validator',
10281 /** @var object The model data. */
10282 data: {
10283 /** @var array The form errors. */
10284 errors: [],
10285 /** @var object The form notice. */
10286 notice: null,
10287 /** @var string The form status. loading, invalid, valid */
10288 status: ''
10289 },
10290 /** @var object The model events. */
10291 events: {
10292 'changed:status': 'onChangeStatus'
10293 },
10294 /**
10295 * addErrors
10296 *
10297 * Adds errors to the form.
10298 *
10299 * @date 4/9/18
10300 * @since ACF 5.7.5
10301 *
10302 * @param array errors An array of errors.
10303 * @return void
10304 */
10305 addErrors: function (errors) {
10306 errors.map(this.addError, this);
10307 },
10308 /**
10309 * addError
10310 *
10311 * Adds and error to the form.
10312 *
10313 * @date 4/9/18
10314 * @since ACF 5.7.5
10315 *
10316 * @param object error An error object containing input and message.
10317 * @return void
10318 */
10319 addError: function (error) {
10320 this.data.errors.push(error);
10321 },
10322 /**
10323 * hasErrors
10324 *
10325 * Returns true if the form has errors.
10326 *
10327 * @date 4/9/18
10328 * @since ACF 5.7.5
10329 *
10330 * @param void
10331 * @return bool
10332 */
10333 hasErrors: function () {
10334 return this.data.errors.length;
10335 },
10336 /**
10337 * clearErrors
10338 *
10339 * Removes any errors.
10340 *
10341 * @date 4/9/18
10342 * @since ACF 5.7.5
10343 *
10344 * @param void
10345 * @return void
10346 */
10347 clearErrors: function () {
10348 return this.data.errors = [];
10349 },
10350 /**
10351 * getErrors
10352 *
10353 * Returns the forms errors.
10354 *
10355 * @date 4/9/18
10356 * @since ACF 5.7.5
10357 *
10358 * @param void
10359 * @return array
10360 */
10361 getErrors: function () {
10362 return this.data.errors;
10363 },
10364 /**
10365 * getFieldErrors
10366 *
10367 * Returns the forms field errors.
10368 *
10369 * @date 4/9/18
10370 * @since ACF 5.7.5
10371 *
10372 * @param void
10373 * @return array
10374 */
10375 getFieldErrors: function () {
10376 // vars
10377 var errors = [];
10378 var inputs = [];
10379
10380 // loop
10381 this.getErrors().map(function (error) {
10382 // bail early if global
10383 if (!error.input) return;
10384
10385 // update if exists
10386 var i = inputs.indexOf(error.input);
10387 if (i > -1) {
10388 errors[i] = error;
10389
10390 // update
10391 } else {
10392 errors.push(error);
10393 inputs.push(error.input);
10394 }
10395 });
10396
10397 // return
10398 return errors;
10399 },
10400 /**
10401 * getGlobalErrors
10402 *
10403 * Returns the forms global errors (errors without a specific input).
10404 *
10405 * @date 4/9/18
10406 * @since ACF 5.7.5
10407 *
10408 * @param void
10409 * @return array
10410 */
10411 getGlobalErrors: function () {
10412 // return array of errors that contain no input
10413 return this.getErrors().filter(function (error) {
10414 return !error.input;
10415 });
10416 },
10417 /**
10418 * showErrors
10419 *
10420 * Displays all errors for this form.
10421 *
10422 * @since ACF 5.7.5
10423 *
10424 * @param {string} [location=before] - The location to add the error, before or after the input. Default before. Since 6.3.
10425 * @return void
10426 */
10427 showErrors: function (location = 'before') {
10428 // bail early if no errors
10429 if (!this.hasErrors()) {
10430 return;
10431 }
10432
10433 // vars
10434 var fieldErrors = this.getFieldErrors();
10435 var globalErrors = this.getGlobalErrors();
10436
10437 // vars
10438 var errorCount = 0;
10439 var $scrollTo = false;
10440
10441 // loop
10442 fieldErrors.map(function (error) {
10443 // get input
10444 var $input = this.$('[name="' + error.input + '"]').first();
10445
10446 // if $_POST value was an array, this $input may not exist
10447 if (!$input.length) {
10448 $input = this.$('[name^="' + error.input + '"]').first();
10449 }
10450
10451 // bail early if input doesn't exist
10452 if (!$input.length) {
10453 return;
10454 }
10455
10456 // increase
10457 errorCount++;
10458
10459 // get field
10460 var field = acf.getClosestField($input);
10461
10462 // make sure the postbox containing this field is not hidden by screen options
10463 ensureFieldPostBoxIsVisible(field.$el);
10464
10465 // show error
10466 field.showError(error.message, location);
10467
10468 // set $scrollTo
10469 if (!$scrollTo) {
10470 $scrollTo = field.$el;
10471 }
10472 }, this);
10473
10474 // errorMessage
10475 var errorMessage = acf.__('Validation failed');
10476 globalErrors.map(function (error) {
10477 errorMessage += '. ' + error.message;
10478 });
10479 if (errorCount == 1) {
10480 errorMessage += '. ' + acf.__('1 field requires attention');
10481 } else if (errorCount > 1) {
10482 errorMessage += '. ' + acf.__('%d fields require attention').replace('%d', errorCount);
10483 }
10484
10485 // notice
10486 if (this.has('notice')) {
10487 this.get('notice').update({
10488 type: 'error',
10489 text: errorMessage
10490 });
10491 } else {
10492 var notice = acf.newNotice({
10493 type: 'error',
10494 text: errorMessage,
10495 target: this.$el
10496 });
10497 this.set('notice', notice);
10498 }
10499
10500 // If in a modal, don't try to scroll.
10501 if (this.$el.parents('.acf-popup-box').length) {
10502 return;
10503 }
10504
10505 // if no $scrollTo, set to message
10506 if (!$scrollTo) {
10507 $scrollTo = this.get('notice').$el;
10508 }
10509
10510 // timeout
10511 setTimeout(function () {
10512 $('html, body').animate({
10513 scrollTop: $scrollTo.offset().top - $(window).height() / 2
10514 }, 500);
10515 }, 10);
10516 },
10517 /**
10518 * onChangeStatus
10519 *
10520 * Update the form class when changing the 'status' data
10521 *
10522 * @date 4/9/18
10523 * @since ACF 5.7.5
10524 *
10525 * @param object e The event object.
10526 * @param jQuery $el The form element.
10527 * @param string value The new status.
10528 * @param string prevValue The old status.
10529 * @return void
10530 */
10531 onChangeStatus: function (e, $el, value, prevValue) {
10532 this.$el.removeClass('is-' + prevValue).addClass('is-' + value);
10533 },
10534 /**
10535 * validate
10536 *
10537 * Vaildates the form via AJAX.
10538 *
10539 * @date 4/9/18
10540 * @since ACF 5.7.5
10541 *
10542 * @param object args A list of settings to customize the validation process.
10543 * @return bool True if the form is valid.
10544 */
10545 validate: function (args) {
10546 // default args
10547 args = acf.parseArgs(args, {
10548 // trigger event
10549 event: false,
10550 // reset the form after submit
10551 reset: false,
10552 // loading callback
10553 loading: function () {},
10554 // complete callback
10555 complete: function () {},
10556 // failure callback
10557 failure: function () {},
10558 // success callback
10559 success: function ($form) {
10560 $form.submit();
10561 }
10562 });
10563
10564 // return true if is valid - allows form submit
10565 if (this.get('status') == 'valid') {
10566 return true;
10567 }
10568
10569 // return false if is currently validating - prevents form submit
10570 if (this.get('status') == 'validating') {
10571 return false;
10572 }
10573
10574 // return true if no ACF fields exist (no need to validate)
10575 if (!this.$('.acf-field').length) {
10576 return true;
10577 }
10578
10579 // if event is provided, create a new success callback.
10580 if (args.event) {
10581 var event = $.Event(null, args.event);
10582 args.success = function () {
10583 acf.enableSubmit($(event.target)).trigger(event);
10584 };
10585 }
10586
10587 // action for 3rd party
10588 acf.doAction('validation_begin', this.$el);
10589
10590 // lock form
10591 acf.lockForm(this.$el);
10592
10593 // loading callback
10594 args.loading(this.$el, this);
10595
10596 // update status
10597 this.set('status', 'validating');
10598
10599 // success callback
10600 var onSuccess = function (json) {
10601 // validate
10602 if (!acf.isAjaxSuccess(json)) {
10603 return;
10604 }
10605
10606 // filter
10607 var data = acf.applyFilters('validation_complete', json.data, this.$el, this);
10608
10609 // add errors
10610 if (!data.valid) {
10611 this.addErrors(data.errors);
10612 }
10613 };
10614
10615 // complete
10616 var onComplete = function () {
10617 // unlock form
10618 acf.unlockForm(this.$el);
10619
10620 // failure
10621 if (this.hasErrors()) {
10622 // update status
10623 this.set('status', 'invalid');
10624
10625 // action
10626 acf.doAction('validation_failure', this.$el, this);
10627
10628 // display errors
10629 this.showErrors();
10630
10631 // failure callback
10632 args.failure(this.$el, this);
10633
10634 // success
10635 } else {
10636 // update status
10637 this.set('status', 'valid');
10638
10639 // remove previous error message
10640 if (this.has('notice')) {
10641 this.get('notice').update({
10642 type: 'success',
10643 text: acf.__('Validation successful'),
10644 timeout: 1000
10645 });
10646 }
10647
10648 // action
10649 acf.doAction('validation_success', this.$el, this);
10650 acf.doAction('submit', this.$el);
10651
10652 // success callback (submit form)
10653 args.success(this.$el, this);
10654
10655 // lock form
10656 acf.lockForm(this.$el);
10657
10658 // reset
10659 if (args.reset) {
10660 this.reset();
10661 }
10662 }
10663
10664 // complete callback
10665 args.complete(this.$el, this);
10666
10667 // clear errors
10668 this.clearErrors();
10669 };
10670
10671 // serialize form data
10672 var data = acf.serialize(this.$el);
10673 data.action = 'acf/validate_save_post';
10674
10675 // ajax
10676 $.ajax({
10677 url: acf.get('ajaxurl'),
10678 data: acf.prepareForAjax(data, true),
10679 type: 'post',
10680 dataType: 'json',
10681 context: this,
10682 success: onSuccess,
10683 complete: onComplete
10684 });
10685
10686 // return false to fail validation and allow AJAX
10687 return false;
10688 },
10689 /**
10690 * setup
10691 *
10692 * Called during the constructor function to setup this instance
10693 *
10694 * @date 4/9/18
10695 * @since ACF 5.7.5
10696 *
10697 * @param jQuery $form The form element.
10698 * @return void
10699 */
10700 setup: function ($form) {
10701 // set $el
10702 this.$el = $form;
10703 },
10704 /**
10705 * reset
10706 *
10707 * Rests the validation to be used again.
10708 *
10709 * @date 6/9/18
10710 * @since ACF 5.7.5
10711 *
10712 * @param void
10713 * @return void
10714 */
10715 reset: function () {
10716 // reset data
10717 this.set('errors', []);
10718 this.set('notice', null);
10719 this.set('status', '');
10720
10721 // unlock form
10722 acf.unlockForm(this.$el);
10723 }
10724 });
10725
10726 /**
10727 * getValidator
10728 *
10729 * Returns the instance for a given form element.
10730 *
10731 * @date 4/9/18
10732 * @since ACF 5.7.5
10733 *
10734 * @param jQuery $el The form element.
10735 * @return object
10736 */
10737 var getValidator = function ($el) {
10738 // instantiate
10739 var validator = $el.data('acf');
10740 if (!validator) {
10741 validator = new Validator($el);
10742 }
10743
10744 // return
10745 return validator;
10746 };
10747
10748 /**
10749 * A helper function to generate a Validator for a block form, so .addErrors can be run via block logic.
10750 *
10751 * @since ACF 6.3
10752 *
10753 * @param $el The jQuery block form wrapper element.
10754 * @return bool
10755 */
10756 acf.getBlockFormValidator = function ($el) {
10757 return getValidator($el);
10758 };
10759
10760 /**
10761 * A helper function for the Validator.validate() function.
10762 * Returns true if form is valid, or fetches a validation request and returns false.
10763 *
10764 * @since ACF 5.6.9
10765 *
10766 * @param object args A list of settings to customize the validation process.
10767 * @return bool
10768 */
10769 acf.validateForm = function (args) {
10770 return getValidator(args.form).validate(args);
10771 };
10772
10773 /**
10774 * acf.enableSubmit
10775 *
10776 * Enables a submit button and returns the element.
10777 *
10778 * @date 30/8/18
10779 * @since ACF 5.7.4
10780 *
10781 * @param jQuery $submit The submit button.
10782 * @return jQuery
10783 */
10784 acf.enableSubmit = function ($submit) {
10785 return $submit.removeClass('disabled').removeAttr('disabled');
10786 };
10787
10788 /**
10789 * acf.disableSubmit
10790 *
10791 * Disables a submit button and returns the element.
10792 *
10793 * @date 30/8/18
10794 * @since ACF 5.7.4
10795 *
10796 * @param jQuery $submit The submit button.
10797 * @return jQuery
10798 */
10799 acf.disableSubmit = function ($submit) {
10800 return $submit.addClass('disabled').attr('disabled', true);
10801 };
10802
10803 /**
10804 * acf.showSpinner
10805 *
10806 * Shows the spinner element.
10807 *
10808 * @date 4/9/18
10809 * @since ACF 5.7.5
10810 *
10811 * @param jQuery $spinner The spinner element.
10812 * @return jQuery
10813 */
10814 acf.showSpinner = function ($spinner) {
10815 $spinner.addClass('is-active'); // add class (WP > 4.2)
10816 $spinner.css('display', 'inline-block'); // css (WP < 4.2)
10817 return $spinner;
10818 };
10819
10820 /**
10821 * acf.hideSpinner
10822 *
10823 * Hides the spinner element.
10824 *
10825 * @date 4/9/18
10826 * @since ACF 5.7.5
10827 *
10828 * @param jQuery $spinner The spinner element.
10829 * @return jQuery
10830 */
10831 acf.hideSpinner = function ($spinner) {
10832 $spinner.removeClass('is-active'); // add class (WP > 4.2)
10833 $spinner.css('display', 'none'); // css (WP < 4.2)
10834 return $spinner;
10835 };
10836
10837 /**
10838 * acf.lockForm
10839 *
10840 * Locks a form by disabeling its primary inputs and showing a spinner.
10841 *
10842 * @date 4/9/18
10843 * @since ACF 5.7.5
10844 *
10845 * @param jQuery $form The form element.
10846 * @return jQuery
10847 */
10848 acf.lockForm = function ($form) {
10849 // vars
10850 var $wrap = findSubmitWrap($form);
10851 var $submit = $wrap.find('.button, [type="submit"]').not('.acf-nav, .acf-repeater-add-row');
10852 var $spinner = $wrap.find('.spinner, .acf-spinner');
10853
10854 // hide all spinners (hides the preview spinner)
10855 acf.hideSpinner($spinner);
10856
10857 // lock
10858 acf.disableSubmit($submit);
10859 acf.showSpinner($spinner.last());
10860 return $form;
10861 };
10862
10863 /**
10864 * acf.unlockForm
10865 *
10866 * Unlocks a form by enabeling its primary inputs and hiding all spinners.
10867 *
10868 * @date 4/9/18
10869 * @since ACF 5.7.5
10870 *
10871 * @param jQuery $form The form element.
10872 * @return jQuery
10873 */
10874 acf.unlockForm = function ($form) {
10875 // vars
10876 var $wrap = findSubmitWrap($form);
10877 var $submit = $wrap.find('.button, [type="submit"]').not('.acf-nav, .acf-repeater-add-row');
10878 var $spinner = $wrap.find('.spinner, .acf-spinner');
10879
10880 // unlock
10881 acf.enableSubmit($submit);
10882 acf.hideSpinner($spinner);
10883 return $form;
10884 };
10885
10886 /**
10887 * findSubmitWrap
10888 *
10889 * An internal function to find the 'primary' form submit wrapping element.
10890 *
10891 * @date 4/9/18
10892 * @since ACF 5.7.5
10893 *
10894 * @param jQuery $form The form element.
10895 * @return jQuery
10896 */
10897 var findSubmitWrap = function ($form) {
10898 // default post submit div
10899 var $wrap = $form.find('#submitdiv');
10900 if ($wrap.length) {
10901 return $wrap;
10902 }
10903
10904 // 3rd party publish box
10905 var $wrap = $form.find('#submitpost');
10906 if ($wrap.length) {
10907 return $wrap;
10908 }
10909
10910 // term, user
10911 var $wrap = $form.find('p.submit').last();
10912 if ($wrap.length) {
10913 return $wrap;
10914 }
10915
10916 // front end form
10917 var $wrap = $form.find('.acf-form-submit');
10918 if ($wrap.length) {
10919 return $wrap;
10920 }
10921
10922 // ACF 6.2 options page modal
10923 var $wrap = $('#acf-create-options-page-form .acf-actions');
10924 if ($wrap.length) {
10925 return $wrap;
10926 }
10927
10928 // ACF 6.0+ headerbar submit
10929 var $wrap = $('.acf-headerbar-actions');
10930 if ($wrap.length) {
10931 return $wrap;
10932 }
10933
10934 // default
10935 return $form;
10936 };
10937
10938 /**
10939 * A debounced function to trigger a form submission.
10940 *
10941 * @date 15/07/2020
10942 * @since ACF 5.9.0
10943 *
10944 * @param type Var Description.
10945 * @return type Description.
10946 */
10947 var submitFormDebounced = acf.debounce(function ($form) {
10948 $form.submit();
10949 });
10950
10951 /**
10952 * Ensure field is visible for validation errors
10953 *
10954 * @date 20/10/2021
10955 * @since ACF 5.11.0
10956 */
10957 var ensureFieldPostBoxIsVisible = function ($el) {
10958 // Find the postbox element containing this field.
10959 var $postbox = $el.parents('.acf-postbox');
10960 if ($postbox.length) {
10961 var acf_postbox = acf.getPostbox($postbox);
10962 if (acf_postbox && acf_postbox.isHiddenByScreenOptions()) {
10963 // Rather than using .show() here, we don't want the field to appear next reload.
10964 // So just temporarily show the field group so validation can complete.
10965 acf_postbox.$el.removeClass('hide-if-js');
10966 acf_postbox.$el.css('display', '');
10967 }
10968 }
10969 };
10970
10971 /**
10972 * Ensure metaboxes which contain browser validation failures are visible.
10973 *
10974 * @date 20/10/2021
10975 * @since ACF 5.11.0
10976 */
10977 var ensureInvalidFieldVisibility = function () {
10978 // Load each ACF input field and check it's browser validation state.
10979 var $inputs = $('.acf-field input');
10980 $inputs.each(function () {
10981 if (!this.checkValidity()) {
10982 // Field is invalid, so we need to make sure it's metabox is visible.
10983 ensureFieldPostBoxIsVisible($(this));
10984 }
10985 });
10986 };
10987
10988 /**
10989 * acf.validation
10990 *
10991 * Global validation logic
10992 *
10993 * @date 4/4/18
10994 * @since ACF 5.6.9
10995 *
10996 * @param void
10997 * @return void
10998 */
10999
11000 acf.validation = new acf.Model({
11001 /** @var string The model identifier. */
11002 id: 'validation',
11003 /** @var bool The active state. Set to false before 'prepare' to prevent validation. */
11004 active: true,
11005 /** @var string The model initialize time. */
11006 wait: 'prepare',
11007 /** @var object The model actions. */
11008 actions: {
11009 ready: 'addInputEvents',
11010 append: 'addInputEvents'
11011 },
11012 /** @var object The model events. */
11013 events: {
11014 'click input[type="submit"]': 'onClickSubmit',
11015 'click button[type="submit"]': 'onClickSubmit',
11016 'click #save-post': 'onClickSave',
11017 'submit form#post': 'onSubmitPost',
11018 'submit form': 'onSubmit'
11019 },
11020 /**
11021 * initialize
11022 *
11023 * Called when initializing the model.
11024 *
11025 * @date 4/9/18
11026 * @since ACF 5.7.5
11027 *
11028 * @param void
11029 * @return void
11030 */
11031 initialize: function () {
11032 // check 'validation' setting
11033 if (!acf.get('validation')) {
11034 this.active = false;
11035 this.actions = {};
11036 this.events = {};
11037 }
11038 },
11039 /**
11040 * enable
11041 *
11042 * Enables validation.
11043 *
11044 * @date 4/9/18
11045 * @since ACF 5.7.5
11046 *
11047 * @param void
11048 * @return void
11049 */
11050 enable: function () {
11051 this.active = true;
11052 },
11053 /**
11054 * disable
11055 *
11056 * Disables validation.
11057 *
11058 * @date 4/9/18
11059 * @since ACF 5.7.5
11060 *
11061 * @param void
11062 * @return void
11063 */
11064 disable: function () {
11065 this.active = false;
11066 },
11067 /**
11068 * reset
11069 *
11070 * Rests the form validation to be used again
11071 *
11072 * @date 6/9/18
11073 * @since ACF 5.7.5
11074 *
11075 * @param jQuery $form The form element.
11076 * @return void
11077 */
11078 reset: function ($form) {
11079 getValidator($form).reset();
11080 },
11081 /**
11082 * addInputEvents
11083 *
11084 * Adds 'invalid' event listeners to HTML inputs.
11085 *
11086 * @date 4/9/18
11087 * @since ACF 5.7.5
11088 *
11089 * @param jQuery $el The element being added / readied.
11090 * @return void
11091 */
11092 addInputEvents: function ($el) {
11093 // Bug exists in Safari where custom "invalid" handling prevents draft from saving.
11094 if (acf.get('browser') === 'safari') return;
11095
11096 // vars
11097 var $inputs = $('.acf-field [name]', $el);
11098
11099 // check
11100 if ($inputs.length) {
11101 this.on($inputs, 'invalid', 'onInvalid');
11102 }
11103 },
11104 /**
11105 * onInvalid
11106 *
11107 * Callback for the 'invalid' event.
11108 *
11109 * @date 4/9/18
11110 * @since ACF 5.7.5
11111 *
11112 * @param object e The event object.
11113 * @param jQuery $el The input element.
11114 * @return void
11115 */
11116 onInvalid: function (e, $el) {
11117 // prevent default
11118 // - prevents browser error message
11119 // - also fixes chrome bug where 'hidden-by-tab' field throws focus error
11120 e.preventDefault();
11121
11122 // vars
11123 var $form = $el.closest('form');
11124
11125 // check form exists
11126 if ($form.length) {
11127 // add error to validator
11128 getValidator($form).addError({
11129 input: $el.attr('name'),
11130 message: acf.strEscape(e.target.validationMessage)
11131 });
11132
11133 // trigger submit on $form
11134 // - allows for "save", "preview" and "publish" to work
11135 submitFormDebounced($form);
11136 }
11137 },
11138 /**
11139 * onClickSubmit
11140 *
11141 * Callback when clicking submit.
11142 *
11143 * @date 4/9/18
11144 * @since ACF 5.7.5
11145 *
11146 * @param object e The event object.
11147 * @param jQuery $el The input element.
11148 * @return void
11149 */
11150 onClickSubmit: function (e, $el) {
11151 // Some browsers (safari) force their browser validation before our AJAX validation,
11152 // so we need to make sure fields are visible earlier than showErrors()
11153 ensureInvalidFieldVisibility();
11154
11155 // store the "click event" for later use in this.onSubmit()
11156 this.set('originalEvent', e);
11157 },
11158 /**
11159 * onClickSave
11160 *
11161 * Set ignore to true when saving a draft.
11162 *
11163 * @date 4/9/18
11164 * @since ACF 5.7.5
11165 *
11166 * @param object e The event object.
11167 * @param jQuery $el The input element.
11168 * @return void
11169 */
11170 onClickSave: function (e, $el) {
11171 this.set('ignore', true);
11172 },
11173 /**
11174 * onSubmitPost
11175 *
11176 * Callback when the 'post' form is submit.
11177 *
11178 * @date 5/3/19
11179 * @since ACF 5.7.13
11180 *
11181 * @param object e The event object.
11182 * @param jQuery $el The input element.
11183 * @return void
11184 */
11185 onSubmitPost: function (e, $el) {
11186 // Check if is preview.
11187 if ($('input#wp-preview').val() === 'dopreview') {
11188 // Ignore validation.
11189 this.set('ignore', true);
11190
11191 // Unlock form to fix conflict with core "submit.edit-post" event causing all submit buttons to be disabled.
11192 acf.unlockForm($el);
11193 }
11194 },
11195 /**
11196 * onSubmit
11197 *
11198 * Callback when the form is submit.
11199 *
11200 * @date 4/9/18
11201 * @since ACF 5.7.5
11202 *
11203 * @param object e The event object.
11204 * @param jQuery $el The input element.
11205 * @return void
11206 */
11207 onSubmit: function (e, $el) {
11208 // Allow form to submit if...
11209 if (
11210 // Validation has been disabled.
11211 !this.active ||
11212 // Or this event is to be ignored.
11213 this.get('ignore') ||
11214 // Or this event has already been prevented.
11215 e.isDefaultPrevented()) {
11216 // Return early and call reset function.
11217 return this.allowSubmit();
11218 }
11219
11220 // Validate form.
11221 var valid = acf.validateForm({
11222 form: $el,
11223 event: this.get('originalEvent')
11224 });
11225
11226 // If not valid, stop event to prevent form submit.
11227 if (!valid) {
11228 e.preventDefault();
11229 }
11230 },
11231 /**
11232 * allowSubmit
11233 *
11234 * Resets data during onSubmit when the form is allowed to submit.
11235 *
11236 * @date 5/3/19
11237 * @since ACF 5.7.13
11238 *
11239 * @param void
11240 * @return void
11241 */
11242 allowSubmit: function () {
11243 // Reset "ignore" state.
11244 this.set('ignore', false);
11245
11246 // Reset "originalEvent" object.
11247 this.set('originalEvent', false);
11248
11249 // Return true
11250 return true;
11251 }
11252 });
11253 var gutenbergValidation = new acf.Model({
11254 wait: 'prepare',
11255 initialize: function () {
11256 // Bail early if not Gutenberg.
11257 if (!acf.isGutenberg()) {
11258 return;
11259 }
11260
11261 // Custommize the editor.
11262 this.customizeEditor();
11263 },
11264 customizeEditor: function () {
11265 // Extract vars.
11266 var editor = wp.data.dispatch('core/editor');
11267 var editorSelect = wp.data.select('core/editor');
11268 var notices = wp.data.dispatch('core/notices');
11269
11270 // Backup original method.
11271 var savePost = editor.savePost;
11272
11273 // Listen for changes to post status and perform actions:
11274 // a) Enable validation for "publish" action.
11275 // b) Remember last non "publish" status used for restoring after validation fail.
11276 var useValidation = false;
11277 var lastPostStatus = '';
11278 wp.data.subscribe(function () {
11279 var postStatus = editorSelect.getEditedPostAttribute('status');
11280 useValidation = postStatus === 'publish' || postStatus === 'future';
11281 lastPostStatus = postStatus !== 'publish' ? postStatus : lastPostStatus;
11282 });
11283
11284 // Create validation version.
11285 editor.savePost = function (options) {
11286 options = options || {};
11287
11288 // Backup vars.
11289 var _this = this;
11290 var _args = arguments;
11291
11292 // Perform validation within a Promise.
11293 return new Promise(function (resolve, reject) {
11294 // Bail early if is autosave or preview.
11295 if (options.isAutosave || options.isPreview) {
11296 return resolve('Validation ignored (autosave).');
11297 }
11298
11299 // Bail early if validation is not needed.
11300 if (!useValidation) {
11301 return resolve('Validation ignored (draft).');
11302 }
11303
11304 // Check if we've currently got an ACF block selected which is failing validation, but might not be presented yet.
11305 if ('undefined' !== typeof acf.blockInstances) {
11306 const selectedBlockId = wp.data.select('core/block-editor').getSelectedBlockClientId();
11307 if (selectedBlockId && selectedBlockId in acf.blockInstances) {
11308 const acfBlockState = acf.blockInstances[selectedBlockId];
11309 if (acfBlockState.validation_errors) {
11310 // Deselect the block to show the error and lock the save.
11311 acf.debug('Rejecting save because the block editor has a invalid ACF block selected.');
11312 notices.createErrorNotice(acf.__('An ACF Block on this page requires attention before you can save.'), {
11313 id: 'acf-validation',
11314 isDismissible: true
11315 });
11316 wp.data.dispatch('core/editor').lockPostSaving('acf/block/' + selectedBlockId);
11317 wp.data.dispatch('core/block-editor').selectBlock(false);
11318 return reject('ACF Validation failed for selected block.');
11319 }
11320 }
11321 }
11322
11323 // Validate the editor form.
11324 var valid = acf.validateForm({
11325 form: $('#editor'),
11326 reset: true,
11327 complete: function ($form, validator) {
11328 // Always unlock the form after AJAX.
11329 editor.unlockPostSaving('acf');
11330 },
11331 failure: function ($form, validator) {
11332 // Get validation error and append to Gutenberg notices.
11333 var notice = validator.get('notice');
11334 notices.createErrorNotice(notice.get('text'), {
11335 id: 'acf-validation',
11336 isDismissible: true
11337 });
11338 notice.remove();
11339
11340 // Restore last non "publish" status.
11341 if (lastPostStatus) {
11342 editor.editPost({
11343 status: lastPostStatus
11344 });
11345 }
11346
11347 // Rejext promise and prevent savePost().
11348 reject('Validation failed.');
11349 },
11350 success: function () {
11351 notices.removeNotice('acf-validation');
11352
11353 // Resolve promise and allow savePost().
11354 resolve('Validation success.');
11355 }
11356 });
11357
11358 // Resolve promise and allow savePost() if no validation is needed.
11359 if (valid) {
11360 resolve('Validation bypassed.');
11361
11362 // Otherwise, lock the form and wait for AJAX response.
11363 } else {
11364 editor.lockPostSaving('acf');
11365 }
11366 }).then(function () {
11367 return savePost.apply(_this, _args);
11368 }, err => {
11369 // Nothing to do here, user is alerted of validation issues.
11370 });
11371 };
11372 }
11373 });
11374 })(jQuery);
11375
11376 /***/ })
11377
11378 /******/ });
11379 /************************************************************************/
11380 /******/ // The module cache
11381 /******/ var __webpack_module_cache__ = {};
11382 /******/
11383 /******/ // The require function
11384 /******/ function __webpack_require__(moduleId) {
11385 /******/ // Check if module is in cache
11386 /******/ var cachedModule = __webpack_module_cache__[moduleId];
11387 /******/ if (cachedModule !== undefined) {
11388 /******/ return cachedModule.exports;
11389 /******/ }
11390 /******/ // Create a new module (and put it into the cache)
11391 /******/ var module = __webpack_module_cache__[moduleId] = {
11392 /******/ // no module.id needed
11393 /******/ // no module.loaded needed
11394 /******/ exports: {}
11395 /******/ };
11396 /******/
11397 /******/ // Execute the module function
11398 /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
11399 /******/
11400 /******/ // Return the exports of the module
11401 /******/ return module.exports;
11402 /******/ }
11403 /******/
11404 /************************************************************************/
11405 /******/ /* webpack/runtime/compat get default export */
11406 /******/ (() => {
11407 /******/ // getDefaultExport function for compatibility with non-harmony modules
11408 /******/ __webpack_require__.n = (module) => {
11409 /******/ var getter = module && module.__esModule ?
11410 /******/ () => (module['default']) :
11411 /******/ () => (module);
11412 /******/ __webpack_require__.d(getter, { a: getter });
11413 /******/ return getter;
11414 /******/ };
11415 /******/ })();
11416 /******/
11417 /******/ /* webpack/runtime/define property getters */
11418 /******/ (() => {
11419 /******/ // define getter functions for harmony exports
11420 /******/ __webpack_require__.d = (exports, definition) => {
11421 /******/ for(var key in definition) {
11422 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
11423 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
11424 /******/ }
11425 /******/ }
11426 /******/ };
11427 /******/ })();
11428 /******/
11429 /******/ /* webpack/runtime/hasOwnProperty shorthand */
11430 /******/ (() => {
11431 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
11432 /******/ })();
11433 /******/
11434 /******/ /* webpack/runtime/make namespace object */
11435 /******/ (() => {
11436 /******/ // define __esModule on exports
11437 /******/ __webpack_require__.r = (exports) => {
11438 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
11439 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
11440 /******/ }
11441 /******/ Object.defineProperty(exports, '__esModule', { value: true });
11442 /******/ };
11443 /******/ })();
11444 /******/
11445 /************************************************************************/
11446 var __webpack_exports__ = {};
11447 // This entry need to be wrapped in an IIFE because it need to be in strict mode.
11448 (() => {
11449 "use strict";
11450 /*!************************************!*\
11451 !*** ./assets/src/js/acf-input.js ***!
11452 \************************************/
11453 __webpack_require__.r(__webpack_exports__);
11454 /* harmony import */ var _acf_field_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_acf-field.js */ "./assets/src/js/_acf-field.js");
11455 /* harmony import */ var _acf_field_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_acf_field_js__WEBPACK_IMPORTED_MODULE_0__);
11456 /* harmony import */ var _acf_fields_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_acf-fields.js */ "./assets/src/js/_acf-fields.js");
11457 /* harmony import */ var _acf_fields_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_acf_fields_js__WEBPACK_IMPORTED_MODULE_1__);
11458 /* harmony import */ var _acf_field_accordion_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_acf-field-accordion.js */ "./assets/src/js/_acf-field-accordion.js");
11459 /* harmony import */ var _acf_field_accordion_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_acf_field_accordion_js__WEBPACK_IMPORTED_MODULE_2__);
11460 /* 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");
11461 /* harmony import */ var _acf_field_button_group_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_acf_field_button_group_js__WEBPACK_IMPORTED_MODULE_3__);
11462 /* harmony import */ var _acf_field_checkbox_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./_acf-field-checkbox.js */ "./assets/src/js/_acf-field-checkbox.js");
11463 /* harmony import */ var _acf_field_checkbox_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_acf_field_checkbox_js__WEBPACK_IMPORTED_MODULE_4__);
11464 /* 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");
11465 /* 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__);
11466 /* 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");
11467 /* 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__);
11468 /* 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");
11469 /* 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__);
11470 /* 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");
11471 /* 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__);
11472 /* 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");
11473 /* 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__);
11474 /* harmony import */ var _acf_field_image_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./_acf-field-image.js */ "./assets/src/js/_acf-field-image.js");
11475 /* harmony import */ var _acf_field_image_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(_acf_field_image_js__WEBPACK_IMPORTED_MODULE_10__);
11476 /* harmony import */ var _acf_field_file_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./_acf-field-file.js */ "./assets/src/js/_acf-field-file.js");
11477 /* harmony import */ var _acf_field_file_js__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(_acf_field_file_js__WEBPACK_IMPORTED_MODULE_11__);
11478 /* harmony import */ var _acf_field_link_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./_acf-field-link.js */ "./assets/src/js/_acf-field-link.js");
11479 /* harmony import */ var _acf_field_link_js__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(_acf_field_link_js__WEBPACK_IMPORTED_MODULE_12__);
11480 /* harmony import */ var _acf_field_oembed_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./_acf-field-oembed.js */ "./assets/src/js/_acf-field-oembed.js");
11481 /* harmony import */ var _acf_field_oembed_js__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(_acf_field_oembed_js__WEBPACK_IMPORTED_MODULE_13__);
11482 /* harmony import */ var _acf_field_radio_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./_acf-field-radio.js */ "./assets/src/js/_acf-field-radio.js");
11483 /* harmony import */ var _acf_field_radio_js__WEBPACK_IMPORTED_MODULE_14___default = /*#__PURE__*/__webpack_require__.n(_acf_field_radio_js__WEBPACK_IMPORTED_MODULE_14__);
11484 /* harmony import */ var _acf_field_range_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./_acf-field-range.js */ "./assets/src/js/_acf-field-range.js");
11485 /* harmony import */ var _acf_field_range_js__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(_acf_field_range_js__WEBPACK_IMPORTED_MODULE_15__);
11486 /* harmony import */ var _acf_field_relationship_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./_acf-field-relationship.js */ "./assets/src/js/_acf-field-relationship.js");
11487 /* harmony import */ var _acf_field_relationship_js__WEBPACK_IMPORTED_MODULE_16___default = /*#__PURE__*/__webpack_require__.n(_acf_field_relationship_js__WEBPACK_IMPORTED_MODULE_16__);
11488 /* harmony import */ var _acf_field_select_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./_acf-field-select.js */ "./assets/src/js/_acf-field-select.js");
11489 /* harmony import */ var _acf_field_select_js__WEBPACK_IMPORTED_MODULE_17___default = /*#__PURE__*/__webpack_require__.n(_acf_field_select_js__WEBPACK_IMPORTED_MODULE_17__);
11490 /* harmony import */ var _acf_field_tab_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./_acf-field-tab.js */ "./assets/src/js/_acf-field-tab.js");
11491 /* harmony import */ var _acf_field_tab_js__WEBPACK_IMPORTED_MODULE_18___default = /*#__PURE__*/__webpack_require__.n(_acf_field_tab_js__WEBPACK_IMPORTED_MODULE_18__);
11492 /* 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");
11493 /* 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__);
11494 /* 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");
11495 /* 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__);
11496 /* harmony import */ var _acf_field_user_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./_acf-field-user.js */ "./assets/src/js/_acf-field-user.js");
11497 /* harmony import */ var _acf_field_user_js__WEBPACK_IMPORTED_MODULE_21___default = /*#__PURE__*/__webpack_require__.n(_acf_field_user_js__WEBPACK_IMPORTED_MODULE_21__);
11498 /* harmony import */ var _acf_field_taxonomy_js__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./_acf-field-taxonomy.js */ "./assets/src/js/_acf-field-taxonomy.js");
11499 /* harmony import */ var _acf_field_taxonomy_js__WEBPACK_IMPORTED_MODULE_22___default = /*#__PURE__*/__webpack_require__.n(_acf_field_taxonomy_js__WEBPACK_IMPORTED_MODULE_22__);
11500 /* 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");
11501 /* 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__);
11502 /* 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");
11503 /* 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__);
11504 /* harmony import */ var _acf_field_url_js__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./_acf-field-url.js */ "./assets/src/js/_acf-field-url.js");
11505 /* harmony import */ var _acf_field_url_js__WEBPACK_IMPORTED_MODULE_25___default = /*#__PURE__*/__webpack_require__.n(_acf_field_url_js__WEBPACK_IMPORTED_MODULE_25__);
11506 /* harmony import */ var _acf_field_wysiwyg_js__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./_acf-field-wysiwyg.js */ "./assets/src/js/_acf-field-wysiwyg.js");
11507 /* harmony import */ var _acf_field_wysiwyg_js__WEBPACK_IMPORTED_MODULE_26___default = /*#__PURE__*/__webpack_require__.n(_acf_field_wysiwyg_js__WEBPACK_IMPORTED_MODULE_26__);
11508 /* harmony import */ var _acf_condition_js__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./_acf-condition.js */ "./assets/src/js/_acf-condition.js");
11509 /* harmony import */ var _acf_condition_js__WEBPACK_IMPORTED_MODULE_27___default = /*#__PURE__*/__webpack_require__.n(_acf_condition_js__WEBPACK_IMPORTED_MODULE_27__);
11510 /* harmony import */ var _acf_conditions_js__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./_acf-conditions.js */ "./assets/src/js/_acf-conditions.js");
11511 /* harmony import */ var _acf_conditions_js__WEBPACK_IMPORTED_MODULE_28___default = /*#__PURE__*/__webpack_require__.n(_acf_conditions_js__WEBPACK_IMPORTED_MODULE_28__);
11512 /* harmony import */ var _acf_condition_types_js__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./_acf-condition-types.js */ "./assets/src/js/_acf-condition-types.js");
11513 /* harmony import */ var _acf_condition_types_js__WEBPACK_IMPORTED_MODULE_29___default = /*#__PURE__*/__webpack_require__.n(_acf_condition_types_js__WEBPACK_IMPORTED_MODULE_29__);
11514 /* harmony import */ var _acf_unload_js__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./_acf-unload.js */ "./assets/src/js/_acf-unload.js");
11515 /* harmony import */ var _acf_unload_js__WEBPACK_IMPORTED_MODULE_30___default = /*#__PURE__*/__webpack_require__.n(_acf_unload_js__WEBPACK_IMPORTED_MODULE_30__);
11516 /* harmony import */ var _acf_postbox_js__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./_acf-postbox.js */ "./assets/src/js/_acf-postbox.js");
11517 /* harmony import */ var _acf_postbox_js__WEBPACK_IMPORTED_MODULE_31___default = /*#__PURE__*/__webpack_require__.n(_acf_postbox_js__WEBPACK_IMPORTED_MODULE_31__);
11518 /* harmony import */ var _acf_media_js__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ./_acf-media.js */ "./assets/src/js/_acf-media.js");
11519 /* harmony import */ var _acf_media_js__WEBPACK_IMPORTED_MODULE_32___default = /*#__PURE__*/__webpack_require__.n(_acf_media_js__WEBPACK_IMPORTED_MODULE_32__);
11520 /* harmony import */ var _acf_screen_js__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ./_acf-screen.js */ "./assets/src/js/_acf-screen.js");
11521 /* harmony import */ var _acf_screen_js__WEBPACK_IMPORTED_MODULE_33___default = /*#__PURE__*/__webpack_require__.n(_acf_screen_js__WEBPACK_IMPORTED_MODULE_33__);
11522 /* harmony import */ var _acf_select2_js__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ./_acf-select2.js */ "./assets/src/js/_acf-select2.js");
11523 /* harmony import */ var _acf_select2_js__WEBPACK_IMPORTED_MODULE_34___default = /*#__PURE__*/__webpack_require__.n(_acf_select2_js__WEBPACK_IMPORTED_MODULE_34__);
11524 /* harmony import */ var _acf_tinymce_js__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./_acf-tinymce.js */ "./assets/src/js/_acf-tinymce.js");
11525 /* harmony import */ var _acf_tinymce_js__WEBPACK_IMPORTED_MODULE_35___default = /*#__PURE__*/__webpack_require__.n(_acf_tinymce_js__WEBPACK_IMPORTED_MODULE_35__);
11526 /* harmony import */ var _acf_validation_js__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ./_acf-validation.js */ "./assets/src/js/_acf-validation.js");
11527 /* harmony import */ var _acf_validation_js__WEBPACK_IMPORTED_MODULE_36___default = /*#__PURE__*/__webpack_require__.n(_acf_validation_js__WEBPACK_IMPORTED_MODULE_36__);
11528 /* harmony import */ var _acf_helpers_js__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./_acf-helpers.js */ "./assets/src/js/_acf-helpers.js");
11529 /* harmony import */ var _acf_helpers_js__WEBPACK_IMPORTED_MODULE_37___default = /*#__PURE__*/__webpack_require__.n(_acf_helpers_js__WEBPACK_IMPORTED_MODULE_37__);
11530 /* harmony import */ var _acf_compatibility_js__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ./_acf-compatibility.js */ "./assets/src/js/_acf-compatibility.js");
11531 /* harmony import */ var _acf_compatibility_js__WEBPACK_IMPORTED_MODULE_38___default = /*#__PURE__*/__webpack_require__.n(_acf_compatibility_js__WEBPACK_IMPORTED_MODULE_38__);
11532
11533
11534
11535
11536
11537
11538
11539
11540
11541
11542
11543
11544
11545
11546
11547
11548
11549
11550
11551
11552
11553
11554
11555
11556
11557
11558
11559
11560
11561
11562
11563
11564
11565
11566
11567
11568
11569
11570
11571 })();
11572
11573 /******/ })()
11574 ;
11575 //# sourceMappingURL=acf-input.js.map